#include // Use instead of #include // Mouse hook procedure for XButton1 and XButton2 LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode != HC_ACTION) // Nothing to do :( return CallNextHookEx(NULL, nCode, wParam, lParam); MSLLHOOKSTRUCT* info = reinterpret_cast(lParam); const char* button_name[] = { "Left", "Right", "Middle", "X" }; enum { BTN_LEFT, BTN_RIGHT, BTN_MIDDLE, BTN_XBUTTON, BTN_NONE } button = BTN_NONE; const char* up_down[] = { "up", "down" }; bool down = false; switch (wParam) { case WM_XBUTTONDOWN: down = true; case WM_XBUTTONUP: button = BTN_XBUTTON; break; } if (button != BTN_NONE) { std::cout << button_name[button]; if (button == BTN_XBUTTON) std::cout << HIWORD(info->mouseData); std::cout << " mouse button " << up_down[down] << '\n'; } return CallNextHookEx(NULL, nCode, wParam, lParam); } // Function to handle console input events void HandleConsoleInput() { HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); if (hInput == INVALID_HANDLE_VALUE) { std::cerr << "Error getting input handle\n"; return; } // Set the console mode to enable mouse input if (!SetConsoleMode(hInput, ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS)) { std::cerr << "Error setting console mode\n"; return; } INPUT_RECORD inputRecord; DWORD eventsRead; while (true) { if (!ReadConsoleInput(hInput, &inputRecord, 1, &eventsRead)) { std::cerr << "Error reading console input\n"; return; } if (inputRecord.EventType == MOUSE_EVENT) { MOUSE_EVENT_RECORD* mouseEvent = &inputRecord.Event.MouseEvent; // Check for button presses if (mouseEvent->dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) { std::cout << "Left mouse button pressed\n"; } if (mouseEvent->dwButtonState & RIGHTMOST_BUTTON_PRESSED) { std::cout << "Right mouse button pressed\n"; } if (mouseEvent->dwButtonState & FROM_LEFT_2ND_BUTTON_PRESSED) { std::cout << "Middle mouse button pressed\n"; } // Check for vertical mouse wheel events if (mouseEvent->dwEventFlags & MOUSE_WHEELED) { short wheelDelta = (short)(mouseEvent->dwButtonState >> 16); if (wheelDelta > 0) { std::cout << "Mouse wheel scrolled up\n"; } else { std::cout << "Mouse wheel scrolled down\n"; } } // Check for horizontal mouse wheel events if (mouseEvent->dwEventFlags & MOUSE_HWHEELED) { short wheelDelta = (short)(mouseEvent->dwButtonState >> 16); if (wheelDelta > 0) { std::cout << "Mouse wheel scrolled right\n"; } else { std::cout << "Mouse wheel scrolled left\n"; } } } } } int main() { // Install the low-level mouse hook for XButton1 and XButton2 HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, GetModuleHandle(NULL), 0); if (mouseHook == NULL) { std::cerr << "Failed to install mouse hook! Error: " << GetLastError() << '\n'; return 1; } std::cout << "Mouse hook installed. Listening for mouse events...\n"; // Start a separate thread to handle console input events HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HandleConsoleInput, NULL, 0, NULL); if (hThread == NULL) { std::cerr << "Failed to create console input thread! Error: " << GetLastError() << '\n'; UnhookWindowsHookEx(mouseHook); return 1; } // Message loop to keep the hook active MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // Uninstall the hook before exiting UnhookWindowsHookEx(mouseHook); std::cout << "Mouse hook uninstalled. Exiting...\n"; // Wait for the console input thread to finish WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); return 0; }