当应用程序拒绝终止,并且窗口中显示有关完成尝试的文本消息(WinAPI C++)时,如何使应用程序运行?

b09cbbtk  于 2023-01-06  发布在  其他
关注(0)|答案(1)|浏览(153)

主要任务如下所示:
编写一个程序,该程序创建一个窗口,该窗口具有自己的光标和图标,并且在程序结束之前具有附加请求。如果终止失败,应用程序将继续运行。该窗口将显示有关完成尝试的文本消息。
如何补充这段代码?或者它有什么问题?如何正确地完成这项任务?

#include <Windows.h>

int CALLBACK wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR szCmdLine, int nCmdShow)
{
    MSG msg{};
    HWND hwnd{};
    WNDCLASSEX wc{ sizeof(WNDCLASSEX) };
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hbrBackground = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
    wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
    wc.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
    wc.hInstance = hInstance;
    wc.lpfnWndProc = [](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ->LRESULT 
    {
        switch (uMsg)
        {
        case WM_CLOSE:
            switch (MessageBox(hWnd, L"Are you sure you want to get out?", L"", MB_YESNO))
            {
            case IDYES:
                DestroyWindow(hWnd);
                break;
            case IDNO:
                ??????????????
            }
        
        case WM_DESTROY:
        {
            PostQuitMessage(EXIT_SUCCESS);
        }
        return 0;

        }
        return DefWindowProc(hWnd, uMsg, wParam, lParam);    
    };
    wc.lpszClassName = L"MyAppClass";
    wc.lpszMenuName = nullptr;
    wc.style = CS_VREDRAW | CS_HREDRAW;

    if (!RegisterClassEx(&wc))
        return EXIT_FAILURE;
    if (hwnd = CreateWindow(wc.lpszClassName, L"", WS_OVERLAPPEDWINDOW, 0, 0, 1200, 1500, nullptr, nullptr, wc.hInstance, nullptr), hwnd == INVALID_HANDLE_VALUE)
        return EXIT_FAILURE;
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);      
    }
    return static_cast<int>(msg.wParam); 
}
idv4meu8

idv4meu81#

根据WM_CLOSE文档:

如果应用程序处理此消息,则应返回零。

应用程序可以在销毁窗口之前提示用户进行确认,方法是处理WM_CLOSE消息并仅在用户确认选择时调用DestroyWindow函数。
默认情况下,DefWindowProc函数调用DestroyWindow函数来销毁窗口。
因此,如果用户决定不关闭窗口,只需从窗口proc中执行return即可。
另外,顺便说一句,你的WM_CLOSE case缺少了一个break语句,所以无论你在里面做什么,代码最终都会掉到WM_DESTROY case中,每当用户试图关闭窗口时都会调用PostQuitMessage(),所以你也需要修复这个问题。
试试这个:

wc.lpfnWndProc = [](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -> LRESULT 
{
    switch (uMsg)
    {
        case WM_CLOSE:
            if (MessageBox(hWnd, L"Are you sure you want to get out?", L"", MB_YESNO) != IDYES)
            {
                // TODO: display text message about completion attempt...
                return 0;
            }
            break;
        
        case WM_DESTROY:
            PostQuitMessage(EXIT_SUCCESS);
            return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);    
};

相关问题