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. */

.

}