剛開始的時候,在一個對話方塊工程exe中,通過CreateControl()可以成功地直接建立一個控制項(ocx),後來由於變化,需要在一個控制項中再手動建立其它的控制項,結果卻失敗了,建立的代碼和在exe中完全一樣,可為什麼不成功呢?
出問題的那一句是:
m_pCtrlCont = afxOccManager->CreateContainer(this);
是windows自己的檔案中,函數如下:
BOOL CWnd::InitControlContainer(BOOL bCreateFromResource)
{
if (m_pCtrlCont == NULL)
{
BOOL bSuccess;
bSuccess = CreateControlContainer( &m_pCtrlCont );
if (bSuccess && (m_pCtrlCont == NULL))
{
// The window wants to use the default control container.
TRY
{
m_pCtrlCont = afxOccManager->CreateContainer(this);
}
END_TRY
}
//When Container is created and it is not during creation from resources,
//populate the list with all resource created Win32 controls.
if (!bCreateFromResource)
{
m_pCtrlCont->FillListSitesOrWnds(GetOccDialogInfo());
}
}
// Mark all ancestor windows as containing OLE controls.
if (m_pCtrlCont != NULL)
{
CWnd* pWnd = this;
while ((pWnd != NULL) && !(pWnd->m_nFlags & WF_OLECTLCONTAINER))
{
pWnd->m_nFlags |= WF_OLECTLCONTAINER;
pWnd = pWnd->GetParent();
if (! (GetWindowLong(pWnd->GetSafeHwnd(), GWL_STYLE) & WS_CHILD))
break;
}
}
return (m_pCtrlCont != NULL);
}
然後查看afxOccManager,發現有
#define afxOccManager AfxGetModuleState()->m_pOccManager
這時,m_pOccManager為NULL,所以建立不成功
這個變數名稱讓我想起可能是和ole有關的環境沒有初始化造成的,查看exe工程的CexeApp::InitInstance()中,有 AfxEnableControlContainer();,而控制項工程中卻沒有,於是把它拷貝到控制項工程的CocxApp::InitInstance()中,編譯運行,控制項建立成功
拷貝之後的函數如下:
BOOL CocxApp::InitInstance()
{
BOOL bInit = COleControlModule::InitInstance();
if (bInit)
{
// TODO: Add your own module initialization code here.
AfxEnableControlContainer();
}
return bInit;
}