С#:Как захватывать глобальные события мыши/HID
Вопрос
Я хочу написать небольшой инструмент, который будет фиксировать глобальное событие, когда пользователь нажимает кнопку Windows и прокручивает колесо мыши вверх или вниз.Когда такое событие фиксируется, я хочу перенаправить указанный вывод на комбинацию виртуальных клавиш Win-+ или Win-- (плюс/минус).Можно ли это сделать?
Если клавиша Windows зарезервирована, подойдет сочетание клавиш ctrl-alt или что-то в этом роде.
Решение
Поскольку он использует ключ Windows, ключ можно захватить глобально с помощью привязки горячей клавиши.Зарегистрируйте HotKey на MSDN.
Редактировать:Кажется, что события колеса мыши не рассматриваются как клавиши, как я предполагал, и нет возможности создать для них глобальную горячую клавишу.
Вам придется создать глобальную перехватку сообщений окна и перехватить сообщение WM_MOUSEWHEEL.Но вам, возможно, придется сделать это на C/C++.Dll C для этого приведена ниже. Вы можете вызвать Hook и Unhook из C#, чтобы включить и отключить эту функцию.
ПРЕДУПРЕЖДЕНИЕ:Я не тестировал этот код и предоставлен только в качестве демонстрации.
#include <windows.h>
HINSTANCE myInstance;
HHOOK thehook = 0;
BOOL isWinKeyDown = FALSE;
extern "C" LRESULT __declspec(dllexport)__stdcall CALLBACK HookHandler(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == WM_KEYDOWN && (wParam == VK_LWIN || wParam == VK_RWIN))
isWinKeyDown = TRUE;
else if (nCode == WM_KEYUP && (wParam == VK_LWIN || wParam == VK_RWIN))
isWinKeyDown = FALSE;
else if (nCode == WM_MOUSEHWHEEL && isWinKeyDown) {
if (HIWORD(wParam) > 0) { //mousewheel up
CallNextHookEx(thehook, WM_KEYDOWN, VK_ADD, 0);
CallNextHookEx(thehook, WM_KEYUP, VK_ADD, 0);
} else { //mousewheel down
CallNextHookEx(thehook, WM_KEYDOWN, VK_SUBTRACT, 0);
CallNextHookEx(thehook, WM_KEYUP, VK_SUBTRACT, 0);
}
return 0;
}
return CallNextHookEx(thehook, nCode, wParam, lParam);
}
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fwdReason, LPVOID lpvReserved) {
switch(fwdReason)
{
case DLL_PROCESS_ATTACH: {
DisableThreadLibraryCalls(hInstance);
myInstance = hInstance;
} break;
case DLL_THREAD_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_DETACH:
break;
}
return(TRUE); // The initialization was successful, a FALSE will abort
// the DLL attach
}
extern "C" void __declspec(dllexport) Hook() {
if (!thehook)
thehook = SetWindowsHookEx(WH_CALLWNDPROC, &HookHandler, myInstance, 0);
}
extern "C" void __declspec(dllexport) UnHook() {
if (thehook)
UnhookWindowsHookEx(thehook);
thehook = 0;
}
Другие советы
Это определенно можно сделать с помощью глобальных хуков, здесь — отличный пример CodeProject, показывающий, как это сделать.