我們知道實現捕獲最大化、最小化、關閉、大小變化等系統消息主要有如下兩種方法:
1、重寫PreTranslateMessage函數
BOOL CSuperSpeedDlg::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class if ( pMsg->message == WM_SYSCOMMAND ) { if ( ( pMsg->wParam & 0xFFF0) == SC_MINIMIZE ) { AfxMessageBox(_T("捕獲到窗口最小化消息")); } else if ( ( pMsg->wParam & 0xFFF0) == SC_MAXIMIZE ) { AfxMessageBox(_T("捕獲到窗口最大化消息")); }else if ( ( pMsg->wParam & 0xFFF0) == SC_CLOSE ) { AfxMessageBox(_T("捕獲到窗口關閉消息")); } } return CDialog::PreTranslateMessage(pMsg); }
注:此方法無法捕獲對話框程序程序中的系統按鈕消息
2、響應WM_SIZE消息(OnSize函數)
void CSuperSpeedDlg::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); switch( nType) { case SIZE_RESTORED: AfxMessageBox( L"捕獲到窗口還原消息" ); break; case SIZE_MINIMIZED: AfxMessageBox( L"捕獲到窗口最小化消息" ); break; case SIZE_MAXIMIZED: AfxMessageBox( L"捕獲到窗口最大化消息" ); break; } }
注:此方法不但可以捕獲對話框程序程序中的系統按鈕消息,同時還可以獲取客戶區高度與寬度。
附加說明:
你也可以用IsZoomed函數來判斷窗口是否最大化了。
3、如何讓子對話框響應這些系統消息
如上所述:
對於最大化、最小化等系統消息的捕獲,通常可以由WM_SIZE來完成,但如果一個對話框是一個子對話框時,通常它的父對話框會擁有這些消息,而子對話框並不會,所以上面的SIZE_RESTORED、SIZE_MINIMIZED、SIZE_MAXIMIZED等消息是子對話框是接收不到的。
那么子對話框怎樣來處理這些系統消息呢?我是這樣想的:我們可以通過父對話框的OnSize函數來捕獲這些消息,之后我們可以給相應的子對話框發送我們自定義的消息,在這些自定義的消息中處理我們進行操作,。這樣操作就是變相的讓子對話框來響應這些接收不到的消息!
下面是一個讓子對話框 變相響應系統消息的例子:
void CSuperSpeedDlg::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); if (nType == SIZE_MAXIMIZED && m_MFCTab.GetActiveTab() == 2) { //AfxMessageBox( L"捕獲到窗口最大化消息" ); HWND hwnd = m_MyPlatformDlg.GetSafeHwnd(); ::PostMessage(hwnd, WM_KEYDOWN, VK_F5, 1); // F5刷新 } }
這里m_MyPlatformDlg是CSuperSpeedDlg對話框的一個子對話框的對象,如果他們同時滿足nType == SIZE_MAXIMIZED && m_MFCTab.GetActiveTab() == 2這兩個條件,我們就讓子對話框對象m_MyPlatformDlg來做一些操作,這里我們直接發送消息,讓子對話框進行F5刷新,當然我們亦可以發送自定義消息給子對話框,然后在子對話框中操作響應這個消息。