Problems with UNICODE files and chinese characters

I was working on a XML parser that we had written some time back. We used Microsoft’s SAX (Simple API’s for XML) for parsing the xml. Here is a very useful and elaborate SAX tutorial. All was working fine until a few XML files with Chinese characters showed up. Well, basically the program revolved around:



–> Parse the input xml

–> do something with the parsed data

–> and create an output xml



The ouput XML, of course, depended on the data we parsed in step 2. The problem was that when the input XML contained chinese characters, our output XML would contain boxes! And this immediately reminded me of this post by Joel Spolsky. I checked the code and found what was wrong. I was reading the data into WCHAR from the input XML and while writing the data I converted it to a multi-byte string using wcstombs. Which obviously was incorrect. When the API tried to convert the chinese characters into multi-byte it went nuts! So I went ahead and changed the code, the changed code looked something like this:



WCHAR buffer[MAX_BUFF_SIZE] = L"";

WCHAR temp;

DWORD bytesWritten = -1, bytesRead = -1;



int counter = 0;



do

{
    //Read from the file and store in buffer

    if(ReadFile(hInputFile, temp, sizeof(temp), &bytesRead, NULL))

    {

        buffer[counter++] = temp;



        if(temp == L’\n’)

        {

            //got a line, do something with it

            ..

            ..

            WriteFile(hOutputFile, buffer, counter, &bytesWritten, NULL);


            //reset the counter for the next line

            counter = 0;

        }

    }



}while (bytesRead > 0);



After this I saw that a lot of things were missing in the output file! You can see the problem at first glance can’t you? The variable counter keeps track of the number of WCHAR characters, each of which is 2 bytes wide. In the call  to WriteFile(), the counter parameter specifies the number of bytes to write, so only half the data was getting written. The write file call should really have been:



WriteFile(hOutputFile, buffer, counter*sizeof(buffer[0]), &bytesWritten, NULL);



That fixed it. But there was still a problem, I was still getting boxes. What else could be wrong now! So I binged around a little and found out that the first two bytes in a unicode file must always be 0xFF 0xFE. Joel mentions this in his post on encoding schemes. The problem is that without the 0xFF 0xFE the text editor thought that it was a normal text file encoded in ANSI or something. Basically making the editor to process every byte of the data as an ANSI character and that turned all zeroes into boxes. 0xFF 0xFE told the editors to process them as UNICODE encoded files, thus making them interpret every two bytes of the file. I wrote the two bytes into the output file before writing anything else into it and it worked. The chinese characters showed correctly in the output file.

Why would the controls not show up!

A colleague of mine had a strange problem today. He had written a small UI application for a Windows Mobile Professional device with many controls. The controls contained several check boxes, text boxes, labels and buttons. When he ran the dialog using the "Run Dialog" option in Visual Studio, it showed up correctly and when the program ran on the device a strange thing happened. Some of the controls would show up and others would not.

It wasn’t random, the same set of controls showed up every time and others didn’t. The UI was divided into three sections each contained within a group box. I could imagine how strange he must have thought it to be. But it had already happened to me before. And when he asked me for help, I couldn’t help a smile (: If you had read this post carefully enough, you would have noticed a small remark on the group box that I had made. "Add these three static controls into a group box, name the group box "Process Info". Remember to create the three static text controls before creating the group box. I was trying the other way around, by creating the group box first, the text controls would not show up, they were hidden behind the group box." And that was the exact problem in this case too. He had added controls to the UI in a particular order, or rather, in no particular order. So all the controls added before the group box showed up correctly and others didn’t.



Update:

As Gato pointed out, this problem occurs because of the Tab order (also called z-order) of the individual controls. See the ‘Comments’ section below.

Lets do some graphics: DirectDraw, Part 1

I always wanted to do stuff with DirectDraw. And when I saw the iPhone UI the urge intensified. But somehow the topic seemed esoteric to me and eluded me for quite some time, or, to put it in other words, laziness won over me (:



Anyways, I was going through the Donuts sample game provided by Microsoft which comes with Win Mob 6 Professional SDK installation. Here is the path:



<InstallDir>\Samples\PocketPC\CPP\win32\directx\DDraw\Donuts2



It seemed a bit too complicated for a first timer and truly I was a held back a little. So I decided to go through some tutorials first  and stop trying to be superman (: This post is what I found. Its quite old and pretty basic but gives you good understanding of what things are and where they stand. Donuts started to make a little sense now (:



The post mentioned about a few samples like DDEX1, DDEX2 etc. and I saw that these were present in the same SDK directory. I was happy to have found a step by step tutorial for DirectDraw. But when I built and tried to run the samples on the emulator the applications failed with a message box saying "This device does not support backbuffers". Of course, you don’t have to be Einstein to figure that the emulator doesn’t support back buffers. Donuts was the only application that ran ): So I got back looking at Donuts’ code. I saw that they were handling the absense of a back buffer intelligently. They got the capabilities of the device:



    lpDD->lpVtbl->GetCaps(lpDD, &ddCaps, &ddHelCaps);



    if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER) || !(ddCaps.ddsCaps.dwCaps & DDSCAPS_FLIP))

    {

        bSingleBuffer = TRUE;

    }



and depending on whether the device supported back buffers or not created other appropriate buffers/surfaces



    // Create surfaces

    memset( &ddsd, 0, sizeof( ddsd ) );

    ddsd.dwSize = sizeof( ddsd );

    if (bSingleBuffer)

    {

        printf("bSingleBuffer is TRUE\n");

        ddsd.dwFlags = DDSD_CAPS;

        ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

    }

    else

    {

        printf("bSingleBuffer is FALSE\n");

        ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

        ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP;

        ddsd.dwBackBufferCount = 1;

    }



    ddrval = lpDD->lpVtbl->CreateSurface( lpDD, &ddsd, &lpFrontBuffer, NULL );

    if (ddrval != DD_OK)

    {

        if (ddrval == DDERR_NOFLIPHW)

            return CleanupAndExit(TEXT("******** Display driver doesn’t support flipping surfaces. ********"));

 

        return CleanupAndExit(TEXT("CreateSurface FrontBuffer Failed!"));

    }



    if (bSingleBuffer)

    {

        ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;

        ddsd.dwWidth = ScreenX;

        ddsd.dwHeight = ScreenY;

        ddrval = lpDD->lpVtbl->CreateSurface( lpDD, &ddsd, &lpBackBuffer, NULL );

        if (ddrval != DD_OK)

        {

            return CleanupAndExit(TEXT("CreateSurface BackBuffer Failed!"));

        }

    }

    else

    {

        ddrval = lpFrontBuffer->lpVtbl->EnumAttachedSurfaces( lpFrontBuffer, &lpBackBuffer, EnumFunction);

        if (ddrval != DD_OK)

        {

            return CleanupAndExit(TEXT("EnumAttachedSurfaces Failed!"));

        }

    }



So this was interesting. I thought I could try to do the same for the DDEX1 sample. I played around with the code a bit; added handling for single buffer changed the Flip() api into Blt(), because that is what Donuts did



    while( 1 )

    {

        if (bSingleBuffer)

        {

            //copy back buffer to front.

            ddrval = lpFrontBuffer->lpVtbl->Blt( lpFrontBuffer, &dest, lpBackBuffer, &src, dwTransType, NULL );

        }

        else

        {

            ddrval = lpFrontBuffer->lpVtbl->Flip( lpFrontBuffer, NULL, 0);

        }



        if( ddrval == DD_OK )

        {

            break;

        }

        if( ddrval == DDERR_SURFACELOST )

        {

            if( !RestoreSurfaces() )

            {

                return;

            }

        }

        if( ddrval != DDERR_WASSTILLDRAWING )

        {

            break;

        }

    }



And voila! It worked (: It showed a screen flip flopping with blinking text. If you have gone through the tutorial above you probably know what Flip() and Blt() do. The only problem I ran into was, to the Blt() function I was passing "DDBLT_KEYSRC" as the second last parameter, and it wasn’t showing anything. I tried "DDBLT_KEYDEST" too but same result. So since the final parameter (a pointer to a structure) was NULL anyways, I passed 0 as the second last parameter. It worked.



You can check the documentation of Blt() here.

More details about the changes I made to DDEX1 and other stuff about DirectDraw, coming soon.

Lets do some graphics: DirectDraw, Part 2

Well, the initial excitement from DDEX1 didn’t last for long. Just flipping between screens having some text ain’t much fun. I moved onto DDEX2. DDEX2 pretty much did the same thing as DDEX1 but on a background image. It drew a fancy background on the back buffer and then flipped some alternating text onto it. Nothing too exciting here, so I didn’t bother trying to make it work on the emulator.DDEX3 turned out to be interesting. It used 4 surfaces in total, a primary surface, a back buffer and two additional surface buffers. The two additional buffers were used to store the upper half and lower half of a bmp image file, respectively. And as and when the timer fired, they Blt one of these buffers onto the back buffer and then flipped the primary surface so that the current image on the back buffer could be displayed. You can check out the bmp file, the upper half says “Even Screen” on a blue background and the lower half says “Odd Screen” on a red background.As I said before, trying to run DDEX3 directly on emulator was not possible because the emulators do not support back buffers (also known as Complex surfaces, i think) and the program quit with an error message. So obviously the code had to be modified a bit, just like we did for DDEX1, to make it work. Here is how to make it work on an emulator:



First create a global BOOL variable bSingleBuffer and initialize it to FALSE. As before, comment out the part in InitApp() function where after doing GetCaps() it fails with an error message saying that the device does not support back buffers. So with that code out of the way, add the following piece of code:

    if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER) || !(ddCaps.ddsCaps.dwCaps & DDSCAPS_FLIP))    
    {
        printf(“Device does not support backbuffer or flip!\n”);         printf(“Using a normal surface (not a backbuffer)\n”);         bSingleBuffer = TRUE;

    }

    memset(&ddsd, 0, sizeof(ddsd));

    ddsd.dwSize = sizeof(ddsd);

    if(bSingleBuffer)

    {

        ddsd.dwFlags = DDSD_CAPS;

        ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

    }

    else

    {

        ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

        ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |

                              DDSCAPS_FLIP;

        ddsd.dwBackBufferCount = 1;

    }

    hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);

If the device does not support back buffer or flip then we set the bSingleBuffer variable to TRUE. Then create our primary surface and store the pointer to the surface in g_pDDSPrimary variable. The next part of code gets the back buffer from the primary surface using EnumAttachedSurfaces() function, that part has to be modified as below:



    if(bSingleBuffer)

    {

        ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;

        ddsd.dwWidth = 240;

        ddsd.dwHeight = 320;

        hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSBack, NULL);

        if(hRet != DD_OK)

        {

            return InitFail(hWnd, hRet, TEXT(“Failed to create normal surface”));

        }

    }

    else

    {

        // Get a pointer to the back buffer

        hRet = g_pDDSPrimary->EnumAttachedSurfaces(&g_pDDSBack, EnumFunction);

        if (hRet != DD_OK)

            return InitFail(hWnd, hRet, szEnumAttachedSurfacesFailMsg);

    }

Here, if bSingleBuffer is set, we create a normal surface, 240 pixels wide and 320 pixels high. The resolution of the emulator. Otherwise we get the back buffer from the primary surface.

Then the two off-screen surfaces are created. This part of code remains the same, the only change is,

   // Create a offscreen bitmap.

    ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;

    ddsd.dwHeight = 320;

    ddsd.dwWidth = 240;

This is same as the original code, only thing I changed here are the height and width.

Next change would be in the InitSurfaces() function,

    DDCopyBitmap(g_pDDSOne, hbm, 0, 0, 240, 320);

    DDCopyBitmap(g_pDDSTwo, hbm, 0, 320, 240, 320);

Originally, the bitmap was getting copied from 0, 0, 640, 480 and 0, 480, 640, 480. I think the original program was intended for a VGA resolution device but since the emulator runs Quarter VGA, I modified the dimensions.

The final change is in the WindowProc() function under the WM_TIMER message inside the while loop. The original code simply called Flip() on the primary surface to display the image in the back buffer, and as I have been repeating like a million times, the emulator does not support flipping (: So the original code,

    hRet = g_pDDSPrimary->Flip(NULL, 0);

becomes,

if(bSingleBuffer)

    {

        //RECT src, dest;

        hRet = g_pDDSPrimary->Blt(NULL, g_pDDSBack, NULL, 0, NULL);

   

        if(hRet != DD_OK)

        {

            printf(“DDEX3: Blt on primary surface failed, errcode:0x%x\n”, GetLastError());

        }

    }

    else

    {

         hRet = g_pDDSPrimary->Flip(NULL, 0);

    }

And that is all! DDEX3 is now ready to be run on the emulator (: Notice that last time I had used the src and dest RECT’s to specify the size and location of the source and destination rectangles on the source and destination surfaces respectively. Specifying NULL for both src and dest would make use of the entire source and destination surfaces, which is exactly what we want. The remaning part of the while loop remains same.

The emulator screen now flips between the following two screens every half-second.

img1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

and

 

img2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

As you can see, I replaced the stale red and blue screens with something a bit more nice (: Well, obviously you know how to do that. Don’t you? (:

 

 

Lets make the spaceship move! DirectDraw, Part 3

Ok, time to get our hands dirty. If you have seen the Donuts sample you would have noticed the tubular spaceship. The donuts sample uses a single image, donuts.bmp, to store all the images used in the game. Well, I just cut off a portion of it to try something out. Just use any image editor and cut out only the spaceship portion of the image. Make sure that the image you cut is 320×384 in size. This will make our calculations easier as you will see later. So the image would look something like this:

Again, make sure the image you cut is 320 pixels wide and 384 pixels high.

Lets move onto some code. Most of the code remains the same as I had modified it here and here to make it work on the emulator. The only changes will be while creating the surfaces and in the UpdateFrame() function.

 

No changes in the way the primary and back buffers were created, just remember to create the back buffer with width as 240 and height as 320. We will need only one extra surface to hold the above image. Create the surface as follows:



    ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;

    ddsd.dwWidth = 320;

    ddsd.dwHeight = 384;

    hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOne, NULL);

    if (hRet != DD_OK)

        return InitFail(hWnd, hRet, szCreateSurfaceFailMsg);



Notice that the dimensions of the surface match the bitmap size, 320×384. Lets load the bitmap onto the surface now, in InitSurfaces():



    DDCopyBitmap(g_pDDSOne, hbm, 0, 0, 320, 384);



So g_pDDSOne now points to a surface that holds our bitmap. Oh and one more thing, just declare a const variable to hold the number of columns in the image,



static const int            TOTAL_COLS = 5;



Yes, you can go back and count (: Anyways, lets take a look at the UpdateFrame() function now:



static void UpdateFrame(HWND hWnd)

{

    static BYTE                 phase = 0;

    HRESULT                     hRet;

    DDBLTFX                     ddbltfx;

    RECT src, dest;

    int row = 0, col = 0;



    memset(&ddbltfx, 0, sizeof(ddbltfx));

    ddbltfx.dwSize = sizeof(ddbltfx);

    ddbltfx.dwFillColor = 0;



    ddbltfx.dwROP = SRCCOPY;



    //the destination rect is in the center of the screen

    dest.top = 128;

    dest.left = 88;

    dest.bottom = 192;

    dest.right = 152;



    //clear the back buffer (color fill with black)

    g_pDDSBack->Blt(&dest, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAITNOTBUSY, &ddbltfx);



    //calculate the src rect depending on the value of ‘phase’

    row = phase/TOTAL_COLS;

    col = phase%TOTAL_COLS;



    src.top = 64*row;

    src.left = 64*col;

    src.bottom = src.top + 64;

    src.right = src.left + 64;



    while (TRUE)

    {

        hRet = g_pDDSBack->Blt(&dest, g_pDDSOne, &src, DDBLT_ROP, &ddbltfx);

        if (hRet == DD_OK)

            break;

        if (hRet == DDERR_SURFACELOST)

        {

            hRet = RestoreAll();

            if (hRet != DD_OK)

                break;

        }

        if (hRet != DDERR_WASSTILLDRAWING)

            break;

    }



    phase = (phase+1)%30;



}

A few points first, every spaceship image in the bitmap is 64×64 in size. There are a total of 30 spaceship images, so we make the ‘phase‘ variable to run between 0 to 29 in a circular fashion, each time selecting the next image in the bitmap and wrapping around. I decided to place the spaceship in the middle of the screen, as you can see the hard coded values for dest RECT. This is not very elegant and I should really have used GetSystemMetrics() with SM_CXSCREEN and SM_CYSCREEN to calculate the position at run time, but since this is for illustration only, I’ll leave it at that. Next we clear that dest portion of the back buffer, to clear the prevous image, calculate the current image to be loaded using the value of ‘phase‘ and putting the values in the src RECT. Finally we Blt() the image onto the back buffer from g_pDDSOne surface, and this back buffer will then be Blt() onto the primary surface under WM_TIMER message in WindowProc(). Before returning we update the ‘phase‘ variable. Well, thats it! Pretty simple right. If you run this, it will display a rotating spaceship at the center of the emulator screen. You can play around with the timer,



#define TIMER_RATE          80

to control the speed at which the spaceship rotates.

 

Thats it for now! In the next post I’ll explain on how to make the rotating spaceship bounce around the screen edges. It can’t get any simpler (:

I took a small video of the rotating spaceship.

 

Lets make the spaceship move! DirectDraw, Part 4

As I had mentioned in my previous post, we’ll make the spaceship move around on the screen and bounce off when it hits the screen edges.

 

I would like to diverge a bit here. When I got the spaceship to rotate at the center of the screen, I was wondering how I can make it move around in the screen and bounce off the edges. I thought motion would be much more complicated and difficult and it would involve line equations along a particular direction, and then use geometrical concepts involving things like "The law of reflection states that the angle of incidence equals the angle of reflection." and much more. I had a discussion with a few of my colleagues about this same topic and our discussion pretty much went along the same lines. It made me apprehensive. And when I looked at Donuts’ code in detail, well, it seemed like we were trying to boil the ocean to make tea, not that you can’t do it (: I could not have ever imagined that moving an object around the screen and making it bounce off the edges perfectly could be more simpler!

 

Here is how the concept works in brief. You decide on the velocity along the x-axis and the velocity along the y-axis.  Generally, it will be the number of pixels the object moves along each axis per frame. The objects new position is calculated by adding to it the velocity along the X and Y axis. And when ever the object reaches the edges, you just negate the velocity along that direction. That’s it. So if the object is about to hit the top or bottom of the screen, just negate the velocity along the Y axis and if its about to hit the left or right edges, you negate the velocity along the X axis. The object bounces around perfectly.

 

I will be building on the code from my previous post. So I would hope that you have already read it. If you remember, each image of the spaceship in the bitmap was 64×64 in size. To keep things simple, we would make a point move along the X and Y axis and then draw our 64×64 square containing the spaceship around that point, such that the point is at the center of the image always. So our image would be about to hit a screen edge when the point is actually 32 pixels away from it.



Define the velocity globals,



//these are the objects velocities along the x and y axis

int                            dwVelX = 4;

int                            dwVelY = 5;

I have just hard coded the values, it would be better to use the Random() function to get the values, in case of a game. Keeps it a bit unpredictable.

 

The next change is to calculate the position of the dest RECT at run time, unlike the center of the screen, which we did last time. Here is the code for UpdateFrame():



static void UpdateFrame(HWND hWnd)

{

    HRESULT                     hRet;

    DDBLTFX                     ddbltfx;

    RECT src;

    int row = 0, col = 0;



    static BYTE                 phase = 0;

    static RECT dest;



    //the destination rect’s position will be calculated around a point (xPos, yPos), initially its the center of the screen

    static int xPos = 120;

    static int yPos = 160;

    static BOOL first = TRUE;



    memset(&ddbltfx, 0, sizeof(ddbltfx));

    ddbltfx.dwSize = sizeof(ddbltfx);

    ddbltfx.dwFillColor = 0;



    ddbltfx.dwROP = SRCCOPY;



    if(!first)

    {

        //clear the back buffer (color fill with black)

        g_pDDSBack->Blt(&dest, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAITNOTBUSY, &ddbltfx);

    }



    //calculate the destination rect’s position (+-32 coz the image is 64 pixels wide and high)

    dest.top = yPos – 32;

    dest.left = xPos – 32;

    dest.bottom = yPos + 32;

    dest.right = xPos + 32;



    if(first)

    {

        //clear the back buffer (color fill with black)

        g_pDDSBack->Blt(&dest, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAITNOTBUSY, &ddbltfx);

        first = FALSE;

    }



    //calculate the src rect depending on the value of ‘phase’

    row = phase/TOTAL_COLS;

    col = phase%TOTAL_COLS;



    src.top = 64*row;

    src.left = 64*col;

    src.bottom = src.top + 64;

    src.right = src.left + 64;



    while (TRUE)

    {

        hRet = g_pDDSBack->Blt(&dest, g_pDDSOne, &src, DDBLT_ROP, &ddbltfx);

        if (hRet == DD_OK)

            break;

        if (hRet == DDERR_SURFACELOST)

        {

            hRet = RestoreAll();

            if (hRet != DD_OK)

                break;

        }

        if (hRet != DDERR_WASSTILLDRAWING)

            break;

    }



    phase = (phase+1)%30;



    //now update xPos, yPos depending on the velocities

    xPos = xPos + dwVelX;

    yPos = yPos + dwVelY;



    //if any of the four boundaries is reached reset xPos or yPos and negate the velocity along that direction

    if(xPos <= 32)

    {

        xPos = 32;

        dwVelX = -dwVelX;

    }



    if(xPos >= (240-32))

    {

        xPos = 240-32;

        dwVelX = -dwVelX;

    }



    if(yPos <= 32)

    {

        yPos = 32;

        dwVelY = -dwVelY;

    }



    if(yPos >= (320-32))

    {

        yPos = 320-32;

        dwVelY = -dwVelY;

    }

}

The first thing to notice is that the dest RECT is now static. This is, of course, because we are updating the destination position relative to its previous value. Two new static variables xPos and yPos are added. These will store the co-oridnates of the point around which we will draw our image. xPos and yPos are initialized to the center of the screen. We then calculate the dest RECT using xPos and yPos by adding and subracting 32 from it. Calculate the src RECT just like before and Blt() it onto the back buffer. The next part is updating the xPos and yPos values. The values are updated by just adding the X velocity to xPos and Y velocity to yPos. Next we do bounds checking to see if our image is about to go off the screen or put in other words, about to hit a edge. If so, then we reset the position and negate the velocity along that axis. This negating has a bouncing effect. I know that I should have used GetSystemMetrics() rather than hard coding values like 240, 320 etc, but I again I am just plain lazy to do it (: And I hope you are not.

 

Here is a video of the bouncing spaceship.

 



 

Applications: Problems with static text control

Today at work, I was working on a small application with my colleague. We had dialog box with a button, an edit control and a static control. What we wanted to do was show the status of the program on the static control once the button was pressed. And the code looked something like this:

case WM_COMMAND:

{

    wmID = LOWORD(wParam);

    wmEvent = HIWORD(wParam);

    switch(wmID)

    {

        case IDM_BUTTON_GMC:

        {

            SetWindowText(GetDlgItem(hDlg, IDC_STATIC_STATUS), L"In progress..");



            /*

            Do some work

            */



            SetWindowText(GetDlgItem(hDlg, IDC_STATIC_STATUS), L"Done.");

        }

        break;

    }

    .

    .

    .

}

break;

The default text on the static control was blank. When I ran the program we noticed that the static control never displayed "In Progress..". After finishing the actual meat of the job, the static control displayed "Done". We wondered whether it was because the actual work was happening too fast, and we put a sleep of 1 second after the first SetWindowText() call, but it didn’t solve the problem. We sat wondering about why this was happening. We checked the return value of the first SetWindowText call and it was non-zero which meant the call was successful. Another colleague of ours walked by and we explained the problem to her briefly, and she stared for a moment and said, UpdateWindow. And we all went "Aww…". So we put UpdateWindow(GetDlgItem(hDlg, IDC_STATIC_STATUS)); after both the calls and it worked, as expected. Painting is one of the most costliest operation and runs at a very low priority. So no wonder the calls before weren’t updating the text immediately. Sometimes we are all so occupied with bigger things that we miss out on the small ones.

Applications: Problems with painting DialogBox

Today I was working on an application with a colleague. The application contained many dialogs, well, it was a settings related app which let the user perform and view all sort of settings on the phone. The application was medium sized with the original code very badly written. And we were supposed to clean up the code and change the look and feel of the various Dialogs used in the app. And also make sure that the same code base worked on both Standard and Professional devices, when compiled with different flags of course. We were almost through most of the things but one problem kept bothering us for a long time. One of the dialogs in the app never displayed correctly. And it was strange because it was exactly the same as other dialogs. The DialogProc of the dialog looked something like this:

BOOL CALLBACK DlgProc((HWND hDlg, UINT uMessage, WPARAM wParam, LPARAM lParam)

{

    BOOL fRet = FALSE;

    switch(uMessage)

    {

        case WM_INITDIALOG:

        {

            /*

            Do SHInitDialog()

            */

            /*

            Do SHCreateMenuBar()

            */

            /*

            Setup controls in the dialog

            */

            return TRUE;

        }

        break;



        case WM_COMMAND:

        {

            /*

            Handle all controls here

            */

            return TRUE;

        }

        break;



        case WM_ACTIVATE:

        {

            /*

            Do some stuff

            */

        }

        break;



        case WM_PAINT:

        {

            hdc = BeginPaint(hDlg, &ps);



            EndPaint(hDlg, &ps);

        }

        break;



        case WM_CLOSE:

        {

            EndDialog(hDlg, uMessage);

        }

        break;

    }



    fRet = TRUE;



    return fRet;

}

Well, the code was a lot more messy than is shown here. Anyways, we sat wondering why only this dialog was not getting displayed properly. The background of the dialog was not at all drawn and the controls on the dialog appeared shabbily. We thought that a certain sequence of events caused the dialog to be displayed that way, so we tried calling the dialog from different places but the result still the same. We checked and compared the dialog properties of various dialogs with this one. They were insignificantly different but we still tried to make them exactly same, but still no luck yet. After about 2 hours I noticed the return value of the dialog proc and saw that it was always returning true no matter what. And I knew. How in the silly world can I miss such an important thing for this long! The return value of a dialog proc is a really important thing. Returning TRUE from the function means that you have handled the message and the OS may or may not take further action, mostly it wont. Returning FALSE would tell the OS that you have not handled the message and the OS would now handle the message and execute the default handling for that message. Why our dialog was not getting displayed correctly was that, we were returning TRUE for all messages, including WM_PAINT. So the OS thought that I have handled the paint message it does not need to take any action. And that is why there were problems in painting the dialog. We changed the return value to be TRUE or FALSE depending on whether we handled that message or not and it worked.

 

Applications: Creating a simple UI application from scratch

In this series of posts I will show how we can create a basic UI application for a Windows Mobile Professional device from scratch, without having to go through all the hidden stuff that the wizard does to your application (the stdafx’s). And there is another reason why I would want to create an application from scratch, while porting applications, which were built using VS2005, to a BSP (in a build environment) I have faced lot of annoying problems. It throws a lot of compilation errors, and its a pain to resolve them. To make the application a little more useful, the application will display all the current running processes, and you will be able to refresh the view. I am planning to use a List View control for this, instead of a stale list box for two reasons, One I have never used a list view control and two you can display icons in a list view, cool right? Anyways, I have just started with the application. More posts coming soon.