關於BS_OWNERDRAW的用法

轉:http://blog.csdn.net/kof2001kop/article/details/7233844


BS_OWNERDRAW用於自繪按鈕,通常與WM_CTLCOLORBTN消息連用,如下:

  1. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  2. {  
  3.     static HWND button0;  
  4.   
  5.     switch (message)  
  6.     {  
  7.     case WM_CREATE:  
  8.         button0 = CreateWindow(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 20, 20, 400, 200,  
  9.                                 hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);    
  10.         return 0;  
  11.   
  12.     case WM_CTLCOLORBTN:  
  13.         return (LRESULT)CreateSolidBrush(RGB(0, 255, 0));  
  14.               
  15.     case WM_DESTROY:  
  16.         PostQuitMessage(0);  
  17.         return 0;  
  18.     }  
  19.   
  20.     return DefWindowProc(hwnd, message, wParam, lParam);  
  21. }  
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函數連用,如下:

  1. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  2. {  
  3.     static HWND button0;  
  4.   
  5.     switch (message)  
  6.     {  
  7.     case WM_CREATE:  
  8.         button0 = CreateWindow(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_ICON, 20, 20, 400, 200,  
  9.                                 hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);    
  10.         SendMessage(button0, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIcon(NULL, IDI_ERROR));  
  11.         return 0;  
  12.   
  13.     case WM_CTLCOLORBTN:                                  //因爲沒有了BS_OWNERDRAW,所以被忽略了  
  14.         return (LRESULT)CreateSolidBrush(RGB(0, 255, 0)); //不起任何作用  
  15.               
  16.     case WM_DESTROY:  
  17.         PostQuitMessage(0);  
  18.         return 0;  
  19.     }  
  20.   
  21.     return DefWindowProc(hwnd, message, wParam, lParam);  
  22. }  
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,那麼按鈕會既有位圖,又有自繪顏色嗎?

即:

  1. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  2. {  
  3.     static HWND button0;  
  4.   
  5.     switch (message)  
  6.     {  
  7.     case WM_CREATE:  
  8.         button0 = CreateWindow(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW | BS_ICON, 20, 20, 400,  
  9.                                200, hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);    
  10.         SendMessage(button0, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIcon(NULL, IDI_ERROR)); //因爲有了BS_OWNERDRAW,導致不起作用  
  11.         return 0;  
  12.   
  13.     case WM_CTLCOLORBTN:                                  //因爲有了BS_OWNERDRAW,再次被觸發  
  14.         return (LRESULT)CreateSolidBrush(RGB(0, 255, 0));   
  15.   
  16.     case WM_DESTROY:  
  17.         PostQuitMessage(0);  
  18.         return 0;  
  19.     }  
  20.   
  21.     return DefWindowProc(hwnd, message, wParam, lParam);  
  22. }  
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)來改變按鈕內文字,都將無效陷入死循環

發佈了8 篇原創文章 · 獲贊 1 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章