我正在使用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。 是吗?
如果它是安全的,那么我需要在其他地方查找堆损坏的过程。 但是,如果没有,有没有一种安全的方法来做我想做的事情?(即注册一个新名称的现有类 - 我这样做是为了能够从他们的窗口识别控件类名,给定一个任意窗口句柄)
我应该提到堆损坏发生在字符串分配中,并且所有参数看起来都是正确的 - 所以问题必须在此之前的某处。
提前致谢, 马丁
答案 0 :(得分:0)
我害怕混合MFC / Win32让它变得更糟。如果您的主框架/ SDK是MFC,那么为什么不遵循MFC的规则和风格?为什么使用:: RegisterClass而不是AfxRegisterClass(更简单)。为什么仅仅为UI控件注册所有不同的类?
通常的MFC程序只为弹出窗口或顶级窗口注册新的窗口类(通过AfxRegisterClass)。 MFC CWnd为此提供了基本的WndProc。如果你想要一个自定义设计按钮控件,你可以使用窗口子类化机制。