问题
I'm trying to send a WM_KEYDOWN/WM_KEYUP pair to an application which normally does NOT respond to the use of the KEYBDINPUT struct. I will need to send the escape key, as well as alphanumeric characters. As the MSDN only gives vague information on using the hardware struct, I could only assume that the uMsg field is meant to hold WM_KEYDOWN/WM_KEYUP messages, and the the next two fields are for the LOWORD and HIWORD of lParam (composed of several bits which define the scan code, whether or not the key is 'repeating', and so on).
But after several hours of tweaking around these values, I'm at a total loss on how to correctly simulate a hardware keystroke. What can I do to get this to work?
回答1:
You should not use HARDWAREINPUT at all. To simulate keyboard input, you must use INPUT.type = INPUT_KEYBOARD and set the INPUT.ki members. The INPUT_HARDWARE option is reserved for input devices other than the mouse or keyboard.
If the app doesn't respond to this input then the next likely problem is that you have a focus problem. SendInput() can only work when the app's window is in the foreground and the child window in the app that needs the input has the focus. This can be difficult to achieve. An alternative for typing keys is to send WM_CHAR messages with SendMessage directly to the window that should receive them. Which also avoids the considerable difficulty of dealing with the active keyboard layout and the state of the modifier keys (Alt, Shift, Ctrl). A new problem you'll now have is retrieving the correct window handle.
回答2:
Turns out I had implemented KEYBDINPUT improperly, and was also sending each keystroke out in a single call to SendInput. The following appears to work for standard and extended virtual keys in my target application:
VOID SimulateKeystroke(USHORT vk, BOOL bExtended)
{
INPUT input = {0};
if(bExtended) input.ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
input.ki.wVk = vk;
input.type = INPUT_KEYBOARD;
SendInput(1, &input, sizeof(input));
ZeroMemory(&input, sizeof(INPUT));
input.ki.dwFlags = KEYEVENTF_KEYUP;
if( bExtended ) input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
input.ki.wVk = vk;
input.type = INPUT_KEYBOARD;
SendInput(1, &input, sizeof(input));
}
来源:https://stackoverflow.com/questions/14546839/what-is-the-proper-way-to-fill-a-hardwareinput-struct-for-use-with-sendinput