MFC wParam与lParam 的问题

原创 2013年12月02日 14:36:33

WPARAM

  WPARAM,消息响应机制
  wParam和lParam 这两个是Win16系统遗留下来的产物,在Win16API中WndProc有两个参数:
  一个是WORD类型的16位整型变量;另一个是LONG类型的32位整型变量。因此根据匈牙利命名法,16位的变量就被命名为wParam,32位的变量就被命名为lParam。
  到了Win32API中,原来的16位变量也被扩展为32位,因此此时wParam和lParam的大小完全相同。
  在Win32API的早期,为了保证和Win16API的代码可移植性MS定义了WPARAM和LPARAM两个宏。
  当时保留了w前缀的原因一方面是由于WPARAM宏也以W开头,还有也因为要提醒程序员注意到可移植性,当然到了现在Win16早已退出历史舞台,这个前缀也就约定俗成的沿用下来了。
  例如:主程序MyDlg.cpp
  1.自定义消息:#define WM_TRAY WM_USER+100
  2.函数原形:afx_msg LRESULT OnTrayNotify(WPARAM wParam,LPARAM lParam);
  3.消息映射:ON_MESSAGE(WM_TRAY,OnTrayNotify)
  4.原函数:
  LRESULT CMyDlg::OnTrayNotify(WPARAM wParam,LPARAM lParam)
  {
  return m_tray.OnTrayNotify(wParam,lParam);
  }
  托盘类的实现程序Tray.cpp
  成员函数:
  int OnTrayNotify(WPARAM wID,LPARAM lEvent)
  {
  if(wID == TRAYNOTIFYDATA.uID)
  return 0;
  if(lEvent == WM_LBUTTONDOWN){
  处理代码
  }
  else if(lEvent == WM_RBUTTONDOWN){
  处理代码
  }
  return 0;
  }
  WPARAM 和 LPARAM 本质上没有什么区别:都是32位数,
  但是区别也还是有的:除了关于16位的的历史问题外,MICROSOFT在使用时两种参数分别代表不同的含义和内容,WPARAM常常代表一些控件的ID或者高位底位组合起来分别表示鼠标的位置,如果消息的发送者需要将某种结构的指针或者是某种类型的句柄时,习惯上用LPARAM来传递,可以参考各种控件的通知消息:可以查看:EN_CHANGE(EDIT控件的一个通知消息),CBEM_INSERTITEM(可扩展组合框的可接受消息)等等来加以领会。
  理论上在使用自定义消息时,WPARAMLPARAM的含义可以程序员任意指定的,但是最好遵从MFC中的习惯。在调用SendMessage()函数时,第二个参数是WPARAM,第三个参数是这个消息的LPARAM,但是你在程序中某个类中写下ON_MESSAGE()宏来处理这个消息时,处理函数SomeHandler(WPARAM,LPRAM(默认是0))中解释这两个参数时必须按照SendMessage调用中的意义来进行。
  消息响应机制
  1、消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)。当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。例如当菜单选中之后会有WM_COMMAND消息发送,WPARAM的低字中(LOWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。
  2、谁将收到消息:一个消息必须由一个窗口接收。在窗口的过程(WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。
  3、未处理的消息到那里去了:M$为窗口编写了默认的窗口过程,这个窗口过程将负责处理那些你不处理消息。正因为有了这个默认窗口过程我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖动时会有很多消息发送,而我们都可以不予理睬让系统自己去处理。
  4、窗口句柄:说到消息就不能不说窗口句柄,系统通过窗口句柄来在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。
  5、示例:下面有一段伪代码演示如何在窗口过程中处理消息
  LONG yourWndProc(HWND hWnd,UINT uMessageType,WPARAM wP,LPARAM)
  {
  switch(uMessageType)
  {//使用SWITCH语句将各种消息分开
  case(WM_PAINT):
  doYourWindow(...);//在窗口需要重新绘制时进行输出
  break;
  case(WM_LBUTTONDOWN):
  doYourWork(...);//在鼠标左键被按下时进行处理
  break;
  default:
  callDefaultWndProc(...);//对于其它情况就让系统自己处理
  break;
  }
  }
  接下来谈谈什么是消息机制:系统将会维护一个或多个消息队列,所有产生的消息都会被放入或是插入队列中。系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统所以Windows可以同时进行多个任务。下面的伪代码演示了消息循环的用法:
  while(1)
  {
  id=getMessage(...);
  if(id == quit)
  break;
  translateMessage(...);
  }
  当该程序没有消息通知时getMessage就不会返回,也就不会占用系统的CPU时间。

相关文章推荐

MFC中 'CString' to 'WPARAM'之间的转换

在实际运用中需要将'CString' to 'WPARAM'之间的转换,之间的转换 用已下方法即可实现: 方法一: 1.在发送消息端使用如下方法:  CString strVa...
  • ljsant
  • ljsant
  • 2016年10月15日 17:30
  • 1297

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数。 1.   最基本的算法是,从小到大遍历: for (i = 2 to A -1)          if (i * B > A)...

利用K-means聚类算法根据经纬度坐标对中国省市进行聚类

K-means聚类算法是一种非层次聚类算法,在最小误差的基础上将数据划分了特定的类,类间利用距离作为相似度指标,两个向量之间的距离越小,其相似度就越高。程序读取全国省市经纬度坐标,然后根据经纬度坐标进...

Radon变换理论介绍与matlab实现--经验交流

本人最近在研究Radon变换,在查阅了各种资料之后在此写下个人的理解,希望与各位牛牛进行交流共同进步,也使得理解更加深刻些。 Radon变换的本质是将原来的函数做了一个空间转换,即,将原来的XY平...

CT图像重建技术

由于csdn贴图不方便,并且不能上传附件,我把原文上传到了资源空间CT图像重建技术 1.引言 计算机层析成像(Computed Tomography,CT)是通过对物体进行不同角度的射线投影测量而...

Matlab绘图-很详细,很全面

Matlab绘图强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到所需图形,这类函数称为高层绘图函数。此外,Ma...

linux查找目录下的所有文件中是否含有某个字符串

查找目录下的所有文件中是否含有某个字符串  find .|xargs grep -ri "IBM"  查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名  find .|xargs g...

Radon变换入门matlab CT原理

http://hi.baidu.com/hi9394/blog/item/0d492b8bfd714700c8fc7aa9.html 简介 图像投影,就是说将图像在某一方向上做线性积分(或理解为累...

Excel2016右键新建工作表,打开时提示“因为文件格式或文件扩展名无效。请确定文件未损坏,并且文件扩展名与文件的格式匹配。”的解决办法

上午新建excel工作表时,发现新建完之后居然打不开 提示: 尼玛这坑爹的,难道我的Excel坏了?? 排查问题之后发现 只有新建“Microsoft Excel 工作表”时...

js弹出框、对话框、提示框、弹窗总结

js弹出框、对话框、提示框、弹窗总结 一、JS的三种最常见的对话框 [javascript] view plaincopy //=...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MFC wParam与lParam 的问题
举报原因:
原因补充:

(最多只允许输入30个字)