![](/img/trans.png)
[英]GetLastError returns 998 when CreateWindow failed and returns 0
[英]CreateWindow() returns nullptr and GetLastError() returns 1400
您好,我最近决定通过 DirectX11 学习图形编程,为此我正在学习如何使用 Windows API。 我按照在线教程设法创建了一个窗口,后来我自己成功创建了一个窗口。 然而,当我尝试制作一个框架来创建 Window 时,问题就开始了,我遇到了一些错误,但是通过研究文档和查找示例,大多数问题都得到了解决,除了一个涉及 CreateWindow() 函数的问题。
每当我尝试获取它返回 nullptr 的窗口句柄时,我尝试通过 GetLastError() 获取错误代码,但我得到的只是 1400,根据 MSDN,这是“无效的窗口句柄”。 我不知道自己做错了什么,也没有找到任何解决问题的线程。 它编译成功,但没有出现窗口。
窗口.hpp
#pragma once
#include "WindowsHeader.hpp"
class Window
{
public:
Window(int width, int height, const char* name);
~Window();
Window(const Window&) = delete;
Window& operator=(const Window&) = delete;
private:
class WindowClass
{
public:
static const char* GetName() noexcept;
static HINSTANCE GetInstance() noexcept;
private:
WindowClass() noexcept;
~WindowClass();
WindowClass(const WindowClass&) = delete;
WindowClass& operator=(const WindowClass&) = delete;
static constexpr const char* window_class_name{ "HardwareAccelerated3D" };
static WindowClass window_class;
HINSTANCE hinst;
};
static LRESULT CALLBACK HandleMsgSetup(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) noexcept;
static LRESULT CALLBACK HandleMsgInvoke(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) noexcept;
LRESULT HandleMsg(HWND, UINT msg, WPARAM wparam, LPARAM lparam) noexcept;
int width;
int height;
HWND hwnd;
};
窗口.cpp
#include "Window.hpp"
#include <sstream>
//Window Class
Window::WindowClass Window::WindowClass::window_class;
Window::WindowClass::WindowClass() noexcept
: hinst(GetModuleHandle(NULL))
{
WNDCLASSEX window_class{ {0} };
window_class.cbSize = sizeof(window_class);
window_class.style = CS_OWNDC;
window_class.lpfnWndProc = &HandleMsgSetup;
window_class.cbClsExtra = NULL;
window_class.cbWndExtra = NULL;
window_class.hInstance = GetInstance();
window_class.hIcon = NULL;
window_class.hCursor = NULL;
window_class.hbrBackground = NULL;
window_class.lpszMenuName = NULL;
window_class.lpszClassName = GetName();
window_class.hIconSm = NULL;
RegisterClassEx(&window_class);
}
Window::WindowClass::~WindowClass()
{
UnregisterClass(GetName(), GetInstance());
}
const char* Window::WindowClass::GetName() noexcept
{
return window_class_name;
}
HINSTANCE Window::WindowClass::GetInstance() noexcept
{
return window_class.hinst;
}
//Window
Window::Window(int width, int height, const char* name)
: width(width), height(height)
{
RECT wndrec;
wndrec.left = 100;
wndrec.right = wndrec.left + width;
wndrec.top = 100;
wndrec.bottom = wndrec.top + height;
if (!AdjustWindowRect(&wndrec, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, false))
{
std::ostringstream oss;
oss << GetLastError();
OutputDebugString(oss.str().c_str());
}
hwnd = CreateWindow(WindowClass::GetName(), name, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, wndrec.right - wndrec.left, wndrec.bottom - wndrec.top, NULL,
NULL, WindowClass::GetInstance(), this);
if (!hwnd)
{
std::ostringstream oss;
oss << GetLastError();
OutputDebugString(oss.str().c_str());
}
ShowWindow(hwnd, SW_SHOWDEFAULT);
}
Window::~Window()
{
DestroyWindow(hwnd);
}
LRESULT WINAPI Window::HandleMsgSetup(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) noexcept
{
if (msg == WM_NCCREATE)
{
const CREATESTRUCTW* const pcreate = reinterpret_cast<CREATESTRUCTW*>(lparam);
Window* const pwnd = static_cast<Window*>(pcreate->lpCreateParams);
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pwnd));
SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&Window::HandleMsgInvoke));
return pwnd->HandleMsg(hwnd, msg, wparam, lparam);
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
LRESULT WINAPI Window::HandleMsgInvoke(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) noexcept
{
Window* const pwnd = reinterpret_cast<Window*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
return pwnd->HandleMsg(hwnd, msg, wparam, lparam);
}
LRESULT Window::HandleMsg(HWND, UINT msg, WPARAM wparam, LPARAM lparam) noexcept
{
switch (msg)
{
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
WinMain.cpp
#include "WindowsMessageMap.hpp"
#include "Window.hpp"
int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
Window window(640, 480, "HardwareAccelerated3D");
MSG msg;
BOOL gresult;
while (gresult = GetMessage(&msg, NULL, NULL, NULL) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (gresult == -1)
return -1;
return msg.wParam;
}
WindowsHeader.hpp 只是一些定义,Windows.h 是为了避免一些 Windows 宏,WindowsMessageMap.hpp 只是将 Windows 消息打印到调试控制台(我用它来查看正在调用哪些消息)。
PS:这是我在这里的第一篇文章,所以请随时指出文章本身的任何问题,以便我下次更清楚。
提前致谢! :-)
您在代码中使用的hwnd
与Window.hpp
的相同:
LRESULT Window::HandleMsg(HWND, UINT msg, WPARAM wparam, LPARAM lparam) noexcept
{
switch (msg)
{
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
Window.hpp的最后一行:
HWND hwnd;
当您调用HandleMsg
, Window.hpp
hwnd
未初始化:
您可以在HandleMsgSetup
使用hwnd
,只需像以下代码一样添加hwnd
参数:
LRESULT Window::HandleMsg(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) noexcept
{
switch (msg)
{
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
它对我有用:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.