Creating a Square Meal Dialog Box
Following are the dialog box procedure and supporting functions for the Square Meal dialog box.
HWND hwndMain;
HWND hwndEdit;
char achTemp[256]; /* temporary buffer */
HBITMAP hbmBread;
HBITMAP hbmDairy;
HBITMAP hbmFruit;
HBITMAP hbmMeat;
HBITMAP hbmBreadMask;
HBITMAP hbmDairyMask;
HBITMAP hbmFruitMask;
HBITMAP hbmMeatMask;
/********************************************************
FUNCTION: FoodDlgProc
PURPOSE: Dialog procedure for Food dialog box.
*********************************************************/
BOOL CALLBACK FoodDlgProc(hwndDlg, msg, wParam, lParam)
HWND hwndDlg;
UINT msg;
WPARAM wParam;
LPARAM lParam;
{
LPMEASUREITEMSTRUCT lpmis;
LPDRAWITEMSTRUCT lpdis;
HBITMAP hbmIcon;
HBITMAP hbmMask;
COLORREF clrBackground;
COLORREF clrForeground;
TEXTMETRIC tm;
HDC hdc;
HWND hwnd;
int x;
int y;
switch (msg) {
case WM_INITDIALOG:
/*
* Call an application-defined function to load
* bitmap resources.
*/
if (!LoadIconBitmaps()) {
EndDialog(hwndDlg, -1);
break;
}
/* Initialize the drop-down list box. */
if (!InitGroupList(hwndDlg)) {
DeleteIconBitmaps();
EndDialog(hwndDlg, -1);
break;
}
/* Select the first food group. */
SendDlgItemMessage(hwndDlg, IDCOMBO, CB_SETCURSEL,
0, 0);
/* List the foods and select the first food. */
InitFoodList(hwndDlg);
SendDlgItemMessage(hwndDlg, IDLIST, LB_SETCURSEL,
0, 0);
break;
case WM_MEASUREITEM:
lpmis = (LPMEASUREITEMSTRUCT) lParam;
if (lpmis->itemHeight < CY_BITMAP + 2)
lpmis->itemHeight = CY_BITMAP + 2;
break;
case WM_DRAWITEM:
lpdis = (LPDRAWITEMSTRUCT) lParam;
if (lpdis->itemID == -1) /* empty item */
break;
/* Determine the bitmaps used to draw the icon. */
switch (lpdis->itemData) {
case ID_BREAD:
hbmIcon = hbmBread;
hbmMask = hbmBreadMask;
break;
case ID_DAIRY:
hbmIcon = hbmDairy;
hbmMask = hbmDairyMask;
break;
case ID_FRUIT:
hbmIcon = hbmFruit;
hbmMask = hbmFruitMask;
break;
default: /* meat */
hbmIcon = hbmMeat;
hbmMask = hbmMeatMask;
break;
}
/*
* The colors depend on whether the item is
* selected.
*/
clrForeground = SetTextColor(lpdis->hDC,
GetSysColor(lpdis->itemState & ODS_SELECTED ?
COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));
clrBackground = SetBkColor(lpdis->hDC,
GetSysColor(lpdis->itemState & ODS_SELECTED ?
COLOR_HIGHLIGHT : COLOR_WINDOW));
/* Calculate the vertical and horizontal position. */
GetTextMetrics(lpdis->hDC, &tm);
y = (lpdis->rcItem.bottom + lpdis->rcItem.top -
tm.tmHeight) / 2;
x = LOWORD(GetDialogBaseUnits()) / 4;
/* Get and display the text for the list item. */
SendMessage(lpdis->hwndItem, CB_GETLBTEXT,
lpdis->itemID, (LPARAM) (LPCSTR) achTemp);
ExtTextOut(lpdis->hDC, CX_BITMAP + 2 * x, y,
ETO_CLIPPED | ETO_OPAQUE, &lpdis->rcItem,
achTemp, lstrlen(achTemp), NULL);
/* Restore the previous colors. */
SetTextColor(lpdis->hDC, clrForeground);
SetBkColor(lpdis->hDC, clrBackground);
/* Show the icon. */
hdc = CreateCompatibleDC(lpdis->hDC);
if (hdc == NULL)
break;
SelectObject(hdc, hbmMask);
BitBlt(lpdis->hDC, x, lpdis->rcItem.top + 1,
CX_BITMAP, CY_BITMAP, hdc, 0, 0, SRCAND);
SelectObject(hdc, hbmIcon);
BitBlt(lpdis->hDC, x, lpdis->rcItem.top + 1,
CX_BITMAP, CY_BITMAP, hdc, 0, 0, SRCPAINT);
DeleteDC(hdc);
/* If the item has the focus, draw focus rectangle. */
if (lpdis->itemState & ODS_FOCUS)
DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDCOMBO:
if (HIWORD(wParam) == CBN_SELENDOK) {
InitFoodList(hwndDlg);
SendDlgItemMessage(hwndDlg, IDLIST,
LB_SETCURSEL, 0, 0);
}
break;
case IDLIST:
if (HIWORD(wParam) != LBN_DBLCLK)
break;
/* For a double-click, process the OK case. */
case IDOK:
/* Get the text for the selected list item. */
hwnd = GetDlgItem(hwndDlg, IDLIST);
SendMessage(hwnd, LB_GETTEXT,
SendMessage(hwnd, LB_GETCURSEL, 0, 0),
(LPARAM) achTemp);
/* Insert the text into the edit window. */
SendMessage(hwndEdit, EM_REPLACESEL, 0,
(LPARAM) achTemp);
EndDialog(hwndDlg, 0);
break;
case IDCANCEL:
hwnd = GetDlgItem(hwndDlg, IDCOMBO);
if (SendMessage(hwnd, CB_GETDROPPEDSTATE,
0, 0))
SendMessage(hwnd, CB_SHOWDROPDOWN,
FALSE, 0);
else
EndDialog(hwndDlg, 0);
}
break;
case WM_DESTROY:
/*
* Call the application-defined function to free
* bitmap resources.
*/
DeleteIconBitmaps();
break;
default:
return FALSE;
}
return TRUE;
}
/********************************************************
FUNCTION: InitGroupList
PURPOSE: Initializes the "food groups" drop-down
list box.
COMMENTS: The ID of the food group associated with
each list item is saved as item data.
*********************************************************/
BOOL PASCAL InitGroupList(HWND hwndDlg)
{
HWND hwndCombo = GetDlgItem(hwndDlg, IDCOMBO);
DWORD dwIndex;
/* Add an item for each food group. */
LoadString(hinst, ID_BREAD, achTemp, sizeof(achTemp));
dwIndex = SendMessage(hwndCombo, CB_ADDSTRING, 0,
(LPARAM) (LPCSTR) achTemp);
SendMessage(hwndCombo, CB_SETITEMDATA, dwIndex, ID_BREAD);
LoadString(hinst, ID_DAIRY, achTemp, sizeof(achTemp));
dwIndex = SendMessage(hwndCombo, CB_ADDSTRING, 0,
(LPARAM) (LPCSTR) achTemp);
SendMessage(hwndCombo, CB_SETITEMDATA, dwIndex, ID_DAIRY);
LoadString(hinst, ID_FRUIT, achTemp, sizeof(achTemp));
dwIndex = SendMessage(hwndCombo, CB_ADDSTRING, 0,
(LPARAM) (LPCSTR) achTemp);
SendMessage(hwndCombo, CB_SETITEMDATA, dwIndex, ID_FRUIT);
LoadString(hinst, ID_MEAT, achTemp, sizeof(achTemp));
dwIndex = SendMessage(hwndCombo, CB_ADDSTRING, 0,
(LPARAM) (LPCSTR) achTemp);
SendMessage(hwndCombo, CB_SETITEMDATA, dwIndex, ID_MEAT);
return TRUE;
}
/********************************************************
FUNCTION: InitFoodList
PURPOSE: Clears the contents of the food list, and
adds the names of foods for the current
food group.
*********************************************************/
void PASCAL InitFoodList(HWND hwndDlg)
{
HWND hwndCombo = GetDlgItem(hwndDlg, IDCOMBO);
HWND hwndList = GetDlgItem(hwndDlg, IDLIST);
UINT idFoodGroup;
LPSTR lpsz;
LPSTR lpszEnd;
/* Determine the current food group. */
idFoodGroup = SendMessage(
hwndCombo,
CB_GETITEMDATA,
SendMessage(hwndCombo, CB_GETCURSEL, 0, 0),
0
);
/* Clear the list contents. */
SendMessage(hwndList, LB_RESETCONTENT, 0, 0);
.
. /* Add food names for the current food group. */
.
}