WM_SYSCOMMAND古怪

时间:2010-05-02 22:07:08

标签: winapi messages systemmenu wm-syscommand

当用户在系统菜单上选择菜单项命令时,应用程序会收到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”这个名称指的是什么(系统菜单上的命令,或操作系统的命令)?

3 个答案:

答案 0 :(得分:2)

  

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

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

现在,进一步向下(隐藏在底部的模糊中):

  

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

您还可以通过将其发送到DefWindowProc来执行特定的WM_SYSCOMMAND。这些包括上面提到的那些,但它们还包括其他的,如SC_SCREENSAVE和SC_TASKLIST。我不知道通过DefWindowProc会有什么样的路径,比如SC_SCREENSAVE会最终触发屏幕保护程序,但就是这样。

所以我看到它的方式是整个WM_SYSCOMMAND类都是系统命令。只是其中一些(从窗口标题可访问的那些)被发送到窗口,而其他一些是由窗口自行决定发送的。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

WM_SYSCOMMANDWM_COMMAND 的系统版本,其中大部分非客户端操作都通过您的窗口路由,因此您可以更改/吃掉它们。

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

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

Taskman Win95