Winapi CreateWindowEx、GetLastError、Windows 7和XP异常和异常行为
下面的代码在Windows7上运行,但当我在WindowsXP上运行它时,它失败了,Windows返回一条错误消息:“系统找不到指定的文件” 当我包含该行时,我得到一个错误“系统无法找到指定的文件”。从RegisterClassEx返回的返回值不会进入Winapi CreateWindowEx、GetLastError、Windows 7和XP异常和异常行为,winapi,windows-7,error-handling,windows-xp,Winapi,Windows 7,Error Handling,Windows Xp,下面的代码在Windows7上运行,但当我在WindowsXP上运行它时,它失败了,Windows返回一条错误消息:“系统找不到指定的文件” 当我包含该行时,我得到一个错误“系统无法找到指定的文件”。从RegisterClassEx返回的返回值不会进入if块,因此RegisterClassEx返回Ok 这只发生在Windows XP上,在Windows 7上工作正常。如果我不包括这一行,它的工作原理就好像没有什么问题 这个示例的目的是让主题在XP和Windows7上都能正常工作。(这不是一项容易
if
块,因此RegisterClassEx返回Ok
这只发生在Windows XP上,在Windows 7上工作正常。如果我不包括这一行,它的工作原理就好像没有什么问题
这个示例的目的是让主题在XP和Windows7上都能正常工作。(这不是一项容易的任务。)
为什么RegisterClassEx返回Ok,但在Windows XP而不是Windows 7上为GetLastError生成错误
另外,它到底在寻找什么文件?我曾看到其他谷歌搜索结果显示,这与混乱的消息循环或窗口过程有关,但这里的情况并非如此。一般错误。。。由于此原因,只有当注册表类“返回值为零”时,才可以检查GetLastError。当
RegisterClassEx
或CreateWindowEx
或任何其他函数成功时,GetLastError
可能会返回垃圾,但不能保证GetLastError
将返回零(如果在返回值一节中未描述不同的行为)。MSDN:“如果函数失败,返回值为零。要获取扩展的错误信息,请调用GetLastError。'好吧,实际上并没有说“不”来调用它,但我明白了重点。有道理,我只是没有这样解释。旧公理回来了,垃圾进来,垃圾出去。因此,仅在发生错误时使用它,否则未定义。谢谢好吧,如果你按照一个你没有被告知要得到的价值行事……:)
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <uxtheme.h>
#include <string>
const char g_szClassName[] = "myWindowClass";
const char title[] = "Window Title\0";
COLORREF WinColor;
HFONT defaultFont;
NONCLIENTMETRICSA Metrics;
DWORD dwVersion;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
HBRUSH hBrushColor;
bool LastError = false;
bool W32Error (const char * Msgtext);
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_NCCREATE:
{
Metrics.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo (SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &Metrics, 0);
defaultFont = (HFONT) CreateFontIndirect (& Metrics.lfMessageFont);
return TRUE;
}
break;
case WM_CTLCOLORSTATIC: {
dwVersion = GetVersion();
dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
if ( (IsAppThemed()) && (dwMajorVersion < 6) ) {
WinColor = GetSysColor(COLOR_WINDOW);
SetBkColor((HDC)wParam, WinColor);
return (LRESULT)hBrushColor;
}
}
break;
case WM_CREATE: {
HWND hButton = CreateWindowEx(
0,
"BUTTON", "Button",
WS_TABSTOP |
WS_VISIBLE |
WS_CHILD |
BS_NOTIFY |
BS_PUSHBUTTON,
10, 10, 96, 32, hwnd,
(HMENU)50,
GetModuleHandle(NULL),
NULL);
if (W32Error ("Button Creation Failed\nReason:")) exit (1);
return TRUE;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
// Initialize common controls.
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_WIN95_CLASSES |
ICC_COOL_CLASSES |
ICC_INTERNET_CLASSES|
ICC_LINK_CLASS |
ICC_STANDARD_CLASSES|
ICC_PROGRESS_CLASS |
ICC_USEREX_CLASSES;
InitCommonControlsEx(&icc);
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// see if something is going on before the window registration takes place....
if (W32Error ("Previous Check for Error?\nReason:")) exit (1);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
if (W32Error ("Window Registration Failed\nReason:")) exit (1);
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if (W32Error ("Window Creation Failed\nReason:")) exit (1);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
SendMessageA(hwnd, WM_SETFONT, WPARAM (defaultFont), TRUE);
SendMessageA(hwnd, WM_SETTEXT, WPARAM(NULL) , LPARAM (title));
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Step 3: The Message Loop
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
bool W32Error (const char * Msgtext)
{
LPTSTR errorText = NULL;
DWORD dwLastError = GetLastError();
if (!dwLastError) {
LastError = false;
return LastError;
}
// use system message tables to retrieve error text
// allocate buffer on local heap for error text
// Important! will fail otherwise, since we're not (and CANNOT) pass insertion parameters
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, // unused with FORMAT_MESSAGE_FROM_SYSTEM
dwLastError,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&errorText, // output
0, // minimum size for output buffer
0); // arguments - see note
if ( NULL != errorText ) {
std::string Message;
Message += Msgtext;
Message += "\n";
Message += errorText;
MessageBoxA(NULL, (LPCSTR)Message.c_str(), "An Internal Error Occurred", MB_OK);
LocalFree(errorText);
errorText = NULL;
LastError = true;
} else {
LastError = false;
}
return LastError;
}
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
if (W32Error ("Window Registration Failed\nReason:")) exit (1);