Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Header Bars in Windows CE Using Win32

0.00/5 (No votes)
30 Aug 2003 1  
Creating and using a header bar style control in Windows CE.

Introduction

This article shows how to create a Microsoft style header bar and status bar control using simple Common Control library calls and messages. No GDI drawing code is required, as all the functionality for these are already built into the common controls library.

Background

For a recent project, I wanted to create a header bar like Microsoft have on most of the applications on the Pocket PC platform. However I did not want to use MFC, in part because of the size.

The dialog box below is from the Inbox application on the Pocket PC 2002. I have masked the areas not of interest, so you can see the header bar control and the status bar control on the main application window.

WinCE_HeaderBarControl/ppc_inbox.gif

The picture has two interesting features on it. The first feature is the header control at the top. This has a dropdown combo box allowing the user to select the sort by option on the right and select the relevant folder and message store to use on the left. To keep the look and feel of the Windows UI, if the user clicks on the drop down, only the dropdown is highlighted. If the user clicks anywhere on the button the entire button is highlighted.

The second feature was the use of the "status bar" at the bottom to allow the user information on the state of the current folder to be displayed, but more on that later.

For the header control bar my first thought was to use the header common control to create the effect in the picture. However this is misleading as I found out after some work with Remote Spy++. What was believed to be a header control is in fact toolbar control.

So now, having established that the header bar control is not in fact a header control, but a toolbar, the question then becomes, how was it done?

A look around the common controls library reveals that the toolbar control does indeed support drop down buttons, but when implementing them the the combo box drop down buttons have a right hand side border that looks unsightly as well as the gap between the left border and the text.

To tackle the second issue is quite simple, when adding the toolbar buttons we want to just display nothing, rather than a blank bitmap. In order to correct this you need to specify that the bitmap to be used is I_IMAGENONE (which is equivalent to -2) and not -1 which means just display an empty bitmap.

The first issue is more problematic. How are the divider lines to be removed from the combo boxes? Initially I thought that I would need to totally rewrite the drawing code for this in order to get it to work. Fortunately in the common controls header file there is an undocumented define CDRF_NOVERTBAR. Using this as part of the custom draw stages when the toolbar control is redrawn allows the divider bar to be removed.

The above is a corrected header bar control with the divider lines removed and the blank icon removed. This code now mirrors the functionality of the controls in the standard Windows applications as far as I am aware.

Below is the extract of code for the WM_NOTIFY handler for the NM_CUSTOMDRAW function. Note how the common control module's notification handler is told that each item will need to be redrawn whenever an item in the toolbar is to be redrawn. Then, when an item is about to be redrawn the CDRF_NOVERTBAR code is returned informing the common control module that the current item being drawn is to be drawn without vertical divider bars. Of course it is also possible to do this on an item by item basis by checking the item in the dwItemSpec or lItemlParam portion of the NMCUSTOMDRAW structure.

case NM_CUSTOMDRAW:
    {
        LPNMCUSTOMDRAW  lpnmcd = (LPNMCUSTOMDRAW)lParam;
        switch(lpnmcd->dwDrawStage)
        {
            case CDDS_PREPAINT
                return CDRF_NOTIFYITEMDRAW;
            case CDDS_ITEMPREPAINT:
                return CDRF_NOVERTBAR
        }
    }

The final section is to handle the command when the toolbar button is clicked. The toolbar button consists of two portions because the button is a dropdown style button. When the dropdown is pressed, the corresponding button needs to simulated as being pressed. To do this the TBN_DROPDOWN notification command needs to be handled and to post a WM_COMMAND message to the main window based on which command was selected. When the command associated with the button is clicked, a message is routed to the parent window where it is handled in the WM_COMMAND handler as would a normal message if the a toolbar button were pressed.

As part of the sample provided, it loads a menu resource and displays it using TrackPopupMenu. Other things you could do would be to build and display a tree view or similar. In fact the sample source code included in the zip file does exactly that for the left dropdown button, however I have not elaborated the code here.

To handle the status bar, it's a bit simpler in that when creating a status bar, the bar is successfully created however it does not appear on the screen. The problem with this is that the control is set to align to the bottom of the screen and not the top of the menu bar, so when the menu bar is created on the bottom of the screen, it actually obscures the status bar and so the status bar appears invisible, but is really hidden behind the menu bar.

To fix this problem it is a simple case of using the CCS_NOPARENTALIGN window style when creating the control so that the control does not align with any of the client area. Of course you will then need to manually realign the controls around it to cater for the status bar between the menu bar and the remainder of the controls on the main window. You will also see when the status bar is initially displayed it has a border and default text from when the window is created. We just set the text in the window using the SB_SETTEXT message.

Using the code

The code in the Win32 sample is just a basic Pocket PC 2002 application with the "Hello World" default implementation.

This was extended to create a new toolbar window at the top of the window. To see how the menu bar control was created, look at the function called CreateHeaderBar.

The main points to note here are that the toolbar window has been created with the TBSTYLE_CUSTOMERASE, TBSTYLE_FLAT and TBSTYLE_LIST. The most important being the TBSTYLE_CUSTOMERASE. This will allow the painting stages to be intercepted and replaced with the new custom draw handler paint stages, allowing the removal of the vertical bars on the dropdown buttons.

Once the toolbar has been successfully created, the two buttons may be added to the control. There are actually three buttons, the middle one's width is calculated as the remaining width after deducting the size of the left and right buttons and just an unpressable standard button.

This code is in the helper function CreateHeaderRowButtons. The function will allow a left and or a right button, but at least one must be present. The reason TBBUTTON structures are passed is that it allows the programmer the fullest scope to configure the look and feel of the button.

One important point to note is that when getting the width of the buttons you will need to call TB_GETITEMRECT rather than TB_GETBUTTONFINO as this gets the correct width of the auto-sized button whereas the TB_GETBUTTONINFO does not.

The use of the status bar is more of an oversight than anything else. It is really easy to correct in that it is only the style that needs to be changed from the implicit CCS_ALIGNBOTTOM to the CCS_NOPARENTALIGN which then allows the programmer the control to set their own size and position for the status bar in the screen.

The handling of the dropdown control is done in the TBN_DROPDOWN sub command in the WM_NOTIFY command handler. This just posts a WM_COMMAND message of the command associated with the button.

Points of interest

It would also be nice if Microsoft provided samples and documentation on the custom draw stuff for CE as well as documenting the CDRF_NOVERTBAR style.

History

Fixed download samples problem

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here