0

我正在使用 VC2010 和混合 MFC/Win32 编写一个框架。我有许多控件类型,它们都注册了自己的窗口类,其中一些使用标准窗口类之一的 WindowProc - 类似于以下示例。

void Button::OnInitClass(WNDCLASS &wndClass)
{       
    Object::OnInitClass(wndClass);
    if(!GetClassInfo(NULL, WC_BUTTON, &wndClass)) {
        throw std::exception("Failed getting window class info.");
    }
    wndClass.lpszClassName = ButtonBase::GetWndClassName();
}

bool Button::Create(CWnd* parent)
{
    if(!WndClassInitialized) {
        static VSCriticalSection cs;
        cs.Enter();
        if(!WndClassInitialized) {
            WNDCLASS wndClass;
            memset(&wndClass, 0, sizeof(WNDCLASS));
            OnInitClass(wndClass);
            assert(wndClass.lpszClassName);
            if(!RegisterClass(&wndClass)) {
                throw std::exception("Error registering window class");
            }
            WndClassInitialized = true;
        }
        cs.Leave();
    }

    DWORD style =   WS_CHILD | WS_CLIPSIBLINGS | BS_PUSHBUTTON | BS_MULTILINE;
    DWORD exStyle = WS_EX_LEFT | WS_EX_LTRREADING;      
    Created = CWnd::CreateEx(exStyle, ButtonBase::GetWndClassName(), "", style , _attribAnchor.Rect, parent, 0) != FALSE;       
    SetFont(_font);
    return Created;
}

这一切都工作了很长时间,但现在我现在遇到了堆损坏。但是,如果我在 CreateEx 调用中直接使用 WC_BUTTON 类,则不会出现堆损坏。

我怀疑这种从 WC_BUTTON 使用 WindowProc 注册窗口类的方式是否安全。是吗?

如果它是安全的,那么我当然需要在其他地方寻找堆损坏的过程。但如果没有,有没有一种安全的方法来做我想做的事情?(即使用新名称注册现有类 - 我这样做是为了能够从它们的窗口类名称中识别控件,给定任意窗口句柄)

我应该提到堆损坏发生在字符串分配中,并且所有参数似乎都是正确的——所以问题一定是在那之前的某个地方。

在此先感谢,马丁

4

1 回答 1

0

恐怕混合 MFC/Win32 会使情况变得更糟。如果您的主要框架/SDK 是 MFC,那么为什么不遵循 MFC 的规则和风格呢?为什么使用 ::RegisterClass 而不是 AfxRegisterClass (简单得多)。为什么只为 UI 控件注册所有不同的类?

通常的 MFC 程序只为弹出窗口或顶级窗口注册新的窗口类(通过 AfxRegisterClass)。MFC CWnd 为此提供了基本的 WndProc。如果您想要自定义设计按钮控件,您可以使用窗口子类化机制。

于 2013-01-22T09:00:56.277 回答