У меня проблема при попытке перехвата событий мыши. Это работает, если я нажимаю за пределами окна моего приложения. Но когда я щелкаю внутри своего окна приложения, оно не обнаруживает событие 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 DOWN\n");
}
break;
case WM_LBUTTONUP:
{
printf_s("LEFT CLICK UP\n");
}
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);
}