`
javababy1
  • 浏览: 1170934 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

WPARAM 和 LPARAM,消息响应机制以及LPVOID的说明 

 
阅读更多

LPVOID  

LPVOID是一个没有类型的指针,也就是说你可以将任意类型的指针赋值给LPVOID类型的变量(一般作为参数传递),然后在使用的时候在转换回来。
  可以将其理解为long型的指针,指向void型。
  例如:
  class CMyClass
  {
  void Start();
  static UINT StartThread(LPVOID lParam);
  };
  void CMyClass::Start()
  {
  AfxBeginThread(StartThread, this);
  }
  UINT CMyClass::StartThread(LPVOID lParam)
  {
  CMyClass * pMyClass = (CMyClass*)lParam;
  ...
  return 0;
  }

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时间。

转载自:
http://hondrif82q.spaces.live.com/blog/cns!776E82726DE60562!145.entry

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhangyanquen/archive/2009/04/12/4066540.aspx

分享到:
评论

相关推荐

    Windows程序设计参数wParam和lParam消息的含义

    Windows程序设计参数wParam和lParam消息的含义

    wParam和lParam消息.doc

    各种WM消息下对应的wParam和lParam消息总结.非常不错!!!

    wParam和lParam消息

    关于MFC中wParam和lParam消息的理解

    类 SDK窗口程序

    这个程序采用了Thunk技术 来自看雪的一个牛人 这个技术用到标准的SDK创建窗口中 就可以在 回调函数中调用 类内 消息响应函数了 回调函数演示: LRESULT CALLBACK CSDK::WndProc HWND hWnd UINT message WPARAM ...

    网络右下角弹出新闻窗口_VC源码.rar

    LRESULT OnControlClick(UINT message, WPARAM wParam, LPARAM lParam); LRESULT OnDestroy(UINT message, WPARAM wParam, LPARAM lParam); LRESULT OnSetCursor(UINT message, WPARAM wParam, LPARAM lParam); }...

    为何在自定义消息处理函数中无法利用wParam或lParam传递指?...VC源代码

    代码示范或实现下列功能:1、实现非模态对话框2、为何在自定义消息处理函数中无法利用wParam或lParam传递指针 关键字:modeless,dialog,wParam,lParam,pointer,非模态,对话框,指针

    wangyue1.rar_ON_MESSAGE_On Message_VK_DELETE_ctrl alt delete_组合键

    5: 响应消息: 声明函数:afx_msg void OnHotKey(WPARAM wParam, LPARAM lParam) 消息映射:ON_MESSAGE(WM_HOTKEY, OnHotKey) 函数实现: void CTrapCADDlg::OnHotKey(WPARAM wParam, LPARAM lParam) {...

    MFC 下获取键盘,鼠标的钩子程序

    #include "windows.h" HHOOK g_hMouse; HHOOK g_hKeyboard; #pragma data_seg("MySec")... ::PostMessage(g_hWnd,WM_MSG,wParam,lParam); // return 1; } return CallNextHookEx(g_hMouse,code,wParam,lParam); }

    delphi_键盘记录例子

    PostMessage(PViewInteger^,WM_HookKEY,wParam,lParam); UnmapViewOfFile(PViewInteger); CloseHandle(FileMapHandle); end; end; Result:=CallNextHookEx(Hook,iCode,wParam,lParam); end;

    动态禁用_启用Window 2000下的Ctrl+Alt+Delete组合键

    5: 响应消息: 声明函数:afx_msg void OnHotKey(WPARAM wParam, LPARAM lParam); 消息映射:ON_MESSAGE(WM_HOTKEY, OnHotKey) 函数实现: void CTrapCADDlg::OnHotKey(WPARAM wParam, LPARAM lParam) {...

    键盘消息源代码

    void ShowKey (HWND hwnd, int iType, char *szMessage,WPARAM wParam, LPARAM lParam) { static char *szFormat[2] = { "%-14s %3d %c %6u %4d %5s %5s %6s %6s", "%-14s %3d %c %6u %4d %5s %5s %6s %...

    ScrollBitmap.rar

    VC60,在dialog上绘图,并实现OnPrintClient(WPARAM wParam, LPARAM lParam)和带参数的OnPaint(WPARAM wParam, LPARAM lParam)

    动态禁用/启用Window 2000下的Ctrl+Alt+Delete组合键(终结版)

    5: 响应消息:声明函数:afx_msg void OnHotKey(WPARAM wParam, LPARAM lParam);消息映射:ON_MESSAGE(WM_HOTKEY, OnHotKey)函数实现:void CTrapCADDlg::OnHotKey(WPARAM wParam, LPARAM lParam){WORD wKey = ...

    VC 6.0 使用消息实现线程通信.rar

     LRESULT CThreadCommunicationDlg::OnDisplayResult(WPARAM wParam,LPARAM lParam)  {   int nResult = (int)wParam;   SetDlgItemInt(IDC_STATIC_RESULT,nResult,FALSE);   return 0;  }  void ...

    不用DLL屏蔽键盘按键

    Result:= CallNextHookEx(hHk,nCode,WParam,LParam) else begin y := 0; case WParam of WM_KEYDOWN,WM_SYSKEYDOWN: //按键后判断所按键 begin p:=PKBDLLHOOKSTRUCT(Lparam); if p^.vkCode = VK_TAB then ...

    delphi_钩子截获鼠标操作

    Result := CallNextHookEx(Hook,iCode,wParam,lParam) else if iCode = HC_SYSMODALON then //不允许回放 // else if iCode = HC_SYSMODALOFF then //允许回放 // else if (iCode = HC_ACTION) then begin ...

    在C#中SendMessage和PostMessage的参数传递

    模块内监视和等待消息处理,直到目标窗口处理完返回。SendMessage 在返回前还做了很多工作,比如,响应别的线程向它 SendMessage。Post 到别的线程时,最好用 PostThreadMessage 代替 PostMessage,PostMessage 的 ...

    explorer重启后图标消失处理

    然后要定义消息处理的函数,这里的函数定义也需要注意要定义成类似afx_msg LRESULT OnAddIconToTaskbar(WPARAM wParam, LPARAM lParam),这里如果不写成LRESULT而写成void,编绎可能通不过。而且如果不加WAPARAM和...

    自定义消息CS端实现

    1自定义消息服务端 1.1建立一个基于对话框的类Csmessage_serverDlg 1.2增加成员函数定义与实现 public: afx_msg LRESULT OnGetTextMessage(WPARAM wParam,LPARAM lParam); afx_msg LRESULT Csmessage_serverDlg::...

    ATL窗口实现

    3.ATL比起MFC的稍微不便的地方是需要手动添加消息处理宏,以及 消息处理函数中需要分清WPARAM wParam和LPARAM lParam两个参数的意义。不过我觉得对于具有MFC基础和Win API基础的程序员而言,这一点不会不算什么困难...

Global site tag (gtag.js) - Google Analytics