我被一个正在编写的应用程序卡住了,我需要监视鼠标点击。
点击可能发生在屏幕上的任何地方,而不是在应用程序窗口内,每次点击我都必须传递一条消息(执行一个动作或其他东西)。
我环顾四周并阅读了一些建议,例如使用
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
但我没有成功。
有谁知道如何实现我需要的东西?
您需要按照MSDN中的说明设置鼠标挂钩。
请注意,在您的情况下,钩子需要是全局的。这意味着您需要在 DLL 中实现一个处理函数,该函数将被加载到系统中所有接收鼠标消息的进程中。此类 DLL 将使用某些进程间通信 (IPC) 机制(如共享内存)或通过从 DLL发布(未发送)到主应用程序的 Windows 消息与您的主应用程序进行通信。
您可以使用此 CodeProject 文章中的源代码作为指南。
更新:根据克里斯的更正,我应该注意,以上适用于同步的“常规”鼠标钩子。低级钩子不需要位于 DLL 中,但它有一定的限制,在相应的 MSDN 文章中有描述。
好吧,我真的不知道你是否解决了你的问题。但愿如此。但是我今天遇到了同样的麻烦,搜索我发现了一种非常容易做到的方法。
所以你在这里:
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
你可以使用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;
}
LRESULT CALLBACK WndProc(...)
,顾名思义是一个(特定的)窗口(消息)处理器,您可以在其中分析和响应队列上的消息,这些消息由系统延迟到您自定义的回调定义以供进一步处理。
正如克里斯在评论中所建议的那样,由于您想检测屏幕上任何位置的鼠标点击并对其采取行动,因此一种方法是通过调用 SetWindowsHookEx() 将自己连接到系统中,这在其定义中非常冗长 - 它允许您跟踪系统上发生的事情并将该信息传递回您的应用程序。
这是您需要使用的语法才能让自己
HHOOK WINAPI SetWindowsHookEx(
__in int idHook,
__in HOOKPROC lpfn,
__in HINSTANCE hMod,
__in DWORD dwThreadId
);
它接受一个特定的钩子 id,它基本上是小的 #defines,它告诉函数你希望从整个系统接收什么样的消息,你像 WndProc 一样向它传递一个回调,但这一次它是为了处理关于整个系统的传入消息。hMod 只是指刚刚提到的 proc 函数回调所在的应用程序或 DLL 的句柄。最后一个与系统上当前运行的线程有关,将其设置为 0 或 NULL 会检索所有现有线程的消息。
重要:
请注意,Aurus 对 SetWindowsHookEx 的示例调用是特定于进程的,这是一个与实际应用程序相关的花哨词,而不是可以附加到系统中多个进程(全局进程)并将信息返回给您的应用程序的 DLL . 花时间和精力研究尤金推荐的方法而不是这种只对实验有用的有力方法是明智的。这有点“难”,但奖励是值得的。
更少的工作并不总是更好或更可取。