DefWindowProc WindowProc TranslateMessage PreTranslateMessage

http://zhidao.baidu.com/question/145495277.html 

 

http://topic.csdn.net/u/20101116/01/52679129-15b2-4717-a209-f3e62150ad1c.html

 

http://zhidao.baidu.com/question/125280664.html

  1. DefWindowProc和WindowProc-----DefWindowProc处理WindowProc没处理的消息

在Windows操作系统里,当窗口显示之后,它就可以接收到系统源源不断地发过来的消息,然后窗口就需要处理这些消息,因此就需要一个函数来处理这些消息。在API里定义了一个函数为回调函数,当系统需要向窗口发送消息时,就会调用窗口给出的回调函数WindowProc,如果WindowProc函数不处理这个消息,就可以把它转向DefWindowProc函数来处理,这是系统的默认消息处理函数。当你按下菜单,或者点击窗口时,窗口需要运行这个消息处理函数。

调用这两个函数的实例如下:
#002 // 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
#004 // 目的: 处理主窗口的消息.
#008 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
#009 {
#010  int wmId, wmEvent;
#011  PAINTSTRUCT ps;
#012  HDC hdc;
#013

#014  switch (message)
#015  {
#016  case WM_COMMAND:
#017         wmId    = LOWORD(wParam);
#018         wmEvent = HIWORD(wParam);
#019         // 菜单选项命令响应:
#020         switch (wmId)
#021         {
#022         case IDM_ABOUT:
#023               DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
#024               break;
#025         case IDM_EXIT:
#026               DestroyWindow(hWnd);
#027               break;
#028         default:
#029               return DefWindowProc(hWnd, message, wParam, lParam);
#030         }
#031         break;
#032  case WM_PAINT:
#033         hdc = BeginPaint(hWnd, &ps);
#034         //
#035         EndPaint(hWnd, &ps);
#036         break;
#037  case WM_DESTROY:
#038         PostQuitMessage(0);
#039         break;
#040  default:
#041         return DefWindowProc(hWnd, message, wParam, lParam);
#042  }
#043  return 0;
#044 }
第8行定义消息处理函数
第14行开始根据不同的消息作处理。
第29行和第41行都是调用DefWindowProc函数来处理未处理的消息。
 
有了窗口消息处理函数,就可以响应不同的消息,实现各种各样的功能。

 

 

     2、PreTranslateMessage

PreTranslateMessage是GetMessage(...)函数的下一级操作,通过PreTranslateMessage 可以过滤和加工一些消息,通过条件送给TranslateMessage和 DispatchMessage
是GetMessage(...)函数的下一级操作,即GetMessage(...)从消息队列中获取消息 后,交由PreTranslateMessage()处理,若其返回FALSE则再交给TranslateMessage和 DispatchMessage处理(进入WindowProc); 
  • 如果用SendMessage, 则消息直接交到WindowProc处理,所以GetMessage 不会取得SendMessage的消息,当然PreTranslateMessage也就不会被调用。

如果用PostMessage,则消息进入消息队列,由GetMessage取得,PreTranslateMessage就有机会进行处理。
当然PreTranslateMessage并不是万能的,它并不能过滤所有的消息,有些消息它处理不了。比如WM_NCPAINT消息3、TranslateMessage 和 PreTranslateMessage 字面上很相似,但是功能完全不同。

3、TranslateMessage

PreTranslateMessage 仅仅是一个类似钩子回调函数 (hook callback function) 的东西,给你一个在  TranslateMessage 之前优先处理消息的机会。伪代码:



MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
PreTranslateMessage(&msg);
TranslateMessage(&msg);
DispatchMessage(&msg);
}



TranslateMessage 是为 WM_KEYDOWN + WM_KEYUP 的组合产生一个 WM_CHAR 或 WM_DEADCHAR 消息;为 WM_SYSKEYDOWN + WM_SYSKEYUP 的组合产生一个 WM_SYSCHAR 或 WM_SYSDEADCHAR 消息。这个消息是直接发送到消息队列里的,所以 PreTranslateMessage 也可以截获这个消息。


虽然不清楚楼主为什么要用 PreTranslateMessage 来代替 TranslateMessage 的功能,不过理论上的确可行。只要判断上述那两组消息,并向消息队列发送 WM_CHAR/WM_SYSCHAR 就可以了,例如简化为: 遇到可映射为 ASCII 的 WM_KEYDOWN 时生成一个 WM_CHAR,遇到一个 WM_SYSKEYDOWN 时生成一个 WM_SYSCHAR。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值