更新时间:2015-10-19 16:18:20浏览次数:1+次
HBRUSH hBrush = (HBRUSH)GetClassLong(hwnd, GCL_HBRBACKGROUND);
你需要用一个HBRUSH画刷类型的变量来接收得到的画刷。因为GetClassLong函数返回的是LONG类型的值,与HBRUSH类型不一样,所以要强制转换。在《Windows零基础入门:4.1 获取窗口类信息之查询窗口类函数详细介绍》,你应该知道了GCL_HBRBACKGROUND索引的意义,就是用来获取窗口类的背景画刷句柄的。case WM_CREATE:// - 窗口创建时
static HBRUSH hBgOld;
hBgOld = (HBRUSH)GetClassLong(hwnd, GCL_HBRBACKGROUND);
这里说一下,这个窗口过程函数,是不停的执行的,每一次都是从头开始执行,所以,窗口过程函数里的变量如果是局部的,下次又重新定义初始化,所以,不要用局部变量存储需要一直存在的值。所以我们使用static局部变量或者全局变量。为了直观方便,所以使用static静态变量类型了。HBRUSH hBrush;
case WM_LBUTTONDOWN:
// - 通过窗口类背景画刷实现窗口背景颜色切换
hBrush = (HBRUSH)GetClassLong(hwnd, GCL_HBRBACKGROUND);// - 获取当前窗口类的背景画刷句柄
if(hBrush == hBgOld)
SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG)GetStockObject(BLACK_BRUSH));// - 如果存储的和获取的画刷一致,就用黑色画刷来设置
else
SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG)hBgOld);// - 如果获取的不是存储的画刷,就用存储的恢复
当鼠标左键不停的单击,就实现不停的切换窗口背景画刷。那么此时我们让背景重新绘画一下,就可以反映出来效果了。因为默认的窗口重画,会使用窗口类指定的背景画刷来重绘的。而我们刚好就修改了窗口类的背景画刷,就可以用我们设置的画刷来切换窗口背景。虽然这是在绘画,但是不用跟我们写任何绘画代码,我们只是改变了绘画的工具而已,给他换了画刷而已,然后系统拿到的就是不同的画刷,画出来的自然就不一样。InvalidateRect(hwnd, NULL, TRUE);
当然,我们只看主窗口,单击可以不停的切换背景颜色。这说明修改窗口类背景画刷改变了窗口的背景颜色,而且修改后就可以了。这意思是,窗口类信息和窗口是动态联系的,窗口需要重绘会去查询窗口类的,而不是创建窗口完毕就和窗口类断绝关系的。如果只看一个窗口,是不够说服力的。所以我们创建了两个窗口。当第一个窗口单击变成黑色之后,表面窗口类的背景画刷设置成了黑色。如果不考虑主窗口,那么窗口2默认的是白色的,然后再点击就会变成黑色的。但是事实上,单击窗口2时第一次并没有变成黑色,而是依然是白色。因为当窗口2单击时获取窗口类背景画刷时已经变成了黑色,所以,他就应该设置成白色的。所以就和默认的一致,所以画出来没有变化。再单击一次窗口2,它就变黑了。这就表明了他们确实在共享一个窗口类的信息,因为修改窗口类背景画刷是相互影响的。这里简单的说一下,SetClassLong就是设置窗口类信息的函数,我们在修改窗口类部分再一个个介绍,这里知道是修改就行了。第二个参数就是索引标志,和GetClassLong指示的窗口类成员是一样的。第三个参数就是传值进去修改。
下面是一个窗口单击前后的效果:
下面是两个窗口的效果图:
#include <Windows.h>
#include <tchar.h>
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);// - 窗口过程函数的声明
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, PSTR szCmdLine, int iCmdShow)
{
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WinProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = L"MyClass";
ATOM atomCls = RegisterClass(&wndclass);
if (!atomCls)
{
MessageBox(NULL, L"注册窗口类失败,此程序需要运行在Windows NT平台下。", L"注册窗口类提示", MB_ICONERROR);
return 0;
}
HWND hwnd = CreateWindow(MAKEINTRESOURCE(atomCls), L"主窗口_C++技术网", WS_OVERLAPPEDWINDOW, 100, 100, 600, 600, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
HWND hwnd2 = CreateWindow(MAKEINTRESOURCE(atomCls), L"窗口2_C++技术网", WS_OVERLAPPEDWINDOW, 100, 100, 600, 600, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd2, SW_SHOWNORMAL);
UpdateWindow(hwnd2);
MSG msg;
// - 消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT rect;
static HBRUSH hBgOld;//-静态变量可以长期存在
HBRUSH hBrush;
switch (message)
{
case WM_CREATE:
hBgOld = (HBRUSH)GetClassLong(hwnd, GCL_HBRBACKGROUND);// - 第一次存储原始的画刷,白色画刷
return 0;
case WM_LBUTTONDOWN:
// - 通过窗口类背景画刷实现窗口背景颜色切换
hBrush = (HBRUSH)GetClassLong(hwnd, GCL_HBRBACKGROUND);// - 获取当前窗口类的背景画刷句柄
if (hBrush == hBgOld)
SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG)GetStockObject(BLACK_BRUSH));// - 如果存储的和获取的画刷一致,就用黑色画刷来设置
else
SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG)hBgOld);// - 如果获取的不是存储的画刷,就用存储的恢复
InvalidateRect(hwnd, NULL, TRUE);// - 让指定的这个矩形大小无效,导致窗口重画。这样系统就会触发WM_PAINT使用窗口类的背景画刷绘制窗口无效区域。
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
相关资讯