使用新名称注册现有的Windows类是否安全?

时间:2013-01-22 08:15:03

标签: winapi heap-corruption registerclass

我正在使用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。 是吗?

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

我应该提到堆损坏发生在字符串分配中,并且所有参数看起来都是正确的 - 所以问题必须在此之前的某处。

提前致谢, 马丁

1 个答案:

答案 0 :(得分:0)

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

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