From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How do I get keyboard events when window is not active


@nanocyte wrote:

Not per se. There is a level between "system wide" and "when the window is not active". OP might want to monitor keystrokes in LabVIEW, while the VI that monitors is not active.

 

In fact, if that is the case, (s)he can do so with normal LabVIEW events by dynamically registering for other VI's events.

 

Guess OP has some explaining to do.


When the user presses an arrow key I want to start an action and then when they lift up off the arrow key I want to stop that action. There's an issue right now where if another window pops up while the user is pressing the arrow, LV doesn't get the key down event and the action continues indefinitely.


Maybe you need to be making sure that the window keeps its focus; i.e., if it loses focus, give it back, if at all possible.

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
0 Kudos
Message 11 of 22
(1,466 Views)

When the user presses an arrow key I want to start an action and then when they lift up off

> the arrow key I want to stop that action.

If you only need to capture 2 keys, global hotkey is the best choice, as wiebe suggested.

 

George Zou
0 Kudos
Message 12 of 22
(1,463 Views)

@nanocyte wrote:

Not per se. There is a level between "system wide" and "when the window is not active". OP might want to monitor keystrokes in LabVIEW, while the VI that monitors is not active.

 

In fact, if that is the case, (s)he can do so with normal LabVIEW events by dynamically registering for other VI's events.

 

Guess OP has some explaining to do.


When the user presses an arrow key I want to start an action and then when they lift up off the arrow key I want to stop that action. There's an issue right now where if another window pops up while the user is pressing the arrow, LV doesn't get the key down event and the action continues indefinitely.


If those popups are VIs, you can catch events of those VIs. If not, you need to go global, or poll.

0 Kudos
Message 13 of 22
(1,440 Views)

@nanocyte wrote:

@Yamaeda wrote:

I believe it's meant to be hard. That's how you make keyloggers ...

/Y


That makes no sense. I can always just poll for your keys with Acquire Input Data so I don't think this is "hard" per se. It's really just a matter of implementation at this point.


I bet the polling won't work when admin login dialog appears. I think it will fail when you need to enter passwords. But if a process can be monitored, it could include those events, and you could in fact monitor login passwords. Something like that.

 

I know global key events are not really possible in .NET, so there probably is a reason. The only reasons I can think of are, security, or system architecture (technical difficulty). My bet is on security. But the details elude me.

 

I've been through this myself (actually still am). I want an easy way to get a ALT key down event. It's in the list, but doesn't trigger an event. Apparently LabVIEW filters that one out for it's menus. I have my own menus (*sigh*), so I need to get that event.

 

Polling is not elegant, but hooking isn't either. This should be easier...

Message 14 of 22
(1,440 Views)

Btw AutoIT seems to have an API for applications. Not sure if AutoHotKey got this, but perhaps by now it does.

 

AutoHotKey can do this, so if you could reuse this, it would save a lot of time. As AutoHotKey is open source, another option is to study it's functionality. Or to start a script that sends something to LabVIEW (maybe a named queue or something).

 

All options would require work, without any guarantees. When working with external APIs it's usually not easy to get events without hanging LabVIEW (e.g. let the DLL stop waiting when the VI stops). So you might end up polling as well. Sometimes you can wait for events, with a timeout. That's somewhere in the middle.

0 Kudos
Message 15 of 22
(1,439 Views)

Just digged a bit onto this.

 

SetWindowsHookExA function

Installs an application-defined hook procedure into a hook chain. You would install a hook procedure to monitor the system for certain types of events. These events are associated either with a specific thread or with all threads in the same desktop as the calling thread.

 

These messages seem to be system wide (optionally).

 

I created a quick dll in LabVIEW, and set it's export function as hook. Good new is this seems to be the case. Bad news is it doesn't seem to unload properly, and Windows explorer needs a reset, sometimes windows needs a reboot. But it does show potential.

0 Kudos
Message 16 of 22
(1,433 Views)

Here's a (not so) quick and (very) dirty solution.

 

Start Hook Exp1.vi. It will hook on keyboard events, the event structure will catch the events passed through by the hook, and then close the hook.

 

If Global Boolean is true, it seems to catch keys (almost) globally 😊.

 

The code is a mess. Full of comments, previous tries, etc. But I've burned enough time for now, and wanted to share it ASAP...

 

Some notes:

+ LabVIEW 2018, 64-bit.

+ Windows only.

+ You need to change the path to the dll (a fixed path works as well).

+ You can recompile the dll, it's a LabVIEW dll.

+ Save previous work.

+ Use at your own risk. Crashes are just around the corner...

+ If you stop the VI with the stop button, the hook won't be removed until you stop LabVIEW.

+ If it's a global hook, the dll might never be released (as it's used by other processes).

 

+ It will not work for all processes. When TaskManager is active, it won't catch keys. Online other processes are mentioned (like Firefox).

+ If no process is active (desktop is showing) it also won't catch keys. *sigh*

+ In fact, most processes don't seem to work nicely with this.

 

The problem might be that there are still lots of 32 bit processes, and the hook only hooks 64 bit processes...

Message 17 of 22
(1,414 Views)

Found the problem.

 

LabVIEW needs to be started with Administrator rights (not UAC). Then it catches all app events, the desktop and taskmanager inclusive.

Message 18 of 22
(1,406 Views)

I'll post a decent soon (probably on GitHub). I want to prevent everyone spending time on it. It's going to be awesome if I can say so myself 😁.

 

+ Filter events option (from within in the event structure, discard only though).

+ Global\LabVIEW only option.

+ VKey translation.

+ Multiple registrations possible (when not filtering).

+ 32 bit and 64 bit LabVIEW (not 32 bit Windows, if that still exists).

+ Automatic unhooking if main VI stops.

+ All native LabVIEW code, incl. the dll.

+ Of course open source.

+ Tried it in 2013 32 bit; also works (after recompiling the LabVIEW dll).

 

Feel free to ping this thread if I forget to finish this. I might (tend to) go on to the next thing.

Message 19 of 22
(1,378 Views)

FYI I'm most likely going to go with polling for now. I just wanted to ping the community in case there was an existing tool I could use. If I were going to go the "dll" route, I might go for hooking the driver with the interception tool. It just seems simpler and maybe more efficient.


I'm very interested though in how you might implement the DLL using LV. I would think you'd need like call backs and other stuff you can't normally do in LV.

0 Kudos
Message 20 of 22
(1,374 Views)