C++ Win32 API无法创建WindowW()

C++ Win32 API无法创建WindowW(),c++,visual-studio,winapi,C++,Visual Studio,Winapi,我正在尝试进入WinAPI。我从VS中的基本Win32应用程序模板开始。我创建了一个自定义对话框IDD_DIALOG1,并希望替换模板附带的标准对话框。但是,每当我启动应用程序时,它几乎会立即终止。我的对话框将不会显示,因为CreateWindowW()失败,并且GetLastError()返回1407(错误\u找不到\u WND \u类)。我不知道问题是什么,因为如果我用任何其他资源(如自动生成的aboutboxIDD_aboutbox)替换自定义对话框,它也会按预期启动,打开一个窗口。我发现

我正在尝试进入WinAPI。我从VS中的基本Win32应用程序模板开始。我创建了一个自定义对话框
IDD_DIALOG1
,并希望替换模板附带的标准对话框。但是,每当我启动应用程序时,它几乎会立即终止。我的对话框将不会显示,因为
CreateWindowW()
失败,并且
GetLastError()
返回1407(错误\u找不到\u WND \u类)。我不知道问题是什么,因为如果我用任何其他资源(如自动生成的aboutbox
IDD_aboutbox
)替换自定义对话框,它也会按预期启动,打开一个窗口。我发现同样的问题有类似的线索,但没有一个解决方案对我有帮助,我也不知道下一步该怎么办

main.cpp:

#include "stdafx.h"
#include "Win32Project1.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;                                // current instance
WCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR    lpCmdLine,
    _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // Initialize global strings
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDD_DIALOG1, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance(hInstance, nCmdShow))
    {
        return GetLastError();
    }

    MSG msg;

    // Main message loop:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex = {};
    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(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT1));
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    hInst = hInstance;

    HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
    if (!hWnd)
    {
        return false;
    }

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

    return true;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) {
        case WM_DESTROY: {
            PostQuitMessage(0);
            break;
        }

        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            EndPaint(hWnd, &ps);
        }
        break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}
资源中心:

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef APSTUDIO_INVOKED
#include "targetver.h"
#endif
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (United States) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_WIN32PROJECT1       ICON                    "Win32Project1.ico"

IDI_SMALL               ICON                    "small.ico"


/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDC_WIN32PROJECT1 MENU
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "E&xit",                       IDM_EXIT
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About ...",                  IDM_ABOUT
    END
END

/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About Win32Project1"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    ICON            IDR_MAINFRAME,IDC_STATIC,14,14,21,20
    LTEXT           "Win32Project1, Version 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX
    LTEXT           "Copyright (C) 2017",IDC_STATIC,42,26,114,8
    DEFPUSHBUTTON   "OK",IDOK,113,41,50,14,WS_GROUP
END

IDD_DIALOG1 DIALOGEX 0, 0, 309, 176
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About Win32Project1"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    ICON            IDR_MAINFRAME,IDC_STATIC,14,14,21,20
    LTEXT           "Win32Project1, Version 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX
    LTEXT           "Copyright (C) 2017",IDC_STATIC,42,26,114,8
    DEFPUSHBUTTON   "OK",IDOK,113,41,50,14,WS_GROUP
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
    IDD_ABOUTBOX, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 163
        TOPMARGIN, 7
        BOTTOMMARGIN, 55
    END

    IDD_DIALOG1, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 163
        TOPMARGIN, 7
        BOTTOMMARGIN, 55
    END
END
#endif    // APSTUDIO_INVOKED


#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#ifndef APSTUDIO_INVOKED\r\n"
    "#include ""targetver.h""\r\n"
    "#endif\r\n"
    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
    "#include ""windows.h""\r\n"
    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE
BEGIN
    IDS_APP_TITLE           "Win32Project1"
    IDC_WIN32PROJECT1       "WIN32PROJECT1"
END

#endif    // English (United States) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

错误“找不到”表示Windows无法使用该类,很可能是因为该类不存在。您从不检查
MyRegisterClass
的返回值

很少使用
LoadString
获取类名,大多数人只是将类名字符串直接放入代码中。您从未检查LoadString是否成功,并且无法加载带有LoadString的对话框(IDD_DIALOG1)


您可能只需替换
WCHAR szWindowClass[MAX_LOADSTRING]带有
常量WCHAR*L“MyClass”并且它应该可以工作。如果仍要从资源中加载类名,则必须确保实际加载的是有效字符串。

IDD\u
是对话框ID的常用前缀,而
IDs\u
用于字符串资源。您正在调用
LoadString
时使用
IDD\u对话框1
。这是故意的吗?我只是从VisualStudio模板中采用了这一点。有更好的方法吗?正如我所说的,如果我用该行中自动生成的aboutbox替换Dialog1,它将打开一个窗口。所以这不应该是问题所在。根据(请参阅备注)的说明,它看起来不错,因为没有专门的功能来加载对话框资源,菜单的处理方式似乎完全不同。
CreateWindow
是您检查失败的唯一调用。很有可能失败发生得更早。将错误处理添加到所有系统调用中,以查看问题从何处开始。GetLastError()告诉您原因。RegisterClassEx的返回值是多少?是否确保在CreateWindow中为窗口类名传递的字符串与RegisterClassEx中为类名传递的字符串相匹配?在Visual Studio 2015 Win32应用程序模板中,资源文件包含一个名为
IDC\uuu
的字符串表项,对应于调用
LoadStringW
中指定的名称,该调用检索
szWindowClass
。您使用的Visual Studio版本可能有一个稍有不同的模板,但我相信您会发现对
LoadStringW
的调用中指定的名称与字符串表中的一个条目匹配。它也可能与对话框、菜单或其他项的名称匹配,但要检索的是字符串表条目。