Using Owner Drawn Buttons The parent window of an owner-drawn button typically responds to at least three messages for the button: WM_INITDIALOG WM_COMMAND WM_DRAWITEM When you must paint an owner-drawn button, the system sends the parent window a WM_DRAWITEM message whose lParam parameter is a pointer to a DRAWITEMSTRUCT structure. Use this structure with all owner-drawn controls to provide the application with the information it requires to paint the control. The itemAction and itemState members of the DRAWITEMSTRUCT structure define how to paint an owner-drawn button. The following example shows how to process WM_INITDIALOG, WM_DRAWITEM, and WM_COMMAND messages for owner-drawn buttons. This example demonstrates how to draw one of two bitmaps for a control, depending on whether the control is selected. You would typically use the wParam parameter of the WM_DRAWITEM message to identify the control; in this example, only one control is assumed. Hide ExampleBOOL CALLBACK OwnDrawProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdcMem; LPDRAWITEMSTRUCT lpdis;
switch (message) { case WM_INITDIALOG:
// hinst, hbm1 and hbm2 are defined globally. 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) // if selected SelectObject(hdcMem, hbm2); else SelectObject(hdcMem, hbm1);
// Destination StretchBlt( lpdis->hDC, // destination DC lpdis->rcItem.left, // x upper left lpdis->rcItem.top, // y upper left
// The next two lines specify the width and // height. lpdis->rcItem.right - lpdis->rcItem.left, lpdis->rcItem.bottom - lpdis->rcItem.top, hdcMem, // source device context 0, 0, // x and y upper left 32, // source bitmap width 32, // source bitmap height SRCCOPY); // raster operation
DeleteDC(hdcMem); return TRUE;
case WM_COMMAND: if (wParam == IDOK || wParam == IDCANCEL) { EndDialog(hDlg, TRUE); return TRUE; } if (HIWORD(wParam) == BN_CLICKED) { switch (LOWORD(wParam)) { case IDC_OWNERDRAW:
// application-defined processing
break; } } break;
case WM_DESTROY: DeleteObject(hbm1); // delete bitmaps DeleteObject(hbm2);
http://www.vckbase.com/english/code/buttonctrl/
The parent window of an owner-drawn button typically responds to at least three messages for the button: WM_INITDIALOG
WM_COMMAND
WM_DRAWITEM
When you must paint an owner-drawn button, the system sends the parent window a WM_DRAWITEM message whose lParam parameter is a pointer to a DRAWITEMSTRUCT structure. Use this structure with all owner-drawn controls to provide the application with the information it requires to paint the control. The itemAction and itemState members of the DRAWITEMSTRUCT structure define how to paint an owner-drawn button. The following example shows how to process WM_INITDIALOG, WM_DRAWITEM, and WM_COMMAND messages for owner-drawn buttons. This example demonstrates how to draw one of two bitmaps for a control, depending on whether the control is selected. You would typically use the wParam parameter of the WM_DRAWITEM message to identify the control; in this example, only one control is assumed. Hide ExampleBOOL CALLBACK OwnDrawProc(HWND hDlg, UINT message, WPARAM wParam,
LPARAM lParam)
{
HDC hdcMem;
LPDRAWITEMSTRUCT lpdis;
switch (message)
{
case WM_INITDIALOG:
// hinst, hbm1 and hbm2 are defined globally.
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) // if selected
SelectObject(hdcMem, hbm2);
else
SelectObject(hdcMem, hbm1);
// Destination
StretchBlt(
lpdis->hDC, // destination DC
lpdis->rcItem.left, // x upper left
lpdis->rcItem.top, // y upper left
// The next two lines specify the width and
// height.
lpdis->rcItem.right - lpdis->rcItem.left,
lpdis->rcItem.bottom - lpdis->rcItem.top,
hdcMem, // source device context
0, 0, // x and y upper left
32, // source bitmap width
32, // source bitmap height
SRCCOPY); // raster operation
DeleteDC(hdcMem);
return TRUE;
case WM_COMMAND:
if (wParam == IDOK
|| wParam == IDCANCEL)
{
EndDialog(hDlg, TRUE);
return TRUE;
}
if (HIWORD(wParam) == BN_CLICKED)
{
switch (LOWORD(wParam))
{
case IDC_OWNERDRAW:
// application-defined processing
break;
}
}
break;
case WM_DESTROY:
DeleteObject(hbm1); // delete bitmaps
DeleteObject(hbm2);
break;
}
return FALSE;
UNREFERENCED_PARAMETER(lParam);
}
2,重载 DrawItem 函数,并在里面写入画图的代码。
3,可以重载鼠标的一些消息处理函数,来动画你的按钮。网上有很多实例,不防参考一下。不管怎样,一定是按上面三个步骤来的。