Global Key Event (KeyUp, KeyDown)

Hi

I use Window.KeyUp event to detect key events, but as described in http://documentation.xojo.com/index.php/Window.KeyUp this is only fired when the window has the focus. Is there any ‘global’ key event for an app? And only for the app, I don’t want to write a key logger :slight_smile: Searched a lot without success.

Add a property TheTimer As Timer to the App.

Create, configure and start the timer in the App’s Open event:

TheTimer = New Timer() AddHandler TheTimer.Action, AddressOf Timer_Action TheTimer.Period = 0 TheTimer.Mode = Timer.ModeMultiple TheTimer.Enabled = True

Add a Timer_Action method to App:

Sub Timer_Action(sender As Timer) If Keyboard.AsyncKeyDown(&h7B) Then // left arrow was pressed End End Sub

Have a look at the other properties of the Keyboard module.

TheTimer.Period = 0 has always worked for this specific case in my projects, but I think it is a bit of a hack, since it just magically “steals” the event from the control currently having the focus.

PERFECT! Thank you!

Just curious: What are the usage scenarios? Menu navigation? Or what would you use it for?

Keyboard navigation for an information screen in a company.

There is a PagePanel with several panels (calendar, tasks, project overview,…) and a ultra small keyboard. So user can switch panels with the keyboard.

Wasn’t far off with my guess then :wink:

Thanks for the explanation. Curiosity was killing me :wink:

If you have a menubar, it would be better to add menu items under the “View” menu for it. At least on OS X all special key combinations should have a corresponding menu item.

I have no menubar. It’s full screen application and I use left-, right-, up-, down-arrow and some letters.

It’s a screen like this:

That’s what I thought too, and as I couldn’t come up with another usage scenario I was puzzled as to how this can be used. Urs explained it. If you know of other usage scenarios then please let us know.

Problem: pressed key is called multiple times in a blink because of Timer.Period = 0.

When I higher the timer period I don’t get always the pressed button. I guess this is because sometimes the control with the actual focus receives the pressed key and App misses the pressed key.

So I implement a timeout. Did this by comparing ticks of the last time a button was pressed:

Add property pLastPressedKeyTicks to App.

In App.Open()

pLastPressedKeyTicks = Ticks

Sub Timer_Action(sender As Timer) If Keyboard.AsyncKeyDown(&h7C) then 'right arrow key HandlePressedKey(&h7C) end if End Sub End Sub

[code]Sub HandlePressedKey(key As Integer)
Dim now As Date = New Date

If Int32(Ticks - pLastPressedKeyTicks) > 10 Then
pLastPressedKeyTicks = Ticks
WinMain.KeyPressed(key)
End If
End Sub[/code]

I use another solution: I’m storing the last key code and if it is the same, I’m not doing anything.

That was my first thought. A bit like an RS latch to eliminate the bouncing of switches.
But the user can press the button (e.g. down arrow) repeatedly or hold down to scroll through all pages.

I would change the timer period on key detect and then change it back the next time the timer fires (if no key detect). No need to have the timer firing in the interim.

For my own key monitoring timer, I found a period of 100 was still responsive and was easy on the CPU also…