線程創建後返回是OK。您應該爲文檔定義一個狀態,如loading
和loaded
。當你啓動線程時,狀態應該是loading
。視圖應該查看狀態並相應地顯示。當線程完成加載文檔時,它應該向文檔發送消息。在處理程序中,將狀態設置爲loaded
並呼叫UpdateAllViews()
爲視圖提供更新新文檔數據的機會。
示例:在文檔加載完成並在視圖中完成加載並加載後,將打印「加載」。
在resource.h中:
#define IDD_NotifyDocumentFinished 101
在文件標頭:
public:
enum DocState
{
None,
Failed,
Loading,
Loaded
};
DocState GetDocState() const {return m_state;}
private:
DocState m_state;
void StartLoading();
在文件執行:
BOOL CMFCDocViewAsyncDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if(!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
m_state = Loading;
StartLoading();
return TRUE;
}
UINT LongRunningFunction(LPVOID param)
{
Sleep(3000);
HWND hWnd = AfxGetApp()->m_pMainWnd->GetSafeHwnd();
NMHDR hdr = {hWnd, IDD_NotifyDocumentFinished, 0};
::SendMessage(hWnd, WM_NOTIFY, 0, reinterpret_cast<LPARAM>(&hdr));
return 0;
}
void CMFCDocViewAsyncDoc::StartLoading()
{
AfxBeginThread(&LongRunningFunction, nullptr);
}
BOOL CMFCDocViewAsyncDoc::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
if(HIWORD(nCode) == WM_NOTIFY)
{
WORD wCode = LOWORD(nCode);
AFX_NOTIFY * notify = reinterpret_cast<AFX_NOTIFY*>(pExtra);
if(notify->pNMHDR->idFrom == IDD_NotifyDocumentFinished)
{
m_state = Loaded;
UpdateAllViews(nullptr);
}
}
return TRUE;
}
在該視圖中:
void CMFCDocViewAsyncView::OnDraw(CDC* pDC)
{
CMFCDocViewAsyncDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CMFCDocViewAsyncDoc::DocState state = pDoc->GetDocState();
CString sstate;
switch(state)
{
case CMFCDocViewAsyncDoc::None:
sstate = "None";
break;
case CMFCDocViewAsyncDoc::Failed:
sstate = "Failed";
break;
case CMFCDocViewAsyncDoc::Loading:
sstate = "Loading";
break;
case CMFCDocViewAsyncDoc::Loaded:
sstate = "Loaded";
break;
}
pDC->TextOut(50, 50, sstate);
}
更新:另請參見類似的更詳細的示例http://www.codeproject.com/Articles/14706/Notifying-the-Document。
你不能希望線程阻塞並同時繼續執行。除非你購買那些昂貴的量子計算機。 – IInspectable
@IInspectable這就是爲什麼我要求一個替代架構 – manatttta
另一種方法是將文件名存儲在OnOpenDocument回調中並按需加載數據。您不能等待加載操作的GUI線程運行完成並同時處理其他消息。您將不得不在文檔加載之前返回,這種或那種方式。 – IInspectable