The Back Button and Other Interesting Buttons

One of the more important components of the Smartphone interface is the Back button. This button allows the user to return to the previous screen from the current screen at any time. For the most part, the Back button works as designed without any assistance from the foreground application. There are, however, times when the Back button needs to act differently, and that's when the application has to do a bit of work.

The rules for the operation of the Back button are as follows:

  • If the current window is not a dialog box and does not have an edit box, the Back button activates the window that was displayed before the current window was activated. The current window isn't destroyed, it's simply covered by the previous window, which now becomes the active window.
  • If the current window is a message box or a modal dialog box without an edit control, the Back button dismisses the message box or dialog box and returns the cancel return code. For message boxes, this value is either IDNO, IDCANCEL, or IDOK for message boxes with only an OK button. For dialog boxes, a WM_COMMAND message is sent to the dialog window with the command ID IDCANCEL.
  • If the window currently displayed contains an edit control, the Back button erases the last character in the control and moves the entry cursor one character to the left.

In the case of the first two rules, the system will provide the default action for the Back button. For the final rule, concerning edit boxes, the application must override the default action and forward the key to the appropriate child control in the window. Fortunately, the Smartphone shell that does most of the work through a couple of helper functions.

If a window contains an edit box, it must override the default action of the Back key in order to pass the key to the child control. To do this, the window sends a SHCMBM_OVERRIDEKEY message to the MenuBar control for the window. The wParam parameter defines the key to override. The following keys are supported for override:

Key Meaning
VK_TBACK Back button
VK_TSOFT1 Left SoftKeyBar button
VK_TSOFT2 Right SoftKeyBar button
VK_TVOLUMEUP Up volume button
VK_TVOLUMEDOWN Down volume button
VK_TRECORD Record button

The lParam parameter designates the keys to override and the action to take. The lower word of lParam contains a mask of flags that designates which flags are valid. The action flags are in the upper word. The first flag that can be set indicates whether a key is to be overridden and the second indicates whether a WM_HOTKEY message is sent to the window when the key is pressed. For example, to override the action of the Back button and to be notified with a WM_HOTKEY message, a window would send the following message to the MenuBar:

SendMessage (SHFindMenuBar (hWnd), SHCMBM_OVERRIDEKEY, VK_TBACK, 
             MAKELPARAM (SHMBOF_NODEFAULT | SHMBOF_NOTIFY, 
                         SHMBOF_NODEFAULT | SHMBOF_NOTIFY));

This line sends a SHCMBM_OVERRIDEKEY message to the MenuBar control owned by hWnd. The wParam parameter, VK_TBACK, indicates the key being overridden. The MAKELPARAM macro forms a DWORD from two 16-bit words. The first parameter of MAKELPARAM, which will become the low word of lParam, is the mask field. Here, the SHMBOF_NODEFAULT flag is used to indicate that the override state of the Back key is to be set or cleared. The SHMBOF_NOTIFY flag indicates that the notification flag will also be set or cleared. The upper word of lParam is created from the second parameter of the MAKELPARAM macro. Here, the flag SHMBOF_NODEFAULT indicates that the Back key will be overridden. The second flag, SHMBOF_NOTIFY, tells the MenuBar to notify its parent when the Back key is pressed.

To override the Back key but not be notified when it's pressed, the following line could be used:

SendMessage (SHFindMenuBar (hWnd), SHCMBM_OVERRIDEKEY, VK_TBACK, 
             MAKELPARAM (SHMBOF_NODEFAULT | SHMBOF_NOTIFY, 
                         SHMBOF_NODEFAULT));

To restore the Back key to its original function, the following line could be used:

SendMessage (SHFindMenuBar (hWnd), SHCMBM_OVERRIDEKEY, VK_TBACK, 
             MAKELPARAM (SHMBOF_NODEFAULT | SHMBOF_NOTIFY, 
                         0));

In the previous line, the first parameter of MAKELPARAM (the mask bits) indicates that the message is going to set the state of both the default action and the notification state of the button. The second MAKELPARAM parameter is 0, which indicates that the default action is to be restored and that notification is to be sent to the MenuBar owner.

When WM_HOTKEY is received by the window, the wParam value contains an ID value for the key that was pressed. The IDs reported by the MenuBar are:

Key Value
VK_TSOFT1 0
VK_TSOFT2 1
VK_TBACK 2
VK_TVOLUMEUP 3
VK_TVOLUMEDOWN 4
VK_TRECORD 5

The lParam value also indicates the key but in a different way. The high word of lParam will contain the virtual key code of the key that was pressed. The lower word of lParam contains the modifier flags for the key. The only flag that is of interest on the Smartphone is MOD_KEYUP, which is set if the key is being released. Other modifier flags are documented such as the Shift, Alt, and Control keys, but those flags are seldom used because the Smartphone doesn't have these keys.

For windows that contain edit controls, the notification of a Back key press needs to be forwarded to the proper child control. This forwarding is done by using a SHCMBM_OVERRIDEKEY message to redirect the Back key. Once the key is overridden, a press of the key sends a WM_HOTKEY message to the owner of the MenuBar. To fully support passing the backspace to the edit control, each WM_HOTKEY message received as a result of a Back key press needs to be forwarded to the control with the function SHSendBackToFocusWindow, defined as:

void SHSendBackToFocusWindow (UINT uMsg, WPARAM wp, LPARAM lp);

The three parameters are the message being handled, as well as the wParam and lParam values for the message. The following code fragment shows the use of this function.

case WM_HOTKEY:
    if (HIWORD (lParam) == VK_TBACK)
        SHSendBackToFocusWindow (wMsg, wParam, lParam);
}

The override state of a key changed by a SHCMBM_OVERRIDEKEY message is removed when the corresponding MenuBar control is destroyed so there's no need to manually restore the default state before the window is destroyed.

This topic is from Programming Microsoft Windows CE, Third Edition, by Douglas Boling, published by Microsoft Press. © 2003 by Douglas McConnaughey Boling. Reprinted here by permission of the author.