Skip to content

Instantly share code, notes, and snippets.

@julien-h
Last active June 17, 2021 15:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save julien-h/7e045c0c66a9af1ef858fc84d1c3ac31 to your computer and use it in GitHub Desktop.
Save julien-h/7e045c0c66a9af1ef858fc84d1c3ac31 to your computer and use it in GitHub Desktop.
This gist show how to use LowLevelMouseProc to print mousemove events. You can find a detailed article about it on this website: https://scripting.tips/
/*
* How to track the mouse using LowLevelMouseProc on Windows
* With proper error handling and resources cleaning.
*
* Copyright (C) 2018 Julien Harbulot
* Produced for https://scripting.tips
*
* LICENCE
* You may do whatever you want with this code as long as you
* credit me and keep the link to https://scripting.tips in the notice.
*/
#include "pch.h"
#include <iostream>
#include <Windows.h>
#include <signal.h>
// This is the handle to our hooked callback
// It is global so that we can access it in the
// SIGINT callback too.
HHOOK handle;
//
// This is the LowLevelMouseProc implementation
// Your implementation must be fast, otherwise
// Windows will remove your hook without notice.
//
LRESULT CALLBACK lowLevelMouseProc(
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
MSLLHOOKSTRUCT* lp = (MSLLHOOKSTRUCT*)lParam;
if (wParam == WM_MOUSEMOVE) {
std::cout << lp->pt.x << lp->pt.y << std::endl;
}
return CallNextHookEx(0, nCode, wParam, lParam);
}
//
// Call this function before exiting your program
//
int cleanup()
{
if (!UnhookWindowsHookEx(handle)) {
std::cout << "Error: unable to unhook" << std::endl;
return -1;
}
return 0;
}
//
// This callback is called when the program receive
// a SIGINT (ctrl+c) signal. Cleanup your resources in there.
//
void sigint_handler(int signum)
{
std::cout << "sigint received." << std::endl;
cleanup();
exit(signum);
}
int main()
{
handle = SetWindowsHookExA(WH_MOUSE_LL, &lowLevelMouseProc, NULL, 0);
if (handle == NULL) {
std::cout << "Error " << GetLastError() << std::endl;
return -1;
}
// Remember to register your SIGINT callback
signal(SIGINT, sigint_handler);
BOOL bRet;
MSG msg;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1) {
std::cout << "GetMessage returned an error" << std::endl;
return -1 + cleanup();
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return cleanup();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment