Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Capture key press in app 6

Status
Not open for further replies.

BiggerBrother

Technical User
Sep 9, 2003
702
GB
I have an app, made of 14 forms and an MDI form. The MDI form has a textbox, used as a command line.

What I want to achieve is that if the user presses a key, and the focus is not currently on another textbox, then the focus snaps to the command line, and the text is entered into the command line.

I realise that VB does not have form_keydown functions that take precidence, and that to use the keydown function, i have to enter this into every control on the forms. Is there any other way to intercept the input from the user?

I guess that it must be an API function, if any, and that is probably the wrong forum, but I reckon it's a good place to start.

Thanks for your help

BB
 
Hello BB,

I am using GetAsyncKeyState to capture the ESC. you might be able to use it for your situation as well. Here is the definition:

Public Declare Function GetAsyncKeyState Lib "user32" _
(ByVal vKey As Long) As Integer

Hope I helped a bit...

nicsin
 
Are your forms MDI Children? if so you could allocate a shortcut key to a menu item on the MDIForm, which will activate even if one of the child forms are in focus.
Another option would be to use a hotkey, search p.s.c. or google
 
Only problem with that nicsin is that you have to use a timer
 
nicsin How do you call the api to get the GetAsyncKeyState on an inactive form?
 
LPlates,

I don't but the API will fire even on an inactive form. So let's say the user presses a button which will eventually call the API, minimises the form, goes on working in WORD or whatever and presses the key there, the API will indeed detect that!
 
>I don't but the API will fire even on an inactive form.


No it wont. You need to call the API in a function that calls the line...

If GetAsyncKeyState(The key you desire) Then
Your action here
End If

In order to determine what the keypressed was, therefore you require a timer, for example: A Keylogger.

 
Sorry I misunderstood your point! Of course one has to call it this way. I've got it in a loop, which takes some time to finish, so if the user presses the ESC key the loop will exit. What I meant before is that even if the loop is running in an inactive form, the event will also fire (and exit my loop).
 
If you set keypreview on the form to TRUE, you only need implement your keypress code in the form's keypress event, and not every individual control.

Maybe that'll help...
 

I'm confused.
Are you (BiggerBrother) talking about catching the key pressed in a child form, or in the MDI form?

If you use the GetAsyncKeyState in a timer to catch the key pressed on the MDI, then you will probably want to catch this only if the MDI has the focus, AND the application has the focus.

Otherwise, the GetAsyncKeyState will also catch the key pressed when another application is the current window and you press the key to be caught there...

Also, you will want add a delay to prevent the key press to be caught in the timer more than once prior to releasing the key (because of the Key Repeat delay)
 
CCLINT,

>Also, you will want add a delay to prevent the key press to be caught in the timer more than once prior to releasing the key (because of the Key Repeat delay)

can you please elaborate? what is the [colo blue]key repeat delay[/color]? what is going to happen if the key press is caught more than once?

thnx
 
CCLINT Thats why I suggested using a menu item from the MDIForm and assigning a shortcut key to it. that way regardless of whether the MDIForm or one of the Child forms has focus the shortcut key will still fire the menu item you allocated to that key
 
i want to be set focus on the MDI form command text box, whenever the following are ALL true:
My app has focus, and is the active app in windows. (Not worried when user is typing word document etc)
Any control, other than text boxes has focus (eg. if user scrolls a page and the presses a key.)
Only a single key is press, not alt+ or ctrl+ key. I have a menu with shortcuts set this way, so I don't want to interupt them.

10 of my forms are children, and the other 4 are standard forms. I need to be able to capture keypresses all of these forms as well, when textboxes do not have focus.

I'm not sure this can be done in one routine, but I thought I'd ask.

Thanks for all your responses

BB
 
Well, if you have code which gets executed after catching a key pressed using GetAsyncKeyState in a timer, that code may execute again if the timer interval is set too low.

Try this in the MDI form:
(make sure your Debug window is opened)
Add a Timer to the MDI and set the interval to 1.

Add this to the code window of the MDI:
Option Explicit
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer

Private Sub Timer1_Timer()
If GetAsyncKeyState(vbKeyEscape) < 0 Then
Debug.Print &quot;ESC pressed&quot;
End If
End Sub

Start the project and after the MDI shows, press the ESC key.

Review the results in the debug window.
 
LPlates

This routine has to work for all alpha and numeric keys. Are you saying that I need to add around 40 menu's to my MDI form, and then call a procedure from all of these?

This will also only work for the MDI and it's children. It will not work for non-child forms.

BB
 
Sorry, I should have mentioned that my response was to nicsin's question
 
In that case add a timer as CCLINT has suggested, check to see if any of the textbox's in question have focus and if not, you can execute your required code
 
You will also have to check that your application has focus because the GetAsyncKeyState API will catch keys pressed even if your app is not in focus at all.
 
Cheers CCLINT.

As LPlates has already mentioned, the API is used as:


If GetAsyncKeyState(The key you desire) Then
Your action here
End If


I was wondering, instead of

>The key you desire

is there another parametre for any key?
 
You have to check fo all the keys you want manually, so you code something like...

[blue]Dim [/blue]KeyResult [blue]As Long

[/blue][green]'F1
[/green]KeyResult = GetAsyncKeyState(112)
[blue]If [/blue]KeyResult = -32767 [blue]Then
[/blue][green]'code here
[/green][blue]GoTo [/blue]KeyFound
[blue]End If


[/blue][green]'F2
[/green]KeyResult = GetAsyncKeyState(113)
[blue]If [/blue]KeyResult = -32767 [blue]Then
[/blue][green]'code here
[/green][blue]GoTo [/blue]KeyFound
[blue]End If


[/blue][green]'F3
[/green]KeyResult = GetAsyncKeyState(114)
[blue]If [/blue]KeyResult = -32767 [blue]Then
[/blue][green]'code here
[/green][blue]GoTo [/blue]KeyFound
[blue]End If
[/blue]KeyFound:
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top