//如果这段代码可以工作,那么它的作者是Jiangsheng
//否则我不知道它的作者
void __stdcall CFrontPageAddin::OnClickButtonExportCHM(IDispatch* /*Office::_CommandBarButton*
*/ Ctrl,VARIANT_BOOL * CancelDefault)
{
AtlTrace(_T(" CFPAnt::OnClickButtonExportCHM\n"));
//create a thread to avoid assert failure
CDialogThread* pDialogThread=
(CDialogThread*)AfxBeginThread(RUNTIME_CLASS(CDialogThread),
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED,NULL);
if(pDialogThread)
{
pDialogThread->m_prc=RUNTIME_CLASS(CExportCHMSheet);
pDialogThread->ResumeThread();
pDialogThread->WaitForDoModal();
delete pDialogThread;
}
}
class CDialogThread : public CWinThread
{


int m_nModalResult;
CRuntimeClass* m_prc;
void WaitForDoModal();


};
CDialogThread::CDialogThread()
{
m_bAutoDelete=FALSE;
m_prc=NULL;
m_nModalResult=0;
}
BOOL CDialogThread::InitInstance()
{
// TODO: perform and per-thread initialization here
AFX_MANAGE_STATE(AfxGetAppModuleState());
AFX_MODULE_STATE* pModuleState=AfxGetModuleState();
pModuleState->m_hCurrentInstanceHandle=_Module.GetModuleInstance();
AfxSetResourceHandle(_Module.GetModuleInstance());
if(m_prc)
{
if(m_prc->IsDerivedFrom(RUNTIME_CLASS(CDialog)))
{
CDialog* pDialog=(CDialog*)m_prc->CreateObject();
if(pDialog)
{
m_pMainWnd=pDialog;
m_nModalResult=pDialog->DoModal();
}
}
else if(m_prc->IsDerivedFrom(RUNTIME_CLASS(CPropertySheet)))
{
CPropertySheet* pDialog=(CPropertySheet*)m_prc->CreateObject();
if(pDialog)
{
m_pMainWnd=pDialog;
m_nModalResult=pDialog->DoModal();
}
}
}
return FALSE;
}
void CDialogThread::WaitForDoModal()
{
//from http://blogs.msdn.com/oldnewthing/archive/2005/02/17/375307.aspx
MSG msg;
UINT cRecords = 0;
while (true) {
switch (MsgWaitForMultipleObjects(1, &m_hThread,
FALSE, INFINITE, QS_ALLINPUT)) {
case WAIT_OBJECT_0:
return ; // event has been signalled
break;
case WAIT_OBJECT_0+1:
// we have a message - peek and dispatch it
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
break;
default:
return ; // unexpected failure
}
}
}
//否则我不知道它的作者
void __stdcall CFrontPageAddin::OnClickButtonExportCHM(IDispatch* /*Office::_CommandBarButton*
*/ Ctrl,VARIANT_BOOL * CancelDefault)
{
AtlTrace(_T(" CFPAnt::OnClickButtonExportCHM\n"));
//create a thread to avoid assert failure
CDialogThread* pDialogThread=
(CDialogThread*)AfxBeginThread(RUNTIME_CLASS(CDialogThread),
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED,NULL);
if(pDialogThread)
{
pDialogThread->m_prc=RUNTIME_CLASS(CExportCHMSheet);
pDialogThread->ResumeThread();
pDialogThread->WaitForDoModal();
delete pDialogThread;
}
}
class CDialogThread : public CWinThread
{
int m_nModalResult;
CRuntimeClass* m_prc;
void WaitForDoModal();
};
CDialogThread::CDialogThread()
{
m_bAutoDelete=FALSE;
m_prc=NULL;
m_nModalResult=0;
}
BOOL CDialogThread::InitInstance()
{
// TODO: perform and per-thread initialization here
AFX_MANAGE_STATE(AfxGetAppModuleState());
AFX_MODULE_STATE* pModuleState=AfxGetModuleState();
pModuleState->m_hCurrentInstanceHandle=_Module.GetModuleInstance();
AfxSetResourceHandle(_Module.GetModuleInstance());
if(m_prc)
{
if(m_prc->IsDerivedFrom(RUNTIME_CLASS(CDialog)))
{
CDialog* pDialog=(CDialog*)m_prc->CreateObject();
if(pDialog)
{
m_pMainWnd=pDialog;
m_nModalResult=pDialog->DoModal();
}
}
else if(m_prc->IsDerivedFrom(RUNTIME_CLASS(CPropertySheet)))
{
CPropertySheet* pDialog=(CPropertySheet*)m_prc->CreateObject();
if(pDialog)
{
m_pMainWnd=pDialog;
m_nModalResult=pDialog->DoModal();
}
}
}
return FALSE;
}
void CDialogThread::WaitForDoModal()
{
//from http://blogs.msdn.com/oldnewthing/archive/2005/02/17/375307.aspx
MSG msg;
UINT cRecords = 0;
while (true) {
switch (MsgWaitForMultipleObjects(1, &m_hThread,
FALSE, INFINITE, QS_ALLINPUT)) {
case WAIT_OBJECT_0:
return ; // event has been signalled
break;
case WAIT_OBJECT_0+1:
// we have a message - peek and dispatch it
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
break;
default:
return ; // unexpected failure
}
}
}
使用VC6.0编译通过。
上面的方法只对于DLL之类的组件比较有用。对于使用MFC的应用程序来说,上面的方法比较繁琐。比较简单的方法还是使用MFC向导来创建应用程序,然后再添加ATL或者.Net之类的额外支持。参考微软知识库文章Q181505和Q824480。
参考
- BUG: You receive an "ASSERT in wincore.cpp" assert when an MFC application calls a function in MFC regular DLL in Visual C++(http://support.microsoft.com/kb/194300)
- PRB: ATL COM AppWizard Doesn't Offer MFC Support for .EXE(http://support.microsoft.com/kb/181505)
- PRB:为 C++ DLL 项目建立托管扩展时出现链接器警告(http://support.microsoft.com/kb/814472)
- BUG: "HRESULT - 0x80010106" Error When You Run a Managed C++ Application(http://support.microsoft.com/kb/824480)
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=459594