关于BS_OWNERDRAW的用法

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);
}


 上述代码的结果会显示出一个绿色的按钮。

但如果想在按钮上显示一个位图或图标,则不能使用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);
}


 上述代码会显示出一个带有错误标记的按钮,而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);
}


上述代码的结果是显示一绿色的按钮,而按钮上不见任何的位图。所以,如果在创建按钮的窗口句柄时,在CreateWindow中使用了BS_OWNERDRAW,那么就不能用SendMessage函数在按钮上载入位图或图标了,即使有BS_ICON也不能载入。
 

PS: 在WM_CTLCOLORBTN内所做的一切代码,只与设备环境句柄(HDC)有关,如果尝试通过窗口句柄(HWND)来更改什么,例如用SetWindowText(用到hwnd)来改变按钮内文字,都将无效陷入死循环

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值