vb5 key press capturing...

I need an api call of some sort that can successfully capture key press events in a DOS BOX from windows 95...I can do it in windows 95 without problems...but it doesn't see anything I type when I use a dos box...this is the problem, please supply code with explination.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

If you can get ahold of the newest copy of VBPJ, they have an article about dealing with dos prompts in VB.  It acutally describes how to create a console app in VB, and caputre input and output with it.
The VBPJ article only tells how to make YOUR app work in as a console app (in a DOS box).  My assumption is that ChrisK want to capture keystrokes from a DOS box opened outside the application doing the capturing?

If you have not already, you probably want to ask this question in the Windows Programming topic
ChrisKAuthor Commented:
rmichels is correct with his thinking...the program itself is vb5, so obviously windows...but I need it to capture events happening outside of "windows" in dos boxes.
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

ChrisK, you might find there is another solution to your problem if you were to explain exactly what it is that you wish to do.
ChrisKAuthor Commented:
I want to be able to run dos based programs (from win95 dos boxes) and capture keys being pressed in those programs.
I understand that much - I thought I might be able to help you resolve a specific issue but I guess you're looking for a generic solution that would work for any program.  I don't know of any.
ChrisKAuthor Commented:
Well, a key press is a key press, doesn't matter what you are running....it can be done as a tsr in C, so surely vb5 must have SOME way of doing it.
I've worked quite a bit with DOS utilities from VB.  I've successfully intercepted input and output - but the solutions I've come up with have been different for different apps.  I doubt there is a generic solution because DOS is running below Windows.

FYI: a TSR is a dos based app and must be loaded before windows.  VB apps can be compiled but they can not be executed without windows; therefore, you can't write a TSR in VB.

ChrisKAuthor Commented:
I know you can't make a "tsr" in vb...I just ment it COULD be done in C so why not vb.  Windows must have some form of control over all it's environments, including dos.
Just tell me some solutions that you've found.  My solution needs to be SOME WHAT generic, but maybe I can incorporate your thoughts to create a solution...
FYI: TSR=Terminate and Stay Resident. It does not necessarily mean that it has to run in DOS. It can be Win95, DOS, NT or any other platform. It's just that it was first introduced with DOS that people often think it has to be a DOS-program, but for other platforms the name is still the same. (you can call it a WinTSR if you like).
MrMick: a TSR can also be loaded after Win95 loaded.

Ok, enough about that discussion.
It is not easily possible to hook the key-presses of a DOS-window. It will get even tougher when that window is maximized (without the border, I mean). Just use Spy++ and you see what I mean. You will need to write a VXD, which is not possible via VB. I've looked on www.ntinternals.com, but they don't have (yet) a utility for this.
Not really encouraging, I know.

There are a few ways how you can do it (but those are all half-way solutions and they only work on non-maximized console-windows and they don't apply to WinNT)
First of all, you can check on a message in the window of a console with class 'tty'. It has the caption of the titlebar. The message is WM_USER + 26. This message is posted by the window everytime a key is pressed. The lparam will be always ZERO and the wparam seems to be randomized. You might use GetMessageExtraInfo to look if it says somehow which key is being pressed, but I haven't tested that and I doubt it works.
Second thing you can do is sending WM_KEYDOWN and WM_KEYUP events with the same keys you use with a normal cut and paste operation in a console window. You can than paste the contents of a window into your app.
Third thing is capturing the window and all it's contents the normal way. The problem with this one is how to retrieve letters from a bitmap, but there are algorithms for that.
Fourth thing you can use is creating such infamous TSR which loads everytime a console opens (which can be done) and captures everything for you, but you'd already considered that possibility.

The most comprehensive solution via the upper layer of software programming (using API and so) is combining the first and the second way together. You will get your information, but the problem is, you can't use this way of spying without your end-user seeing it. (selecting an area means making white black and vice versa, no way you can hide that for your users). The other problem is that it's not very fast. You have to capture the screen (or a part of it if you make your program smart enough). This way you can also capture strings written to the screen by command.com (type dir for example) or another program, but again: it's slow. Besides, when the writing goes beyond the screen and starts scrolling, you need to pause it somehow to capture it.

-No NT
-No maximized console (via alt-enter)

Well, that's about it I guess. I've seen your question in the Windows area as well, but since you use VB I thought it would be best answering it here.
BTW, I don't know what you consider easy, but capturing keystrokes to a console is amongst the most difficult Win32 programming tasks I've ever seen (ever tried making a VXD?).

I hope this helps you a bit, let me know if I can be of anymore help for you.

Sorry, I meant posting it as an answer, I'll try again (see below for answer)

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial

I am fully aware that TSR is an acronym for "Terminate and Stay Resident".  This acronym was coined by Microsoft and applied only to DOS.  The term wasn't ported to Windows because Windows is a multitasking OS.  I was referring to the Microsoft meaning of TSR and not the phrase "terminate and stay resident" because terminate AND staying resident doesn't even make since except in the DOS environment because all Windows apps stay resident until they terminate.

DOS terminate and stay resident provided a means for a program to pass control back to the OS (unnecessary in Windows) while continuing to run (staying resident).  A Microsoft TSR is created when an app written to run under DOS is exited by calling DOS Interrupt 21h, Function 31h with:
AH = 31h
AL = return code
DX = amount of memory to reserve in paragraphs

Normal apps exit by calling DOS Interrupt 21h, Function 4ch.  Not only can VB not call DOS or Hardware Interrupts, VB can't produce an excitable that can run under DOS without Windows.  Thus, VB can't be used to create a TSR.

ChrisKAuthor Commented:
Abel, I must say that you're answer is quite extensive and good, but I'm having troubles incorporating it into my code.  Could you perhaps make a simple sample program and send it to me?  My e-mail is ChrisK@yankton.com and I'll raise the points up to 100 if you do write a sample app for me :)
ChrisK: It's not that much, so I can post it here as well. Other people can see the answer then and use it if they like (which is what Experts-Exchange is about, isn't it?) But before I need to know what your problem is and/or what part of the code you want me to write a sample about.

Mick: You're right. I used an explanation from a book which found TSR applicable to Win-apps as well. The author would even find the kernel a TSR... In some way it made sense, but you are right with your explanation.

ChrisKAuthor Commented:
Well, I don't really understand many API calls yet so a simple form that can do what I'm trying to do (send keys/capture keys to/from a dos box app in win95) it would be very much appreciated.
ChrisKAuthor Commented:
Oh and regarding to the TSR's, the author of that book is correct, windows IS just 1 big tsr running out of dos.  Supposedly even 95 is but I have my doubts on that one...
Since you are don't understand API's so well, I think it's better for starters to do it the VB-way. Let's say you have your app running and the DOS-app is the second in the Z-order (that won't be the case always, but it's easier for showing my example).
Make a new app in VB and create a textbox (Text1) with multiline to TRUE and a commanbutton (Command1) on the main form.
Paste the code below in the forms code-window. Run your app, start a dos box and type DIR (followed by enter off course) switch with one Alt-Tab to you app and hit Command1. See what happens. (the textbox should now be filled with the text of the dosbox)
You got the picture? You don't need any API-knowledge for doing that, and it's still an "easy" solution....
When you want it more sophisticated, take a look at MsgHoo32.ocx and look up some info at there website on how to use it. You can hook in the WM_USER + 26 message if you want and combine some code.

BTW. As long as you don't hook, the below solution does work on NT as well, but is not a monitoring program off course. It probably will be too slow as well when you want to cut and paste everytime you get the WM_USER + 26 message.

Private Sub Command2_Click()
Dim Right80 As String
Dim Down25 As String
Dim i As Integer

Down25 = "+(": Right80 = "+("
For i = 1 To 25
  Down25 = Down25 & "{DOWN}"
Next i
For i = 1 To 80
  Right80 = Right80 & "{RIGHT}"
Next i
Down25 = Down25 & ")"
Right80 = Right80 & ")"

         Right80 & Down25 & "{ENTER}", True
Text1 = Clipboard.GetText

End Sub

ChrisKAuthor Commented:
I need code using api's...this code didn't work for me and would be way too slow.  All I need are examples on how to use the api's for the task and I'll understand it.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.