Winapi-WM_CLOSE的替代项

问题描述 投票:0回答:2

我知道Windows通知消息,WM_CLOSE是指通过窗口右上角的“ X”按钮关闭窗口。

有人知道通过File-> Exit关闭的通知消息吗?

我问的原因是因为我正在尝试实现JNI本机代码以在用户启动系统关闭时正常关闭窗口。请参阅我以前的文章(Winapi - SetWindowLongPtr in ShutdownBlockReasonCreate / Destroy implementation of JNI native code)作为背景。

单击“ X”以关闭时,将显示确认对话框,该对话框可防止关闭原因消息消失(当我希望它在一段时间后消失)。我知道菜单栏中的File-> Exit不会要求您进行确认,但是如何使用Windows通知消息来实现这一点?

经过一番挖掘后,我发现唯一的建议是使用DestroyWindow。因此,我尝试使用DestroyWindow()函数关闭窗口,但它仅“破坏”了窗口,而不是结束整个应用程序。这是WndProc CallBack函数中的switch语句:

switch (message) {
            case WM_QUERYENDSESSION:
                PostMessage(hWnd, WM_CLOSE, 0, 0);
                return 0;
            case WM_ENDSESSION:
                PostMessage(hWnd, WM_CLOSE, 0, 0);
                return 0;
            case WM_CLOSE:
                DestroyWindow(hWnd);
                break;
            case WM_NCDESTROY:
                RemoveWindowSubclass(hWnd, AppWndProc, uIdSubclass);
                break;
}

任何帮助将不胜感激!

欢呼声

c++ winapi java-native-interface shutdown wndproc
2个回答
2
投票

我知道Windows通知消息,WM_CLOSE是指通过窗口右上角的“ X”按钮关闭窗口。

实际上,当单击窗口的标准“ X”按钮时(或者如果已启用,则选择了窗口左上角菜单上的标准“关闭”项,或者窗口接收到一个[[ALT + F4击键),带有WM_SYSCOMMAND标志的wParam消息被发送到窗口。如果该消息传递给SC_CLOSE(默认行为),则会向窗口发出DefWindowProc()消息。

请参见WM_CLOSE

[其他条件也可能导致发出Closing the Window消息。

有人知道通过File-> Exit关闭的通知消息吗?

选择该菜单项时发生的情况是由应用程序而不是操作系统定义的。该应用程序可以执行所需的任何操作,包括在需要时立即销毁该窗口。

但是,如果菜单是标准的Win32菜单,则该窗口将至少收到WM_CLOSE消息,其中包含所选菜单项的ID。

我问的原因是因为我正在尝试实现JNI本机代码以在用户启动系统关闭时正常关闭窗口。

默认情况下,您不需要为此做任何事情。在系统关闭期间,操作系统会自动关闭所有打开的窗口。如果您需要清理任何资源,则应该手动关闭窗口,而不是手动关闭窗口。

[单击'X'以关闭时,将显示确认对话框,防止关闭原因消息消失(当我希望它在一段时间后消失)。

然后,应用程序无法正确处理系统关闭。

[大多数应用程序响应于接收到WM_COMMAND消息而显示这样的确认框。如果确认中止,则应用程序将丢弃该消息并继续前进。但是,应用程序不应在系统关闭期间提示用户进行确认。但并非所有应用程序都遵循该规则。

我知道文件->从菜单栏退出不要求确认

同样,由应用程序决定,而不由操作系统决定。

我如何使用Windows通知消息来实现这一点?经过一番挖掘后,我发现的唯一建议是使用DestroyWindow。

正确。或者,您也可以将WM_CLOSE消息发布到消息队列中。参见WM_QUIT功能。

因此,我尝试使用DestroyWindow()函数关闭窗口,但是它仅“破坏”了窗口,而不是结束整个应用程序。

应用程序有责任自行终止,通常是在其主窗口被破坏时退出其消息循环。

这是我的WndProc CallBack函数中的switch语句:

无需响应PostQuitMessage()WM_CLOSE发布WM_QUERYENDSESSION。让操作系统为您处理。

如果您不希望在系统关闭期间显示确认,请将代码更改为类似以下内容:

WM_ENDSESSION


0
投票
没有具体消息来处理您的文件>退出。您必须像处理其他任何菜单项一样处理它:

    定义菜单项的标识符。选择所需的任何内容,对于Windows来说没有任何特殊含义。
  1. 构建菜单时,请在AppendMenu / InsertMenu / etc中指定此标识符。或在您的资源文件中
  2. 在您的窗​​口过程中,截获WM_COMMAND消息。如果bool shuttingDown = false; LRESULT CALLBACK AppWndProc( _In_ HWND hWnd, _In_ UINT message, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ UINT_PTR uIdSubclass, _In_ DWORD_PTR dwRefData ) { switch (message) { case WM_QUERYENDSESSION: shuttingDown = true; break; case WM_ENDSESSION: if (wParam == FALSE) shuttingDown = false; break; case WM_CLOSE: if (shuttingDown) { DestroyWindow(hWnd); // or: // PostQuitMessage(0); return 0; } break; case WM_NCDESTROY: RemoveWindowSubclass(hWnd, AppWndProc, uIdSubclass); break; } return DefSubclassProc(hWnd, message, wParam, lParam); } 对应于标识符,则表示菜单项已被激活
  • 处理退出命令的一种典型方法是发送WM_CLOSE消息,就像在示例代码中已经做过的那样。因此,您将避免代码重复,并确保无论用户选择如何退出应用程序,行为都是相同的(通过菜单,单击“ x”或Alt + F4)

    在WM_CLOSE的处理中,您可以选择显示消息框,销毁窗口,发布退出消息或其他任何所需的内容。默认情况下,DefWindowProc调用DestroyWindow,后者依次发送WM_DESTROY消息。请注意,选择系统菜单的“关闭”项时也会触发WM_CLOSE(Alt + Space或单击窗口标题旁边左侧的窗口图标)

  • © www.soinside.com 2019 - 2024. All rights reserved.