views:

58

answers:

3

I'm trying to send Key combinations like Shift F8, etc to a specific window. I am able to send F8 by itself by posing a WM_KEYDOWN, then a WM_KEYUP and specifing (int)System.Windows.Forms.Keys.F8 as the wParam, but can't figure out how to do it with the shift key. I've tried ORing it with System.Windows.Forms.Keys.SHIFT as well as System.Windows.Forms.Keys.SHIFTKEY but that doesn't seem to work. Is there some other way?

Note that I can't use SendInput or possibly because they don't take window handles, and my window may not be in the foreground. Any suggestions appreciated...

+1  A: 

Send individual WM_KEYDOWN messages, one for each key pressed.

WM_KEYDOWN -> Shift

WM_KEYDOWN -> F8

WM_KEYUP -> F8

WM_KEYUP -> Shift

Here is a message capture from Spy++ of the message sequence when pressing shift+f8 in notepad.

WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:36 fExtended:0 fAltDown:0 fRepeat:0 fUp:0

WM_KEYDOWN nVirtKey:VK_F8 cRepeat:1 ScanCode:42 fExtended:0 fAltDown:0 fRepeat:0 fUp:0

WM_KEYUP nVirtKey:VK_F8 cRepeat:1 ScanCode:42 fExtended:0 fAltDown:0 fRepeat:1 fUp:1

WM_KEYUP nVirtKey:VK_SHIFT cRepeat:1 ScanCode:36 fExtended:0 fAltDown:0 fRepeat:1 fUp:1

Chris Taylor
Yes, the messages get sent, but they don't matter. Most app use `GetKeyState` to check for modifier keys, the messages for them don't affect what that returns.
Donnie
It's wierd. I am doing exactly this, and it is still not working. If I use Spy++ to capture the WM_KEYDOWN and WM_KEYUP messages that I'm sending, and to capture the messages generated from a SHIFT F8 keypress, they look identical, just as you described above, but for some reason the application does not responde to the messages that I'm sending.
Jeremy
@Jeremy, @Donnie's point is correct. Sending the WM_KEYDOWN/WM_KEYUP pair for VK_SHIFT does not affect the actual key state so if the app is using GetKeyState this will not work.
Chris Taylor
The documentation for GetKeyState could be read to imply that the state is modified by the WM_KEY messages. In practice it seems that a snapshot of the entire keyboard state is stored with each (Real) WM_KEYxxx message: Principally because WM_KEY messages only include VK_CONTROL - but GetKeyState will return the state of VK_LCONTROL or VK_ RCONTROL - information it cannot have if it used the data from the actual message.
Chris Becke
An interesting question then is, if we manually post a WM_KEYxxx message, what key state does GetKeyState actually access?
Chris Becke
A: 

This should do the trick:

if (e.Shift && e.KeyCode == Keys.F8)
{
    MessageBox.Show("hello");
}
virious
-1 For not answering the question.
C. Ross
@C. Ross: someone was waiting on the phone so I was typing this response in a hurry, yes I didn't answer the question. I'm sorry.
virious
Sorry but -1 for not answering the question
Peter Kelly
A: 

You must use keybd_event or SendInput to send modifier keys to another application because of the way windows handles modifier keys (fun, yes?). I think both may require the other application to have focus to work correctly.

Just sending a series of keydowns / keyups as if you were pushing and holding the modifier keys doesn't (or, at least, didn't last I tried it) work since most applications poll for those keys separately instead of listening for messages about them. I suppose if you control the source for both applications this may work.

Donnie