我一直在尝试在类中使用d3d来包装一些基本的win32功能,并且难以理解为什么CreateWindowEx函数在我使用RegisterClassEx创建一个有效类之后失败说一个类不存在,没有错误谈到 :\ 。我觉得我错过了一些愚蠢的小事,但我找不到它。以下是一些代码:
我有一个像这样扩展WNDCLASSEX的类,所以它有一个普通的std :: string作为类名和一个简化的构造函数:
#ifndef WINDOWCLASS_H
#define WINDOWCLASS_H
#include <Windows.h>
#include <string>
#include "WindowAbstract.h"
using namespace std;
class WindowClass : public WNDCLASSEX
{
public:
WindowClass(string className, WindowAbstract * window);
~WindowClass();
bool Register();
string ClassName() {return m_className;}
friend class WindowAbstract;
private:
string m_className;
};
#endif
这是该类的构造函数:
WindowClass::WindowClass(string className, WindowAbstract * window)
{
cbSize = sizeof(WNDCLASSEX);
style = 0;
lpfnWndProc = window->WndProc;
cbClsExtra = 0;
cbWndExtra = 0;
hInstance = hInstance;
hIcon = LoadIcon(NULL, IDI_APPLICATION);
hCursor = LoadCursor(NULL, IDC_ARROW);
hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
lpszMenuName = NULL;
lpszClassName = className.c_str();
hIconSm = LoadIcon(NULL, IDI_APPLICATION);
m_className = className;
}
这是在构造之后调用的寄存器函数:
bool WindowClass::Register()
{
if(RegisterClassEx(this) == 0)
return false;
return true;
}
WindowAbstract类包含窗口过程并首先创建,以将指向它的函数的指针传递给WindowClass对象。
#ifndef WINDOWABSTRACT_H
#define WINDOWABSTRACT_H
#include <Windows.h>
#include <string>
using namespace std;
class WindowAbstract
{
public:
WindowAbstract();
~WindowAbstract();
bool Create(string windowTitle, string className, DWORD styles, DWORD extendedStyles, int top, int left, int bot, int right, HWND parent, HMENU id);
void Show();
friend class WindowClass;
private:
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
HWND m_hwnd;
};
#endif
这是创建功能:
bool WindowAbstract::Create(string windowTitle, string className, DWORD styles, DWORD extendedStyles, int top, int left, int bot, int right, HWND parent, HMENU id)
{
m_hwnd = CreateWindowEx(extendedStyles, className.c_str() , windowTitle.c_str(), styles, top, left, bot, right, parent, id, GetModuleHandle(NULL), NULL);
if(!m_hwnd)
return false;
return true;
}
所以在看到这一切之后,这里是我测试的实际winmain:
#include "WindowAbstract.h"
#include "WindowClass.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
DWORD error;
bool result;
char buffer[100];
WindowAbstract * window = new WindowAbstract();
WindowClass * myClass = new WindowClass("myClass", window);
result = myClass->Register();
if(!result)
{
error = GetLastError();
sprintf_s(buffer, "error: %i", error);
MessageBox(NULL, buffer, "Registration Failed!", MB_OK);
}
result = window->Create("my Window", myClass->ClassName(), WS_OVERLAPPEDWINDOW, WS_EX_CLIENTEDGE, 20, 20, 200, 200, NULL, NULL);
if(!result)
{
error = GetLastError();
sprintf_s(buffer, "error: %i", error);
MessageBox(NULL, buffer, "Window Creation Failed!", MB_OK);
}
window->Show();
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(window)
{
delete window;
window = 0;
}
if(myClass)
{
delete myClass;
myClass = 0;
}
return msg.wParam;
}
所以,总之,这是如此令人困惑,因为WindowClass对象的Register函数返回正常,但是创建函数在WindowAbstract对象中失败,因为没有有效的类(错误1407),具有该名称? Whuh?
答案 0 :(得分:5)
我认为lpszClassName = className.c_str()
构造函数中的问题是WindowClass
。一般情况下,您不应该依赖c_str()
返回的值在任何时间段内可用。
在这种情况下,您(有效地)获取本地变量的地址,该地址变量在您致电RegisterClassEx
时可能已不复存在。所以RegisterClassEx
正在成功,但谁知道它看到了什么名字?
lpszClassName = m_className.c_str()
可能会起作用(如果您先分配m_className
),但它仍然是粗略的。最好在致电c_str()
之前立即致电RegisterClassEx
。
答案 1 :(得分:3)
目前尚不清楚该行
hInstance = hInstance;
旨在完成。实际上,它所做的是用自己初始化hInstance,因此它实际上是未初始化的。该未初始化的值可能与传递给CreateWindowEx的值不同。