现在的位置: 首页 > 综合 > 正文

如何在对话框程序中让对话框捕获WM_KEYDOWN消息

2018年01月11日 ⁄ 综合 ⁄ 共 1721字 ⁄ 字号 评论关闭

在对话框程序中,我们经常利用对话框上的子程序的子控件进行命令响应处理一些事件。如果我们想要让对话框(子控件的符窗口)类来响应我们的按键消息,则可以通过CLASS WIZARD对WM_KEYDOWN消息进行响应,当程序运行时,我们按下键盘上的按键,当对话框不会有人会反应,这是因为在对话框程序中,某些特定的消息,例如按键消息,它们被Window内部的对话框过程处理了(即在基类中完成了处理,有兴趣的读者可以查看MFC的源代码),或者被发送给子控件进行处理,所以我们在对话框类中就捕获不到按键的消息了。

既然我们知道了这个处理的过程,就可以找到底层的按键消息的函数,然后再子类中重载它,便能在对话框程序中处理按键消息。在MFC中,是利用BOOL ProcessMessage Filter(int code,LPMSG lpMSG)这个虚函数来过滤响应菜单和对话框的特定Windows消息,下面我们通过程序给大家演示基于对话框的应用程序对WM_KEYDOWN消息的捕获。

在CWinSunApp类上添加成员变量:

HWND m_hwndDlg;


BOOL CWinSunApp::InitInstance()函数中添加:m_hwndDlg=NULL;


WinSun.cpp中写虚函数

BOOL CWinSunApp::ProcessMessageFilter(int code, LPMSG lpMsg) 
{
// TODO: Add your specialized code here and/or call the base class
if(m_hwndDlg!=NULL)
{
if (lpMsg->hwnd==m_hwndDlg||::IsChild(m_hwndDlg,lpMsg->hwnd))
{
if (lpMsg->message==WM_KEYDOWN)
{
AfxMessageBox("捕获WM_KEYDOWN消息成功");
}
}
}
return CWinApp::ProcessMessageFilter(code, lpMsg);
}

BOOL CWinSunDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);
// Set big icon
SetIcon(m_hIcon, FALSE);
// Set small icon

// TODO: Add extra initialization here
((CWinSunApp*)AfxGetApp())->m_hwndDlg=m_hWnd;
return TRUE;  // return TRUE  unless you set the focus to a control
}



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

// TODO: Add your message handler code here
((CWinSunApp*)AfxGetApp())->m_hwndDlg=NULL;
}

抱歉!评论已关闭.