日期:2014-05-17  浏览次数:20848 次

Windows消息机制VC

Windows消息机制VC
2011年03月31日
  在Windows中,用户或系统中所发生的任何活动被当作事件来处理,例如,用户按下了鼠标按钮,就产生一鼠标事件。对于所发生的每一个事件,Windows将其转换成消息的形式放在一个称为消息队列的内存区中,然后由Windows的消息发送程序选择适合的对象,将消息队列中的消息发送到欲接受消息的对象上。Windows的消息可分为四种类型:   
  (1)输入消息:对键盘和鼠标输入作反应。这类输入消息首先放在系统消息队列中,然后Windows将它们送入应用程序的消息队列,使消息得到处理。   
  (2)控制消息:用来与Windows的特殊控制对象,例如,对话框、列表框、按钮等进行双向通信。这类消息一般不通过应用程序的消息队列,而是直接发送到控制对象上。   
  (3)系统消息:对程式化的事件或系统时钟中断作出反应。有些系统消息,例如大部分DDE消息(程序间进行动态数据交换时所使用的消息)要通过Windows的系统消息队列。而有些系统消息,例如窗口的创建及删除等消息直接送入应用程序的消息队列。   
  (4)用户消息:这些消息是程序员创建的,通常,这些消息只从应用程序的某一部分进入到该应用程序的另一部分而被处理,不会离开应用程序。用户消息经常用来处理选单操作:一个用户消息与选单中的一选项相对应,当它在应用程序队列中出现时被处理。   
  Windows应用程序通过执行一段称为消息循环的代码来轮询应用程序的消息队列,从中检索出该程序要处理的消息,并立即将检索到的消息发送到有关的对象上。典型的Windows应用程序的消息循环的形式为:   
  MSG msg;   
  while   (GetMessage(&msg,   NULL,   0,   0L))   
  {   
  TranslateMessage(&msg);   
  DispatchMessage(&msg);   
  }   
  函数GetMessage从应用程序队列中检索出一条消息,并将它存于具有MSG类型的一个变量中,然后交由函数TranslateMessage对该消息进行翻译,紧接着,函数DispatchMessage将消息发送到适当的对象上。
  关于自定义消息的参数
  自定义消息如果光是消息那只能是一个通知。   
  你知道什么时候该干什么事了。但是有的情况下需要具体的数据。这样参数就起作用了。   
  比如说要在消息处理中填充一个结构。   
  如struct   mystruct{   
  int   i;   
  char   buf[255];   
  }   
  可以把这个结构的一个指针强制转换为long  ,即(lparam)&mystruct,然后做为消息参数进入消息处理函数。   其他结构可以此类推。
  消息处理函数只要将WParam   或是LParam   强制转换为mystruct   *   就可以只用这个结构指针。可以为这个结构中的成员附值。或是使用这个结构中的数据。
  1.SendMessage函数功能描述:将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口过程,直到窗口过程处理完消息后才返回。
  .函数原型:
  LRESULT SendMessage(
  HWND hWnd, // 目标窗口句柄
  UINT Msg, // 被发送的消息
  WPARAM wParam, // 第一个消息参数
  LPARAM lParam // 第二个消息参数
  );
  .参数:
  hWnd
  窗口过程接收消息的窗口句柄。如果此参数为HWND_BROADCAST,则消息被送到系统的所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口。消息不被送到子窗口。
  Msg 
  指定被发送的消息; 
  wParam 
  指定附加消息的特定信息; 
  lParam 
  指定附加消息的特定信息。
  .返回值:
  返回值返回消息处理的结果,其依赖于所发送的消息。
  .备注:
  需要以 HWND_BROADCAST 方式通信的应用程序应该使用 RegisterWindowMessage 函数来获得应用程序间通信的独特消息。
  如果指定的窗口通过调用线程被创建,则窗口过程作为子程序被立即调用。如果指定的窗口通过调用不同线程被创建,则系统切换到该线程并调用适当的窗口过程。线程间的消息只有在接收线程执行消息检索代码时才被处理。发送线程将被阻塞到接收线程处理完消息为止。
  Windows CE:Windows CE不支持Windows桌面平台所支持的所有消息。在使用SendMessage函数之前,应检查发送的消息是否被Windows CE所支持。
  .使用环境:
  Windows NT: 3.1及以上版本;
  Windows:95及以上版本;
  Windows CE:1.0及以上版本;
  头文件:winuser.h;
  输入库:user32.lib;
  Unicode:在WindowsNT(Windows2000)环境下以Unicode和ANSI方式实现。
  .示例代码: .常见问题
  1)使用SendMessage来实现剪切、复制和粘贴 2)SendMessage与PostMessage的区别
  PostMessage将消息放入消息队列后马上返回,而SendMessage直到窗口过程处理完消息后才返回
  3)SendMessage发送WM_COPYDATA消息在进程间传送数据
  WM_COPYDATA消息主要目的是允许在进程间传递少量只读数据。SDK文档推荐用户使用SendMessage()函数,接收方在数据复制完成前不返回,这样发送方就不可能删除和修改数据。
  例如:  函数功能:该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,并立即返回。当窗口程序处理完消息后,系统调用指定的回调函数,将消息处理的结果和一个应用程序定义的值传给回调函数。 函数原型:BOOL SendMessageCallback(HWND hwnd,UINT Msg,WPARAM wParam,LPARAM IParam, SEhDASYNCPROC IpResultCallBack,DWORD dwData); 参数: hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。 Msg:指定被发送的消息。 wParam:指定附加的消息指定信息。 IParam:指定附加的消息指定信息。 IpResultCallBack:指向回收函数的指针,窗曰程序处理完消息后调用该回调函数。参见SendAsyncProc可得到合适的回调函数的信息。如果hwnd为HWND_BROADCAST,系统为每个顶层窗口调用一次SendASyncProc回调函数。 dwData:一个应用程序定义的值,被传给由参数IPResultCallBack指向的回调函数。 返回值:如果函数调用成功,返回非零值。如果函数调用失败,返回值是零。若想获得更多的错误信息,请调用GetLastError函数。 备注:如果发送一个低于WM_USER范围的消息给异步消息函数(PostMessage,SendNotifyMesssge;SendMessageCa