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

解决方案 »

  1.   

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

  2.   

    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 processLRESULT 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. 
      

  3.   

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