一、需求
與標准的 MessageBox 相比,MFC提供了 AfxMessageBox 的方法是我們對消 息框的變得更加容易。然而簡單的 AfxMessageBox 有時已經不能夠滿足我們的 需求了:有時候我僅僅想提示用戶一下,並不需要用戶確認,也就是說過一段時 間消息框就能自動關閉。
您可能馬上會想到,使用自己定義的對話框來替代程序中的 AfxMessageBox ,沒錯,這樣的結果非常能夠讓你滿意,但怎麼實現呢?
您也許會說,我自己寫一個 OwnMessageBox 函數,先前調用 AfxMessageBox 的地方都換成它就好了,非常好的主意!但你終歸要去一個個的替換,是不是感 覺很沒有挑戰性呢?現在本文將介紹一個比較好的辦法解決此問題。
二、解決辦法
MFC中的CWinApp提供了一個名為 DoMessageBox 的虛函數供它的子類進行重 載操作,我們先來看一下AfxMessageBox的源代碼:
int AFXAPI AfxMessageBox(LPCTSTR lpszText, UINT nType, UINT nIDHelp)
{
CWinApp* pApp = AfxGetApp();
if (pApp != NULL)
return pApp->DoMessageBox(lpszText, nType, nIDHelp);
else
return pApp->CWinApp::DoMessageBox(lpszText, nType, nIDHelp);
}
重載 DoMessageBox 後我們得到了什麼呢?
int COwnAfxMessageBoxApp::DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt)
{
return CWinApp::DoMessageBox(lpszPrompt, nType, nIDPrompt);
}
其中 CWinApp::DoMessageBox 就是對 Windows API 中的 ::MessageBox 的封裝,再此不多敘。
從代碼中看出,調用 AfxMessageBox 先要到 DoMessageBox 這裡審核,審核 通過再執行標准的MessageBox,這下你該知道怎麼做了吧?到這時,可能你會這 樣寫到:
int COwnAfxMessageBoxApp::DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt)
{
OwnMessageBox(lpszPrompt, nType, nIDPrompt);
// return CWinApp::DoMessageBox(lpszPrompt, nType, nIDPrompt);
}
這樣的寫法沒有問題,但也許有的時候仍然需要彈出標准的 MessageBox 需要用戶確認,怎麼設計才更加合理呢?AfxMessageBox 的第二個 參數 nType 是指定 MessageBox 的類型,在 Winuser.h 中定義了一些標准的類 型,請注意 nType 是 UINT 類型的,而標准類型的定義才不到10個,你完全可 以添加自己的 MessageBox 類型!在 OwnAfxMessageBoxApp.h 中定義:
#define MB_USERDEFINE 0x10000000
你的 DoMessageBox 處理函數:
int COwnAfxMessageBoxApp::DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt)
你的調用代碼:
{
if (MB_USERDEFINE == nType)
{
OwnMessageBox(lpszPrompt, nType, nIDPrompt);
return TRUE;
}
return CWinApp::DoMessageBox(lpszPrompt, nType, nIDPrompt);
}
void COwnAfxMessageBoxDlg::OnOK()
{
::AfxMessageBox("我是標准的 AfxMessageBox!");
::AfxMessageBox("我是被重載的 AfxMessageBox!", MB_USERDEFINE);
// CDialog::OnOK();
}
到這裡原理部分已經講完了,具體的實現方法請查看代碼。感謝 CSDN 的 bongny (金輝)提供了思路。
三、結束語
其實這個根本都稱不上技術,只要善於發現就會有新的收獲。祝大家身體健 康,萬事如意!
本文配套源碼