以下示例显示如何绘制包含五个所有者绘制项目的列表框:四个绘图工具和一个叉子。每个列表项显示为一个位图,后跟该对象的名称。按钮提示用户选择不像其他项目的一个项目。选择使用叉子的按钮显示“你是对的!”消息并关闭对话框。选择任何其他列表项目的按钮显示“再试一次!”信息。
除了标准列表框样式之外,列表框还具有LBS_OWNERDRAW和LBS_HASSTRINGS样式。代码通过发送LB_ADDSTRING消息来设置文本来初始化列表框,然后发送LB_SETITEMDATA消息,将位图与每个列表框项相关联。代码还通过处理WM_MEASUREITEM消息来设置每个列表框项目的高度,并通过处理WM_DRAWITEM消息为每个项目绘制文本和位图。
#define YBITMAP 20
DWORD APIENTRY DlgDrawProc(
#define BUFFER MAX_PATH
HBITMAP hbmpPencil, hbmpCrayon, hbmpMarker, hbmpPen, hbmpFork;
HBITMAP hbmpPicture, hbmpOld;
void AddItem(HWND hwnd,LPSTR lpstr,HBITMAP hbmp)
{
int nItem;
nItem = SendMessage(hwndList, LB_ADDSTRING, 0, lpstr);
SendMessage(hwndList, LB_SETITEMDATA, nItem, hbmp);
}
DWORD APIENTRY DlgDrawProc(la
HWND hDlg,/ *对话框的窗口句柄* /
UINT消息,/ *消息类型* /
UINT wParam,/ *消息特定信息* /
LONG lParam)
{
int nItem;
TCHAR tchBuffer[BUFFER];
HBITMAP hbmp;
HWND hListBox;
TEXTMETRIC tm;
int y;
HDC hdcMem;
LPMEASUREITEMSTRUCT lpmis;
LPDRAWITEMSTRUCT lpdis;
RECT rcBitmap;
switch(message){
case WM_INITDIALOG:
/ *加载位图。 * /
hbmpPencil = LoadBitmap(hinst, MAKEINTRESOURCE(700));
hbmpCrayon = LoadBitmap(hinst, MAKEINTRESOURCE(701));
hbmpMarker = LoadBitmap(hinst, MAKEINTRESOURCE(702));
hbmpPen = LoadBitmap(hinst, MAKEINTRESOURCE(703));
hbmpFork = LoadBitmap(hinst, MAKEINTRESOURCE(704));
/ *检索列表框句柄。*/
hListBox = GetDlgItem(hDlg, IDL_STUFF);
/*
*初始化列表框文本并关联位图
*与每个列表框项目。
*/
AddItem(hListBox, "pencil", hbmpPencil);
AddItem(hListBox, "crayon", hbmpCrayon);
AddItem(hListBox, "marker", hbmpMarker);
AddItem(hListBox, "pen", hbmpPen);
AddItem(hListBox, "fork", hbmpFork);
SetFocus(hListBox);
SendMessage(hListBox, LB_SETCURSEL, 0, 0);
return TRUE;
case WM_MEASUREITEM:
lpmis = (LPMEASUREITEMSTRUCT) lParam;
/ *设置列表框项目的高度。*/
lpmis->itemHeight = 20;
return TRUE;
case WM_DRAWITEM:
lpdis = (LPDRAWITEMSTRUCT) lParam;
/ *如果没有列表框项目,请跳过此消息。*/
if (lpdis->itemID == -1) {
break;
}
/*
*绘制列表框项目的位图和文本。画一个
*如果选择了位图的周围矩形。
*/
switch(lpdis- > itemAction){
case ODA_SELECT:
case ODA_DRAWENTIRE:
/ *显示与项目关联的位图。*/
hbmpPicture = (HBITMAP) SendMessage(lpdis->hwndItem,
LB_GETITEMDATA, lpdis->itemID, (LPARAM) 0);
hdcMem = CreateCompatibleDC(lpdis->hDC);
hbmpOld = SelectObject(hdcMem, hbmpPicture);
BitBlt(lpdis->hDC,
lpdis- > rcItem.left,lpdis- > rcItem.top,
lpdis- > rcItem.right - lpdis- > rcItem.left,
lpdis- > rcItem.bottom - lpdis- > rcItem.top,
hdcMem, 0, 0, SRCCOPY);
/ *显示与该项目相关联的文本。*/
SendMessage(lpdis- > hwndItem,LB_GETTEXT,
lpdis->itemID, (LPARAM) tchBuffer);
GetTextMetrics(lpdis->hDC, &tm);
y = (lpdis->rcItem.bottom + lpdis->rcItem.top -
tm.tmHeight) / 2;
TextOut(lpdis->hDC,
XBITMAP + 6,
y,
tchBuffer,
strlen(tchBuffer));
SelectObject(hdcMem, hbmpOld);
DeleteDC(hdcMem);
/ *是否选择项目? * /
if(lpdis- > itemState & ODS_SELECTED){
/*
*设置RECT坐标仅包围
*位图。
*/
rcBitmap.left = lpdis->rcItem.left;
rcBitmap.top = lpdis->rcItem.top;
rcBitmap.right = lpdis->rcItem.left + XBITMAP;
rcBitmap.bottom = lpdis->rcItem.top + YBITMAP;
/*
*围绕位图绘制一个矩形来指示
*选择。
*/
DrawFocusRect(lpdis->hDC, &rcBitmap);
}
break;
case ODA_FOCUS:
/*
*不要处理焦点变化。焦点插入符号
*(轮廓矩形)表示选择。
*哪一个? (IDOK)按钮指示最终
*选择。
*/
break;
}
return TRUE;
case WM_COMMAND:
开关(LOWORD(wParam)){
case IDOK:
/ *获取所选项目的文本。*/
nItem = SendMessage(GetDlgItem(hDlg, IDL_STUFF),
LB_GETCURSEL, 0, (LPARAM) 0);
hbmp = SendMessage(GetDlgItem(hDlg, IDL_STUFF),
LB_GETITEMDATA, nItem, 0);
/*
*如果项目不正确答案,请告诉
*用户再试一次。
*
*如果项目是正确的答案,祝贺
*用户并销毁对话框。
*/
if (hbmp != hbmpFork) {
MessageBox(hDlg, "Try again!", "Oops.", MB_OK);
return FALSE;
}
else {
MessageBox(hDlg,“你说得对!”,
"Congratulations.", MB_OK);
/ *通过。 * /
}
case IDCANCEL:
/ *销毁对话框。*/
EndDialog(hDlg, TRUE);
return TRUE;
默认:
return FALSE;
}
case WM_DESTROY:
/ *释放位图使用的任何资源。*/
DeleteObject(hbmpPencil);
DeleteObject(hbmpCrayon);
DeleteObject(hbmpMarker);
DeleteObject(hbmpPen);
DeleteObject(hbmpFork);
return TRUE;
默认:
return FALSE;
}
return FALSE;
}