WinAPI挂钩鼠标

WinAPI - hooking mouse

本文关键字:鼠标 WinAPI      更新时间:2023-10-16

我在尝试挂接鼠标事件时遇到问题。如果我在应用程序窗口外单击,它就会工作。但当我在应用程序窗口内单击时,它不会检测到WM_LBUTTONUP事件。在几秒钟内,鼠标移动非常缓慢。从那时起,它不会检测到任何事件。即使我在应用程序窗口外单击。

所以我的应用程序无限期运行。我想知道这是不是和线程有关。也许如果我想在计算机的所有线程中全局跟踪某个东西(例如跟踪鼠标移动(,那么我在应用程序线程中什么都做不了?但这对我来说很奇怪。

这是鼠标挂钩的代码。main.cpp

#include <windows.h>
#include <iostream>
#include "MyHook.h"
using namespace std;
int main()
{
MyHook::Instance().InstallHook();
return MyHook::Instance().Messsages();
}

MyHook.h

#pragma once
#include <Windows.h>
class MyHook
{
public:
//single ton
static MyHook& Instance()
{
static MyHook myHook;
return myHook;
}
// function to install our mouseHook
void InstallHook();
// function to uninstall our mouseHook
void UninstallHook();
// function to "deal" with our messages
int Messsages();
public:
HHOOK mouseHook; // handle to the mouse hook
HHOOK windowHook; // handle to the window hook
MSG msg; // struct with information about all messages in our queue
};
LRESULT CALLBACK MyMouseCallback(int nCode, WPARAM wParam, LPARAM lParam);

MyHook.cpp

#include "MyHook.h"
#include <stdio.h>
void MyHook::InstallHook()
{
/*
SetWindowHookEx(
WM_MOUSE_LL = mouse low level mouseHook type,
MyMouseCallback = our callback function that will deal with system messages about mouse
NULL, 0);
c++ note: we can check the return SetWindowsHookEx like this because:
If it return NULL, a NULL value is 0 and 0 is false.
*/
if (!(mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MyMouseCallback, NULL, 0)))
{
printf_s("Error: %x n", GetLastError());
}
}
// function to uninstall our mouseHook
void MyHook::UninstallHook()
{
UnhookWindowsHookEx(mouseHook);
}
MSG msg; // struct with information about all messages in our queue
// function to "deal" with our messages
int MyHook::Messsages()
{
// while we do not close our application
while (msg.message != WM_QUIT)
{
if (GetMessage(&msg, NULL, 0, 0/*, PM_REMOVE*/))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Sleep(1);
}
UninstallHook(); // if we close, let's uninstall our mouseHook
return (int)msg.wParam; // return the messages
}
LRESULT CALLBACK MyMouseCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
MSLLHOOKSTRUCT* pMouseStruct = (MSLLHOOKSTRUCT*)lParam; // WH_MOUSE_LL struct
/*
nCode, this parameters will determine how to process a message
This callback in this case only have information when it is 0 (HC_ACTION): wParam and lParam contain info
wParam is about WINDOWS MESSAGE, in this case MOUSE messages.
lParam is information contained in the structure MSLLHOOKSTRUCT
*/
// we have information in wParam/lParam ? If yes, let's check it:
if (nCode == 0)
{ 
// Mouse struct contain information?    
// if (pMouseStruct != NULL)
// {
//  printf_s("Mouse Coordinates: x = %i | y = %i n", pMouseStruct->pt.x, pMouseStruct->pt.y);
// }
switch (wParam)
{
case WM_LBUTTONDOWN:
{
printf_s("LEFT CLICK DOWNn");
}
break;
case WM_LBUTTONUP:
{
printf_s("LEFT CLICK UPn");
}
break;

}
}
/*
Every time that the nCode is less than 0 we need to CallNextHookEx:
-> Pass to the next mouseHook
MSDN: Calling CallNextHookEx is optional, but it is highly recommended;
otherwise, other applications that have installed hooks will not receive mouseHook notifications and may behave incorrectly as a result.
*/
return CallNextHookEx(MyHook::Instance().mouseHook, nCode, wParam, lParam);
}

我没有运行您的代码,所以我不确定,但我有一个想法。

printf_s进行控制台输出。点击控制台窗口可以选择/复制输出,并阻止printf_s等功能,以避免选择失控。由于挂钩功能被阻止,鼠标也被阻止。稍后,Windows可能会删除这种长时间运行钩子过程的行为的钩子。

改为记录到文件,或者将日志发布到队列并从该队列打印。