轉:http://blog.csdn.net/kof2001kop/article/details/7233844
BS_OWNERDRAW用於自繪按鈕,通常與WM_CTLCOLORBTN消息連用,如下:
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- static HWND button0;
- switch (message)
- {
- case WM_CREATE:
- button0 = CreateWindow(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 20, 20, 400, 200,
- hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
- return 0;
- case WM_CTLCOLORBTN:
- return (LRESULT)CreateSolidBrush(RGB(0, 255, 0));
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND button0;
switch (message)
{
case WM_CREATE:
button0 = CreateWindow(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 20, 20, 400, 200,
hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
return 0;
case WM_CTLCOLORBTN:
return (LRESULT)CreateSolidBrush(RGB(0, 255, 0));
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
上述代碼的結果會顯示出一個綠色的按鈕。
但如果想在按鈕上顯示一個位圖或圖標,則不能使用BS_OWNERDRAW,而要用BS_ICON或BS_BITMAP,並和SendMessage函數連用,如下:
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- static HWND button0;
- switch (message)
- {
- case WM_CREATE:
- button0 = CreateWindow(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_ICON, 20, 20, 400, 200,
- hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
- SendMessage(button0, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIcon(NULL, IDI_ERROR));
- return 0;
- case WM_CTLCOLORBTN: //因爲沒有了BS_OWNERDRAW,所以被忽略了
- return (LRESULT)CreateSolidBrush(RGB(0, 255, 0)); //不起任何作用
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND button0;
switch (message)
{
case WM_CREATE:
button0 = CreateWindow(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_ICON, 20, 20, 400, 200,
hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
SendMessage(button0, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIcon(NULL, IDI_ERROR));
return 0;
case WM_CTLCOLORBTN: //因爲沒有了BS_OWNERDRAW,所以被忽略了
return (LRESULT)CreateSolidBrush(RGB(0, 255, 0)); //不起任何作用
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
上述代碼會顯示出一個帶有錯誤標記的按鈕,而WM_CTLCOLORBTN的觸發標誌是按鈕被重繪,因爲沒有了BS_OWNERDRAW,所以按鈕不能被重繪,即WM_CTLCOLORBTN消息不會被觸發。
但如果在上述代碼中,再加入BS_OWNERDRAW,那麼按鈕會既有位圖,又有自繪顏色嗎?
即:
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- static HWND button0;
- switch (message)
- {
- case WM_CREATE:
- button0 = CreateWindow(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW | BS_ICON, 20, 20, 400,
- 200, hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
- SendMessage(button0, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIcon(NULL, IDI_ERROR)); //因爲有了BS_OWNERDRAW,導致不起作用
- return 0;
- case WM_CTLCOLORBTN: //因爲有了BS_OWNERDRAW,再次被觸發
- return (LRESULT)CreateSolidBrush(RGB(0, 255, 0));
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND button0;
switch (message)
{
case WM_CREATE:
button0 = CreateWindow(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW | BS_ICON, 20, 20, 400,
200, hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
SendMessage(button0, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIcon(NULL, IDI_ERROR)); //因爲有了BS_OWNERDRAW,導致不起作用
return 0;
case WM_CTLCOLORBTN: //因爲有了BS_OWNERDRAW,再次被觸發
return (LRESULT)CreateSolidBrush(RGB(0, 255, 0));
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
上述代碼的結果是顯示一綠色的按鈕,而按鈕上不見任何的位圖。所以,如果在創建按鈕的窗口句柄時,在CreateWindow中使用了BS_OWNERDRAW,那麼就不能用SendMessage函數在按鈕上載入位圖或圖標了,即使有BS_ICON也不能載入。
PS: 在WM_CTLCOLORBTN內所做的一切代碼,只與設備環境句柄(HDC)有關,如果嘗試通過窗口句柄(HWND)來更改什麼,例如用SetWindowText(用到hwnd)來改變按鈕內文字,都將無效或陷入死循環。