我从 MFC 控件 CListCtrl 进行派生,在其中添加了一个CEdit成员变量 m_edit,需要在控件初始化时调用 m_edit.Create(),应该放在哪里呢?
首先,我放在 OnCreate() 里,但是发现在对话框模版中 DDX 使用时,根本不发送 WM_CREATE 消息,OnCreate() 也就不被调用;
然后,我放在 PreSubclassWindow() 里,但是当我用代码 CListCtrl::Create() 动态创建的时候,执行到 PreSubclassWindow() 程序会报错。
参考了一个第三方的控件库,它在 PreSubclassWindow() 里这样写:
_AFX_THREAD_STATE* pThreadState=AfxGetThreadState();
// hook not already in progress
if(pThreadState->m_pWndInit==NULL)
{
m_edit.Create(WS_CHILD|WS_BORDER|ES_AUTOHSCROLL,CRect(0,0,0,0),this,0x1001);
}
就一切正常了。但是其原理不明,MSDN 里也没有关于 _AFX_THREAD_STATE 的说明,哪位高人可以指点一二?
首先,我放在 OnCreate() 里,但是发现在对话框模版中 DDX 使用时,根本不发送 WM_CREATE 消息,OnCreate() 也就不被调用;
然后,我放在 PreSubclassWindow() 里,但是当我用代码 CListCtrl::Create() 动态创建的时候,执行到 PreSubclassWindow() 程序会报错。
参考了一个第三方的控件库,它在 PreSubclassWindow() 里这样写:
_AFX_THREAD_STATE* pThreadState=AfxGetThreadState();
// hook not already in progress
if(pThreadState->m_pWndInit==NULL)
{
m_edit.Create(WS_CHILD|WS_BORDER|ES_AUTOHSCROLL,CRect(0,0,0,0),this,0x1001);
}
就一切正常了。但是其原理不明,MSDN 里也没有关于 _AFX_THREAD_STATE 的说明,哪位高人可以指点一二?
是不是可以这样理解,凡是从 MFC 派生的控件,考虑到对话框模版和动态创建两种情况,都必须写双份初始化代码,并且用 AfxGetThreadState()->m_pWndInit 加以判断?