WM_CTLCOLORBTN 应与BS_OWNERDRAW 一起使用。
也就是说,只有添加了BS_OWNERDRAW,才会触发WM_CTLCOLORBTN,并且可以重绘按钮。
但是当你使用BS_OWNERDRAW时,你原来的复选框样式会被替换,像这样。
check = CreateWindowEx(0,L"BUTTON",L"text", WS_CHILD | WS_VISIBLE | BS_CHECKBOX | BS_OWNERDRAW, 150, 100, 60, 20, hWnd, (HMENU)ID_CHECK, (HINSTANCE)GetWindowLong(hWnd, GWLP_HINSTANCE), NULL);
case WM_CTLCOLORBTN:
{
return (INT_PTR)CreateSolidBrush(RGB(0, 0, 0));
break;
}
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT pDIS = (LPDRAWITEMSTRUCT)lParam;
if (pDIS->hwndItem == check)
{
SetTextColor(pDIS->hDC, RGB(255, 255, 255));
SetBkColor(pDIS->hDC, RGB(0, 0, 0));
WCHAR Text[99];
int len = SendMessage(check, WM_GETTEXT,
ARRAYSIZE(Text), (LPARAM)Text);
TextOut(pDIS->hDC, pDIS->rcItem.left, pDIS->rcItem.top, Text, len);
}
return TRUE;
}
调试结果:
你会发现和你想的不一样。
根据 MSDN,创建一个所有者绘制的按钮。所有者窗口
当按钮的视觉方面有时收到 WM_DRAWITEM 消息
改变了。不要将 BS_OWNERDRAW 样式与任何其他按钮组合
样式。
所以,我建议你这样做。
check = CreateWindowEx(0,L"BUTTON",L"text123", WS_CHILD | WS_VISIBLE | BS_CHECKBOX ,150, 100, 60, 20, hWnd, (HMENU)ID_CHECK, (HINSTANCE)GetWindowLong(hWnd, GWLP_HINSTANCE), NULL);
case WM_CTLCOLORSTATIC:
{
HDC hdc = (HDC)wParam;
HWND hWnd = (HWND)lParam;
if (hWnd == check)
{
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(255, 255, 255));
return (INT_PTR)CreateSolidBrush(RGB(0, 0, 0));
}
break;
}
通过触发WM_CTLCOLORSTATIC,文字和背景颜色自绘。