LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

LabWindows - How to detect key release?

Solved!
Go to solution

My application uses a callback with EVENT_KEY_PRESS to detect when function keys are pressed on the keyboard. A routine is executed based on the function key. This all works fine.

 

Is there a way to tell when the pressed key has been released?

 

The goal is for the routine to execute only once and not repeat if the user is holding down the key for an extended period of tiime.

 

Any insights are appreciated,

 

Thanks,

 

Scott T.

 

0 Kudos
Message 1 of 10
(6,016 Views)

Scott:

 

I don't know of the equivalent of a KEY_UP event.  As you already know, EVENT_KEYPRESS is fired when the key is pressed down, not when it's released.

 

With some limitations, you can use a timer to help ignore a key held too long.

 

For EVENT_KEYPRESS, eventData1 is the code for the key you pressed.  When the event is fired, check if the same key was pressed as last time.  If it is the same, check how much time has passed since the last press.  If it's less than some time period you choose, ignore it as a held key.  If the time between events is longer than your chosen delay, consider it to be a new keypress.

 

The limitation with this approach is the keyboard typematic repeat delay.  If you press and hold a key, there is a delay (typically 0.5 seconds) set in BIOS before the key starts repeating.

If the set delay in your program is less than the keyboard typematic repeat delay, you will get a double count when the key is held the length of the typematic repeat delay.
If the set delay is longer than the typematic repeat delay, you won't get the double count, but you may miss fast repeated taps at the key.

 

Look at the attached sample program to see what I mean.

0 Kudos
Message 2 of 10
(5,988 Views)

Hi Scott,

 

You may also want to take a look at this forum:

http://forums.ni.com/t5/LabWindows-CVI/How-to-catch-events-like-KEY-UP-KEY-DOWN-in-CVI-it-is-availab...

 

It's an old forum but it suggests an alternate method of detecting Key Up events.

 

Let me know if this works for you!

Tanya Visser
National Instruments
LabVIEW Group Manager
0 Kudos
Message 3 of 10
(5,949 Views)

Thanks Tanya.  I'm sorry I missed that.  Using the Windows KeyUp message works better and is easier (and easier is better)!

 

Forget the timer, forget checking if the same key is pressed.

Just set a global variable for keydown.

Install a callback for the Windows WM_KEYUP message.

Start with the keydown global FALSE.

When EVENT_KEYPRESS is received, check if keydown is TRUE.  If it is, ignore the event.

If keydown is not TRUE, that means it's a new keypress.  Do whatever you want for the new keypress.

When the Windows message WM_KEYUP is received, set keydown FALSE.

 

I attached a simple example to this post which demonstrates this.  The user interface has a checkbox to allow the user to test for keyup or not, to demonstrate the difference.

0 Kudos
Message 4 of 10
(5,927 Views)
Solution
Accepted by Scott_T

Note: You can also use this method to avoid multiple keypress events for any key.

 

Scott used the example of function keys.  If you also want to avoid entering repeated alpha-numeric keys, return 1 from your textbox callback to swallow the event if it's not a new keypress.

 

A new .c file (to replace the one in my previously posted project) is attached which demonstrates this.

 

 

0 Kudos
Message 5 of 10
(5,919 Views)

Al & Tanya

 

Thanks for the input. Works great on the individual panels of my application.

 

Still trying to come up with a solution to work across panels.

 

For example: A key is pressed and a new full screen panel is displayed. If the key remains held down, then the function associated with the key on the new panel is executed rather than waiting for a key release and then another press.

 

Scott

0 Kudos
Message 6 of 10
(5,869 Views)

Scott:

 

If you get an EVENT_KEYPRESS on a new panel, the callback from the new panel will be called, but in that callback you'll check the global g_keydown.

g_keydown needs to be global for the entire project and needs to be checked in any callback for which you're concerned about a held key.

 

I don't see a problem with a new panel if you check g_keydown.  As a side note, you need to be careful any time you have a global that can be modified in multiple places, but in this case you don't really care which control or panel is waiting for it to be released: you just care if it was released.

0 Kudos
Message 7 of 10
(5,863 Views)

Al

 

The key release check is now working across all panels. My application was set up as you had described.

 

I was using the F1 thorough F10 function keys for inputs. I reprogrammed to use the 1 through 0 number keys instead. Everything works fine now.

 

When I used F10, the new panel would be displayed, but the key release was never detected (even with repeated presses).

 

If the number 0 key is used instead, the release is always detected in the new panel.

 

When the application is loaded on another PC via the distribution kit, the same F10 anomaly is present.

 

Not sure what the F10 is about, but at least the app is operational.

 

Scott T

0 Kudos
Message 8 of 10
(5,855 Views)

F10 is treated as if it were an an Alt key combination so WM_SYSKEYUP is sent instead of WM_KEYUP.

 

Michael

NI

0 Kudos
Message 9 of 10
(5,844 Views)

Michael:

 

Thanks for the info.  I wonder why Windows treats F10 differently than the other function keys.  Function keys F1 through F9, and F11 and F12 all generate WM_KEYUP, but F10 generates WM_SYSKEYUP.  Here's a link from Microsoft that explains a little more: http://msdn.microsoft.com/en-us/library/gg153546(v=vs.85).aspx

 

Scott:

 

If you want to use the function keys, the solution could be as simple as installing callbacks (can even be the same function) for both messages.

 

 InstallWinMsgCallback (panelHandle, WM_KEYUP, KeyupCallback,
       VAL_MODE_IN_QUEUE, NULL, &postinghandle);
  
 InstallWinMsgCallback (panelHandle, WM_SYSKEYUP, KeyupCallback,
       VAL_MODE_IN_QUEUE, NULL, &postinghandle);
  

0 Kudos
Message 10 of 10
(5,828 Views)