【转】详解Windows消息分类以及WM_COMMAND与WM_NOTIFY的区别,以及模拟发送控件通知消息

转自:http://blog.sina.com.cn/s/blog_4b3c1f950100nten.html

 

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  message.

  • No return value.

lpnmhdrAddress of an  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确实是以呈现的,它包含以一个结构体指针的形式包含在lParam中。

typedef struct tagNMHDR { HWND hwndFrom; UINT idFrom; UINT code; } NMHDR;

Contains information about a notification message.

hwndFromWindow handle to the control sending a message.idFromIdentifier of the control sending a message.codeNotification 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
    idCtrl = (int) wParam;
    pnmh = (LPNwCtrlIdentifier of the common control sending the message.pnmhAddress of an  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)));

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436137.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

宽字符串忽略大小写比较的实现(原)

宽字符串忽略大小写比较的实现(原) 孙文涛 2008-07-24 在Mac机器平台上没有wcsicmp 或 wcscasecmp之类的函数实现对宽字符忽略大小写的比较&#xff0c;所以实现了好几种方法。 一个自然的思路是: (1) wcscpy 原字符串到tmp字符串; (2) tolower tmp字符串; (3) 然后调用仅存的w…

有关JAVA考试中数据库的题,javaee期末考试题库,用javaEE编写一个题库系统,要怎么做...

javaEE数据库简单问题。你插入2113数据库的时候是把5261它封装为一4102个对象插入的吗&#xff1f;1653如果封装为一个User对象版的权话(User对象有ID和LEVEL两个属性)ResultSet rs ps.executeQuery();User user new User();if(rs.hasNext()){user rs.next();}关于javaee 中j…

wince下获取mac地址的简单方法!

下&#xff0c;可以通过访问注册表获取mac地址&#xff0c;可是非常可惜的是有些系统的注册表不提供这个键值&#xff0c;另外也可以通过 DeviceIoControl这类函数获得&#xff0c;但是所有方法要么不全面&#xff0c;要么不够简单或者有些平台bsp包根本就不支持&#xff0c;我…

【转】虚拟键码

虚拟键码保存在WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN和WM_SYSKEYUP讯息的wParam参数中。此代码标识按下或释放的键。 中文名 虚拟键码 保存在 WM_KEYDOWN等 程 序 Windows程序 代码标识 按下或释放的键 目录 1 简介2 虚拟键表▪ 完整的虚拟键码表▪ 键盘的扫描码、…

循环赛日程表算法

题目&#xff1a;有n2^k个运动员要进行循环赛。现要设计一个满足以下要求的比赛日程表&#xff1a; &#xff08;1&#xff09;每个选手必须与其他n-1个选手各赛一次 &#xff08;2&#xff09;每个选手一天只能赛一次 &#xff08;3&#xff09;循环赛一共进行n-1天 解题思路&…

js有没有类似php的sleep函数,JavaScript-jQuery有没有类似sleep方法?

cronRun.sleep function(n) {for (var i0,jn*1000;i}}小飞写的function sleep(n) {var start new Date().getTime();while(true) if(new Date().getTime()-start > n) break;}貌似 Date new 的过多啊不过我在我本本上测的 好像不怎么管用&#xff0c;不知道为什么 是不是和…

GetAdaptersInfo获取MAC地址

源代码&#xff1a;#include<atlbase.h>#include<atlconv.h>#include"iphlpapi.h"#pragma comment(lib,"Iphlpapi.lib")int main(int argc,char*argv[]){PIP_ADAPTER_INFO pAdapterInfo;PIP_ADAPTER_INFO pAdapterNULL;DWORD dwRetVal0;pAdapt…

【转】Windows 窗体消息大全(速查)

阅读目录 通用窗口消息滚动条消息按钮控件消息按钮控件通知消息组合框控件消息组合框控件通知消息列表框控件消息列表框控件通知消息DDE消息(Dde.h)工具提示控件消息Rich Edit控件消息(带格式编辑控件)Listview控件消息Listview控件通知消息树控件消息树控件通知消息Header Co…

整数表示

在计算机中&#xff0c;不管程序还是数据都表示为二进制格式。对于我们平常编程常使用的整数有两种类型&#xff0c;一种是无符号整数&#xff0c;另外一种是有符号整数。 相应地&#xff0c;就有两种整数的二进制表达方式。一般我们使用的计算机都是32位,因此对两种整数的二进…

char 转wchar_t 及wchar_t转char

利用widechartomultibyte来转换的函数 通常适合于window平台上使用 #include <tchar.h>#include <windows.h>int _tmain(int argc, _tchar* argv[]){wchar_t pwstr[] l"我是中国人";wchar_t pwstr2[20];char *pcstr (char *)malloc(sizeof(char)*(2 * w…

oracle 12c sql图形化,Oracle 12c PL/SQL程序设计终极指南

Oracle 12c PL/SQL程序设计终极指南作者&#xff1a;孙风栋;王澜;郭晓惠出版日期&#xff1a;2015年06月文件大小&#xff1a;11.73M支持设备&#xff1a;&#xffe5;60.00在线试读适用客户端&#xff1a;言商书局iPad/iPhone客户端&#xff1a;下载 Android客户端&#xff1a…

CSS的语法结构

今天又看了一点书&#xff0c;哎我看书的速度可是够慢的。现摘录下来自己也增强下记忆&#xff0c;反正闲着也是闲着o(∩_∩)o...。 CSS的语法结构 CSS的语法结构由三个部分组成&#xff1a;选择符&#xff0c;(Selector)&#xff0c;属性(Porperty)和值(Value)。 使用方法…

WinCE 控制面板的创建

控制面板的组件,其实就是一个地地道道的DLL文件,所不同的是其后缀名为.CPL而已.控制面板组件对外必须要实现一个CPlApplet接口,其原型为:LONG CALLBACK CPlApplet(HWND hwndCPL,UINT message, LPARAM lParam1, LPARAM lParam2).而在此函数之中,为了使组件正常运作,我们必须要处…

oracle 存储同步,Oracle数据库知识——存储过程篇

在线QQ客服&#xff1a;1922638专业的SQL Server、MySQL数据库同步软件存储过程是一组用于完成特定功能的SQL语句&#xff0c;该语句已编译并存储在数据库中。用户通过指定存储过程的名称并提供参数(如果存储过程具有参数)来执行它。存储过程是数据库中的重要对象。任何设计良好…

【转】C++中的static_cast ,reinterpret_cast的用法和区别

转自&#xff1a;https://www.cnblogs.com/heyonggang/p/3361643.html 原文地址&#xff1a;https://www.cnblogs.com/heyonggang/p/3361643.html 用法&#xff1a;static_cast < type-id > ( expression ) 该运算符把expression转换为type-id类型&#xff0c;但没有运…

使用MvcContrib的FormHelper

MvcContrib的FormHelper提供了三大Helper Html辅助 验证HelperGrid表格Helper下载 下载后将MvcContrib.dll与MvcContrib.Samples.FormHelper.dll引用到Asp.net MVC工程 在Web.Config pages.namespaces加入以下节点 <add namespace"MvcContrib.UI.Tags"/><ad…

WinCE控制面板添加应用程序

WinCE系统中的控制面板和Windows系统中的控制面板原理是一样的&#xff0c;里面就是包含了一些应用程序。WinCE系统的控制面板由Ctlpnl.exe&#xff0c;Control.exe和一些.cpl文件组成&#xff0c;其中Ctlpnl.exe和Control.exe用于控制控制面板的文件夹显示和架构&#xff0c;而…

【转】滚动条消息(WM_VSCROLL和WM_HSCROLL)

转自&#xff1a;https://blog.csdn.net/zmq5411/article/details/6756189 &#xff08;1&#xff09;当用户单击滚动条或者是拖动滑块时&#xff0c;Windows会向窗口过程发送WM_VSCROLL消息&#xff08;垂直滚动时&#xff09;或者是WM_HSCROLL消息&#xff08;水平滚动时&am…

【转】CMMI环境下,该如何实施Agile?

“CMMI与敏捷之间是否有什么样的关系&#xff1f;是矛盾的&#xff1f;还是可融合的&#xff1f;”“在CMMI环境下如何实施敏捷&#xff1f;”自从“敏捷”诞生以后&#xff0c;此类话题就此起彼伏&#xff0c;从未停止。前几日&#xff0c;在AgileChina的讨论组中&#xff0c;…

透析WINCE的控制面板

WindowsCE是微软公司嵌入式、移动计算平台的基础&#xff0c;它是一个开放的、可升级的32位嵌入式操作系统&#xff0c;是基于掌上型电脑类的电子设备操作系统&#xff0c;它是精简的Windows 95,Windows CE的图形用户界面相当出色。Windows CE作业系统是Windows家族中最新的成员…