Following are the window procedure for the toolbar and the subclass procedure for the two combo boxes.
#define WM_TAB (WM_USER)
#define WM_ESC (WM_USER + 1)
#define WM_ENTER (WM_USER + 2)
HWND hwndMain;
HWND hwndEdit;
WNDPROC lpfnEditWndProc; /* original window procedure for */
/* the combo box edit windows */
int cyToolbar; /* toolbar window height */
/********************************************************
FUNCTION: ToolbarWindowProc
PURPOSE: Window procedure for the toolbar window
*********************************************************/
LRESULT CALLBACK ToolbarWindowProc(hwnd, msg, wParam, lParam)
HWND hwnd;
UINT msg;
WPARAM wParam;
LPARAM lParam;
{
static HWND hwndEdit1;
static HWND hwndEdit2;
static HWND hwndCombo1;
static HWND hwndCombo2;
.
.
.
POINT pt;
DWORD dwBaseUnits;
HWND hwndCombo;
DWORD dwIndex;
switch (msg) {
case WM_CREATE:
/* Create two combo box child windows. */
dwBaseUnits = GetDialogBaseUnits();
hwndCombo1 = CreateWindow("COMBOBOX", "",
CBS_DROPDOWN | WS_CHILD | WS_VISIBLE,
(6 * LOWORD(dwBaseUnits)) / 4,
(2 * HIWORD(dwBaseUnits)) / 8,
(100 * LOWORD(dwBaseUnits)) / 4,
(50 * HIWORD(dwBaseUnits)) / 8,
hwnd, NULL, hinst, NULL);
hwndCombo2 = CreateWindow("COMBOBOX", "",
CBS_DROPDOWN | WS_CHILD | WS_VISIBLE,
(112 * LOWORD(dwBaseUnits)) / 4,
(2 * HIWORD(dwBaseUnits)) / 8,
(100 * LOWORD(dwBaseUnits)) / 4,
(50 * HIWORD(dwBaseUnits)) / 8,
hwnd, NULL, hinst, NULL);
/* Get the edit window handle for each combo box. */
pt.x = 1;
pt.y = 1;
hwndEdit1 = ChildWindowFromPoint(hwndCombo1, pt);
hwndEdit2 = ChildWindowFromPoint(hwndCombo2, pt);
/*
* Change the window procedure for both edit windows
* to the subclass procedure.
*/
lpfnEditWndProc = (WNDPROC) SetWindowLong(hwndEdit1,
GWL_WNDPROC, (DWORD) SubClassProc);
SetWindowLong(hwndEdit2, GWL_WNDPROC,
(DWORD) SubClassProc);
break;
case WM_SETFOCUS:
SetFocus(hwndCombo1);
break;
case WM_TAB:
if (GetFocus() == hwndEdit1)
SetFocus(hwndCombo2);
else
SetFocus(hwndCombo1);
break;
case WM_ESC:
hwndCombo = GetFocus() == hwndEdit1 ?
hwndCombo1 : hwndCombo2;
/* Clear the current selection. */
SendMessage(hwndCombo, CB_SETCURSEL,
(WPARAM) (-1), 0);
/* Set the focus to the main window. */
SetFocus(hwndMain);
break;
case WM_ENTER:
hwndCombo = GetFocus() == hwndEdit1 ?
hwndCombo1 : hwndCombo2;
SetFocus(hwndMain);
/* If there is no current selection, set one. */
if (SendMessage(hwndCombo, CB_GETCURSEL, 0, 0)
== CB_ERR) {
if (SendMessage(hwndCombo, WM_GETTEXT,
sizeof(achTemp), (LPARAM) achTemp) == 0)
break; /* empty selection field */
dwIndex = SendMessage(hwndCombo,
CB_FINDSTRINGEXACT, (WPARAM) (-1),
(LPARAM) achTemp);
/* Add the string, if necessary, and select it. */
if (dwIndex == CB_ERR)
dwIndex = SendMessage(hwndCombo, CB_ADDSTRING,
0, (LPARAM) achTemp);
if (dwIndex != CB_ERR)
SendMessage(hwndCombo, CB_SETCURSEL,
dwIndex, 0);
}
break;
.
. /* Process additional messages. */
.
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
/********************************************************
FUNCTION: SubClassProc
PURPOSE: Process TAB and ESCAPE keys, and pass all
other messages to the class window
procedure.
*********************************************************/
LRESULT CALLBACK SubClassProc(hwnd, msg, wParam, lParam)
HWND hwnd;
UINT msg;
WPARAM wParam;
LPARAM lParam;
{
switch (msg) {
case WM_KEYDOWN:
switch (wParam) {
case VK_TAB:
SendMessage(hwndToolbar, WM_TAB, 0, 0);
return 0;
case VK_ESCAPE:
SendMessage(hwndToolbar, WM_ESC, 0, 0);
return 0;
case VK_RETURN:
SendMessage(hwndToolbar, WM_ENTER, 0, 0);
return 0;
}
break;
case WM_KEYUP:
case WM_CHAR:
switch (wParam) {
case VK_TAB:
case VK_ESCAPE:
case VK_RETURN:
return 0;
}
}
/*
* Call the original window procedure for default
* processing.
*/
return CallWindowProc(lpfnEditWndProc, hwnd,
msg, wParam, lParam);
}