Win32 Dynamic Wizard Style Buttons

Using the Windows API to Create Self-Managing GUI Elements

© Guy Lecky-Thompson

A tutorial useful for those wanting to make intelligent GUI elements like dynamic buttons using the Windows Win32 API with child window and control ID processing.

Introduction

This article is a follow on from the Dynamic User Interface Trick article which covers a general approach to maintaining a dynamic user interface. If the reader is not familiar with creating dynamic child controls, they should read that article first, as this borrows heavily on some of the techniques described in it.

Creating the Window

The buttons need to be created with a call to CreateWindow, specifying "button" as the class, WS_CHILD and probably WS_PUSHBUTTON in the style parameter, with the wizard window (or dialog box) as the parent. The ID needs to be set dynamically, so that the window procedure associated with the wizard can process the WM_COMMAND notification messages correctly.

Setting and Getting Window Text

The initial window text (such as Previous, Next, Finish, Cancel etc.) can be set in the call to CreateWindow, but it might also need to be changed depending on the interaction with the user. There are 2 methods to get or set window text for child window controls. The first method requires a window handle to the button:

GetWindowText ( HWND, LPSTR, int );
SetWindowText ( HWND, LPSTR);

The last parameter of the GetWindowText function is the maximum number of characters we can cope with in the LPSTR. If we have not stored the result of the initial CreateWindow call, then we have to use GetDlgItem to obtain the window handle. An easier method is just to use the API calls:

GetDlgItemText( HWND, int, LPSTR, int);
SetDlgItemText( HWND, int, LPSTR);

In these, the second parameter is the child ID, as we would have used in the GetDlgItem call. Again, the last parameter of GetDlgItemText is the number of characters we can cope with. We can use these to create, for example, a Start/Stop button:

char szText[255];
GetDlgItemText( hWizard, nButton, szText, 255 );
if (strcmp(szText,"Start") == 0)
{
SetDlgItemText(hWinzard, nButton, "Stop");
}
else
{
SetDlgItemText(hWinzard, nButton, "Start");
}

The ideal place to put this would be as part of the notification message processing in the wizard window procedure.

Intercepting the WM_COMMAND Message

The notification that the user has clicked the button comes through a WM_COMMAND message sent to the parent, as if it were a menu item that had been selected. We can intercept this as in the Dynamic User Interface Trick article.

During the processing, we can alter the text, or send messages to other screen elements. In a wizard we might just need to move to the next screen, which may also entail enabling or disabling some of the elements.

Enabling and Disabling the Button

There might be times when we want the button to be disabled but still visible. For example, on the first screen of a wizard, the Previous button is usually grayed out rather than not present, and there is also usually a Finish button in a similar state. This is also useful if, for example, we want to allow the user to click Finish before the end of the process - rather like the Excel Data Import Wizard does.

This is achieved by using the EnableWindow function:

EnableWindow( HWND, BOOL );

The second parameter is either TRUE or FALSE, depending on whether we want the window to be enabled or not. For buttons, this causes the item to be grayed. If the button is oner-drawn, then processing the WM_ENABLE message that is sent to the button might be required.

To use this function to enable or disable a child item, where we have not stored the window handle, we could, of course, use the following:

EnableWindow( GetDlgItem(hWnd, nItem) );

Where the hWnd is the parent and nItem is the child ID. Note that, despite the name of the function, the parent does not have to be a dialog box, just a containing window where the child ID refers to an item that has been created with the style WS_CHILD, and the hParent parameter in CreateWindow set to hWnd.


The copyright of the article Win32 Dynamic Wizard Style Buttons in Windows Programming is owned by Guy Lecky-Thompson. Permission to republish Win32 Dynamic Wizard Style Buttons must be granted by the author in writing.




Post this Article to facebook Add this Article to del.icio.us! Digg this Article furl this Article Add this Article to Reddit Add this Article to Technorati Add this Article to Newsvine Add this Article to Windows Live Add this Article to Yahoo Add this Article to StumbleUpon Add this Article to BlinkLists Add this Article to Spurl Add this Article to Google Add this Article to Ask Add this Article to Squidoo