Winapi WM_系统命令异常

Winapi WM_系统命令异常,winapi,messages,systemmenu,wm-syscommand,Winapi,Messages,Systemmenu,Wm Syscommand,当用户在系统菜单上选择菜单项命令时,应用程序会收到消息,因此wParam可以是SC\u关闭、SC\u上下文帮助、SC\u最大化、SC\u最小化、SC\u还原等。这是合乎逻辑的。(当然,您也可以通过单击最小化、最大化、关闭按钮等发送这些消息。) 但是也可以发送WM_SYSCOMMAND消息来向Windows Shell发送命令。例如,可以显示“开始”菜单(SC_任务列表)、激活屏幕保护程序(SC_屏幕保存)和关闭显示器(SC_显示器电源)。这没有道理,是吗?这与应用程序的系统菜单有什么关系?这更像

当用户在系统菜单上选择菜单项命令时,应用程序会收到消息,因此wParam可以是SC\u关闭、SC\u上下文帮助、SC\u最大化、SC\u最小化、SC\u还原等。这是合乎逻辑的。(当然,您也可以通过单击最小化、最大化、关闭按钮等发送这些消息。)

但是也可以发送WM_SYSCOMMAND消息来向Windows Shell发送命令。例如,可以显示“开始”菜单(SC_任务列表)、激活屏幕保护程序(SC_屏幕保存)和关闭显示器(SC_显示器电源)。这没有道理,是吗?这与应用程序的系统菜单有什么关系?这更像是一个“系统命令”,即对消息的名称“WM_SYSCOMMAND”的完全其他解释。这就像消息被用来向系统发送命令请求一样

为什么这个消息用于两个看起来完全不同的事情,“SYSCOMMAND”是指什么(系统菜单上的命令,或操作系统的命令)

当用户从窗口菜单(以前称为系统或控制菜单)选择命令时,或当用户选择最大化按钮、最小化按钮、恢复按钮或关闭按钮时,窗口接收此消息

当用户使用系统菜单或标题按钮时,这些WM_系统命令(最大化、最小化、还原、关闭和系统菜单中的命令)可能会发送到您的窗口。我相信(我的Win32非常生锈)这些通常是由DefWindowProc处理的,它完成所有的脏工作,然后向您的窗口发送通知(WM_SIZE/WM_SIZE,WM_CLOSE,等等)

现在,再往下看(隐藏在底部的简介中):

通过将WM_SYSCOMMAND消息传递给DefWindowProc,应用程序可以在任何时候执行任何系统命令。应用程序未处理的任何WM_SYSCOMMAND消息必须传递给DefWindowProc

还可以通过将特定WM_SYSCOMMAND发送到DefWindowProc来执行该命令。其中包括上述内容,但也包括其他内容,如SC_屏幕保存和SC_任务列表。我不知道像SC_SCREENSAVE这样的DefWindowProc最终会以何种方式触发屏幕保护程序,但事实就是这样


所以我认为整个WM_SYSCOMMANDs类都是系统命令。只是其中一些(可从窗口标题访问的)被发送到窗口,其他的由窗口自行发送。

WM\u SYSCOMMAND只是WM\u命令的系统版本,它遵循相同的语义。当用户从菜单中选择项目、单击按钮、选择单选按钮等时,WM_命令消息将发送到应用程序。ID参数指示单击的内容。也可以使用SendMessage()或PostMessage()手动发送该命令。

这是16位Windows的遗留版本

请用谷歌搜索Bob Gunderson的文章:《GetMessage和PeekMessage内部》,微软开发者网络技术集团,1992年12月11日


在Windows3.1时代,操作系统是非抢占式的单线程操作系统。当GetMessage/PeekMessage函数访问系统队列并遇到CTRL-ESC键按下时,一条WM_SYSCOMMAND消息被发布到活动应用程序(请记住,它是一个单线程系统),其中包含wParam中的SC_任务列表。按键向下事件是指示窗口显示任务管理器窗口。

WM\u SYSCOMMAND
WM\u COMMAND
的系统版本,大多数非客户端操作都通过您的窗口发送,以便您可以更改/执行它们

SC_SCREENSAVE
在屏幕保护程序计时器过期时由系统发送到前台窗口。这使前台窗口能够通过不将消息传递给
DefWindowProc
来阻止屏幕保护程序。这对于视频播放器、演示文稿(PowerPoint等)和游戏非常有用

我不确定为什么将
SC_TASKLIST
(这只是一个可以发送的命令)与这些其他命令组合在一起,但可能有一些遗留原因。请记住,Win 3.x和95/98/ME有非常不同的“任务管理器”,还附带了一个小任务应用程序,其作用有点像浮动任务栏:


这实际上是一个语义问题,如果微软认为这符合逻辑,那么这就是他们实现的。