c ++:如何在任何地方捕获鼠标点击

时间:2012-05-30 14:01:09

标签: c++ winapi mouse

我遇到了我正在编写的应用程序,我需要监视鼠标点击。

点击可能发生在屏幕上的任何位置,而不是在应用程序窗口内,对于每次点击,我必须传递消息(执行操作或其他内容)。

我环顾四周,阅读了一些建议,比如使用

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

但我没有成功。

有没有人知道如何实施我需要的东西?

4 个答案:

答案 0 :(得分:9)

您需要按照MSDN中的说明设置鼠标挂钩。

请注意,在您的情况下,钩子需要是全局的。这意味着您需要在DLL中实现处理函数,该函数将被加载到系统中接收鼠标消息的所有进程中。这样的DLL将使用某些进程间通信(IPC)机制(如共享内存)或通过Windows消息发布(未发送)从DLL到主应用程序与主应用程序进行通信。

您可以使用this CodeProject article中的源代码作为指南。

更新:根据Chris的更正,我应该注意上面适用于同步的“常规”鼠标钩子。低级挂钩不需要位于DLL中,但它具有corresponding MSDN article中描述的某些限制。

答案 1 :(得分:6)

好吧,我真的不知道你是否解决了你的问题。希望如此。 但是今天我遇到了同样的麻烦并且搜索我找到了一种非常容易实现的方法。

所以你在这里:

int keyPressed(int key){
    return (GetAsyncKeyState(key) & 0x8000 != 0);
}

int main(){
    while(1){
        if(keyPressed(VK_LBUTTON)){
            printf("%s\n","Click izquierdo");
        }
        if(keyPressed(VK_RBUTTON)){
            printf("%s\n","Click Derecho");
        }
    }
    return 0;
}

此解决方案的关键是函数GetAsyncKeyState(key),其中键入此处显示的任何代码https://msdn.microsoft.com/en-us/library/dd375731(VS.85).aspx

答案 2 :(得分:4)

您可以使用SetWindowsHookEx

这是一个小样本:

#define _WIN32_WINNT 0x0500
#include <windows.h>

HHOOK MouseHook;

LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam){

        PKBDLLHOOKSTRUCT k = (PKBDLLHOOKSTRUCT)(lParam);
        POINT p;


        if(wParam == WM_RBUTTONDOWN)
        { 
          // right button clicked 
          GetCursorPos(&p);
        }

}

void StayAlive(){
        while(_getch() != 27) { }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpCmdLine, int nShowCmd){
        FreeConsole();

        MouseHook = SetWindowsHookEx(WH_MOUSE_LL,MouseHookProc,hInstance,0);
        StayAlive();

        UnhookWindowsHookEx(MouseHook);
        return 0;
}

答案 3 :(得分:2)

LRESULT CALLBACK WndProc(...),顾名思义是一个(特定的)窗口(消息)处理器,您可以在其中分析和响应队列中的消息,这些消息被系统推迟到您的回调的自定义定义以进行进一步处理

由于您希望在屏幕上的任何位置检测并执行鼠标单击,正如Chris在评论中建议的那样,一种方法是通过调用SetWindowsHookEx()将自己挂钩到系统中,这在其定义中非常详细 - 它允许您可以跟踪系统上发生的事情并将该信息转发回您的应用程序。

这是您需要使用的语法

HHOOK WINAPI SetWindowsHookEx(
  __in  int idHook,
  __in  HOOKPROC lpfn,
  __in  HINSTANCE hMod,
  __in  DWORD dwThreadId
);

它接受一个特定的钩子id,它基本上是很少的#defines,告诉函数你希望从整个系统接收什么样的消息,你像WndProc一样传递一个回调,但这次它意味着处理有关整个系统的传入消息。 hMod只是引用应用程序的句柄或刚刚提到的proc函数回调所在的DLL。最后一个涉及当前在系统上运行的线程,将其设置为0或NULL检索所有现有线程的消息。 / p>

重要

请注意,Aurus对SetWindowsHookEx的示例调用是特定于进程的,这是一个将它与实际应用程序相关联的奇特单词,而不是可以附加到整个系统中的多个进程的DLL(全局的)并返回信息到您的申请。谨慎的做法是花时间和精力去研究Eugene推荐的方法,而不是仅仅对实验有用的强有力的方法。这有点“难”,但奖励是值得的。

减少工作并不总是更好或更好。