我正在尝试通过以下教程学习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;
}
答案 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;