如何给对话框中的控件发送消息呢?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)));

时间: 2024-12-14 12:03:12

如何给对话框中的控件发送消息呢?Windows消息分类的相关文章

[转]MFC子线程中更新控件内容的两种办法

一.概述 每个系统中都有线程(至少都有一个主线程),而线程最重要的作用就是并行处理,提高软件的并发率.针对界面来说,还能提高界面的响应能力.一般的,为了应用的稳定性,在数据处理等耗时操作会单独在一个线程中运行,而所有与主UI线程有关的控件数据刷新应该到主UI线程中处理.也就是数据处理线程发消息,让界面UI去更新控件.在MFC中线程分为界面线程和工作者线程,界面实际就是一个线程画出来的东西,这个线程维护一个"消息队列","消息队列"也是界面线程和工作者线程的最大区别,

MFC中给控件添加变量,DoDataExchange中

DoDataExchange函数其实是一项数据动态绑定技术.比如你在写动态按钮过程中须对按钮添加变量时,怎么添加?控件类已经写好了,其变量是已经固定的.你要添加新的变量就要用到DoDataExchange函数. 你要在对话框的构造函数里面初始化一个变量,再用DoDataExchange函数将它绑定到你的动态按扭中,比如:DDX_Check(pDX, IDC_CHECK1, m_Lesson1);这就是将m_Lesson1(这是一个外部变量,其定义在对话框的构造函数里)绑定到IDC_CHECK1中

Android自定义控件系列 十:利用添加自定义布局来搞定触摸事件的分发,解决组合界面中特定控件响应特定方向的事件

这个例子是比较有用的,基本上可以说,写完这一次,以后很多情况下,直接拿过来addView一下,然后再addInterceptorView一下,就可以轻轻松松的达到组合界面中特定控件来响应特定方向的触摸事件了. 请尊重原创劳动成果,转载请注明出处:http://blog.csdn.net/cyp331203/article/details/45198549,非允许请勿用于商业或盈利用途,违者必究. 在写Android应用的过程之中,经常会遇到这样的情况:界面包含了多个控件,我们希望触摸在界面上的不

在子线程中更改主线程中的控件的信息,在子线程中用toast

一丶在子线程中不允许更改主线程中的控件的信息,也不允许在子线程中用toast,我们要更改的话 (1)消息机制:使用handler (由主线程调用) 在主程序中Handler handler = new Handler(){ public void handleMessage(Message msg){ int type = msg.what ;//拿到msg的类型,再判断            switch (type) {                case SUCCESS:      

Android中常用控件及属性

在之前的博客为大家带来了很多关于Android和jsp的介绍,本篇将为大家带来,关于Andriod中常用控件及属性的使用方法,目的方便大家遗忘时,及时复习参考.好了废话不多讲,现在开始我们本篇内容的介绍. 1.控制应用显示的方向: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖直显示效果. setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LA

获取屏幕高宽,在代码中设置控件大小的方法

获取屏幕高宽的方法: 1 import android.view.Display; 2 import android.view.WindowManager; 3 WindowManager windowManager = getWindowManager(); 4 Display display = windowManager.getDefaultDisplay(); 5 if(display.getWidth()==480 && display.getHeight()== 272 ||

MFC中按钮控件的用法笔记(转)

VC学习笔记1:按钮的使能与禁止 用ClassWizard的Member Variables为按钮定义变量,如:m_Button1:则m_Button1.EnableWindow(true); 使按钮处于允许状态m_Button1.EnableWindow(false); 使按钮被禁止,并变灰显示 VC学习笔记2:控件的隐藏与显示 用CWnd类的函数BOOL ShowWindow(int nCmdShow)可以隐藏或显示一个控件. 例1:CWnd *pWnd;pWnd = GetDlgItem(

向asp.net项目中添加控件AspNetPager

1.打开项目,把.dll文件放入项目中: 2.在工具栏中添加一个自定义选项卡 3.右键选项卡,点击"选择项" 4.在打开的对话框中点击:"浏览" 5.找到要添加的控件文件AspNetPager.dll,确定,添加成功啦 向asp.net项目中添加控件AspNetPager

Delphi中WebBrowser控件打开部分网站报&quot;Invalid floating point operation”解决

Delphi中WebBrowser控件打开部分网站报"Invalid floating point operation”解决 EmbeddedWBWebBrowserDelphi 最近用EmbeddedWB控件做浏览器相关应用的时候,发现有些网页只要一打开就一定会蹦出一个“Invalid floating point operation”异常(关掉异常对话框以后,浏览器无响应),而程序仅仅是一句 WebBrowser1.Navigate(Edit1.Text);貌似很多含有Silverlight