Friday, December 29, 2006

Lost in Space

While using XmlSerializer in .NET 2.0, I found that spaces in my string values are lost during a round-trip of serialization and de-serialization. Looking at the serialized XML string, I can find that space is preserved during serialization. The XML looks like this:
<Text> </Text>


But after de-serialization the string variable Text only has value string.Empty. After a little research, I found that using the following code segment to de-serialize can avoid the above problem:

//variable xmlString contains the XML string to be de-serialized.
//varialbe result of type T is to be de-serialized from the string
T result;
XmlSerializer s = new XmlSerializer(typeof(T));
StringReader r = new StringReader(xmlString);
XmlReaderSettings settings = new XmlReaderSettings();
//white space are especially important for string types
//if "IgnoreWhitespace" is true, a string value equal to " "
//may be lost during serialization and deserialization.
//the line below is the key of this posting
settings.IgnoreWhitespace = false;
XmlReader reader = XmlReader.Create(r, settings);
result = (T)s.Deserialize(reader);


For comparison, below is my old de-serialization code that causes lost of space:

//variable xmlString contains the XML string to be de-serialized.
//varialbe result of type T is to be de-serialized from the string
T result;
XmlSerializer s = new XmlSerializer(typeof(T));
StringReader r = new StringReader(xmlString);
result = (T)s.Deserialize(r);

Tuesday, December 19, 2006

KB909095 Patch for Windows XP hibernate problem

Bought a new souped up computer or upgraded your computer recently. Did you notice that hibernate no longer works on your computer?

That is what happened to my new DELL Precision Laptop. I get a mysterious error message: "Insufficient System Resources Exist to Complete the API." Long story short, if your computer has more than 1 GB memory, Microsoft KB909095 is here for the rescue. Install it, the problem goes away instantly. Does not seem to have any side effects.

Friday, December 01, 2006

Bug in YUI 0.12.0 causing "secure and nonsecure items" warning in IE6

Just when I am about to have a rest after I happily cleared the "secure and nonsecure" warning in IE7. Today, I test my web application in IE6. I got the "secure and nonsecure" warning again.

Here come the nightmare again, having to test your application in X different browsers on Y different Operating Systems. You fumble to fix bugs for one specific platform and seeing your fixes screwed up totally in another platform.

Fortunately, this time, "I'm Feeling Lucky". I tried keyword "yui secure nonsecure" in google, and found an answer on the first page 3rd item, titled: "Bug in iframe shim code in 0.12.0 container.js?". It is only a one line change in container.js. But, I know it could take me a couple of days to narrow down to it. Thanks to Arun, it only took me 10 minutes to fix the problem this time.

Thursday, November 30, 2006

Loading Indicator in Animated GIF

http://www.ajaxload.info/
This web site provides more than 20 different styles for free (foreground and background colors are configurable).
  • Very easy to use.
  • Seems like no string attached.
  • Nice Graphics

Wednesday, November 29, 2006

IE7 Warning: "This page contains both secure and nonsecure items."

IE 7 come with much enhanced security features and tabbed viewing. But along with the enhancements, we (programmers) also see some new problems to work on. The one I will present below is especially hard, because it is not consistently repeatable.

Problem: serving page through HTTPS, IE7 shows the warning: "This page contains both secure and nonsecure items. Do you want to display the nonsecure items?".

According to past experience, there are 2 main reasons for this warning:
  1. There are content on the web page from non-secure source. You should remove any link to nonsecure content in order to get rid of this warning;
  2. An "IFrame" does not specify source, or specify "about:blank" as the source. IE consider this as nonsecure. You have to point the IFrame to "Javascript:false" to make IE happy;
But the one I am facing has a new twist: the warning does not show up consistently. If I refresh the page by pressing "F5", only 2 out of 10 times, I get the warning.

Findings:
After some painful experiments, I found that the the source of the problem came from my use of YUI panel. I added a background image to the panel like this:
<div class="bd" style="background-image: url(images/back.gif);">
</div>
Guess what, this combined with JavaScript in YUI constitutes the new offense for IE7. According to MSDN Knowledge Base, Article 925014 , using "removeChild()" method to delete a DIV element that references a background image is considered "nonsecure itme". I suppose somewhere in YUI library my DIV is detached and wrapped into something else than attached to the HTML document again.

Solution:
There are 2 workarounds recommended in MSDN KB 925014. The second method meets my need very well. I just moved the specification of background image to CSS. This seems to solve the problem.


More:
It still puzzles me, as why this warning only appears 2 out of 10 times. Following "Workaround" in the article did fix the warning permanently.

Although I finally fixed the problem. I wish IE7 could have provided a little more hint in why it complains about the nonsecure content or the source of the nonsecure content. Better yet, IE7 should give developer's a way to see the rendered HTML content. As far as I know, the only thing I can do is to remove elements on my page one by one, until the warning is gone.

Reference:
MSDN KB 925014 http://support.microsoft.com/kb/925014

Friday, March 24, 2006

A Welcoming Breaking-Change in .Net Framework 2.0

Finally, after a few years waiting, Microsoft admits its implementation of DateTime serialization in web service is flawed, and made a breaking change to it. See the last item on this page: http://msdn.microsoft.com/netframework/programming/breakingchanges/runtime/xmlserial.aspx

In one sentence, under the old framework, only local time can be transmitted correctly by web service. If you save UTC time in database, and try to transmit using web service, bad luck. You will have to convert all the time in to your web server's local time, then send it out. And, on the other end, the receiving computer will have to convert again the date time to UTC time. And, under the hood the web server and receiving computer both did some conversion during XML serialization and de-serialization too. That is about 4 times CPU time wasted on the conversion that leads you back to where you started!!! Even worse, this behavior is not well documented in MSDN, and causes big confusion for developers.

I had to send an internal memo to all developers in my company to raise the awarness of this issue back in 2004. Really glad it finally gets attention and being resolved.

srand() and threads in MFC

This is an old problem I only run into recently: You should call srand() for each and every thread that calls rand().

In its multi-thread version, the CRT implemenation in VC++6.0 will save seed to thread local storage. So, it is necessary to seed the rand() function in every new thread your program created. Otherwise, the random number sequence is same as if seeded by 1. This poses 2 serious questions:
  1. How can I write a class that is thread safe, and caller won't have to worry about calling srand() whenever they create a new thread? I do not have a solution yet. The best I can think of is to ask callers, when not sure, always call srand() whenever a new thread is created;
  2. A second question is what if user creates multiple threads in a batch, this will make the recommended intialization code: srand( (unsigned) time(NULL)); fail, because the threads are created within 1 second, and you will get the same sequence in all your threads. After some searching, I found this discussion thread to be quite helpful: It proposed to multiply time by the thread ID to seed rand().

Using Transition Channel in Macromedia Director

I tried the transition channel in Macromedia Director MX 2004 recently. It
turns out to be quite tricky to use it correctly. At first, I just double clicked
in the score and selected a transition effect. And it works immediately. What
a relief, it is as easy as PowerPoint. Soon, I realized that I was wrong.

The first problems showed up after I tried to add some Lingo scripts to the
frame with transition effect.

First, I want the movie to loop on the frame until user clicks some
button. I find that the movie becomes extremely slow on this frame, and the movie takes about
50% CPU time. Then, in the "Using Director" online help, I found this
warning:
  • Avoid looping on a frame that contains a transition. Playing a transition continuously
    might cause performance issues.
So, I have made a well-documented mistake here. That is the first
tricky issue I have with transition channel.

However, it took me longer than it should be to fingure out the above problem, because
I used the "Dissolve Patterns" transition effect. It won't show any visual changes
when I am looping the frame, although it still takes 50% CPU time to calculate
the transition effect. This fooled me into believing it only did the transition
once and stopped, and was not suspecious of the transition being the source
of performance problem on that frame. If I had used the "Cover Up"
transition, I should have seen the screen repeatedly rolling up, and discover
the problem in the first test run.

The second issue appears when I am trying to add a sprite to show me the current
frame number. I first added a text
member to the lower left corner of the stage like this:



Then I added this behavior to the
sprite:

on prepareFrame me
frameString = "" && _movie.frame
if(frameString <> member("FrameNumber").text) then
member("FrameNumber").text = frameString
end if
end

Again, the transition stopped working, the screen just freeze for 2 seconds (the default
duration used by the transition) then move on. I have not found any document
about this problem yet. But, my investigation showed that the offending code
is the highlighted line above. If I run the same code in enterFrame event handler, it won't be a problem. Or if I remove the line from prepareFrame handler, the transition will showup normally. I am not sure why is this a problem. For now, I will just avoid doing anything like this on a transition frame.

The lessons:

  1. Never loop on a frame that contains a transition;

  2. Do not change a text member's text property in "prepareFrame"
    event of the transition frame (there may be a more general description about this problem);

Tuesday, February 07, 2006

Permission of "Network Configuration Operators" group

The permission for the "Network Configuration Operators" group is documented in Microsoft's knowledge base 297938.
But, there is no language specifically about wireless network configuration
in the KB. So I set out to do a little test. It turns out "Network Configuration Operators" can:

  • Disable, enable wireless adapter and configure wireless connection properties.

  • Change IP filter setting of TCP/IP protocol.


But, can NOT: change firewall settings.


For the sake of completeness, I include Microsoft's list below.


  • Modify the Transmission Control Protocol/Internet Protocol (TCP/IP) properties
    for a local area network (LAN) connection, which includes the IP address,
    the subnet mask, the default gateway, and the name servers.

  • Rename the LAN connections or remote access connections that are available
    to all of the users.

  • Enable or disable a LAN connection.

  • Modify the properties of all of the remote access connections of the user.

  • Delete all of the remote access connections of the user.

  • Rename all of the remote access connections of the user.

  • Issue ipconfig, release, or renew commands.

Wednesday, January 25, 2006

HTML Validator (Firefox Extension)

Recently, I discovered this tool. And it soon becomes the "must-have" tool for me. I develop web pages using ASP.NET. I always call HtmlEncode function before I insert any text from database to web page. But, there is one problem this function call won't solve. And I didn't notice this problem until I used the "HTML Validator" tool to inspect all the web pages I created.

In this case, I grabbed a piece of text from database and inserted it into the web page as tooltip. I called HtmlEncode function before inserting the text to the "title" attribute. Guess what, I forgot one thing: replace the single quote "'"! So, HTML like this can be generated.
<span title="'blogger's">space<font>

Of course it is wrong. You will only see this tooltip: "blogger". But, no web browsers have complained about this. And no users complained about this (well, they just don't know what they should see). I bet it won't be noticed by anybody not for this wonderful extension.

Link to this extension:
https://addons.mozilla.org/extensions/moreinfo.php?id=249&application=firefox

Tuesday, January 17, 2006

FlashBlock (Firefox extension)

I only have 3 Firefox extensions installed. FlashBlock is one of them.

Pros: It replaces flash animation with a button which user can click to start the flash content. Since 99% of flash contents on the web are Ads that just distract your attention from reading and slow down the CPU, this extension is a big saver. It also has a white list option to allow some customization.

Cons: Uninstall is not as easy as install. There are other known problems.

Thursday, January 12, 2006

Dialog Data Validation for MFC

Problem: Data validation in MFC is a bit difficult. We only get
a couple of DDV functions that left a lot to be desired. For example, there is
no easy way to make sure a “Dropdown Combo Box” is not empty.


Solution: After some searching in MSDN documents and
googling, I cannot find a good clean solution. But, I am inspired by the MFC
source code and found the following solution.


In the "DoDataExchange" function of your dialog, you only need to add a few
lines of code (highlighted below) to validate an empty combo box.
Following this logic, you can easily add more sophiscate validation logic, and
make sure the focus will be set to the control that you want user to change.


void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
CMyDlg::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTaskMTTPage)
DDX_CBString(pDX, IDC_COMBOFILENAME, m_strFilename);
//}}AFX_DATA_MAP

//customized data verification
if(pDX->m_bSaveAndValidate)
{
//we will only check data during validation
if(m_strFilename.IsEmpty())
{
CString errorMessage = "The file name field cannot be empty.";
AfxMessageBox(errorMessage, MB_ICONEXCLAMATION);
errorMessage.Empty();

pDX->PrepareCtrl(IDC_COMBOFILENAME); //make sure pDX will focus to this control
pDX->Fail();
}
}

}

Extra: In the process of searching for the solution mentioned
above, I found this interesting problem: VC7 and VC98 have slightly different
definition of public members of CDataExchange class (notice the highlighted
code segment below). Why should Microsoft change definition of public member of
their library? Isn't public member supposed to be some sort of binding
contract?


Another interesting discovery is that Visual Studio intell-sense won't show "m_hWndLastControl"
although it is public member of the class. Did I miss something here?


Why do I care about this obscure member of CDataExchange? Well, I
am trying to find a way to make sure the dialog will set focus on the correct
control after an error condition occurs. My first intent was to manipulate the
m_hWndLastControl
or m_idLastControl member, thus lead
to the discovery. Eventually, I found out calling function PrepareCtrl
is a much better solution.


Definition of class CDataExchange in VC98 include:

// CDataExchange - for data exchange and validation
class CDataExchange
{
// Attributes
public:
BOOL m_bSaveAndValidate; // TRUE => save and validate data
CWnd* m_pDlgWnd; // container usually a dialog

// Operations (for implementors of DDX and DDV procs)
HWND PrepareCtrl(int nIDC); // return HWND of control
HWND PrepareEditCtrl(int nIDC); // return HWND of control
void Fail(); // will throw exception

#ifndef _AFX_NO_OCC_SUPPORT
CWnd* PrepareOleCtrl(int nIDC); // for OLE controls in dialog
#endif

// Implementation
CDataExchange(CWnd* pDlgWnd, BOOL bSaveAndValidate);

HWND m_hWndLastControl; // last control used (for validation)
BOOL m_bEditLastControl; // last control was an edit item
};


Definition of class CDataExchange in VC7 include:

// CDataExchange - for data exchange and validation
class CDataExchange
{
// Attributes
public:
BOOL m_bSaveAndValidate; // TRUE => save and validate data
CWnd* m_pDlgWnd; // container usually a dialog

// Operations (for implementors of DDX and DDV procs)
HWND PrepareCtrl(int nIDC);
HWND PrepareEditCtrl(int nIDC);
void Fail(); // will throw exception

CDataExchange(CWnd* pDlgWnd, BOOL bSaveAndValidate);

#ifndef _AFX_NO_OCC_SUPPORT
COleControlSite* PrepareOleCtrl(int nIDC); // for OLE controls in dialog
#endif

// Implementation
UINT m_idLastControl; // last control used (for validation)
BOOL m_bEditLastControl; // last control was an edit item
};