CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  进程/线程/DLL

全局钩子问题

楼主mingbao(★情已逝★)2005-06-10 15:36:32 在 VC/MFC / 进程/线程/DLL 提问

 
          我做了一个全局的鼠标钩子,可以捕获正常的鼠标事件。  
          但我发现当鼠标在一个窗口的标题栏上点击左键时,完全捕获不到点击事件。  
          还有鼠标在标题栏上移动时也捕获不到。  
   
          哪位能回答我的问题,200分全给他!  
  问题点数:200、回复次数:8Top

1 楼zkxz(挑战)回复于 2005-06-10 16:36:34 得分 0

你是怎么捕获鼠标点击事件和移动事件的?在窗体客户区点击的消息和在窗体标题栏点击的消息可不是一个噢!Top

2 楼mingbao(★情已逝★)回复于 2005-06-10 16:50:17 得分 0

楼上的,那你说说在窗体标题栏点击的消息应该是什么消息?不是   WM_LBUTTONDOWN   ?  
   
  难道全局钩子捕获不到这样的消息?  
  Top

3 楼DentistryDoctor(不在无聊中无奈,就在沉默中变态)回复于 2005-06-10 18:05:39 得分 0

还应该呀,帖出来。Top

4 楼CPPLOVER_78(CPP爱好者)回复于 2005-06-10 18:08:36 得分 60

WM_NCLBUTTONDOWN   看看.Top

5 楼kingzai(stevenzhu)回复于 2005-06-10 18:24:40 得分 70

This   article   was   contributed   by   Robert   Wiejak.    
    Environment:   MFC,   Windows   95,   98,   Me,   NT   3.51,   4.0,   5.0    
   
  If   you   spend   time   investigating   what   happens   when   you   click   and   release   the   left   button   over   the   title   bar,   you   will   find   out   that   instead   of   getting   "non-client   left   button   up"   message,   you   just   get   "left   button   up".   One   could   actually   work   with   it,   if   the   message   found   it's   way   into   the   application.   It   does   not.  
   
  I   was   in   a   middle   of   writing   an   application   when   I   discovered   this.   I   looked   all   over   the   internet   for   articles   regarding   WM_NCLBUTTONUP   problem,   but   the   only   thing   I   could   find   were   questions   about   the   problem.   After   some   more   investigating   I   have   come   up   with   a   patch   that   could   be   adopted   by   each   application   requiring   such   notification.  
   
  The   patch   consists   of   installing   a   "windows   hook"   that   will   intercept   all   mouse   messages   for   this   application   before   they   enter   into   the   message   pump.   To   do   that   you   need   to   call   SetWindowsHookEx(...)   function,   soon   after   the   main   window   is   created.   Here   is   the   call:    
   
  hMHook   =   SetWindowsHookEx(    
                                            //   hook   type:    
                                  WH_MOUSE,  
                                            //   hook   procedure:    
                                  (HOOKPROC)   MouseHookProc,  
                                            //   handle   to   application   instance:    
                                  AfxGetInstanceHandle(),  
                                            //   thread   identifier:    
                                  AfxGetThread()->m_nThreadID  
                          );  
  It   is   very   important   that   you   supply   handle   to   application   instance   and   thread   identifier,   otherwise   every   application   running   on   your   computer   will   attempt   to   hook   it's   mouse   messages   through   your   program   and   it   could   be   disastrous.   By   supplying   these   two   parameters   you   will   insure   that   only   messages   from   your   application   will   end   up   in   your   callback   function.    
   
  Equally   important   is   a   call   to   remove   the   hook   before   your   application   terminates.   The   UnhookWindowsHookEx(...)   function   removes   a   hook   procedure   installed   in   a   hook   chain.   Most   likely   you   will   call   it   somewhere   in   OnDestroy(),   like   this:    
   
        if(hMHook   !=   NULL)  
              UnhookWindowsHookEx(hMHook);  
  The   callback   function   is   where   you   will   receive   WM_NCLBUTTONDOWN   message   and   the   next   time   you   receive   WM_LBUTTONUP   message   you   will   post   WM_NCLBUTTONUP   directly   into   the   application   message   pump.   Therefore,   no   special   handling   will   be   required   to   service   these   messages.   You   will   simply   write   your   code   inside   of   OnNcLButtonUp(...),   just   like   you   would   for   any   other   message.    
   
  Here   is   the   callback   code:    
   
  //   ////////////////////////////////////////////////////  
  //   handle   to   the   mouse   hook  
  HHOOK   hMHook   =   NULL;  
   
  //   status   of   non-client   left   button   down  
  BOOL   bNcLButtonDown   =   FALSE;      
   
  //   /////////////////////////////////////////////////////  
  //   Mouse   hook   process  
   
  LRESULT   CALLBACK   MouseHookProc(   int   nCode,    
                                                                  WPARAM   wParam,  
                                                                  LPARAM   lParam)    
  {    
      if(nCode   ==   HC_ACTION)    
      {    
          //   get   a   pointer   to   the   mouse   hook   struct.    
          PMOUSEHOOKSTRUCT   mhs   =   (PMOUSEHOOKSTRUCT)   lParam;    
           
          //   intercept   messages   for   left   button   down   and   up  
          switch(wParam)    
          {    
                  case   WM_NCLBUTTONDOWN:    
                    {  
                            //   get   the   pointer   to   the   main   window    
                            CWnd   *pWnd   =     AfxGetMainWnd();    
   
                            //   if   the   message   is   from   your   window   and    
                            //   the   hit   test   indicates   title   bar    
                            if((mhs->hwnd   ==   pWnd->GetSafeHwnd())    
                                    &&   (mhs->wHitTestCode   ==   HTCAPTION))  
                            {    
                                    //   then   indicate   non-client   left   button   down    
                                    bNcLButtonDown   =   TRUE;    
                                   
                                  //     there   is   no   problem   with   this   message    
                                  //   so   you   don't   have   to   do   anything   else    
                            }    
                  }    
                  break;    
                   
                  case   WM_NCLBUTTONUP:    
                          //   you   will   get   this   message   if   you   double-click    
                          //           on   the   title   bar    
                          //   reset   the   status    
                          bNcLButtonDown   =   FALSE;      
                          break;  
   
                  case   WM_LBUTTONUP:    
                      {  
                              //     get   the   pointer   to   the   main   window    
                              CWnd   *pWnd   =   AfxGetMainWnd();    
   
                              //   if   the   message   is   from   your   window   and    
                              //   non-client   left   button   is   down  
                              if((mhs->hwnd   ==   pWnd->GetSafeHwnd())    
                                      &&   (bNcLButtonDown   ==   TRUE))    
                              {  
                                    //   then   post   WM_NCLBUTTONUP   message   directly    
                                    //   into   your   window   message   pump    
                                    //   Note:   I'm   hardcoding   HTCAPTION   because   the    
                                    //   left   button   was   down,   and   while   it   is   down,  
                                    //   the   mouse   does   not   move   in   respect   to   the    
                                    //   window,   but   it   does   in   respect   to   the   screen,  
                                    //   so   the   mouse   should   still   be   over   the   caption  
                                    //   bar   of   your   window   when   you   release   the   button.  
                                    pWnd->PostMessage(WM_NCLBUTTONUP,   HTCAPTION,    
                                                                  MAKELONG(mhs->pt.x,mhs->pt.y));  
   
                                    //   reset   non-client   left   button   down    
                                    bNcLButtonDown   =   FALSE;  
                              }  
                      }    
                      break;    
   
                  default:    
                          break;    
          }    
      }    
      //   let   the   messages   through   to   the   next   hook    
    return   CallNextHookEx(hMHook,   nCode,   wParam,   lParam);    
  }  
   
  I   am   including   two   sample   projects.   The   "nclbxExample"   is   technical,   and   the   "AlphaDialogExample"   is   more   practical.   The   "nclbxExample"   is   better   documented   so   you   can   see   how   and   were   I   have   implemented   the   code.    
   
  NOTE:   If   you   are   going   to   use   mousepatch.cpp   the   way   I'm   using   it,   DO   NOT   add   it   to   your   project.    
  Top

6 楼krh2001(边城浪子)回复于 2005-06-10 18:28:17 得分 70

非客户区消息,   在对应   的客户区消息前加   NC,   如   客户区的   左键按下为:  
  WM_LBUTTONDOWN.      
   
  而对应的   非客户区按下则为:  
  WM_NCLBUTTONDOWN.  
   
   
  WINDOWS里就是这样的,   客户区和非客户区的很多消息都是分开的      
  Top

7 楼mingbao(★情已逝★)回复于 2005-06-10 19:08:51 得分 0

谢谢各位!  
   
  我先试试可能解决问题啊,如果行的话我马上散分!Top

8 楼zkxz(挑战)回复于 2005-06-10 21:12:06 得分 0

唉~来晚了,我要说的都被楼上的先说了。Top

相关问题

  • 又是全局钩子
  • 关于全局钩子(HOOK)
  • 全局钩子的问题/
  • 请问如何设置全局钩子?
  • 请问:怎样注册全局钩子??
  • 关于全局钩子的问题
  • 全局钩子问题求助?
  • 求一鼠标全局钩子
  • 关于全局钩子的问题
  • 问一个全局钩子的问题。

关键词

  • 鼠标
  • 客户
  • 消息
  • bnclbuttondown
  • hmhook
  • 钩子
  • nclbuttonup
  • 全局
  • 捕获
  • mhs

得分解答快速导航

  • 帖主:mingbao
  • CPPLOVER_78
  • kingzai
  • krh2001

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo