原文网址:http://www.cnblogs.com/renyuan/archive/2012/11/26/2789103.html

SendMessage及WPRAME、LPARAME 

 typedef unsigned int UINT

  typedef UINT WPARAM

  typedef LONG LPARAM

  typedef LONG LRESULT

  到了Win32API中,原来的16位变量也被扩展为32位,因此此时wParam和lParam的大小完全相同。WPARAM常常代表一些控件的ID或者高位底位组合起来分别表示鼠标的位置,如果消息的发送者需要将某种结构的指针或者是某种类型的句柄时,习惯上用LPARAM来传递。

  理论上在使用自定义消息时,WPARAM、LPARAM的含义可以程序员任意指定的,但是最好遵从MFC中的习惯。在调用SendMessage()函数时,第二个参数是WPARAM,第三个参数是这个消息的LPARAM,但是你在程序中某个类中写下ON_MESSAGE()宏来处理这个消息时,处理函数SomeHandler(WPARAM,LPRAM(默认是0))中解释这两个参数时必须按照SendMessage调用中的意义来进行。

SendMessage的基本结构如下:
SendMessage(
    HWND hWnd,  //消息传递的目标窗口或线程的句柄。
    UINT Msg, //消息类别(这里可以是一些系统消息,也可以是自己定义,下文具体介绍,)
    WPARAM wParam, //参数1 (WPARAM 其实是与UINT是同种类型的,
  //在vc编译器中右键有个“转到WPARAM的定义”的选项可以查看。 
    LPARAM lParam); //参数2

例如:::SendMessage(this->m_hWnd, WM_MY_DOSOME, (WPARAM) 0, (LPARAM) 0);

这里我发送的消息是本窗体接收的,(所以接收消息的也是本窗口)所以句柄用:this->m_hWnd,这里的消息类别WM_MY_DOSOME就是我自定义的,
在接收消息的窗体或线程所在的头文件里:
#define WM_MY_DOSOME WM_USER+1 // do something
当然你还可以定义更多如:
#define WM_DOOTHER WM_USER+2 // do other

表示要做一些事情。

MFC中的SendMessage()则是,谁调用它,则其就是接收消息的载体,必须实现消息。例如:pView->SendMessage(),则有pView窗口接收消息(视也是一个窗口)。

消息响应机制

  1、消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)组成。当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。例如当菜单选中之后会有WM_COMMAND消息发送,WPARAM的低字中(LOWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。

  2、谁将收到消息:一个消息必须由一个窗口接收。在窗口的过程(WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。

  3、未处理的消息到那里去了:MS为窗口编写了默认的窗口过程,这个窗口过程将负责处理那些你不处理消息。正因为有了这个默认窗口过程我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖动时会有很多消息发送,而我们都可以不予理睬让系统自己去处理。
  
  4、窗口句柄:说到消息就不能不说窗口句柄,系统通过窗口句柄来在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。
 
  消息机制:系统将会维护一个或多个消息队列,所有产生的消息都回被放入或是插入队列中。系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统所以Windows可以同时进行多个任务。
 

MFC中SendMessage的用法与相应函数的添:

1、 ::SendMessage(AfxGetMainWnd()->m_hWnd,WM_CHILDFRAMEDBCLK ,0,0);

其中WM_CHILDFRAMEDBCLK是自定义的消息ID(其ID为WM_USER+1), AfxGetMainWnd()->m_hWnd是获得主窗口(这里不能使用GetParent()->m_hWnd或者GetParentFrame()->m_hWnd, 因为这是获得父窗口,但父窗口不一定是主窗口,一定要注意,不然消息就会发错导致接收不到。

2、 然后接下来定义一个消息需要映射的函数,如下:

afx_msg LRESULT OnChlidFrameDBClick(WPARAM wParam, LPARAM lParam);

注意格式必须是:两个参数必不可少,返回类型一定为LRESULT,网上很多文章都忽略了这两点,这也是网上文章普遍错误的地方。

3、 添加消息函数映射

ON_MESSAGE(WM_CHILDFRAMEDBCLK,OnChlidFrameDBClick)

注意这里必须是ON_MESSAGE, 不能使用ON_COMMAND, 前者主要针对用户自定义消息,后者针对WM_COMMAND命令,比如菜单、工具栏等.

4、 实现消息函数:

  我们在接收窗体里定义一个这样的事情(过程),

  LRESULT CMainFrame::OnChlidFrameDBClick(WPARAM wParam, LPARAM lParam)
      {
            CancelFullScreenWin();  // 这里调用了一个使子窗口全屏的自写函数,我就不贴出来了,以后专题将的时候会提到

return 0;
      }

【转】SendMessage及WPRAME、LPARAME的更多相关文章

  1. C#调用SendMessage 用法

    函数功能:该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.该函数是应用程序和应用程序之间进行消息传递的主要手段之一.    函数原型:LRESUL ...

  2. Handler sendMessage 与 obtainMessage (sendToTarget)比较

    转自:http://iaiai.iteye.com/blog/1992196 obtainmessage()是从消息池中拿来一个msg 不需要另开辟空间new new需要重新申请,效率低,obtian ...

  3. Handler.sendMessage 与 Handler.obtainMessage.sendToTarget比较

    原文地址: http://www.cnblogs.com/android007/archive/2012/05/10/2494766.html 话说在工作中第一次接触android 的Handler ...

  4. winform窗体之间通过 windows API SendMessage函数传值

    -----------------------------------------------------------‘接收窗体’代码.cs------------------------------ ...

  5. [C#.net]PostMessage与SendMessage的区别

    用 PostMessage.SendNotifyMessage.SendMessageCallback 等异步函数发送系统消息时,参数里不可以使用指针,因为发送者并不等待消息的处理就返回,接受者还没处 ...

  6. [C#.net] SendMessage

    函数功能:该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.该函数是应用程序和应用程序之间进行消息传递的主要手段之一.     函数原型:LRESU ...

  7. android wifi obtainmessage sendmessage解析

    obtainmessage 从message pool获取一个对象 sendmessage 将message插入message queue java中wait和notify是一对,wait进入睡眠等待 ...

  8. 【转】在C#中使用SendMessage

    SendMessage是一个在user32.dll中声明的API函数,在C#中导入如下: using System.Runtime.InteropServices; [DllImport(" ...

  9. [外挂6]在指定位置下棋 SendMessage函数

    a.鼠标软件模拟,函数SendMessage b.分析窗口内棋子相对坐标X,Y c.软件模拟点击棋盘坐标x,y处的棋子 ::SendMessage(hwnd,WM_LBUTTOMDOWN,0,YX); ...

随机推荐

  1. jQuery获取radio选中项的值【转藏】

    <title></title> <script src="js/jquery-1.7.2.min.js"></script> < ...

  2. Css3 兼容新旧浏览器

    想想10年前用 IE6,火狐,遨游,谷歌等浏览器学习css时,那叫一个艰苦,各种hack各种抓耳挠腮,不是margin塌陷就是元素飞了... 当前借着css3这个东风,如果各大浏览器厂商能统一一下,也 ...

  3. ASP.NET项目中使用CKEditor +CKFinder 实现上传图片

    CKEditor是什么 CKEidtor是一个在线富文本编辑器,可以将让用户所见即所得的获得编辑在线文本,编辑器或自动将用户编辑的文字格式转换成html代码. 在ASP.NET工程中添加CKEdito ...

  4. 黑马入学基础测试(三)求斐波那契数列第n项,n<30,斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55

    .获得用户的输入 计算      3打印就行了.   这里用到了java.util.Scanner   具体API  我就觉得不常用.解决问题就ok了.注意的是:他们按照流体的方式读取.而不是刻意反复 ...

  5. 关于wordpress中更换CKEditor编辑器

    wordpress中自带的编辑器实在是功能太简,连插入表格都没有,使用插件的方式太过于麻烦,干脆就直接更换编辑器了,在网上找了一些方法,下文引自http://down.chinaz.com/try/2 ...

  6. easyui实现datagrid数字排序问题

    我们在使用easyui对列进行自动排序的时候(即顺序倒序),正常情况下是通过设置field中的sortable:true属性来控制是否可以排序.但是我们会发现一个有趣的问题,在对数字进行排序的时候,这 ...

  7. iOS中打印系统详细日志

    Q:如何打印当前的函数和行号? A:我们可以在打印时使用一些预编译宏作为打印参数,来打印当前的函数和行号.如: 1 NSLog(@"%s:%d obj=%@", __func__, ...

  8. C# 进程 和线程

    进程 没有应用程序可以看做是一个进程 线程:就是对cpu执行的最小单位 单线程:前台线程和后台线程 带来的问题:假死 net中不能跨线程访问

  9. CoreAnimation1-图层树、寄宿图以及图层几何学

    (一)图层的树状结构 Core Animation其实是一个令人误解的命名.你可能认为它只是用来做动画的,但实际上它是从一个叫做Layer Kit这么一个不怎么和动画有关的名字演变而来,所以做动画这只 ...

  10. Javascript面试题浅析

    分享几道JavaScript相关的面试题. 字符串反转 这这里提供了两种解题思路.如果各位读者还有其他的思路,可以分享交流! 第一方法: function reverse(str){ var sp = ...