【问题标题】:Why is this call to CreateWindow failing, and how can I fix it?为什么对 CreateWindow 的调用失败,我该如何解决?
【发布时间】:2019-02-02 22:07:40
【问题描述】:

我正在关注directx12 的教程,甚至无法完成窗口D 的创建:有一个已实现的错误窗口告诉我在创建我实际想要创建的窗口时出现错误。 这应该意味着它“没有成功获得窗口句柄”...... 我不知道这意味着什么,但我非常感谢一些帮助。

#include "stdafx.h"

//Handle to the window
HWND hwnd = NULL;

//Name of the window
LPCTSTR WindowName = L"GameEngineApp";

//Title of the window
LPCTSTR WindowTitle = L"My Game Engine";

//Width and height of the window
int Width = 800;
int Height = 600;

//Toggle for fool screen
bool FullScreen = false;

//Toggle for window creation
bool InitializeWindow(HINSTANCE hInstance,
    int ShowWnd, int width, int height, bool fullscreen);

//Main application loop
void mainLoop()
{
    //The message var hold any windows message received through the 
    //PeekMessage function
    MSG msg;
    ZeroMemory(&msg, sizeof(MSG));

    while (true)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            //If there is a message, it is translated
            //then dispatched so Windows 
            //knows the program hasn't stopped working
            if (msg.message = WM_QUIT) {
                break;

                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            else {
                //If there is no message the game 
                //code will run and the loop will continue
            }
        }
    }
}

//Callback function for windows messages
LRESULT CALLBACK WndProc(HWND hWnd,
    UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_KEYDOWN:
        if (wParam == VK_ESCAPE) {
            if (MessageBox(0, L"Are you sure you want to exit?",
                L"Really?", MB_YESNO | MB_ICONQUESTION) == IDYES)
                DestroyWindow(hwnd);
        }
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd,
        msg, wParam, lParam);
}

//Main Windows function
int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nShowCmd)
{
    //Toggle window creation
    if (!InitializeWindow(hInstance, nShowCmd, Width, Height, FullScreen))
    {
        MessageBox(0, L"Window Initialization - Failed",
            L"Error", MB_OK);
        return 0;
    }

    mainLoop(); //Call main loop to start

    return 0;
}

bool InitializeWindow(HINSTANCE hInstance,
    int ShowWnd, int width, int height, bool fullscreen)
{
    //Check if fullscreen is needed and set to fullscreen if so
    if (fullscreen)
    {
        HMONITOR hmon = MonitorFromWindow(hwnd,
            MONITOR_DEFAULTTONEAREST);
        MONITORINFO mi = { sizeof(mi) };
        GetMonitorInfo(hmon, &mi);

        width = mi.rcMonitor.right - mi.rcMonitor.left;
        height = mi.rcMonitor.bottom - mi.rcMonitor.top;
    }

    //Window class structure
    WNDCLASSEX wc;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = NULL;
    wc.cbWndExtra = NULL;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = WindowName;
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    //Registering the window class
    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, L"Error registering class",
            L"Error", MB_OK | MB_ICONERROR);
        return false;
    }

    //Create the window with the now registered window class
    hwnd = CreateWindowEx(NULL,
        WindowName,
        WindowTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        width, height,
        NULL,
        NULL,
        hInstance,
        NULL);

    //Return error msg if unsuccessful in getting a window handle
    if (!hwnd)
    {
        MessageBox(NULL, L"Error creating window",
            L"Error", MB_OK | MB_ICONERROR);
        return false;
    }

    //Removing the style from the window when fullscreen
    if (fullscreen)
    {
        SetWindowLong(hwnd, GWL_STYLE, 0);
    }

    //Showing and updating the window
    ShowWindow(hwnd, ShowWnd);
    UpdateWindow(hwnd);

    return true;
}

我尝试将 CreateWINdowEx 更改为 CreateWindowA,这确实是唯一似乎可能有效果的东西,但我没有看到任何结果。 我试过打印错误,但没有错误。

使用 C++ 代码在 Windows 中创建一个窗口,以便我可以制作游戏引擎。

【问题讨论】:

  • 请附上您的代码,没有minimal reproducible example 将很难为您提供帮助。
  • 感谢您的快速回答!抱歉,我正在处理它,因为我可以弄清楚如何在我的文本框中缩进它。
  • 您的消息循环已关闭。您可能打算在 WM_QUIT 上中断,但您仅在消息为 WM_QUIT 时才处理该消息。固定大括号。
  • 投票以拼写错误结束
  • 你至少需要msg.message == WM_QUIT

标签: c++ windows visual-studio winapi


【解决方案1】:

虽然不应滥用全局变量。

您在 WndProc 中调用 DefWndProc 并使用 hwnd 作为句柄参数。但这直到CreateWindowEx 回归时才确定,并且在窗口站立期间有很多非常重要的消息通过WndProc 翻阅。这些消息需要窗口句柄,而您没有传递它。相反,您只是传递了NULLhwnd 的启动值)。

WndProc 中的all hwnd 更改为hWnd(参数名称)

cmets中提到的其余问题我留给你解决。

【讨论】:

  • 嘿,感谢您的帮助,这确实奏效了!我真的没有发现我在 if 语句中有错字,这很糟糕,但现在我必须在任务管理器中结束进程才能关闭,我不知道这是否正常,因为我相信我已经实现了关闭窗口的函数。
猜你喜欢
  • 2012-10-25
  • 2010-12-16
  • 1970-01-01
  • 2015-11-02
  • 1970-01-01
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多