所有者绘制的按钮的父窗口通常响应至少三个消息:WM_INITDIALOG,WM_COMMAND和WM_DRAWITEM.没有必要处理自己绘制的按钮的WM_MEASUREITEM消息。
当您必须绘制所有者绘制按钮时,Windows将父窗口发送到【lParam的】指向DRAWITEMSTRUCT结构的WM_DRAWITEM消息。将这个结构与所有所有者绘制的控件一起使用,为应用程序提供绘制控件所需的信息。ITEMSTATE结构的itemAction和ITEMSTATE成员定义了如何绘制所有者绘制的按钮。
以下示例显示如何处理所有者绘制的按钮的WM_INITDIALOG,WM_DRAWITEM和WM_COMMAND消息。此示例演示了如何绘制控件的两个位图中的一个,具体取决于是否选择了控件。通常使用WM_DRAWITEM消息的【wParam中】参数来识别控件;在这个例子中,只假设一个控件。
LRESULT APIENTRY OwnDrawProc(hDlg,message,wParam,lParam)
HWND hDlg; //对话框的窗口句柄
UINT message; //消息类型
UINT wParam; //消息特定信息
LONG lParam;
{
HDC hdcMem;
LPDRAWITEMSTRUCT lpdis;
switch(message){
case WM_INITDIALOG:
// hinst,hbm1和hbm2是全局定义的。
hbm1 = LoadBitmap((HANDLE) hinst, "OwnBit1");
hbm2 = LoadBitmap((HANDLE) hinst, "OwnBit2");
return TRUE;
case WM_DRAWITEM:
lpdis = (LPDRAWITEMSTRUCT) lParam;
hdcMem = CreateCompatibleDC(lpdis->hDC);
if (lpdis->itemState & ODS_SELECTED) //如果选择
SelectObject(hdcMem, hbm2);
其他
SelectObject(hdcMem, hbm1);
//目的地
StretchBlt(
lpdis->hDC, //目的地DC
lpdis->rcItem.left, // x左上角
lpdis->rcItem.top, //左上角
//接下来的两行指定宽度和
// height。
lpdis- > rcItem.right - lpdis- > rcItem.left,
lpdis- > rcItem.bottom - lpdis- > rcItem.top,
hdcMem, //源设备上下文
0, 0, // x和y左上角
32, //源位图宽度
32, //源位图高度
SRCCOPY); //光栅操作
DeleteDC(hdcMem);
return TRUE;
case WM_COMMAND:
if (wParam == IDOK
|| wParam == IDCANCEL) {
EndDialog(hDlg, TRUE);
return TRUE;
}
if (HIWORD(wParam) == BN_CLICKED) {
开关(LOWORD(wParam)){
case IDB_OWNERDRAW:
.
. //应用程序定义的处理
.
break;
}
}
break;
case WM_DESTROY:
DeleteObject(hbm1); //删除位图
DeleteObject(hbm2);
break;
}
return FALSE;
UNREFERENCED_PARAMETER(lParam);
}