关于winapi:WM_SYSCOMMAND奇数

WM_SYSCOMMAND oddities

当用户在系统菜单上选择菜单项命令时,应用程序会收到WM_SYSCOMMAND消息,因此wParam可以是SC_CLOSE,SC_CONTEXTHELP,SC_MAXIMIZE,SC_MINIMIZE,SC_RESTORE等。这是合乎逻辑的。 (当然,您还可以通过单击最小化,最大化,关闭按钮等来发送这些消息。)

但是也可以发送WM_SYSCOMMAND消息以将命令发送到Windows Shell。例如,可以显示开始菜单(SC_TASKLIST),激活屏幕保护程序(SC_SCREENSAVE),然后关闭监视器(SC_MONITORPOWER)。这没有道理,对吗?这与应用程序的系统菜单有什么关系?这更多是"系统命令",即更多是消息名称" WM_SYSCOMMAND"的完全其他解释。就像消息用于将命令请求发送到系统一样。

为什么此消息用于两个看似完全不同的事物," SYSCOMMAND"这个名称是指什么事物(系统菜单上的命令或操作系统的命令)?


A window receives this message when the user chooses a command from the Window menu (formerly known as the system or control menu) or when the user chooses the maximize button, minimize button, restore button, or close button.

当用户使用系统菜单或字幕按钮时,这些WM_SYSCOMMAND(最大化,最小化,还原,关闭以及系统菜单中的窗口)可能会发送到您的窗口。我相信(我的Win32非常生锈)通常由DefWindowProc处理,该工作完成所有肮脏的工作,然后将通知发送到您的窗口(WM_SIZE / WM_SIZING,WM_CLOSE等)。

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

An application can carry out any system command at any time by passing a WM_SYSCOMMAND message to DefWindowProc. Any WM_SYSCOMMAND messages not handled by the application must be passed to DefWindowProc.

您还可以通过将特定的WM_SYSCOMMAND发送到DefWindowProc来执行。这些包括上面提到的内容,但也包括其他内容,例如SC_SCREENSAVE和SC_TASKLIST。我不知道通过DefWindowProc之类的路径(如SC_SCREENSAVE)最终会触发屏幕保护程序,但是事实就是如此。

因此,我的看法是WM_SYSCOMMAND的整个类都是系统命令。只是其中一些(可从窗口标题访问的)被发送到窗口,而另一些则由窗口自行决定。


这是Windows 16位的遗产。

请通过Google鲍勃·冈德森(Bob Gunderson)的文章在Google上搜索:《 GetMessage和PeekMessage内部》,微软开发人员网络技术小组,1992年12月11日

在Windows 3.1时代,操作系统是非抢占式和单线程的。当GetMessage / PeekMessage函数访问系统队列并按下CTRL-ESC键时,在wParam中带有SC_TASKLIST的WM_SYSCOMMAND消息已发布到活动应用程序(请记住它是单线程系统)。按键事件是指导Windows显示任务管理器窗口。


WM_SYSCOMMAND只是WM_COMMAND的系统版本,它遵循相同的语义。当用户从菜单中选择一个项目,单击一个按钮,选择一个单选按钮等时,WM_COMMAND消息将发送到您的应用程序。ID参数指示单击了什么。也可以使用SendMessage()或PostMessage()手动发送命令。