I'm trying to do activate mouse-things only by keyboard.
However my code makes my computer go wrong. For not a long moment with executes it, it works well, but after some minutes, all of the mouse-inputs become to be not accepted well. For example, I can't click programs on my taskbar, and I can't click windows start button, not only by my program (keyboard) but also by my real mouse. Even after exit my program, with unhook.
Here's code. It is wrotten by C, and compiled by cl.exe
If I press A or S, then SendInput send mouse left-click or right-click respectively, and ignore all other hook by return 1. (I also added method for mouse moving, but I think it makes no problem)
#include <windows.h>
#pragma comment(lib, "User32")
#define HKPARAM_ON 30
#define HKPARAM_OFF 31
#define HKPARAM_EXIT 32
#define LCLICK_KEY 'A'
#define RCLICK_KEY 'S'
#define MOVE_INITIAL 1
#define MOVE_DELTA 2
HHOOK hook_id;
int curMode = 0;
int repeat = MOVE_INITIAL;
BOOL isActive = FALSE;
int l_isUP = TRUE;
int r_isUP = TRUE;
void moveCursor( int x, int y ){
INPUT input = {0};
DWORD flag = MOUSEEVENTF_MOVE;
if( GetAsyncKeyState( LCLICK_KEY ) ){ flag |= MOUSEEVENTF_LEFTDOWN; }
if( GetAsyncKeyState( RCLICK_KEY ) ){ flag |= MOUSEEVENTF_RIGHTDOWN; }
input.type = INPUT_MOUSE;
input.mi.dx = x;
input.mi.dy = y;
input.mi.dwFlags = flag;
input.mi.dwExtraInfo = GetMessageExtraInfo();
SendInput( 1, &input, sizeof( INPUT ) );
}
LRESULT CALLBACK HOOKFUNC( int nCode, WPARAM wParam, LPARAM lParam ){
if(nCode < 0){ return CallNextHookEx(0, nCode, wParam, lParam); }
KBDLLHOOKSTRUCT *kbdstru;
DWORD flag;
INPUT input;
if( isActive ){
kbdstru = (KBDLLHOOKSTRUCT *) lParam;
if( wParam == WM_KEYDOWN ){
switch( kbdstru->vkCode ){
case LCLICK_KEY: if( l_isUP ){ l_isUP = FALSE; flag = MOUSEEVENTF_LEFTDOWN; goto call_input; } goto ignore_next_hook;
case RCLICK_KEY: if( r_isUP ){ r_isUP = FALSE; flag = MOUSEEVENTF_RIGHTDOWN; goto call_input; } goto ignore_next_hook;
case VK_LEFT:
if( curMode == VK_LEFT ) repeat += MOVE_DELTA;
else{ curMode = VK_LEFT; repeat = 1; }
moveCursor(-repeat, 0); goto ignore_next_hook;
case VK_RIGHT:
if( curMode == VK_RIGHT ) repeat += MOVE_DELTA;
else{ curMode = VK_RIGHT; repeat = 1; }
moveCursor(repeat, 0); goto ignore_next_hook;
case VK_UP:
if( curMode == VK_UP ) repeat += MOVE_DELTA;
else{ curMode = VK_UP; repeat = 1; }
moveCursor(0, -repeat); goto ignore_next_hook;
case VK_DOWN:
if( curMode == VK_DOWN ) repeat += MOVE_DELTA;
else{ curMode = VK_DOWN; repeat = 1; }
moveCursor(0, repeat); goto ignore_next_hook;
}
}
else if( wParam == WM_KEYUP ){
switch( kbdstru->vkCode ){
case LCLICK_KEY: if( !l_isUP ){ l_isUP = TRUE; flag = MOUSEEVENTF_LEFTUP; goto call_input; } goto ignore_next_hook;
case RCLICK_KEY: if( !r_isUP ){ r_isUP = TRUE; flag = MOUSEEVENTF_RIGHTUP; goto call_input; } goto ignore_next_hook;
}
}
}
return CallNextHookEx(0, nCode, wParam, lParam);
call_input:
FillMemory( &input, sizeof(INPUT), 0 );
input.type = INPUT_MOUSE;
input.mi.dwFlags = flag;
input.mi.dwExtraInfo = GetMessageExtraInfo();
SendInput( 1, &input, sizeof(INPUT) );
ignore_next_hook:
return 1;
}
int main(){
// ON with CTRL+SHIFT+X
// OFF with CTRL+SHIFT+C
// EXIT with CTRL+SHIFT+V
if( !RegisterHotKey( NULL, HKPARAM_ON, MOD_CONTROL | MOD_SHIFT, (int)'X' ) ){
MessageBox( NULL, "ctrl + shift + X error", NULL, MB_OK | MB_ICONSTOP);
return 0;
}
if( !RegisterHotKey( NULL, HKPARAM_OFF, MOD_CONTROL | MOD_SHIFT, (int)'C' ) ){
MessageBox( NULL, "ctrl + shift + C error", NULL, MB_OK | MB_ICONSTOP);
return 0;
}
if( !RegisterHotKey( NULL, HKPARAM_EXIT, MOD_CONTROL | MOD_SHIFT, (int)'V' ) ){
MessageBox( NULL, "ctrl + shift + V error", NULL, MB_OK | MB_ICONSTOP);
return 0;
}
hook_id = SetWindowsHookEx( WH_KEYBOARD_LL, HOOKFUNC, (HINSTANCE) GetModuleHandle(NULL), 0 );
printf("hooked keyboard with hookid = 0x%X\n", hook_id);
MSG msg;
while( GetMessage(&msg, NULL, 0, 0) != 0 ){
switch( msg.wParam ){
case HKPARAM_ON:
isActive = TRUE;
printf("ON\n");
break;
case HKPARAM_OFF:
isActive = FALSE;
printf("OFF\n");
break;
case HKPARAM_EXIT:
UnhookWindowsHookEx( hook_id );
UnregisterHotKey( NULL, HKPARAM_ON );
UnregisterHotKey( NULL, HKPARAM_OFF );
UnregisterHotKey( NULL, HKPARAM_EXIT );
return 0;
}
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}