如何给对话框中的控件发送消息呢?Windows消息分类
以博文CTabCtrl中介绍的那样,给Tab添加子对话框来显示Tab内容。那么如果这个子对话框中含有个CTreeCtrl控件,有个Button控件,我想要模拟给这两个控件发送消息,该怎么办呢?直接把给控件的消息给控件容器(控件的父窗口)是没有用的。为什么呢?首先要明白windows的消息分类:
Windows消息的分类
1. 标准消息(队列消息)
除WM_COMMAND之外,所有以WM_开头的消息都是标准消息,如WM_MOUSEMOVE、WM_LBUTTONUP、WM_KEYDOWN、WM_CHAR。
从CWnd派生的类都可以接收到这类消息。
Windows每次从系统消息队列移走一个消息,确定它是送给哪个窗口的和这个窗口是由哪个线程创建的,然后,把它放进窗口创建线程的线程消息队列。线程消息队列接收送给该线程所创建窗口的消息。线程从消息队列取出消息,通过Windows 把它送给适当的窗口过程来处理。除了键盘、鼠标消息以外,队列消息还有WM_PAINT、WM_TIMER 和WM_QUIT。
例如:
宏名称 对应消息 消息处理函数
ON_WM_CHAR WM_CHAR OnChar
ON_WM_CLOSE WM_CLOSE OnClose
ON_WM_CREATE WM_CREATE OnCreate
ON_WM_DESTROY WM_DESTROY OnDestroy
ON_WM_LBUTTONDO WM_LBUTTONDOWN OnLButtonDown
ON_WM_LBUTTONUP WM_LBUTTONUP OnLButtonUp
ON_WM_MOUSEMOVE WM_MOUSEMOVE OnMouseMove
ON_WM_PAINT WM_PAINT OnPaint
......... ............ .......
2.命令消息
来自菜单、加速键或工具栏按钮的消息均是命令消息。
这类消息都以WM_COMMAND形式呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。从CCmdTarget派生的类都可以接收到这类消息,其wParam 记录着该消息来自哪一个菜单项目。
例如:ON_COMMAND(IDM_ABOUT, OnAbout)
ON_COMMAND(IDM_FILENEW, OnFileNew)
ON_COMMAND(IDM_FILEOPEN, OnFileOpen)
ON_COMMAND(IDM_FILESAVE, OnFileSave)
...........
3.通告消息
由控件产生的消息,例如按钮,列表框的选择等都会产生通告消息,目的是为了向其父窗口(通常是对话框)通知事件的发生。
这类消息是以WM_COMMAND或WM_NOTIFY形式呈现的。从CCmdTarget派生的类(如CDocument可以接受命令消息和通告消息,但不能接收标准消息(队列消息)),都可以接收到这类消息。
注意:由于CWnd类派生于CCmdTarget类,所以凡是从CWnd派生的类,他们既可以接收标准消息,也可以接收命令消息和通告消息。而对于从CCmdTarget类派生的类只能接收命令消息和通告消息,不能接受标准消息。
例如: 控件 宏 消息处理函数
Button ON_BN_CLICKED(<id>,<memberFxn>) memberFxn
ComboBox ON_CBN_DBLCLK(<id>,<memberFxn>) memberFxn
Edit ON_EN_SETFOCUS(<id>,<memberFxn>) memberFxn
ListBox ON_LBN_DBLCLK(<id>,<memberFxn>) memberFxn
......... ...................... ...........
标准消息和非标准消息的区分:
标准消息:代有控制后后续操作;
非标准消息:只是简单提示。
MFC命令消息的路由:
AfxWndProc(替换了窗口过程函数)->AfxCallWndProc->WindowProc->OnWnddMsg->(如果是命令消息则调用Oncommand;如果是通告消息则调用OnNotify)->OnCmdMsg
那么通告消息到底是WM_COMMAND还是WM_NOTIFY呢?
解释一:WM_NOTIFY比WM_COMMAND 功能更强大,可以存储一些额外的信息,WM_COMMAND 并不被所有的控件所支持。
解释二:Edit,Button,ListBox等发送WM_COMMAND消息,ListView,Toolbar,Tree等编译时如果不联接comctl32.lib就通不过的。Common,Controls发送WM_NOTIFY消息,因为需要提供的信息更多。
给对话框中的控件发送消息:
想要给CTreeCtrl控件模拟发送一个TCN_SELCHANGE消息。
想要给CButton控件模拟发送一个BN_CLICKED消息。
★ 由上面对windows消息的分类,我们得知,这两个消息都是通告消息。那是用 WM_COMMAND还是WM_NOTIFY呢?
根据上面的解释,我们使用 TCN_SELCHANGE--WM_NOTIFY ,BN_CLICKED--WM_COMMAND。
是不是这样呢?咱们参看MSDN:
TCN_SELCHANGE
TCN_SELCHANGE
lpnmhdr = (LPNMHDR) lParam;
Notifies a tab control's parent window that the currently selected tab has changed. This message is sent in the form of a WM_NOTIFY message.
- No return value.
- lpnmhdr
- Address of an NMHDR structure. The hwndFrom member is the handle to the tab control. The idFrommember is the child window identifier of the tab control. The code member is TCN_SELCHANGE.
由上看出TCN_SELCHANGE确实是以WM_NOTIFY呈现的,它包含以一个结构体指针的形式包含在lParam中。
typedef struct tagNMHDR { HWND hwndFrom; UINT idFrom; UINT code; } NMHDR;
Contains information about a notification message.
- hwndFrom
- Window handle to the control sending a message.
- idFrom
- Identifier of the control sending a message.
- code
- Notification code. This member can be a control-specific notification code or it can be one of the common notification codes.
BN_CLICKED
The BN_CLICKED notification message is sent when the user clicks a button. The parent window of the button receives this notification message through the WM_COMMAND message.
BN_CLICKED idButton = (int) LOWORD(wParam); // identifier of button hwndButton = (HWND) lParam; // handle to button
由上看出BN_CLICKED确实是包含在WM_COMMAND 中的。
★ 怎样把通告消息溶到WM_COMMAND 和 WM_NOTIFY中呢?
WM_NOTIFY
idCtrl = (int) wParam;
pnmh = (LPNMHDR) lParam;
- idCtrl
- Identifier of the common control sending the message.
- pnmh
- Address of an NMHDR structure that contains the notification code and additional information.
WM_COMMAND
wNotifyCode = HIWORD(wParam); // notification code
wID = LOWORD(wParam); // item, control, or accelerator identifier
hwndCtl = (HWND) lParam; // handle of control
组装参数:
LPARAM MAKELPARAM(
WORD wLow, // low-order word
WORD wHigh // high-order word
);
或者
DWORD MAKELONG(
WORD wLow, // low-order word of long value
WORD wHigh // high-order word of long value );
★ 向控件发消息我们可以使用以下两个方法:
LONG SendDlgItemMessage(
HWND hDlg, // handle of dialog box
int nIDDlgItem, // identifier of control
UINT Msg, // message to send
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
或者
LRESULT SendMessage(
HWND hWnd, // handle of destination window
UINT Msg, // message to send
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
★ 实例,验证成功:
//模拟发送TCN_SELCHANGE消息
NMHDR nmhdr;
nmhdr.code = TCN_SELCHANGE;
nmhdr.hwndFrom = g_pMainDlg->m_TabCtrl.GetSafeHwnd();
nmhdr.idFrom= g_pMainDlg->m_TabCtrl.GetDlgCtrlID();
::SendDlgItemMessage(g_pMainDlg->m_hWnd,IDC_TAB1,WM_NOTIFY,MAKELONG(TCN_SELCHANGE,0),(LPARAM)(&nmhdr));
//发送BN_CLICKED消息
::SendMessage(g_pMainDlg->m_VNOnLine.m_hWnd,WM_COMMAND,MAKELPARAM(IDC_RANG_OFF,BN_CLICKED),(LPARAM)(::GetDlgItem(g_pMainDlg->m_VNOnLine.m_hWnd,IDC_RANG_OFF)));
如何给对话框中的控件发送消息呢?Windows消息分类的更多相关文章
- MFC的停靠窗口中插入对话框,在对话框中添加控件并做控件自适应
单文档程序添加了停靠窗口后,可能会在停靠窗口中添加一些控件.在这里我的做法是在对话框上添加控件并布局,然后将这个对话框插入到停靠窗口中. 步骤 1.插入对话框,在对话框中放入控件(我的为树形控件),并 ...
- 041. asp.net中内容页访问母版页中的控件
母版页运行机制: 用户通过输入内容也的URL来请求某个页面, 获取该页面后, 读取@Page指令, 如果该指令引用了一个母版页, 则也读取该母版页, 如果也是第一次请求这两个页面, 则母版页和被请求的 ...
- C#中combobox 控件属性、事件、方法
一 .combobox 属性.事件.方法公共属性 名称 说明 AccessibilityObject 获取分配给该控件的 AccessibleObject. AccessibleDefaultActi ...
- wxPython中基本控件学习
wxPython工具包提供了多种不同的窗口部件,包括了本章所提到的基本控件.我们涉及静态文本.可编辑的文本.按钮.微调.滑块.复选框.单选按钮.选择器.列表框.组合框和标尺.对于每种窗口部件,我们将提 ...
- [转]MFC子线程中更新控件内容的两种办法
一.概述 每个系统中都有线程(至少都有一个主线程),而线程最重要的作用就是并行处理,提高软件的并发率.针对界面来说,还能提高界面的响应能力.一般的,为了应用的稳定性,在数据处理等耗时操作会单独在一个线 ...
- Android中常用控件及属性
在之前的博客为大家带来了很多关于Android和jsp的介绍,本篇将为大家带来,关于Andriod中常用控件及属性的使用方法,目的方便大家遗忘时,及时复习参考.好了废话不多讲,现在开始我们本篇内容的介 ...
- Qt在表格中加入控件
任务:使用QTableWidget动态生成表格,在每行的某两列中加入QComboBox下拉框控件和QPushButton按钮控件 有添加,删除,编辑功能,每行的按钮可以浏览文件夹并选择文件 1.新建一 ...
- 基于VB中WINSOCK控件的网上象棋系统的实现
本文发表在<微型机与应用>杂志2001年第3期. 基于VB中WINSOCK控件的网上象棋系统的实现 马根峰1 , 孙艳2 , 王平1 (1.重庆邮电学院自动化学院,重庆,40006 ...
- MFC中ComboBox控件用法
MFC ComboBox 一.入门篇 ComboBox (组合框)控件很简单,可以节省空间.从用户角度来看,这个控件是由一个文本输入控件和一个下拉菜单组成的.用户可以从一个预先定义的列表里选择一个选项 ...
随机推荐
- jni中的参数含义
#include <jni.h> JNIEXPORT jstring JNICALL Java_com_example_hellojni_MainActivity_helloFromC ( ...
- PHP文件相关函数试题
一.问答题 1.返回路径中的文件名部分的函数是什么? 2.改变文件模式的函数是什么? 3.拷贝文件的函数是什么? 4.返回路径中的目录部分的函数是什么? 5.将上传的文件移动到指定位置的函数是? 6. ...
- webstorm比dreamweaver强大的地方 转
比dw强大的地方有: . 对js的开发有长足的支持,那些自动提示,代码主题,调试之类的我就不说了,主要是对流行技术的支持,比如Node.js,less,sass,jq,ext,prototype等框架 ...
- tablehost
返回键的拦截 @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEven ...
- Delphi XE2 生成的.exe 在未安装有Delphi的电脑上运行提示 “丢失 rtl160.bpl”
解决方案: XE2中加入了多平台的概念,默认的Release模式,也是带包编译,带运行时库的,所以,需要手工设置一下工程选项: 打开工程以后,Project-->Options-->左侧树 ...
- 轻松搭建docker应用的mesos集群
7条命令在docker中部署Mesos集群 所有使用的Docker容器构建文件是有也.您可以在本地构建每个容器或只使用位于Docker Hub预构建的容器.下面的命令会自动下载所需的预建的容器为您服务 ...
- overflow:hidden
超出之后隐藏,比如有一个div,高度和宽度都是100像素,当里面的内容很多,div里撑不下时,如果设置overflow:hidden,就会把超出的内容隐藏掉不显示
- http协议--笔记
HTTP协议的缺点:1.通信使用明文(不加密),内容可能会被窃听2.不验证通信方的身份,因此有可能遭遇伪装3.无法证明报文的完整性,所以有可能已遭篡改 防止窃听保护信息的几种对策:加密技术通信的加密H ...
- hdu1426 Sudoku Killer
Sudoku Killer Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total ...
- java 线程的同步
Example12_7.java public class Example12_7 { public static void main(String args[]) { Bank bank = new ...