创建所有者列表框

【勇芳软件工作室】汉化HomePreviousNext

以下示例显示如何绘制包含五个所有者绘制项目的列表框:四个绘图工具和一个叉子。每个列表项显示为一个位图,后跟该对象的名称。按钮提示用户选择不像其他项目的一个项目。选择使用叉子的按钮显示“你是对的!”消息并关闭对话框。选择任何其他列表项目的按钮显示“再试一次!”信息。

除了标准列表框样式之外,列表框还具有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;

}