ProcessMessageFilter的使用

来源:互联网 发布:郑州直销大师软件 编辑:程序博客网 时间:2024/06/07 06:51

在对话框程序中,我们经常是利用对话框上的子控件进行命令响应来处理一些事件。如果我们想要让

对话框(子控件的父窗口)类来响应我们的按键消息,我们可以通过ClassWizard对WM_KEYDOWN消息进行

响应,当程序运行后,我们按下键盘上的按键,但对话框不会有任何的反应。这是因为在对话框程序中,

某些特定的消息,例如按键消息,它们被Windows内部的对话框过程处理了(即在基类中完成了处理,有

兴趣的读者可以查看MFC的源代码),或者被发送给子控件进行处理,所以我们在对话框类中就捕获不到

按键的消息了。
    既然我们知道了这个处理的过程,我们就可以找到底层处理按键消息的函数,然后在子类中重载它,

就可以在对话框程序中处理按键消息了。在MFC中,是利用BOOL ProcessMessageFilter(int code, LPMSG

lpMsg)这个虚函数来过滤或响应菜单和对话框的特定Windows消息。下面我们通过程序给大家演示基于对

话框的应用程序对WM_KEYDOWN消息的捕获。

第一步:新建一个工程,选择MFC AppWizard (exe),工程名为KeyPress,点击ok,进入下一步,选择

Dialog based,点击Finish。

第二步:在CKeyPressApp类中增加一个类型为HWND,变量名m_hwndDlg的public的变量。 

第三步:在CKeyPressApp类中的InitInstance()函数中初始化m_hwndDlg=NULL 

第四步:在CKeyPressDlg类中的OnInitialDialog()函数中添加:
 ((CKeyPressApp*)AfxGetApp())->m_hwndDlg=m_hWnd;  //将对话框的句柄传递到CWinSunApp类中。

第五步:在CKeyPressApp类中Add Virtual Function,选择ProcessMessageFilter

BOOL CKeyPressApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
    if(m_hwndDlg!=NULL)
    {
       //判断消息,如果消息是从对话框发出的或者其子控件发出的,我们就进行处理。
       if((lpMsg->hwnd==m_hwndDlg) || ::IsChild(m_hwndDlg,lpMsg->hwnd))
       {
          if(lpMsg->message==WM_KEYDOWN) //如果消息是WM_KEYDOWN,我们就弹出一个消息框。
          {
              AfxMessageBox(L"捕获WM_KEYDOWN消息成功!");
          }
       }
    }
    return CWinApp::ProcessMessageFilter(code, lpMsg);
}

第六步:在对话框窗口销毁后,将CKeyPressApp类中的变量m_hwndDlg置为NULL,为此我们在

CKeyPressDlg类上点击右键,选择Add Windows Message Handler,在左边一栏中选择WM_DESTROY,在右

边按钮上选择Add and Edit,然后加入以下代码:

void CWinSunDlg::OnDestroy() 
{
    CDialog::OnDestroy();
    ((CWinSunApp*)AfxGetApp())->m_hwndDlg=NULL;
}

如果我们想捕获WM_KEYUP或WM_CHAR消息,也是类似。

0 0
原创粉丝点击