atl中的mfc線程

來源:互聯網
上載者:User
MFC提供了許多十分有用的類和對象,在很多時候在Office外掛程式、BHO、常規DLL這樣的工程中加入MFC支援是一個不錯的選擇。但是,MFC中的很多功能,例如資源尋找,訊息預先處理等等都依賴於在進程或者線程建立時被初始化的MFC內部資料;而對於需要添加MFC支援的工程,這些資料並不會被自動地初始化。這時候使用一些MFC的功能,例如使用CString從字串表載入一個字串,或者使用CDialog::DoModal()建立一個模態對話方塊,都會有斷言錯誤,用ATL嚮導建立的支援MFC的程式也沒有多少改善,在CWinApp的DLL版本中沒有初始化線程資料,所以調用AfxGetThread會返回null 指標。解決這個問題的一個辦法是使用AfxBeginThread來啟動一個MFC線程,這樣MFC會初始化線程相關的資料。在下面的樣本中,我線上程初始化時建立了一個模態對話方塊,以避免直接建立模態對話方塊會觸發的宣告失敗資訊。為了類比模態對話方塊的效果,在CDialogThread::WaitForDoModal()這個函數中建立了一個訊息迴圈來等待線程結束,同時用MsgWaitForMultipleObjects來避免死結。因為MFC中和進程相關的資料並不總是被正確初始化,在調用模態對話方塊之前也需要手動設定一下。 //如果這段代碼可以工作,那麼它的作者是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
        }
    }
}

使用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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.