搜索
首页运维windows运维Win32 SDK基础(十二)之WM_PAINT消息的处理(图)

一、引言

        在计算机中,屏幕上显示的一切东西几乎都是绘制的,包括窗口、对话框、图片、以及一切文字,而WM_PAINT消息就是在绘制这些对象时,系统触发的消息。我们在计算机中的每一个操作,几乎都会触发这个消息,它也是WIndows中最重要的消息之一。本文主要针对该消息进行试验,以进行全面的学习。

二、WM_PAINT基础

 2.1 宏定义

#define WM_PAINT                        
0x000F

2.2 携带参数

        我们知道,在使用sendmessage/postmessage发送消息时,往往会携带WPARAM和LPARAM两个参数,而使用GetMessage或者PeekMessage接收消息时,也会接收到这两个参数。其中部分消息,会在参数中携带一些必要信息,比如鼠标位置、窗口长度和宽度等等。WM_PAINT的这两个参数为空,没有携带消息。

2.3 触发时机

        为了获取到该消息的触发时机,我们先创建一个Win32窗口项目作为试验对象。其窗口的处理函数定义如下:

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
	switch (uMsg)  
	{  
	case WM_DESTROY:  
		PostQuitMessage(0);//可以使GetMessage返回0  
		break;
	case  WM_PAINT:
		{
			WriteConsole(hOutput,"WM_PAIN\n",10,NULL,NULL);
		}
		break;
	default:  
		break;  
	}  
	return DefWindowProc(hWnd, uMsg, wParam, lParam);  
}

        我们WM_PAINT的处理语句中,向控制台的标准输出,写入了一个"WM_PAINT\n"的字符串,以此来验证触发了WM_PAINT消息。下面就WM_PAINT的触发时机分别进行验证:

1、程序启动时,绘制窗口时触发。

        在我们启动程序时,由于需要绘制窗口,会触发WM_PAINT消息,此时会打印上述字符串:


2、用鼠标调整窗口的大小,时会连续触发:

        由于调整窗口大小时,需要不断的重绘窗口,所以此时表现出来的就是不断的触发WM_PAINT消息:


3、最小化时不会触发WM_PAINT消息,但是从最小化还原时会进行触发

        下面这张图,是在两次从最小化到还原窗口的过程,可以看到多了两次字符串的打印


4、最大化时会触发WM_PAINT消息

        当图片最大化和还原后分别触发一次WM_PAINT消息,如下图所示:


5、当向屏幕外拖动窗口时,不会触发WM_PAINT消息,但是拉回到屏幕内时会不断的触发WM_PAINT消息

        下面的截图,就是在将窗口拉回屏幕时,窗口在不断的进行重绘,触发着WM_PAINT消息。


6、使用InvalidateRect函数触发WM_PAINT消息

        InvalidateRect的函数原型如下,每次调用都会触发一次WM_PAINT消息:

BOOL InvalidateRect(
HWND hWnd, // handle of window with changed update region
CONST RECT *lpRect, // address of rectangle coordinates
BOOL bErase // erase-background flag
);

hWnd:要更新的客户区所在的窗体的句柄。如果为NULL,则系统将在函数返回前重新绘制所有的窗口, 然后发送 WM_ERASEBKGND 和 WM_PAINT 给窗口过程处理函数。
lpRect:无效区域的矩形代表,它是一个结构体指针,存放着矩形的大小。如果为NULL,全部的窗口客户区域将被增加到更新区域中。
bErase:指出无效矩形被标记为有效后,是否重画该区域,重画时用预先定义好的画刷。当指定TRUE时需要重画。
返回值:
函数成功则返回非零值,否则返回零值。

        为了验证InvalidateRect函数的作用,我们需要在窗口处理函数中增加一个对WM_LBUTTONDOWN消息的处理,每点击一次鼠标左键就调用一次InvalidateRect:

//窗口处理函数  
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
	switch (uMsg)  
	{  
	case WM_DESTROY:  
		PostQuitMessage(0);//可以使GetMessage返回0  
		break;
	case  WM_PAINT:
		{
			WriteConsole(hOutput,"WM_PAIN\n",10,NULL,NULL);
		}
	case WM_LBUTTONDOWN:
		{
			InvalidateRect(hWnd,NULL,true);
		}
		break;
	default:  
		break;  
	}  
	return DefWindowProc(hWnd, uMsg, wParam, lParam);  
}

        下图为执行结果,点击了3次鼠标左键,触发了3次WM_PAINT消息。

总结:

        触发WM_PAINT消息的本质是改变窗口对应的显存的大小就触发一次,我们进行的每一次窗口最大化、最小化并恢复都是因为改变了窗口的显存而触发了该消息。在我们向屏幕外面拖动窗口时,这点比较特殊,窗口的显存是在一点点被擦除的,此时不会触发WM_PAINT,但是拉回窗口后,显存需要将擦除的部分重新绘制,这就又会触发一次该消息。而InvalidateRect函数,就是通过强制的清除并重绘显存来实现触发WM_PAINT消息。

三、WM_PAINT消息的处理

        我们尝试处理WM_PAINT消息,并在窗口上绘制一个矩形,绘图步骤如下:

1、开始绘图处理

HDC BeginPaint(
        HWND hwnd,//绘图窗口
        LPPAINTSTRUCT  lpPaint
	);

        我们利用BeginPaint获取绘图设备的句柄---一个HDC对象,然后在改绘图设备上进行绘制。

2、利用HDC对象进行绘图

3、结束绘图处理

Bool EndPoint(
        HWND hWnd,
        CONST PAINTSTRUCT *lpPaint
);

        绘制过程参考下面的代码:

//窗口处理函数  
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
	
	switch (uMsg)  
	{  
	case WM_DESTROY:  
		PostQuitMessage(0);//可以使GetMessage返回0  
		break;
	case  WM_PAINT:
		{
			PAINTSTRUCT pt;
			HDC hdc;
			hdc=BeginPaint(hWnd,&pt);
			Rectangle(hdc,0,0,100,100);
			EndPaint(hWnd,&pt);
		}
	case WM_LBUTTONDOWN:
		{
			//InvalidateRect(hWnd,NULL,true);
		}
		break;
	default:  
		break;  
	}  
	return DefWindowProc(hWnd, uMsg, wParam, lParam);  
}

        执行结果如下,我们成功绘制了一个矩形:


以上是Win32 SDK基础(十二)之WM_PAINT消息的处理(图)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。