Visual C++ 窗口创建失败

Posted

技术标签:

【中文标题】Visual C++ 窗口创建失败【英文标题】:Visual C++ Window creation failed 【发布时间】:2017-01-25 15:56:44 【问题描述】:

我最近完成了关于 C++ 的入门课程,并决定跳入 Visual C++ 尝试制作一个小应用程序。

到目前为止,我想要的只是至少创建并显示一个窗口,没有更进一步。 我使用了许多 Microsoft 教程来获取我拥有的代码。

请注意,我有很多 cmets 可以帮助我理解我在做什么。 我正在使用 Microsoft Visual Studio 2015

#include <tchar.h>  //A Win32 character string that can be used to describe ANSI, DBCS, or Unicode strings
                    //Enclose the strings in _T() if an incompatibility error occures or (LPCWSTR)L""
#include <windows.h>

// Global variable 
HINSTANCE hinst;

//Function prototype for the window procedure so the inside of the program knows wazup
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL InitApplication(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);

//Instead of your usual console program, you get WinMain() instead of int main(int argc,char *argv[])
INT WINAPI wWinMain(HINSTANCE hInst, //Instance of the program being executed
    HINSTANCE hPrevInst,             //Previous instance, not used much anymore
    LPWSTR lpCmdLine,                //Holds command line arguments
    INT nShowCmd)                    //Tells how the program should start(minumised, maximised...)

    /*Steps to create a window:
        - Register a window class
        - Create the window
        - Show the window
        - Setup a callback procedure
    */

    //We can tell if the window class has failed if RegisterClassEx() returns 0. 
    //Fortunatley, there is another handy function, namely GetLastError(). 
    //GetLastError() will return an error code, which can then be used to track down the cause of the error.
    //https://msdn.microsoft.com/en-us/library/ms681381.aspx
    if (!InitApplication(hInst))
    
        int nResult = GetLastError();
        MessageBox(NULL,
            _T("Window class creation failed"),
            _T("Window Class Failed"),
            MB_ICONERROR);
        return 1;
    
    //Window creation & display:
    if (!InitInstance(hInst, nShowCmd))
        int nResult = GetLastError();
        MessageBox(NULL,
            _T("Window creation failed"),
            _T("Window Creation Failed"),
            MB_ICONERROR);
        return 1;
    

    //The windows 'callback procedure' is necessary to continue
    MSG msg;    //Message handler
    ZeroMemory(&msg, sizeof(MSG));
    //Main loop for the program
    while (GetMessage(&msg, NULL, 0, 0))
    
        TranslateMessage(&msg);//translates virtual key messages to character messages
        DispatchMessage(&msg); //Sends any messages to the callvack procedure, so it can be handled
    
    //Still returns an int!
    return 0;


BOOL InitApplication(HINSTANCE hinstance)

    //The window class defines the overall 'look and feel' of the window that we want to create.
    //First we create an instance of a window class
    WNDCLASSEX wClass;
    //For more about WNDCLASSEX: https://msdn.microsoft.com/en-us/library/ms633577(VS.85).aspx

    //Clearing all the parameters of the WNDCLASSEX instance wClass to zero
    ZeroMemory(&wClass, sizeof(WNDCLASSEX));
    //Now we are setting up all sotrts of parameters for our instance:
    wClass.cbClsExtra = NULL;                       // cbClsExtra           Additional parameters
    wClass.cbSize = sizeof(WNDCLASSEX);             // cbSize               Specifies the size of the window class
    wClass.cbWndExtra = NULL;                       // cbWndExtra           Additional parameters
    wClass.hbrBackground = (HBRUSH)COLOR_WINDOW;    // hbrBackground        Sets background color for the window
    wClass.hCursor = LoadCursor(NULL, IDC_ARROW);   // hCursor              The cursor that will appear in the window
    wClass.hIcon = NULL;                            // hIcon                Icon for the window
    wClass.hIconSm = NULL;                          // hIconSm              Small icon for the window
    wClass.hInstance = hinstance;                   // hInstance            Handle to the application instance
    wClass.lpfnWndProc = (WNDPROC)WinProc;          // lpfnWndProc          The callback procedure (more on that later)
    wClass.lpszClassName = _T("Window Class");      // lpszClassName        The unique name of the window class
    wClass.lpszMenuName = NULL;                     // lpszMenuName     Used for menus
    wClass.style = CS_HREDRAW | CS_VREDRAW;         // style                The look and feel of the window

    // Register the window class. 
    return RegisterClassEx(&wClass);


BOOL InitInstance(HINSTANCE hinstance, int nCmdShow)

    // Save the application-instance handle. 
    hinst = hinstance;
    // Create the main window. 
    //CreateWindowEx returns a HWND
    HWND hwnd = CreateWindowEx(  // A "handle" is a generic identifier + like "new"
        0,                       // DWORD, extended window style of the window being created https://msdn.microsoft.com/en-us/library/windows/desktop/ff700543(v=vs.85).aspx
        _T("MainsWClass"),       // LPCTSTR, A null-terminated string or a class atom created by a previous call to the RegisterClass or RegisterClassEx function.
        _T("Sample"),            // LPCTSTR, The window name.
        WS_OVERLAPPEDWINDOW,     // DWORD, Style of the window created

        CW_USEDEFAULT,           // int, X - default horizontal position 
        CW_USEDEFAULT,           // int, Y - default vertical position 
        CW_USEDEFAULT,           // int, nWidth - default width 
        CW_USEDEFAULT,           // int, nHeight - default height 

        (HWND)NULL,              // HWND, hWndParent - handle to the parrent or owner window of the window being created (opptional for pop-up)
        (HMENU)NULL,             // HMENU, hMenu 
        hinstance,               // HINSTANCE, hInstance - A handle to the instance of the module to be associated with the window.
        (LPVOID)NULL);           // LPVOID, Pointer to a value to be passed to the window through the CREATESTRUCT structure 

    //If the creation fails, returns FALSE
    if (!hwnd)
        return FALSE;
    else
        // Show the window and send a WM_PAINT message to the window procedure. 
        ShowWindow(hwnd, nCmdShow);
        UpdateWindow(hwnd);
        return TRUE;
    


//callback procedure
LRESULT CALLBACK WinProc(
    HWND hWnd,      //Handle of the window that we want to monitor
    UINT msg,       //Message we are receiving
    WPARAM wParam,  //Additionnal info for the received message
    LPARAM lParam)

    switch (msg)
    
    case WM_DESTROY:    //Message sent to the application if the program was closed using the X on the top of the window
    
        PostQuitMessage(0);
        return 0;
    
    break;
    

    return DefWindowProc(hWnd, msg, wParam, lParam);

【问题讨论】:

哪里你的程序失败了?而GetLastError返回的error code又是什么? 除了@Someprogrammerdude 所说的 - 使用调试器找出你的程序在哪里失败。 我强烈建议使用基于控制台的应用程序来掌握这门语言。 UI 添加了一个您现在不需要的非常复杂的关卡。 @Dan:我没有看到在Learn to Program for Windows in C++ 上编写 UWP 应用程序更容易。编写 UWP 应用需要您知道 - 除了 C++ - XAML、COM 以及 WRL 或 C++/CX。 @Dan:这甚至不能解决我的担忧:UWP 比普通的原始 Win32 C 应用程序更难。而且我还没有找到一个项目,知道 Windows API 是没有好处的。对于 C++/MFC、.NET 或 UWP 项目来说,情况就是如此。 【参考方案1】:

您正在注册一个名为"Window Class" 的窗口类,但尝试创建一个"MainsWClass" 类的窗口。那个班级是未知的。您需要创建之前已注册的窗口类的窗口(您可以自己创建,也可以使用预定义的窗口类之一,如"BUTTON")。

【讨论】:

@Artur:这也是你评论说的:// LPCTSTR, A null-terminated string or a class atom created by a previous call to the RegisterClass or RegisterClassEx function.

以上是关于Visual C++ 窗口创建失败的主要内容,如果未能解决你的问题,请参考以下文章

Visual C++编程技巧之三

创建项目,项目创建失败visual studio

Visual C++编程技巧之四

Visual C++ 6 中对话窗口的有效重叠

在 Visual C++ 中切换子进程窗口可见性而不重新启动子进程

我的 Visual C++ 编译器编译过时的源代码