?
Solved

Posting Keystrokes to the top window

Posted on 2003-03-11
13
Medium Priority
?
425 Views
Last Modified: 2008-02-01
Hi,

I want to post keystrokes to the active Window (can be notepad, wordpad, ...)
I tried with the GetForegroundWindow and then PostMessage with WM_KEYDOWN, WM_KEYUP or PostMessage with WM_CHAR.

The only program however that accepts the input is a CMD prompt. No other programs.
What am I doing wrong here?

OS : XP

Thanks for your help,

JOHan.
0
Comment
Question by:johanhz
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 5
13 Comments
 
LVL 12

Expert Comment

by:Salte
ID: 8110270
You find the wrong window is one possibility.

GetForegroundWindow can be used to get the window that is in the foreground at the moment and that window is very likely to be a CMD prompt window if you start your program from the CMD prompt.

Try FindWindow() or FindWindowEx() functions to find the correct window and send WM_CHAR to it.

If you do send the WM_CHAR messages to the active window and it doesn't respond to those messages it can be that the program doesn't care about WM_CHAR messages. When you press a key on the keyboard windows send several messages to the application. First windows send a WM_KEYDOWN message to tell the application that "a key has been pressed". This message send the key in "raw" form and uses an enumeration defined by windows so that the return key is called VK_RETURN, The F1 key is VK_F1 etc.

Next windows send a WM_CHAR message. This is only used for 'translated' characters, i.e. letters and other characters that are input to the program. However, function keys and other such keys do not send a WM_CHAR message.

Further, some programs uses IME to read their input incase the user has an IME. I would assume wordpad or something used IME input in which case you have another set of messages for handling IME.

So, the applications may very well receive WM_CHAR messages and ignore them if it handles the WM_KEYDOWN or similar messages instead.

Alf
0
 

Author Comment

by:johanhz
ID: 8120316
Thanks for your comment, Alf
The problem is I don't know what application will be on top. It can be notepad, it can be wordpad, Visual Studio, etc ... So i don't think I can use the functions findwindow, findwindow ex.

If you take eg notepad, it has two windows. The main window and an edit window. Only if you send messages to the edit window, it will work. With Getforgroundwindow you get the main window. This throws away the keys.
But this presumes I know what application is on top, which I don't know.

Do I really need to write a driver to accomplish my question.
0
 
LVL 12

Expert Comment

by:Salte
ID: 8122260
A driver won't solve your problem.

What happened if you tried WM_KEYDOWN to the application? This is the most basic windows message telling an application "the user pressed a key on the keyboard". WM_CHAR is a 'processed message.

To be safe you need to send booth messages in the correct sequence (WM_KEYDOWN first and then WM_KEYUP and then WM_CHAR).

Sending this to the 'main' window of an application should give some form of result.

The only exception is if the application uses IME messages, in that case you need to send IME messages also.

Are you sure you get the correct window with GetForegroundWindow?

If you get the wrong window it won't throw away the keys but it won't be the right window.

You could try to show some debug info and show the title of the window you get as 'Foregroundwindow' if this is a different window it is no wonder the application doesn't respond.

If you get the right window, then try to send it WM_KEYDOWN, WM_KEYUP and then WM_CHAR.

If that doesn't work, then tell me what you got from the debug printout.

Alf
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:johanhz
ID: 8126116
This is what I did :
I used the SPy++ tool that comes with visual Studio.
studied case : notepad
There are 2 windows present: a "main window handle" and a "edit window handle". If I use getforegroundwindow : I get the main window handle. If I send the keys to this window, nothing happens (but with spy++ i see that they enter the window). If I send the messages to the "edit window handle" : works great (Also works with all edit boxes, but I just need to know what the handle is, and with spy++ i know)
As you say : the sequence is WM_KEYDOWN, WM_CHAR, WM_KEYUP (i can trace this also with spy++)
So I am pretty sure the keys that I send work, but I just don't know where to send them to.

JOHan.
0
 
LVL 12

Expert Comment

by:Salte
ID: 8126484
First off, it is possible it is wrong to send the keys directory to the edit window. This is because the application might want to process them first. sending the keys directly to the edit box will just insert the data into the edit window and it won't even bother to tell the application that it did so, the only way the application can find out is that it intercept the messages to the edit box and explicitely check for this possibility (most applications don't).

Of course, if the application just take the raw data from the edit box and save them to a file that is no problem but if the application is supposed to process the input first you're likely to end up in trouble. In other words, this won't work independently of the application.

You can easily get the handle of all sub windows of an application by using the FindWindow and related function calls.

It is possible that the notepad application simply doesn't process input but just set the edit box to have focus and then let the processing be done by the edit box itself. In that case it won't help to send keys to the application window. However, I would imagine that the normal way to handle it would be instead to let the application window take keyboard input and then forward it to the edit box.

It is possible that this isn't what notepad does. If so, you just have to find that edit box and send the keys directly to it. However, this is very application specific and there simply isn't any way to do this independent of the application.

May I ask what is the purpose of your application? Why do you want to send keys to 'whatever program is in forground'? If you don't know what application it is, you're most likely to not be able to know what to send to it anyway so why bother to make it 'application independent'?

Alf
0
 

Author Comment

by:johanhz
ID: 8126535
Alf,

Just found something interesting : have a look at the GetGUIThreadInfo API.
This is exactly what I want. If you call this api, it tells you which "window" from the foregroundwindow has the keyboard focus. (amongst other things)
The only thing now is that i get an error when compiling : 'GUITHREADINFO' : undeclared identifier. It is defined in winuser.h, and I included the file (and windows.h). I just can't figure out why my program gives this error.

JOHan.
0
 

Author Comment

by:johanhz
ID: 8127313
Sorry,

Forgot to answer the purpose of the application...
We have to our PC a serial keyboard attached. I want this keyboard to behave like a standard AT keyboard, so I must send the (serial) keys to the topmost application that has the keyboard focus, so it receives the keys just as if they were comming from the at keyboard.

As I mentioned, with getforegroundwindow() this works only in 50% of the applcitions.

JOHan.
0
 

Author Comment

by:johanhz
ID: 8127472
Sorry,

Forgot to answer the purpose of the application...
We have to our PC a serial keyboard attached. I want this keyboard to behave like a standard AT keyboard, so I must send the (serial) keys to the topmost application that has the keyboard focus, so it receives the keys just as if they were comming from the at keyboard.

As I mentioned, with getforegroundwindow() this works only in 50% of the applcitions.

JOHan.
0
 

Author Comment

by:johanhz
ID: 8129071
OK, this does the JOB 100% correct

bla bla ..
GUITHREADINFO gui;

gui.cbSize = sizeof(GUITHREADINFO);
GetGUIThreadInfo(NULL,&gui); // get the foreground handle
hwndForeGround = gui.hwndFocus; // get the handle of the foregroundwindow that has the keyboard focus
::PostMessage(hwndForeGround,WM_CHAR,0x36,0x36); // just testing; in fact use WM_KEYDOWN, WM_CHAR,WM_KEYUP


Note : min requirements: WIN98 and WINNT SP3
You must install the SDK from microsoft, otherwise it wont compile!!

Thanks for your help, Alf.
Post me your comment And I will give you the points.

JOHan.
0
 
LVL 12

Expert Comment

by:Salte
ID: 8130280
Sounds like you found an answer to your problem.

Yes, if you get the window that has the focus for the application it is - by definition - the one that is supposed to receive keyboard keys etc.

It is possible you can find it by searching through child windows and query if they have focus or not but why bother if there is a function that does it for you.

Only problem is that it appears it won't work for more modern systems such as WinXP so when you upgrade to those systems you probably have to use some other function to get it done.

I have no idea how you can do it on WinXP.

Alf
0
 
LVL 12

Accepted Solution

by:
Salte earned 150 total points
ID: 8130290
wait, you are using XP?

or did you mean that it works on any system starting from Win98/WinNT so that it also works on WinXP?

If so it should be no problem.

Guess I misunderstood a bit there :)

Alf
0
 

Author Comment

by:johanhz
ID: 8134601
Yep,

Tested on XP and 2000.
Works fine.

Thanks for your support.

JOHan.
0
 

Author Comment

by:johanhz
ID: 8134606
Your points ...
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
Suggested Courses

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question