views:

791

answers:

6

I'm a bit rusty on my Windows system programming...

Is it possible for a program to send a keystroke (I'm guessing by SendMessage() api call) to another application, if the (open) target application does not currently have the focus? If it is possible, does it then make the target application become the active application, or does it still remain in the background?

Thanks in advance for any info you may be able to provide!

+1  A: 

No, It will not change the focus, unless subsequent calls do setfocus. It will remain the same window order

lakshmanaraj
A: 

From memory: Yes, No.

You are looking for WM_KEYDOWN:

PostMessage(hwndOther, WM_KEYDOWN, VK_ENTER, 0);
Simon Buchan
Don't think that's correct. The target window will also be expecting WM_KEYDOWN for one thing.
MarkJ
You should delete this Simon, it's wrong
MarkJ
PostMessage() does work, just tried it. MarkJ, not sure what you mean by "target window will also be expecting WM_KEYDOWN"? It's contained there right in the 2nd parameter of PostMessage.
I'm guessing he meant WM_KEYUP - but it's pretty obvious when an app cares about getting a matching up. I was building a test for PostMessage(), just in case my memory failed me, but I got sidetracked :(.
Simon Buchan
A: 

Yes you can send keystrokes, no it won't bring the other window to the top.

MarkJ
Thanks for the links. I'm familiar with SendKeys() from VB/VBA. The problem is that it only sends keys to the active app, hence the need to roll my own version. The .NET link looks interesting, will look into it further.
The first link doesn't use the native VB SendKeys, it's a replacement using the API call SendInput, so it doesn't have that limitation.
MarkJ
Alas, it *does* have the limitation since the SendInput() api call which it uses has the same limitation of the keystroke being to "sent to the foreground application." - found by checking the msdn info for SendInput()...about to investigate PostMessage() as suggested above...
PostMessage() as suggested by Simon Buchan is the one to use...have tested it with Notepad and it works.
A: 

For a directed send of keystrokes, SendInput is the native method of choice, though it is subject to UIPI (integrity level) checks on Vista/2008/W7. You can't send keystrokes to an app that has an IL > yours.

A more general solution for capturing and redirecting input is a global keyboard hook (See the help for SetWindowsHookEx). But this is fairly hairy stuff - you have to cope with how you send the keystrokes on, you affect every process in the system because your code is effectively inserted in the input stream, it involves writing a native DLL... you have to know exactly what you're doing.

We use a global keyboard hook in our system (I wrote it), but we're a special case - a single function emergency call handling system. I wouldn't advise a global hook as a solution in general purpose Windows computing.

Bob Moore
Cheers for responding and thanks for the heads up about Vista UIPI. As I have subsequently found, SendInput() sends it to the foreground application. In the end, PostMessage() has worked for my simple needs. Note: UIPI applies also to PostMessage().
A: 

You don't need SendInput() or hooks

The answer with PostMessage is wrong.

You must attach remotely your thread. See on Win32 api Group where it's a very classic question (C code, right MS method)

Broken link, and a bit incomprehensible! He's asking how to send keystrokes - never heard of attaching thread to do that? Sometimes people attach thread in order to bring non-foreground window to the front but that's not what he's asking about.
MarkJ
He might be referring to AttachThreadInput()? That's completely different.
Simon Buchan
A: 

PostMessage(hwndOther, WM_KEYDOWN, VK_ENTER, 0);

This works for me, but only under Windows XP. On Vista and Windows Seven I've got problem. Propably with UIPI. I am trying to send a message to process from a DLL injected to this process. How to fix it?

Raga