Created
November 30, 2016 19:48
-
-
Save LiamKarlMitchell/89f7784de196d9491d5b3b0eef2a576e to your computer and use it in GitHub Desktop.
Suppresses the Back and Forward mouse button actions and the Left Windows Key action on Windows 7+?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//// InhibitWindowsEvents.cpp : Defines the entry point for the console application. | |
//// | |
#define WIN32_LEAN_AND_MEAN // Note: This could use WIN_NT 403 | |
#include <windows.h> | |
#include <stdio.h> | |
HHOOK llMouseHook = NULL; | |
HHOOK llKeyboardHook = NULL; | |
// Just for debug/log purposes. | |
char Message[200] = { 0 }; | |
// Note: Any long running interactions in the hooks should be done in your own thread or windows will likely discard the message and system will be unstable. | |
// Note for debugging: Ctrl+Alt+Delete to show the window options screen (Log off/Task Manager etc) then closing it with Esc fixed any mouse instability I had early on. | |
// Increasing timeout in registry helped a lot too. | |
// Return 1 from hooks to prevent event. | |
// Return a call to CallNextHooksEx for any nCode < 0 or if not handling event. | |
// lParam [in] Pointer to a MSLLHOOKSTRUCT structure. | |
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) | |
{ | |
if (nCode >= 0) { | |
//if (nCode == HC_ACTION) { // && (wParam == WM_MOUSEMOVE) // WM_NCMOUSEMOVE | |
MSLLHOOKSTRUCT *mouse = reinterpret_cast<MSLLHOOKSTRUCT *>(lParam); | |
switch (wParam) { | |
/*case WM_LBUTTONDOWN: puts("WM_LBUTTONDOWN"); break; | |
case WM_RBUTTONDOWN: puts("WM_RBUTTONDOWN"); break; | |
case WM_MBUTTONDOWN: puts("WM_MBUTTONDOWN"); break;*/ | |
//case WM_XBUTTONDOWN: //puts("WM_XBUTTONDOWN"); | |
//sprintf(Message, "WM_XBUTTONDOWN #%i", button); | |
//puts(Message); | |
//break; | |
case WM_XBUTTONDOWN: | |
case WM_XBUTTONUP: | |
//sprintf(Message, "WM_XBUTTONUP #%i Suppressed!", button); | |
//puts(Message); | |
// Note: Can be used to get the extra mouse button index. (I didn't care just wanted to mute them all). | |
// int button = mouse->mouseData >> 16; | |
return 1; | |
break; | |
} | |
// Get window handle under cursor and the mouse location. | |
//HWND hiWnd = WindowFromPoint(p->pt); | |
//if (hiWnd) | |
//{ | |
// POINT pt = p->pt; | |
// ScreenToClient(hiWnd, &pt); | |
// if (IsWindowUnicode(hiWnd)) | |
// { | |
// LPWSTR buf = (LPWSTR)GlobalAlloc(GMEM_FIXED, 33 * sizeof(WCHAR)); | |
// if (buf) | |
// { | |
// swprintf(buf, 33, L"X:%ld, Y:%ld", pt.x, pt.y); | |
// SendMessageW(hiWnd, WM_SETTEXT, 0, (LPARAM)buf); | |
// GlobalFree(buf); | |
// } | |
// } | |
// else | |
// { | |
// LPSTR buf = (LPSTR)GlobalAlloc(GMEM_FIXED, 33); | |
// if (buf) | |
// { | |
// snprintf(buf, 33, "X:%ld, Y:%ld", pt.x, pt.y); | |
// SendMessageA(hiWnd, WM_SETTEXT, 0, (LPARAM)buf); | |
// GlobalFree(buf); | |
// } | |
// } | |
//} | |
} | |
return CallNextHookEx(llMouseHook, nCode, wParam, lParam); | |
} | |
// lParam [in] Pointer to a KBDLLHOOKSTRUCT structure. | |
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { | |
KBDLLHOOKSTRUCT *keyboard = reinterpret_cast<KBDLLHOOKSTRUCT *>(lParam); | |
if (nCode >= 0) { | |
UINT msg = wParam; | |
WPARAM w = keyboard->vkCode; | |
LPARAM l = 1 | (keyboard->scanCode << 16); | |
if (keyboard->flags & LLKHF_EXTENDED) | |
l |= 0x1000000; | |
if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) | |
l |= 0xC0000000; | |
// Suppressing left windows key. | |
if (w == VK_LWIN) { | |
return 1; | |
} | |
} | |
return CallNextHookEx(llKeyboardHook, nCode, wParam, lParam); | |
} | |
int WINAPI | |
WinMain(HINSTANCE hInstance, // handle to current instance | |
HINSTANCE hPrevInstance, // handle to previous instance | |
LPSTR lpCmdLine, // command line | |
int nCmdShow // show state | |
) | |
{ | |
// Puts into realtime priority. (Could cause unstability). | |
// But should execute faster. | |
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); | |
AllocConsole(); | |
freopen("CON", "wt", stdout); | |
puts("Inhibit Windows Events started..."); | |
// Note: This is just for debug purposes. | |
// Print the user's LowLevelHooksTimeout registry key for debugging purposes. | |
// On Windows 7 and greater, Windows will silently remove badly behaving hooks | |
// without telling the application. Users can tweak the timeout themselves | |
// with this registry key. (200 ms is default) | |
HKEY key = NULL; | |
DWORD type = 0; | |
DWORD value = 0; | |
DWORD len = sizeof(DWORD); | |
puts("Checking existance and value of the key HKEY_CURRENT_USER\\Control Panel\\Desktop\\LowLevelHooksTimeout this should exist."); | |
if (RegOpenKeyExA(HKEY_CURRENT_USER, "Control Panel\\Desktop", NULL, KEY_READ, &key) == ERROR_SUCCESS) { | |
LONG err = RegQueryValueExA(key, "LowLevelHooksTimeout", NULL, &type, reinterpret_cast<LPBYTE>(&value), &len); | |
if (err == ERROR_SUCCESS && type == REG_DWORD) { | |
printf_s("GlobalShortcutWin: Found LowLevelHooksTimeout with value = 0x%x that is %u ms\n", value, value); | |
if (value < 50) { | |
puts("A value too small on Windows 7 is known to cause system instability."); | |
puts("Try killing explorer.exe or restarting if that occures and increase the value in the registry."); | |
} | |
} | |
else if (err == ERROR_FILE_NOT_FOUND) { | |
printf_s("GlobalShortcutWin: No LowLevelHooksTimeout registry key found.\n"); | |
} | |
else { | |
printf_s("GlobalShortcutWin: Error looking up LowLevelHooksTimeout. (Error: 0x%x, Type: 0x%x, Value: 0x%x)\n", err, type, value); | |
} | |
} | |
puts("Suppressed actions are:"); | |
puts("Mouse side buttons (Back and Forward in browser)"); | |
puts("Left Windows Key UP"); | |
// Set up the hooks. | |
llMouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, hInstance, 0); | |
llKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0); | |
MSG msg; | |
msg.message = NULL; // Just in case msg is not 0'd out by default. | |
// This is the message pump loop. | |
// Needed or the system will go very unresponsive. | |
while (msg.message != WM_QUIT) { //while we do not close our application | |
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
Sleep(0); | |
} | |
puts("Closing"); | |
// Uninstall the hooks. | |
UnhookWindowsHookEx(llKeyboardHook); | |
UnhookWindowsHookEx(llMouseHook); | |
FreeConsole(); | |
return 0; | |
} |
Does appear to have some kind of infinite loop, or lots of CPU usage sometimes.
Maybe I should remake this as an extension in better discord.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Mostly a proof of concept although I will likely run it on my own computer instead of leaving mumble running like I have been.
Was fun to learn about and useful for Discord as it does not yet support suppression of push to talk keys / button shortcuts.
Disables the Left windows key and extended mouse buttons (Back/Forward) functionality in windows. Which lets you use them as voice push to talk hot keys / shortcuts nicely.
Download Compiled if you want to test.
https://cdn.discordapp.com/attachments/112149447118483456/253606035586154506/InhibitWindowsEvents.exe