LRESULT与wParam和lParam的问题

在微软vc提供的头文件中有定义在winnt.h中typedef long LONG;在windef.h中typedef LONG LRESULT;

所以LRESULT就是long,也就是长整形之所以取名类LRESULT,L=>longresult表示结果,说明这个函数的返回值是某个结果仅此而已
WPARAM 和 LPARAM,消息响应机制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(可扩展组合框的可接受消息)等等来加以领会。理论上在使用自定义消息时,WPARAM LPARAM的含义可以程序员任意指定的,但是最好遵从MFC中的习惯。在调用SendMessage()函数时,第二个参数是WPARAM,第三个参数是这个消息的LPARAM,但是你在程序中某个类中写下ON_MESSAGE()宏来处理这个消息时,处理函数SomeHandler(WPARAM,LPRAM(默认是0))中解释这两个参数时必须按照SendMessage调用中的意义来进行。

消息响应机制1、消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)。当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。例如当菜单转中之后会有WM_COMMAND消息发送,WPARAM的高字中(HIWORD(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时间。
时间: 2024-10-28 14:24:08

LRESULT与wParam和lParam的问题的相关文章

wParam与lParam的区别

Delphi中的消息 消息是Windows发出的一个通知,它告诉应用程序某个事件发生了.在Delphi中,大多数情况下Windows的消息被封装在VCL的事件中,我们只需处理相应的VCL事件就可以了,但如果我们需要编写自己的控件.截获或过滤消息就必须深入研究Win32的消息处理机制. 在Delphi中消息以TMessage记录的方式定义.打开Message.pas文件,我们可以看到Tmessage是这样定义的: type TMessage = packed record Msg: Cardina

wParam和lParam两个参数到底是什么意思?

在Windows的消息函数中,有两个非常熟悉的参数:wParam,lParam. 这两个参数的字面意义对于现在的程序来说已经不重要了,因为它是16位系统的产物,为了保持程序的可移植性,就将它保存了下来. 它的字面意义,w表示word,l表示long,对于32为系统来说,分别是无符号整数(unsigned int)和长整型(long),都是32位整数.所以,根据具体的消息解析参数即可,不用在乎其字面意义了. 下面是Windows的定义 /* Types use for passing & retu

WinMain与WndProc以及窗口诞生过程总结

一.int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nCmdShow) 四个参数: hInstance:程序当前实例的句柄(handle to current instance),以后随时可以用GetModuleHandle(0)来获得 hPrevInstance:前一个实例的句柄(handle to previous instance),在Win32中,每一个进程都有一个

OpenCV系列1-简单高效:MFC显示图片、播放视频

先看图: 拉伸显示 居中显示 原始大小显示 显示视频: 实现图片显示,只需要两句话: 只需要包含一个h文件: 调整显示方式: 下面是CvImgCtrl.h的源代码,复制保存下来即可用,或者也可以下载demo,不要积分 控件采用的是双缓冲绘图,显示效率很高,不会闪烁,支持视频.图片的显示 /************************************************************************/ /* OpenCV MFC图像显示控件 v1.0 /* 该控件

C++ vc中怎么使用SendMessage自定义消息函数

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

VC进程间通信之消息传递PostMessge()或SendMessage()

1.  进程内消息: (1). 仅仅传消息码 (2). 传送消息串 发送端: void CTestDlg::OnBnClickedButtonSend() { CString* msg = new CString("发送的字符串"); ::SendMessage(m_hWnd,WM_USER+1,0,(LPARAM)msg); delete msg; } 接收端: afx_msg HRESULT OnClickBtn(WPARAM,LPARAM); BEGIN_MESSAGE_MAP

如何响应BCG的属性列表(CBCGPPropList)改变的事件?

afx_msg LRESULT OnProChanged(WPARAM uProListID,LPARAM pPro); BEGIN_MESSAGE_MAP(CPlotSingleDlg, CAcUiDialog) ON_REGISTERED_MESSAGE(BCGM_PROPERTY_CHANGED, OnProChanged) END_MESSAGE_MAP() LRESULT CPlotSingleDlg::OnProChanged(WPARAM uProListID,LPARAM pPr

Meandering Through the Maze of MFC Message and Command Routing

Meandering Through the Maze of MFC Message and Command Routing Paul DiLascia Paul DiLascia is a freelance software consultant specializing in developing C++ applications for Windows. He is the author of Windows++: Writing Reusable Code in C++ (Addiso

VC进程间通信之消息传递

PostMessge或者SendMessage()实现进程间通讯 方法1: PostMessge或者SendMessage()消息机制 项目1中发送消息: #define WM_MYMESSAGE WM_USER + 1 //目标进程的窗口类名(可通过Spy++工具查看)和窗口名 CWnd *pWnd = CWnd::FindWindow("#32770", "MfcTest"); if (NULL != pWnd) { pWnd->PostMessage(W