首先申明,本文参考"c++ - MFC 打开大文件"和"Notifying the Document"两篇文章写成。
在编写Windows软件时,打开一个Excel文件或实际计算需要耗费一定的时间,使得Windows窗口不流畅,此时在窗口显示等待过程的状态特别有意义。
1. 在resource.h中:
#define IDD_NotifyDocumentFinished 101
2. 在ReadStateDoc.h中的class CReadStateDoc : public CDocument中:
public:
enum DocState { None, Failed, Loading, Loaded };
DocState GetDocState() const { return m_state; }
DocState m_state;
void StartLoading();
3. 在ReadStateDoc.cpp中:
UINT LongRunningFunction(LPVOID param)
{
Sleep(12000);
HWND hWnd = AfxGetApp()->m_pMainWnd->GetSafeHwnd();
NMHDR hdr = { hWnd, IDD_NotifyDocumentFinished, 0 };
::SendMessage(hWnd, WM_NOTIFY, 0, reinterpret_cast(&hdr));
return 0;
}
void CReadStateDoc::StartLoading()
{
AfxBeginThread(&LongRunningFunction, nullptr);
}
4. 使用类向导添加函数CReadStateDoc::OnCmdMsg,并添加代码:
BOOL CReadStateDoc::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
// TODO: 在此添加专用代码和/或调用基类
if (HIWORD(nCode) == WM_NOTIFY)
{
WORD wCode = LOWORD(nCode);
AFX_NOTIFY* notify = reinterpret_cast(pExtra);
if (notify->pNMHDR->idFrom == IDD_NotifyDocumentFinished)
{
m_state = Loaded;
UpdateAllViews(nullptr);
}
}
return CDocument::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
5. 在CReadStateView::OnFileOpen()中:
CReadStateDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
pDoc->m_state = pDoc->Loading;
Invalidate();
pDoc->StartLoading();
6. 在CReadStateView::OnDraw(CDC* pDC)中:
void CReadStateView::OnDraw(CDC* pDC)
{
CReadStateDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
CFont font;
CFont* pFont;
font.CreatePointFont(120, _T("Arial"));
pFont = pDC->SelectObject(&font);
CReadStateDoc::DocState state = pDoc->GetDocState();
CString sstate;
switch (state)
{
case CReadStateDoc::None:
sstate = "None";
break;
case CReadStateDoc::Failed:
sstate = "Failed";
break;
case CReadStateDoc::Loading:
sstate = "Loading ... ";
break;
case CReadStateDoc::Loaded:
sstate = "Loaded";
break;
}
pDC->TextOut(50, 50, sstate);
// Release the font object
pDC->SelectObject(pFont);
}
点击“文件->打开”,窗口出现“Loading ...”:
过一会,窗口出现“Loaded”: