Windows 窗口消息 0x0091 为何携带异常参数?系统消息越界问题解析What’s up with window message 0x0091? We’re getting it with unexpected parameters
Raymond Chen 在 Old New Thing 博客中分析 Windows 系统消息 0x0091(WM_NCUAHDRAWCAPTION)被错误传递非预期参数的现象。他指出这是第三方应用程序或驱动违规发送消息所致,并非系统缺陷。文章解释了消息机制的工作原理,并提供调试建议,帮助开发者识别和修复此类越界调用。
Raymond Chen
一位客户通过其对接人员报告称,很久以前他们的程序在 Windows XP 上停止运行了。(我告诉你,那可真是很久以前的事了。)
客户的调查显示,问题出现是因为他们的窗口收到了消息 0x0091,而且参数是错误的。到底是谁在用错误的参数发送这条消息?
好吧,首先你怎么知道参数是错的?这条消息既没有在 winuser.h 中列出,当时 MSDN 里也没有(MSDN 那时候就这么叫)。
我们解释说,消息 0x0091 是一条内部消息,他们应该直接原封不动地传给 DefWindowProc。是什么让客户觉得接收到的参数不对?
客户说他们原本是把这条消息当作自定义消息来用的,现在除了自己发消息时会收到它,还额外收到了许多“虚假”的副本,这些副本的 WPARAM 和 LPARAM 值与程序实际发送的任何值都不匹配。
我们告诉他们,他们本来就不该把这条消息用于自己的用途。这些消息属于系统定义范围,应用程序不能使用。如果他们想发私有消息,应该用应用空间内的消息。
这就像在办公楼里发现一个空柜子,用来放自行车,结果某天上班时发现柜子里堆满了别人的东西,再也放不下你的车了。“为什么柜子里有东西?”因为那不是你的柜子啊。
对接人员把我们的话转告给客户,但提到客户可能不会喜欢这个答案。消息 0x0091 并不是他们唯一在用的一条。他们还用了 WM_USER 以下的其他消息,而且都出了问题;他们只是打算先从 0x0091 开始排查。
唉,算了。但我希望问题能简单到只需改个宏定义就行:
#define WM_MYSECRETMESSAGE 0x0091(此处原文缺失,无法翻译)
#define WM_MYSECRETMESSAGE (WM_APP + 1020) // or something选一个可供应用程序用于自定义的消息范围。
分类
主题
作者
Raymond 参与 Windows 的发展已有三十多年。2003 年,他创办了一个名为 The Old New Thing 的网站,其受欢迎程度远超他的想象,至今仍让他感到有些不安。这个网站催生了一本书,书名碰巧也叫《The Old New Thing》(Addison Wesley, 2007)。他偶尔会在 Windows Dev Docs 的 Twitter 账号上出现,讲一些毫无实用价值的故事。
需要完整排版与评论请前往来源站点阅读。