MFC:如何在對話框程序中讓對話框捕獲WM_KEYDOWN消息

想要讓對話框(子控件的父窗口)類響應按鍵消息,則可以通過類嚮導對WM_KEYDOWN消息進行響應,當程序運行後,按下鍵盤上的按鍵,但對話框不會有任何的反應。這是因爲在對話框程序中,某些特定的消息,例如按鍵消息,它們被Windows內部的對話框過程處理了(即在基類中完成了處理,或者被髮送給子控件進行處理,所以在對話框類中就捕獲不到按鍵的消息了。

可以找到底層處理按鍵消息的函數,然後在子類中重載它,便能在對話框程序中處理按鍵消息了。在MFC中,是利用 ProcessMessageFilter虛函數過濾或者響應菜單和對話框的特定Windows消息。聲明:

BOOL ProcessMessageFilter(int code,LPMSG lpMsg)

1)建立一個基於對話框的MFC項目,工程名:WinSun。

運行:

2)在CWinSunApp類上點擊右鍵,選擇添加下的添加變量子菜單項,增加一個類型爲HWND,變量名m_hwndDlg的public的變量:


3)在WinSun.cpp ( CWinSunApp類)文件中的InitInstance函數的return語句前添加m_hwndDlg=NULL;


BOOL CWinSunApp::InitInstance()
{
    ......
    
	m_hwndDlg = NULL;
	return FALSE;
}

4)在CWinSunApp類上單擊右鍵,選擇屬性,在重寫條目下添加ProcessMessageFilter:


BOOL CWinSunApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
	// TODO: 在此添加專用代碼和/或調用基類

	return CWinApp::ProcessMessageFilter(code, lpMsg);
}

添加如下代碼:

BOOL CWinSunApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
	// TODO: 在此添加專用代碼和/或調用基類
	if (m_hwndDlg != NULL) {
		//判斷消息,如果消息是從對話框發出的或者其子控件發出的,就進行處理
		if ((lpMsg->hwnd == m_hwndDlg) || ::IsChild(m_hwndDlg, lpMsg->hwnd)) {
			//如果消息是WM_KEYDOWN,就彈出一個消息框
			if (lpMsg->message == WM_KEYDOWN) {
				AfxMessageBox(_T("捕獲WM_KEYDOWN消息成功!"));
			}
		}
	}
	return CWinApp::ProcessMessageFilter(code, lpMsg);
}

5)在WinSunDlg.cpp (CWinSunDlg類)中的OnInitialDialog()函數中加入以下代碼:

BOOL CWinSunDlg::OnInitDialog()
{
	......
	
	// TODO: 在此添加額外的初始化代碼
	//將對話框的句柄傳遞到CWinSunApp類中
	((CWinSunApp*)AfxGetApp())->m_hwndDlg= m_hWnd;
	return TRUE;  // 除非將焦點設置到控件,否則返回 TRUE
}

6)在對話框窗口銷燬後,將CWinSunApp類中的變量m_hwndDlg置爲NULL,爲此給CWinSunDlg類添加消息響應函數:

void CWinSunDlg::OnDestroy()
{
	CDialogEx::OnDestroy();

	// TODO: 在此處添加消息處理程序代碼
}

添加代碼:

void CWinSunDlg::OnDestroy()
{
	CDialogEx::OnDestroy();

	// TODO: 在此處添加消息處理程序代碼
	((CWinSunApp*)AfxGetApp())->m_hwndDlg = NULL;
}

運行程序,按下鍵盤按鍵:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章