以前写过用钩子拦截按键消息实现改键,最近在论坛上看到下面这种方法,在此总结一下与大家分享。欢迎指正。
//模拟按键,把自定义消息添加到消息队列中。
该方法是先借用低级键盘钩子判断按键消息。
1,sendinput函数的介绍:
UINT SendInput(UINT nInputs,//在消息队列中添加消息的个数【Number of structures in the pInputs array】
LPINPUT pInputs, //指向INPUT结构体的一个指针
int cbSize //给结构体的大小sizeof(INPUT)
);
2,INPUT结构体的介绍
union是联合体,在联合体中,系统只为他分配一块联合体中最大的那个变量的空间,一旦其中一个被赋值其他的变量就不能再被赋值。
typedef struct tagINPUT {
DWORD type; //INPUT_NOUSE(鼠标事件) INPUT_KEYBOARD(键盘事件) INPUT_HARDWARE(其他硬件事件)
union { MOUSEINPUT mi; //包含鼠标事件的结构体
KEYBDINPUT ki;//键盘事件的结构体
HARDWAREINPUT hi;//硬件事件的结构体
};
}INPUT, *PINPUT;
3,三种不同的消息对应的结构体
(1)KEYBOARDINPUT
typedef struct tagKEYBDINPUT {
WORD wVk;//虚拟键的编码,范围1-254,
WORD wScan;
DWORD dwFlags;
DWORD time;// 事件的时间戳,当为0时,系统会自动分配。
ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT;
(2)MOUSEINPUT(3)HARDWAREINPUT
LRESULT CALLBACK lowlevekeyboardproc(int ncode, WPARAM wparam,LPARAM lparam)
{
if (((PKBDLLHOOKSTRUCT)lparam)->vkCode=='A')
{
INPUT Input[2];
Input[0].type = INPUT_KEYBOARD;
Input[0].ki.wVk='B';
Input[0].ki.dwFlags = ((PKBDLLHOOKSTRUCT)lparam)->flags&LLKHF_UP?KEYEVENTF_KEYUP:0;
Input[0].ki.wScan= MapVirtualKeyExW('C',0,0);
Input[0].ki.time=0;
Input[0].ki.dwExtraInfo=0;
//SendInput(1,Input,sizeof(INPUT));
Input[1].type = INPUT_KEYBOARD;
Input[1].ki.wVk='C';
Input[1].ki.dwFlags = ((PKBDLLHOOKSTRUCT)lparam)->flags&LLKHF_UP?KEYEVENTF_KEYUP:0;
Input[1].ki.wScan= MapVirtualKeyExW('D',0,0);
Input[1].ki.time=0;
Input[1].ki.dwExtraInfo=0;
SendInput(2,Input,sizeof(INPUT));
return 1;
}
return CallNextHookEx(0,ncode,wparam,lparam);
}
int main()
{
MSG msg;
SetWindowsHookEx(WH_KEYBOARD_LL,lowlevekeyboardproc,GetModuleHandle(0),0);
while (GetMessageW(&msg,0,0,0))
DispatchMessageW(&msg);
return 0;
}