Winapi CreateWindowEx、GetLastError、Windows 7和XP异常和异常行为

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上都能正常工作。(这不是一项容易

下面的代码在Windows7上运行,但当我在WindowsXP上运行它时,它失败了,Windows返回一条错误消息:“系统找不到指定的文件”

当我包含该行时,我得到一个错误“系统无法找到指定的文件”。从RegisterClassEx返回的返回值不会进入
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);