c++ - 即使注册成功,CreateWindowEx 也会失败并出现错误 1407?

标签 c++ winapi

当我使用 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),具有该名称?嗯?

最佳答案

我认为问题出在WindowClass 构造函数中的lpszClassName = className.c_str()。一般而言,您不应依赖从 c_str() 返回的值在任何时间段内都可用。

在这种情况下,您(有效地)获取了一个局部变量的地址,该变量在您调用 RegisterClassEx 时可能已经不复存在。所以 RegisterClassEx 成功了,但谁知道它看到的是什么名字?

lpszClassName = m_className.c_str() 可能会起作用(如果您首先分配了 m_className),但它仍然很粗略。最好在调用 RegisterClassEx 之前调用 c_str()

关于c++ - 即使注册成功,CreateWindowEx 也会失败并出现错误 1407?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9152280/

相关文章:

c++ - 如何从作为模板参数传递的类中获取静态模板方法的地址

c++ - WinAPI:钩子(Hook)函数中的非dll数据

c# - 如何在 C# 中使用 CreateUserProfileEx

c++ - GetMessage 失败会发生什么?

c++ - 我无法使用继承 setter 和 getter 返回 const char * 变量

c++ - 在不同平台上处理#include 路径

c++ - 从 while 循环计算值?

c++ - 从 std::map 调用函数

C++ WCHAR 操作

c++ - 使用 SecureZeroMemory 新建/删除问题