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

作者:孙鑫                  日期:2003-9-4

原文地址:http://www.sunxin.org/sunxin/002.asp

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

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

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

第二步:在CWinSunApp类上点击右键,选择Add Member Varialbe,增加一个类型为HWND,变量名m_hwndDlg的public的变量。代码如下:

WinSun.h

class CWinSunApp : public CWinApp

{

public:

HWND m_hwndDlg;

CWinSunApp();

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CWinSunApp)

public:

virtual BOOL InitInstance();

//}}AFX_VIRTUAL

// Implementation

//{{AFX_MSG(CWinSunApp)

// NOTE - the ClassWizard will add and remove member functions here.

//    DO NOT EDIT what you see in these blocks of generated code !

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

第三步:在WinSun.cpp(CWinSunApp类)文件中的InitInstance()函数中添加如下代码:

WinSun.cpp

BOOL CWinSunApp::InitInstance()

{

AfxEnableControlContainer();

// Standard initialization

// If you are not using these features and wish to reduce the size

//  of your final executable, you should remove from the following

//  the specific initialization routines you do not need.

#ifdef _AFXDLL

Enable3dControls();                     // Call this when using MFC in a shared DLL

#else

Enable3dControlsStatic();      // Call this when linking to MFC statically

#endif

CWinSunDlg dlg;

m_pMainWnd = &dlg;

int nResponse = dlg.DoModal();

if (nResponse == IDOK)

{

// TODO: Place code here to handle when the dialog is

//  dismissed with OK

}

else if (nResponse == IDCANCEL)

{

// TODO: Place code here to handle when the dialog is

//  dismissed with Cancel

}

// Since the dialog has been closed, return FALSE so that we exit the

//  application, rather than start the application's message pump.

m_hwndDlg=NULL;

return FALSE;

}

第四步:在CWinSunApp类上点击右键,选择Add Virtual Function,在左边一栏里,选择ProcessMessageFilter,在右边按钮上选择Add and Edit,然后加入以下代码:

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)

{

//判断消息,如果消息是从对话框发出的或者其子控件发出的,我们就进行处理。sunxin

if((lpMsg->hwnd==m_hwndDlg) || ::IsChild(m_hwndDlg,lpMsg->hwnd))

{

//如果消息是WM_KEYDOWN,我们就弹出一个消息框。sunxin

if(lpMsg->message==WM_KEYDOWN)

{

AfxMessageBox("捕获WM_KEYDOWN消息成功!");  //可以调用SendMessage对消息再分配

}

}

}

return CWinApp::ProcessMessageFilter(code, lpMsg);

}

第五步:在WinSunDlg.cpp(CWinSunDlg类)中的OnInitialDialog()函数中加入以下代码:

WinSunDlg.cpp

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类中。sunxin

((CWinSunApp*)AfxGetApp())->m_hwndDlg=m_hWnd;

return TRUE;  // return TRUE  unless you set the focus to a control

}

第六步:在对话框窗口销毁后,将CWinSunApp类中的变量m_hwndDlg置为NULL,为此我们在CWinSunDlg类上点击右键,选择Add Windows Message Handler,在左边一栏中选择WM_DESTROY,在右边按钮上选择Add and Edit,然后加入以下代码:

WinSunDlg.cpp

void CWinSunDlg::OnDestroy()

{

CDialog::OnDestroy();

// TODO: Add your message handler code here

((CWinSunApp*)AfxGetApp())->m_hwndDlg=NULL;

}

至此,我们的工作就做完了,现在我们可以按Ctrl+F5运行程序,看到我们想要的结果。当然,如果我们想捕获WM_KEYUP或WM_CHAR消息,也是类似,这就交给读者下来自行完成了。想要浏览更多技术文章,请登录网站:http://www.sunxin.org。

如何在对话框程序中让对话框捕获WM_KEYDOWN消息相关推荐

  1. 基础语法篇_8——MFC:如何在对话框程序中让对话框捕获WM_KEYDOWN消息

  2. MFC对话框程序中添加工具栏及工具栏上的Button响应UPDATE_COMMAND_UI消息

    对话框中添加工具栏及工具栏上的Button响应UPDATE_COMMAND_UI消息 在对话框程序中添加工具栏其实很简单,网上能找到很多的例子.一般的步骤就是:1.在资源中添加工 具栏资源:2.在对话 ...

  3. 微信小程序中如何发送客服消息给用户

    微信小程序是一种快速开发和发布应用程序的平台,可以为用户提供各种服务和功能.而与用户进行沟通和交互是实现这些目标的重要步骤之一.因此,在本文中,我们将介绍如何在微信小程序中使用客服消息来与用户进行联系 ...

  4. VS2010环境下用c++语言在MFC对话框程序中连接及操作Mysql 数据库

    小编近来由于工作需要,需要折腾一下MySql据库, 由于以前用的数据库不是 MySql, 也不是在 VS2010 , 更不是在 MFC 中连接数据库.所以还颇费了一番周折才实现了把数据插入到数据库表格 ...

  5. android 中dialog对话框,Android中的对话框dialog

    普通对话框 单选对话框 多选对话框 进度条对话框 底部弹出框 1.普通对话框 this 代表当前类 最终继承Context 相当于是子类 getApplicationContext:直接返回的是Con ...

  6. 发送linux键盘消息,在C#程序中模拟发送键盘按键消息

    using System.Runtime.InteropServices; 引入键盘事件函数 [DllImport("user32.dll")] public static ext ...

  7. MFC——基于MFC对话框程序中添加菜单栏 (CMenu)解决方案

    开发环境 Visual C++ 6.0 MFC 解决方案 一.将Menu加入Resource视图中 在WorkSpace中的Resource视图下,在任意一个文件夹图标上,右击选择Insert(插入) ...

  8. javascript对话框_JavaScript中的对话框

    javascript对话框 JavaScript对话框 (JavaScript Dialog Boxes) Dialog boxes are a great way to provide feedba ...

  9. 对话框响应WM_KEYDOWN消息

    对于按键消息,WM_CHAR 也一样,我敢肯定地告诉你你将会失败,为什么,问题就是出在WM_CHAR上,你可以试一试,当你不把光标移动到Edit控件时,对话框可以捕获到WM_CHAR消息,但是一旦你把 ...

  10. VS2017 MFC对话框程序打印及打印预览的实现

    VS2017 MFC对话框程序打印及打印预览的实现 花了一个星期,研究了网上大量的MFC对话框打印及打印预览功能的demo之后,网上现有的版本都比较旧,所以选中了几个版本,合并修改,得到这个比较完美的 ...

最新文章

  1. oralce rollup 小计合计_总计与小计–WITH ROLLUP
  2. oracle对象权限回收,【Privilege】Oracle对象权限级联收回现象测试
  3. 利用VMware Infrastructure SDK编程控制虚拟机集群(1)
  4. STL笔记(4)关于erase,remove
  5. HashMap深度解析:一文让你彻底了解HashMap
  6. Linux下部署Tomcat项目笔记
  7. mysql可以用视图insert_MySql-视图操作
  8. python数据可视化代码_Python实现简单的数据可视化
  9. FPGA学习笔记---任务(task) 和函数 (function)
  10. java 管道流的读写操作 用于两个线程之间的通信
  11. fastapi 基础使用
  12. 天梯—重要的话说三遍(C语言)
  13. 【Android开发】范例2-实现带图标的ListView
  14. 190704每日一句
  15. 浅析CSDN的下载积分
  16. java-jna win32 api使用
  17. ABSynthe : 侧信道攻击加密函数窃取密钥
  18. Java 枚举 ordinal 使用以及介绍
  19. 基于AD9854信号发生电路和MSK调制信号
  20. 【学术】英文写作中值得参考的语法、句式(二)

热门文章

  1. 金融系统中BER-TLV的解析,更改、增加、删除TAG的实现
  2. linux HBA 卡驱动安装
  3. 深入浅出InfoPath——如何在项目中引用GAC中的dll文件
  4. MSTP拓扑计算过程与实验
  5. python 调用父类方法, 重写父类构造方法, 不显式调用,会报错
  6. Vector Math for 3D Computer Graphics (Bradley Kjell 著)
  7. js中的object
  8. 从头开始学Android之(一)——— Android架构
  9. Python-字典遍历
  10. NO.170 六问禅道1:为什么任务的剩余工时不自动更新?