windows 为什么更改窗口类名称会影响Win32程序的退出代码?

xzv2uavs  于 2023-04-07  发布在  Windows
关注(0)|答案(1)|浏览(169)

在下面的可重现代码示例中,为什么关闭创建的窗口会导致退出代码134(0x86)?
我还发现,改变const wchar_t CLASS_NAME[]变量会导致不同的退出代码。似乎类名增加1个字符,退出代码增加2个。
我期望从这段代码中得到的,是一个0的退出代码,对吗?是什么导致了这一点?

#include <Windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR lpCmdLine, _In_ int nShowCmd) {
    const wchar_t CLASS_NAME[] = L"AFEWCHARACTERS";

    WNDCLASSW wc = {};
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    RegisterClassW(&wc);

    HWND hwnd = CreateWindowExW(
        0,
        CLASS_NAME,
        L"Window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        nullptr,
        nullptr,
        hInstance,
        nullptr
    );

    if (hwnd != nullptr) {
        ShowWindow(hwnd, nShowCmd);
    }

    MSG msg{};
    while (GetMessageW(&msg, nullptr, 0, 0) > 0) {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
wi3ka0sx

wi3ka0sx1#

您的代码表现出undefined behavior,因为您的wWinMain()函数在其消息循环完成后缺少所需的return语句:

MSG msg{};
    while (GetMessageW(&msg, nullptr, 0, 0) > 0) {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }

    return 0; // or msg.wParam // <-- ADD THIS!
}

wWinMain()的返回值用于设置调用进程在优雅退出时的退出代码(即,如果事先没有调用ExitProcess()/TerminateProcess(),并且没有抛出未捕获的异常)。根据GetExitCodeProcess()文档:
此函数立即返回。如果进程尚未终止且函数成功,则返回的状态为STILL_ACTIVESTATUS_PENDINGminwinbase.h)的宏)。如果进程已终止且函数成功,则返回的状态为以下值之一:

  • ExitProcess()TerminateProcess()函数中指定的退出值。
    *进程的main()WinMain()函数返回值。
  • 导致进程终止的未处理异常的异常值。

只有main()(由C/C++标准定义,因此具有特殊处理)允许省略return语句,在这种情况下,其返回值将隐式为0。任何其他具有非void返回类型的函数都需要显式的return,否则其返回值将 * 不确定 *。

相关问题