1

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

4

4 回答 4

2

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

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

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

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

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

所以我看到它的方式是整个 WM_SYSCOMMAND 类都是系统命令。只是其中一些(可从窗口的标题访问的)被发送到窗口,而其他的则由窗口根据您的判断发送。

于 2010-05-02T23:19:48.083 回答
0

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

于 2010-05-02T23:40:35.163 回答
0

这是 16 位 Windows 的遗留问题。

请搜索 Bob Gunderson 的文章:《GetMessage and PeekMessage Internals》,Microsoft Developer Network Technology Group,1992 年 12 月 11 日

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

于 2017-09-22T01:10:53.620 回答
0

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

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

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

特工Win95

于 2021-01-17T18:04:52.797 回答