Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

NTVDM and simulated keyboard input

122 views
Skip to first unread message

Dave Lange

unread,
Dec 16, 2003, 3:56:54 PM12/16/03
to
How can I simulate keyboard input to a DOS program? I
have tried VB SendKeys, keybd_event, and posting KEYDOWN
and KEYUP messages to the application's message queue
(under NTVDM). None of those techniques works. So what is
the correct method? Thanks for your help and insights!

Dave

Gary Chanson

unread,
Dec 16, 2003, 4:38:31 PM12/16/03
to

"Dave Lange" <dave....@verizon.net> wrote in message
news:043e01c3c417$22f7c160$a101...@phx.gbl...

I don't know how SendKeys works in VB but the keybd_event or SendInput
APIs should work. I can send keyboard input from one console program to
another using keybd_event.

Are you sure that the destination window has the keyboard focus when you
send the keystrokes?

--

-GJC [MS Windows SDK MVP]
-Software Consultant (Embedded systems and Real Time Controls)
-gcha...@mvps.org

-Abolish public schools


Dave Lange

unread,
Dec 16, 2003, 5:35:43 PM12/16/03
to
Thanks for your reply. I was pretty puzzled and
disappointed when keybd_event didn't work. The target is
a full-screen DOS program. When it's running in the
foreground, it's the only thing visible. It takes
keystrokes entered at the keyboard, which indicates it
has the focus. But it ignores anything I send from
keybd_event.

Dave

>.
>

Gary Chanson

unread,
Dec 17, 2003, 1:27:45 AM12/17/03
to

"Dave Lange" <dave....@verizon.net> wrote in message
news:02d901c3c424$f1130c50$a501...@phx.gbl...

> Thanks for your reply. I was pretty puzzled and
> disappointed when keybd_event didn't work. The target is
> a full-screen DOS program. When it's running in the
> foreground, it's the only thing visible. It takes
> keystrokes entered at the keyboard, which indicates it
> has the focus. But it ignores anything I send from
> keybd_event.

It works for me here. I'm running Win2K-SP4 and using CMD.exe or DOS
EDIT.exe as the target programs. I don't know if another DOS program might
work differently (but I doubt it).

I suspect that your test procedure is disturbing the keyboard focus.
Assuming that you're generating valid date using keybd_event and that the
target window has the focus, it should work.

Dave Lange

unread,
Dec 17, 2003, 10:54:23 PM12/17/03
to
OK, I'm thoroughly puzzled. My test is very simple. A
VB program responds to a button click by sleeping for 5
seconds and then making two keybd_event calls,
sending "A" keydown and then "A" keyup. I start the test
program, plus Notepad and Edit.com. I click the button
and then give the focus to the Notepad window (by
clicking on it or alt-tabbing to it). After a few
seconds an "a" shows up. I click the button again and
give the focus to the Edit window. And nothing happens.

How come it works for you and not for me? What's going
on???

Dave

>
> It works for me here. I'm running Win2K-SP4 and
using CMD.exe or DOS
>EDIT.exe as the target programs. I don't know if
another DOS program might
>work differently (but I doubt it).
>
> I suspect that your test procedure is disturbing the
keyboard focus.
>Assuming that you're generating valid date using
keybd_event and that the
>target window has the focus, it should work.
>
>--
>
>-GJC [MS Windows SDK MVP]
>-Software Consultant (Embedded systems and Real Time
Controls)
>-gcha...@mvps.org
>
>-Abolish public schools
>
>

>.
>

Gary Chanson

unread,
Dec 17, 2003, 11:59:03 PM12/17/03
to

"Dave Lange" <dave....@verizon.net.invalid> wrote in message
news:052901c3c51a$9f9ffdf0$a601...@phx.gbl...

> OK, I'm thoroughly puzzled. My test is very simple. A
> VB program responds to a button click by sleeping for 5
> seconds and then making two keybd_event calls,
> sending "A" keydown and then "A" keyup. I start the test
> program, plus Notepad and Edit.com. I click the button
> and then give the focus to the Notepad window (by
> clicking on it or alt-tabbing to it). After a few
> seconds an "a" shows up. I click the button again and
> give the focus to the Edit window. And nothing happens.
>
> How come it works for you and not for me? What's going
> on???

Probably, the focus window is still the button you clicked on.

I'm testing by sending keyboard events from a command line environment
(either running in a console window or a GUI terminal window) to a DOS or
console program. The source executes a command which waits several seconds
end then sets the target window to the foreground and sends a string of
keyboard events. During the wait, I manually switch the target console to
full screen (before the script sets the foreground window).

Dave Lange

unread,
Dec 18, 2003, 1:33:22 PM12/18/03
to

>-----Original Message-----
> Probably, the focus window is still the button you
clicked on.
>
> I'm testing by sending keyboard events from a command
line environment
>(either running in a console window or a GUI terminal
window) to a DOS or
>console program. The source executes a command which
waits several seconds
>end then sets the target window to the foreground and
sends a string of
>keyboard events. During the wait, I manually switch the
target console to
>full screen (before the script sets the foreground
window).
>
>--
>
>-GJC [MS Windows SDK MVP]
>-Software Consultant (Embedded systems and Real Time
Controls)
>-gcha...@mvps.org
>
>-Abolish public schools
>
>
>.
>

Sorry to be a pest... I think I am now doing the same
thing you are (except that I'm not switching Edit to full
screen), with a C console app. Here's the code:

int main(int argc, char* argv[])
{
HWND hWnd;

Sleep (5000);
hWnd = FindWindow("ConsoleWindowClass", "MS-DOS
Editor");
SetForegroundWindow (hWnd);
keybd_event (65, 0, 0, 0);
keybd_event (65, 0, KEYEVENTF_KEYUP, 0);
return 0;
}

I can see the focus shift to the Edit window, but the
character does not appear. The same thing with Notepad
works fine. BTW, I'm running on XP (Pro and Home). Could
you send me your code (dave....@verizon.net)? Thanks.

Gary Chanson

unread,
Dec 18, 2003, 3:13:58 PM12/18/03
to

"Dave Lange" <dave....@verizon.net.invalid> wrote in message
news:013501c3c595$6ad94a10$a401...@phx.gbl...

>
> Sorry to be a pest... I think I am now doing the same
> thing you are (except that I'm not switching Edit to full
> screen), with a C console app. Here's the code:
>
> int main(int argc, char* argv[])
> {
> HWND hWnd;
>
> Sleep (5000);
> hWnd = FindWindow("ConsoleWindowClass", "MS-DOS
> Editor");
> SetForegroundWindow (hWnd);
> keybd_event (65, 0, 0, 0);
> keybd_event (65, 0, KEYEVENTF_KEYUP, 0);
> return 0;
> }
>
> I can see the focus shift to the Edit window, but the
> character does not appear. The same thing with Notepad
> works fine. BTW, I'm running on XP (Pro and Home). Could
> you send me your code (dave....@verizon.net)? Thanks.

Not quite. My code is also explicitly setting the focus to the target
window (and also restoring it and the foreground window after).

Dave Lange

unread,
Dec 19, 2003, 12:13:52 PM12/19/03
to
>
> Not quite. My code is also explicitly setting the
focus to the target
>window (and also restoring it and the foreground window
after).
>
>--
>
>-GJC [MS Windows SDK MVP]
>-Software Consultant (Embedded systems and Real Time
Controls)
>-gcha...@mvps.org
>
>-Abolish public schools

I thought that maybe the key was the explicit SetFocus.
So now I'm calling AttachThreadInput (attaching the two
threads from GetCurrentThreadId and
GetWindowThreadProcessId), then either SetActiveWindow or
SetForegroundWindow, and finally SetFocus. SetFocus and
SetActiveWindow always return error 126 if I target the
DOS Edit window. They succeed if I target Notepad.

HELP!!!

Dave

Gary Chanson

unread,
Dec 19, 2003, 2:36:01 PM12/19/03
to

"Dave Lange" <dave....@verizon.net.invalid> wrote in message
news:000e01c3c653$79d519e0$a401...@phx.gbl...

>
> I thought that maybe the key was the explicit SetFocus.
> So now I'm calling AttachThreadInput (attaching the two
> threads from GetCurrentThreadId and
> GetWindowThreadProcessId), then either SetActiveWindow or
> SetForegroundWindow, and finally SetFocus. SetFocus and
> SetActiveWindow always return error 126 if I target the
> DOS Edit window. They succeed if I target Notepad.

Why are you using AttachThreadInput?

SetForegroundWindow can be problematic. Using SwitchToThisWindow may
make a difference.

Dave Lange

unread,
Dec 19, 2003, 3:42:02 PM12/19/03
to

I'm using AttachThreadInput so I "can call the SetFocus
function to set the keyboard focus to a window of a
different thread" (quoted from the doc).
SwitchToThisWindow is not in my version of the SDK, so my
C console program can't use it. (And Microsoft says it's
deprecated and not for general use anyway.) When I tried
SwitchToThisWindow in my VB program, I got the same
result as SetForegroundWindow.

Since you're able to make this work, what sequence of
calls are you using?

Dave

Gary Chanson

unread,
Dec 19, 2003, 5:49:45 PM12/19/03
to

"Dave Lange" <dave....@verizon.net.invalid> wrote in message
news:085c01c3c670$8eaaa250$a001...@phx.gbl...

>
> I'm using AttachThreadInput so I "can call the SetFocus
> function to set the keyboard focus to a window of a
> different thread" (quoted from the doc).
> SwitchToThisWindow is not in my version of the SDK, so my
> C console program can't use it. (And Microsoft says it's
> deprecated and not for general use anyway.) When I tried
> SwitchToThisWindow in my VB program, I got the same
> result as SetForegroundWindow.


If you don't execute AttachThreadInput, does it work any differently?

> Since you're able to make this work, what sequence of
> calls are you using?

The code I'm using calls:

SetForegroundWindow
SwitchToThisWindow (if possible)
SetFocus
keybd_event for each down and up event for each character and shift key
restore foreground window
restore focus

Dave Lange

unread,
Dec 19, 2003, 11:22:16 PM12/19/03
to
> If you don't execute AttachThreadInput, does it work
any differently?
>

For DOS Edit, no difference. SetFocus returns error 126
no matter what. For Notepad, SetFocus works if I use
AttachThreadInput and fails with error 126 if I don't.
But it really doesn't matter, because Notepad gets the
keystrokes whether I use SetFocus or not.

>
> The code I'm using calls:
>
>SetForegroundWindow
>SwitchToThisWindow (if possible)
>SetFocus
>keybd_event for each down and up event for each
character and shift key
>restore foreground window
>restore focus

I've got my program coded to use this same sequence. (I
can do SwitchToThisWindow via LoadLibrary and
GetProcAddress.) But DOS Edit still doesn't get the
keystrokes.

Anything special I need to do with keybd_event? For a
lower-case "a", I'm doing

keybd_event (65, 0, 0, 0);
keybd_event (65, 0, KEYEVENTF_KEYUP, 0);

Dave

Gary Chanson

unread,
Dec 20, 2003, 2:31:22 AM12/20/03
to

"Dave Lange" <dave....@verizon.net.invalid> wrote in message
news:042201c3c6b0$d9d82230$a401...@phx.gbl...

Yes, I think so. I looked at this before and thought it wasn't relevant
but it turns out that DOS EDIT behaves differently from other programs I
tested. My code supplies the scan code as the second parameter. MSDN says
that this parameter is not used but I found that it sometimes is important.
I think it depends on the code which processes the key message, not
keybd_event itself. With this parameter set to zero, my code works in most
other cases but fails with EDIT.

I use MapVirtualKey(vkey,0) to generate the scan code.

Dave Lange

unread,
Dec 20, 2003, 11:07:20 AM12/20/03
to
>
> Yes, I think so. I looked at this before and
thought it wasn't relevant
>but it turns out that DOS EDIT behaves differently from
other programs I
>tested. My code supplies the scan code as the second
parameter. MSDN says
>that this parameter is not used but I found that it
sometimes is important.
>I think it depends on the code which processes the key
message, not
>keybd_event itself. With this parameter set to zero, my
code works in most
>other cases but fails with EDIT.
>
> I use MapVirtualKey(vkey,0) to generate the scan
code.


That was the key. I got it to work by including the scan
code in keybd_event. Correct documentation would have
saved me a lot of time and grief. Thanks for all your
patience and help!

Dave

0 new messages