随机win32退出代码

时间:2012-12-03 21:35:20

标签: c winapi

我正在尝试通过以下教程学习win32 API (虽然,我做了很小的调整来创建一个无边框的固定窗口。)

但是,我最简单的窗口应用程序正在退出一些随机代码 我不知道为什么它没有退出代码'0'
有关额外信息,我使用的是Visual Studio 2012 Pro 源代码的文件扩展名为.c,编译器设置可能是默认值 我将项目创建为空的win32应用程序(而不是控制台)
请帮助一些帮助 谢谢。

#include <Windows.h>
#include <windowsx.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int __stdcall WinMain(HINSTANCE hInstance,
                      HINSTANCE hPrevInstance,
                      LPSTR lpCmdLine,
                      INT nCmdShow) {
    HWND hWnd;
    WNDCLASSEX wcex;
    MSG msg;

    ZeroMemory(&wcex, sizeof(WNDCLASSEX));

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc  = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"WindowClass1";
    wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&wcex))
    {
        MessageBox(
            NULL,
            L"Failed to register window!",
            L"ERROR",
            MB_OK | MB_ICONEXCLAMATION);
        return EXIT_FAILURE;
    }

    hWnd = CreateWindowEx(
        0,
        L"WindowClass1",
        L"Application",
        WS_POPUP,
        0, 0,
        GetSystemMetrics(SM_CXSCREEN),
        GetSystemMetrics(SM_CYSCREEN),
        NULL, NULL, hInstance, NULL);


    if (hWnd == NULL)
    {
        MessageBox(
            NULL,
            L"Failed to create window!",
            L"ERROR",
            MB_OK |  MB_ICONEXCLAMATION);
        return EXIT_FAILURE;
    }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    while (GetMessage(&msg, hWnd, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
    case WM_CLOSE:
        DestroyWindow(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, Msg, wParam, lParam);
    }

    return 0;
}

2 个答案:

答案 0 :(得分:3)

在您的计划中,GetMessage实际上正在返回-1这是一个错误条件。当GetMessage返回值&lt; = 0时,您的消息循环终止,因此当GetMessage返回-1时它将终止。

现在,因为对GetMessage的最终调用失败并出现错误,所以msg.wParam的值没有明确定义。您不应该将其作为退出代码返回。当msg.wParam的最终调用返回0时,您应该只返回GetMessage作为退出代码。documentation中已明确了这一点。

如果您将消息循环更改为以下内容,则可以看到所有这些:

while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{ 
    if (bRet == -1)
    {
        return GetLastError();
    }
    else
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
}

return msg.wParam;

在我的计算机上,选择了bRet == -1路由,错误代码为1400.这是ERROR_INVALID_WINDOW_HANDLE。我不太清楚为什么你的应用程序会以这种方式表现,但我很满意我已经回答了你提出的有关退出代码的问题!

答案 1 :(得分:2)

除了覆盖整个屏幕的空白窗口,需要使用ALT-F4退出你的应用程序,事情看起来不错,除了一件事:

GetMessage,尽管声称返回'BOOL'实际上返回int:成功时为正值,接收WM_QUIT时为0,出现错误时为-1。从GetMessage(和其他函数)返回“ BOOL加上一些东西”的政策是愚蠢和危险的,因为这个原因,它们应该被鞭打。

如果GetMessage返回-1,则msg的内容可能有效,也可能无效;换句话说,wParam可以是零,也可以是potato。这可能会转化为您所看到的“随机”退出代码。

我建议这样的事情:

int nRet;

do
{
    nRet = GetMessage(&msg, hWnd, 0, 0);

    if(nRet == -1)
        return GetLastError();

    if(nRet != 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
} while(nRet != 0);

return msg.wParam;