Win32 SDK基础(十)之详解几种常见的Windows消息处理的示例代码
一 引言
本文主要介绍几种Windows常见的消息的处理,在《Win32 SDK基础(8)—— Windows消息机制》中,我们介绍了WM_CREATE消息的处理,在窗口创建之前,我们利用消息处理函数弹出了一个MessageBox,本文在此基础之上,介绍WM_DESTROY、WM_SYSCOMMAND、WM_QUIT、WM_SIZE等其它常见的Windows消息。首先,我们引入在《Win32 SDK基础(8)—— Windows消息机制》文中的代码,后续的实验都在此代码的基础之上。
#include "stdafx.h" #include "MessageTs.h" HINSTANCE g_hInstance = 0; //窗口处理函数 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 break; case WM_CREATE: MessageBox(NULL,"WM_CREATE消息被处理了","消息处理",MB_OK); default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } //注册窗口类 BOOL Register(LPSTR lpClassName, WNDPROC wndProc) { WNDCLASSEX wce = { 0 }; wce.cbSize = sizeof(wce); wce.cbClsExtra = 0; wce.cbWndExtra = 0; wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wce.hCursor = NULL; wce.hIcon = NULL; wce.hIconSm = NULL; wce.hInstance = g_hInstance; wce.lpfnWndProc = wndProc; wce.lpszClassName = lpClassName; wce.lpszMenuName = NULL; wce.style = CS_HREDRAW | CS_VREDRAW; ATOM nAtom = RegisterClassEx(&wce); if (nAtom == 0) return FALSE; return true; } //创建主窗口 HWND CreateMain(LPSTR lpClassName, LPSTR lpWndName) { HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, g_hInstance, NULL); return hWnd; } //显示窗口 void Display(HWND hWnd) { ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); } //消息循环 void Message() { MSG nMsg = { 0 }; while (GetMessage(&nMsg, NULL, 0, 0)) { TranslateMessage(&nMsg); DispatchMessage(&nMsg); } } int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { // TODO: Place code here. g_hInstance = hInstance; BOOL nRet = Register("Main", WndProc); if (!nRet) { MessageBox(NULL, "注册失败", "Infor", MB_OK); return 0; } HWND hWnd = CreateMain("Main", "window"); Display(hWnd); Message(); return 0; }
二、WM_CREATE消息
我们还是要再介绍下WM_CREATE消息。因为在上一文中我们只通过弹出MessageBox验证了WM_CREATE消息的产生时机,却没有介绍它另外一个很重要的构成——WPARAM和LPARAM参数。我们在发送消息时,往往可以通过这两个参数携带一些信息。WM_CREATE消息是我们在创建窗口时由系统自动发送的消息,同样也会利用这两个参数携带信息。LPARAM携带了我们创建窗口的CreateWindowEx的12个参数信息,WPARAM没有被使用,下面我们在处理WM_CREATE消息时,在弹出的对话框上显示窗口类和窗口名称。
//窗口处理函数 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 break; case WM_CREATE: { CREATESTRUCT crt = *((CREATESTRUCT*)lParam); char buf[256] = {0}; sprintf(buf,"创建的窗口类名称是%s,窗口名称是%s",crt.lpszClass,crt.lpszName); MessageBox(NULL, buf, "消息处理", MB_OK); } default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
运行程序,我们发现在窗口创建之前我们成功捕获了窗口的注册窗口类名称和窗口名称,并在对话框上显示出来:
三、WM_DESTROY消息
这个消息在之前的文章中我们其实早已经解除过。他是Windows窗口关闭时发送的一个消息,简单点说就是,当你点击Windows窗口的关闭按钮时,会发出这个消息。我们在之前的代码中,处理这个消息的操作是PostQuitMessage(0),这其实是我们发送了一个接下来要介绍的WM_QUIT消息用来结束程序的进程。WM_DESTORY消息的LPARAM和WPARAM都没被使用,它一般被用来做一些窗口关闭前资源的回收和内存的释放工作等等,我们调用的PostQuitMessage(0)就是一个很常见的用法。
四、WM_QUIT消息
前面我们已经介绍过,这是我们使用PostQuitMessage(0)发送的一个消息,用来结束程序进程,它的WMPARAM是PostQuitMessage中传递的参数,LPARAM参数未被使用。通常情况下我们发送了WM_QUIT后,会引起消息循环中的GetMessage函数返回,从而使得进程退出。WM_QUIT消息是无法传递到我们自己的窗口处理函数中的。但是我们可以从侧面验证有这么一个消息:我们先在代码中增加对WM_QUIT消息的处理。
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 break; case WM_CREATE: { CREATESTRUCT crt = *((CREATESTRUCT*)lParam); char buf[256] = {0}; sprintf(buf,"创建的窗口类名称是%s,窗口名称是%s",crt.lpszClass,crt.lpszName); MessageBox(NULL, buf, "消息处理", MB_OK); } case WM_QUIT: { int param = (int)wParam; char buf[256]; sprintf(buf, "进程退出,退出码:%d", param); MessageBox(NULL, buf, "消息处理", MB_OK); } default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
运行程序,在关闭处理WM_CREATE消息的对话框后,发现弹出了我们验证WM_QUIT消息的对话框。
这是因为,弹出的处理WM_CREATE消息MessageBox也是一个窗口,但它属于我们的进程。每个窗口都有一个消息循环,但是消息队列一个进程却只有一个,当MessageBox的窗口关闭时,它的窗口处理函数也调用PostQuitMessage(0)发送了一个WM_QUIT消息。它的消息循环中GetMessage接收到WM_QUIT消息后返回并退出。而这个消息又会被我们的消息循环捕获到,但是由于它不是我们的窗口发出的消息,所以不会导致我们的GetMessage返回结束循环,反而被传给我们的窗口处理函数汇总进行处理,所以出现了上面截图显示的对话框。
五、WM_SYSCOMMAND消息
系统命令消息,当我们点击最大化、最小化和关闭命令时会触发这个消息(这么说来点击关闭按钮时会同时触发WM_DESTROY和WM_SYSCOMMAND两个消息哦)。它的wParam参数携带了具体的窗口操作:
关闭:SC_CLOSE
最大化:SC_MAXIMIZE
最小化:SC_MINIMIZE
这里只列举了三种常见的WM_SYSCOMMAND携带的参数宏,其它的可以参照MSDN。WM_SYSCOMMAND的lParam携带的是产生该消息的鼠标的位置,位置的X和Y坐标分别被存放在lParam的低位和高位字中,我们用下面的代码来验证在窗口最大化时,我们鼠标的位置:
case WM_SYSCOMMAND: { if (wParam == SC_MAXIMIZE) { short x = LOWORD(lParam); short y = HIWORD(lParam); char buf[256]; sprintf(buf, "窗口最大化,x坐标:%d,y坐标:%d", x,y); MessageBox(NULL, buf, "消息处理", MB_OK); } }
当我们点击窗口的最大化按钮时,出现下面的提示:
六 WM_SIZE消息
每当我们调整窗口的大小时,都会触发WM_SIZE消息。它的wParam参数携带的是该消息产生的原因:
SIZE_RESTORED —— 重新调整窗口大小
SIZE_MAXIMIZED —— 最大化显示
SIZE_ MINIMIZED —— 最小化显示
其他参数宏详见MSDN
它的lParam参数携带的是重新调整大小后的窗口的高和宽,其中低字节代表宽,高字节代表高,这里我们通过代码验证,当窗口最大化后窗口的高和宽:
case WM_SIZE: { if (wParam == SIZE_MAXIMIZED) { short width = LOWORD(lParam); short hight = HIWORD(lParam); char buf[256]; sprintf(buf, "窗口最大化,高度:%d,宽度:%d", hight, width); MessageBox(NULL, buf, "消息处理", MB_OK); } }
运行程序,最大化时可以显示最大化后的窗口高度和宽度:
以上是Win32 SDK基础(十)之详解几种常见的Windows消息处理的示例代码的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

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

热门文章

热工具

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

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

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

Dreamweaver CS6
视觉化网页开发工具

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

MySQL 中的复制粘贴包含以下步骤:选择数据,使用 Ctrl C(Windows)或 Cmd C(Mac)复制;在目标位置右键单击,选择“粘贴”或使用 Ctrl V(Windows)或 Cmd V(Mac);复制的数据将插入到目标位置,或替换现有数据(取决于目标位置是否已存在数据)。

VS Code可以在Windows 8上运行,但体验可能不佳。首先确保系统已更新到最新补丁,然后下载与系统架构匹配的VS Code安装包,按照提示安装。安装后,注意某些扩展程序可能与Windows 8不兼容,需要寻找替代扩展或在虚拟机中使用更新的Windows系统。安装必要的扩展,检查是否正常工作。尽管VS Code在Windows 8上可行,但建议升级到更新的Windows系统以获得更好的开发体验和安全保障。

开源VNC工具Tigervnc兼容众多操作系统,其中包括Windows、Linux和macOS。本文将详细介绍Tigervnc在Debian系统上的应用情况。Tigervnc在Debian系统的应用系统集成:在Debian系统中,Tigervnc作为VNC服务器组件被集成到系统中。用户可通过命令行工具(例如vncserver)启动VNC服务,并自定义显示设置,如分辨率和色彩深度。跨平台连接:Tigervnc客户端支持Windows、Linux和macOS,这意味着用户可以从任何运行这

在 Sublime 中运行代码的方法有六种:通过热键、菜单、构建系统、命令行、设置默认构建系统和自定义构建命令,并可通过右键单击项目/文件运行单个文件/项目,构建系统可用性取决于 Sublime Text 的安装情况。

要安装 Laravel,需依序进行以下步骤:安装 Composer(适用于 macOS/Linux 和 Windows)安装 Laravel 安装器创建新项目启动服务访问应用程序(网址:http://127.0.0.1:8000)设置数据库连接(如果需要)

Mac 系统维护包括:磁盘管理(使用 OmniDiskSweeper 清理磁盘空间,用磁盘工具检查磁盘错误)内存管理(用 Activity Monitor 监控内存占用,结束占用过高的进程)启动项管理(用 Linc 或 LaunchControl 管理启动项,禁用不必要的启动项)系统缓存清理(用 CleanMyMac X 或手动清理系统缓存)软件更新(及时更新系统和应用程序)定期备份(使用 Time Machine 定期备份数据)良好使用习惯(不过度安装应用程序,定期清理文件,监控系统日志)

在Laravel开发中,处理复杂的模型关系一直是个挑战,特别是当涉及到多层级的BelongsToThrough关系时。最近,我在处理一个多级模型关系的项目中遇到了这个问题,传统的HasManyThrough关系无法满足需求,导致数据查询变得复杂且低效。经过一番探索,我找到了staudenmeir/belongs-to-through这个库,它通过Composer轻松安装并解决了我的困扰。
