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中文网其他相关文章!

热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

Windows 11 的原生应用(如文件资源管理器)和其他 shell 应用默认使用圆角和 Fluent Design 元素(如 Acrylic)。除了圆角,Windows 11 的另一个重要设计特点是云母等材质,它将应用程序的背景颜色与桌面对齐。云母与亚克力类似,但其工作方式略有不同。正如微软所描述的,Windows Mica 材料通过将背景与应用程序对齐来创建“颜色层次结构

用于build22523的新Windows11SDK透露,微软正在为Windows11开发新的模糊效果。该效果称为Tabbed,并且是对Acrylic和Mica的补充。22523SDK中的新DWMWA_SYSTEMBACKDROP_TYPE、云母、亚克力的公共Win32API及其奇怪的新“选项卡”混合:pic.twitter.com/dbsu7ZFiIi-一切都回来了(@StartIsBack)2021年12月15日可以在以下SDK的示例应用程序

防病毒软件有时可能会在 Windows 32 笔记本电脑上显示一条警告,指出 Trojan/win11.casdet rfn。它表示PC感染了特洛伊木马恶意软件,导致其出现故障。幸运的是,有一些可能的方法可以解决此问题,如下所述。此外,您可能对我们关于 cdn.districtm.io 是否为弹出窗口/病毒/恶意软件的详细指南感兴趣。什么是 Trojan/win32.casdet rfn?Trojan/win32.casdet rfn 是一种严重的木马病毒感染,可以超越系统并杀死其进程,使其容易

win32和win64的区别是:1、win32是指Microsoft Windows操作系统的32位环境,win64是指Microsoft Windows操作系统的64位版本,比32位版本更加稳定快速;2、win32最高支持2G的内存,win64必须是4G以上内存;3、win64支持基于64位的处理器,而win32却不能完全支持;4、win32追求简洁,win64追求性能。

早在2021年8月,微软就承诺Windows10和Windows11上的OneNote将在未来几个月内收到一系列主要功能更新,这是这家科技巨头将多个版本的笔记应用程序统一为一个单一版本的努力的一部分客户。OneNote在过去几年中发生了许多变化。2018年,当微软真正希望人们使用其UWP版本的OneNote时,该公司停止将原始且功能丰富的OneNote版本与预装的Office应用程序捆绑在一起。相反,微软只提供了UWP客户端并为现代版本添加了新功能。微软后来改

掌握Java海康SDK二次开发的必备技巧引言:随着信息技术的迅猛发展,视频监控系统在各个领域得到了广泛的应用。而作为国内领先的视频监控解决方案提供商,海康威视的产品和技术一直在市场中占据着重要的地位。为了满足不同项目的需求,海康威视提供了SDK供开发者进行二次开发。本文将介绍一些掌握Java海康SDK二次开发的必备技巧,并附上相应的代码示例。一、了解海康威视

WindowsAppSDK是一组工具和API,开发人员可以在其Windows应用程序中使用这些工具和API,以便在使用Windows10(版本1809及更高版本)和Windows11的各种设备上提供“一致”的功能。了解它确实很重要它不会取代现有的应用程序类型,例如.NET或WindowsSDK,它只是提供一个统一的API工具集,可以用来补充您现有的应用程序。今天,微软发布了具有许多新功能的WindowsAppSDK1.2版本。此版本的亮点可能是第三方开发人

sdk全称“Software Development Kit”,中文意思为“软件开发工具包”,是由硬件平台、操作系统(OS)或编程语言的制造商提供的一套工具。SDK可协助软件开发人员面向特定的平台、系统或编程语言创建应用。一个基本的SDK通常由编译器、调试器和应用编程接口(API)组成,但也可能包含其他内容,比如:文档、库、运行时/开发环境、测试/分析工具、网络协议等。
