Hook for keyboard events

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Aleksey Vaneev wrote:I'll think more on this matter, but I'll probably try that 'hook' approach with "1" return - will implement it in Overtone GEQ soon.

I'm just thinking - since hook function call sequence is not defined in the Win32 API, what if Steinberg or some other host producer overtakes this hook approach? They'll simply block all other hooks, and there will be no way for plug-in to control keyboard events. Hooks do not look elegant after these thoughts.

Maybe 'window in another thread' approach is better? (Still, it won't stop host from reacting on the Q or any other key). Beside that users usually dislike it when plug-in uses SetFocus function.
I've already tried return 1 but in any case it doesn't work.

Post

AdmiralQuality wrote:What are edit controls doing to capture the keyboard? For example, I can type a Q into the "Enter the key" field in SCAMP when it's in Wavelab and no Wavelab dialog pops up. Try it: http://www.admiralquality.com/products/SCAMP/

Might be a clue here somewhere.
Ok it works, but how?
:shock: :cry: :-o :-o

Post

kensuperken wrote:I've already tried return 1 but in any case it doesn't work.
It works here. This apporach blocks Sonar's hot keys while I have all key input I need. So, probably you are not installing the hook in the right place - I'm doing it 'just in time' (when plug-in's UI opens), not at the plug-in load.
Image

Post

may be I do something wrong! I'll try your suggestion
Thanks

Post

You may want to consider api hooking. Assuming the host uses getmessage/peekmessage, you could hook those apis within your vsti dll file, then have a proxy function return the results from the getmessage/peekmessage if you are not going to block them. If you will not block them, you simply have to not return the message in your proxy function.

Post

fenril, keyboard event hooking is basically the same thing.
Image

Post

Hi All,

I need to have my VST grab keyboard events. OnKeyDown () and OnKeyUp() fonctions works but not all VST host will pass along the keyboard messages. How can it be done then?

Steph

Post

oifii wrote:Hi All,

I need to have my VST grab keyboard events. OnKeyDown () and OnKeyUp() fonctions works but not all VST host will pass along the keyboard messages. How can it be done then?

Steph
It can't. (At least not consistently, in a way that no host can interfere with and that won't interfere with any hosts.) Find another form of input.

Post

kensuperken wrote:
AdmiralQuality wrote:What are edit controls doing to capture the keyboard? For example, I can type a Q into the "Enter the key" field in SCAMP when it's in Wavelab and no Wavelab dialog pops up. Try it: http://www.admiralquality.com/products/SCAMP/

Might be a clue here somewhere.
Ok it works, but how?
:shock: :cry: :-o :-o
Sorry I missed this question. Here's the answer, 8 years too late. I don't know offhand why it works and your other plugin doesn't, but SCAMP's interface at that time was VSTGUI 3.0 based. (It is now based on VSTGUI 3.6 RC2. Though the key-entry field no longer exists as we've changed to key-files instead of C/R codes.)

Post

There are functions in windows you can call to set the focus for various events, including keyboard events. It is a very complicated and difficult situation to deal with due to the interference between the OS, applications, plugins and so on.

The solution I've found is to create a hidden text entry class window (use the system default class for this) which seems to automatically grab focus for text entry. The window can remain completely invisible and you can get both events as well as allow multi-line editing to occur inside the window itself even while on the GUI your own window retains graphical focus.

This requires a bit of effort to code specifically for each type of control as opposed to using some generic sort of messages (onKey() or so on) but I find it is far more reliable and doesn't pollute the core of the GUI lib with rarely used functionality.

Code: Select all

handle = CreateWindowEx(exstyle, (LPCSTR)"edit", name, style, 0, 0, 0, 0, (HWND)parent_window, 0, (HINSTANCE)instance, (void *)this);
This is built in to my abstract window interface. The "text entry" control then in my GUI library implements an abstract event handler (works same on windows, xlib, osx) which handles keyboard events directly rather than having them pass through the GUI library. So, in other words the events, the window, the handler are all components of the widget implementation itself rather than parts of the generic GUI interface.

I'm then able to handle how the UI is represented graphically by drawing the box, text, cursor and so on in the same identical way across all systems.

(Of course this doesn't actually "steal" events beyond the capability of the "edit" class. If the host implements a keyboard hook or steals events from you while dispatching them, you'll still never get the events. A completely unique message queue is still required to ensure you get all messages... although again if your host irritatingly implements system level keyboard hooks you're screwed.)
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

AdmiralQuality wrote:
kensuperken wrote:
AdmiralQuality wrote:What are edit controls doing to capture the keyboard? For example, I can type a Q into the "Enter the key" field in SCAMP when it's in Wavelab and no Wavelab dialog pops up. Try it: http://www.admiralquality.com/products/SCAMP/

Might be a clue here somewhere.
Ok it works, but how?
:shock: :cry: :-o :-o
Sorry I missed this question. Here's the answer, 8 years too late. I don't know offhand why it works and your other plugin doesn't, but SCAMP's interface at that time was VSTGUI 3.0 based. (It is now based on VSTGUI 3.6 RC2. Though the key-entry field no longer exists as we've changed to key-files instead of C/R codes.)
lol, kensuperken was graziano, a guy working of first alpha release of nebula. Basically the question was mine.
We solved using a input keyboard hook, but thank you lol

Post

:tu:

Post

A major pain is that a bunch of hosts that send raw WM_KEYUP/WM_KEYDOWN messages still won't send you WM_CHAR (or WM_UNICHAR, etc) that you'd really want to use for text entry (since it makes it far easier to deal with different layouts and various oddities).

Aciddoses idea has some potential .. but I think one could improve it by creating the "keyboard window" in a separate thread. Then the messages go to the queue of that thread (rather than host UI thread) and you can have your own private message loop. Setting it up so it works properly could be a bit tricky.

Post

I suggested that earlier in this thread. Unfortunately yes, this is very tricky.

When we're talking about proper handling of events which should be in all ways compatible between multiple clients - that is if we're going to be a "well behaved" client - I feel using the "edit" class is the best possible solution on windows.

Keyboard hooks are undoubtedly "naughty" because they are certain to create issues for other clients on the system.

Relying upon the host not to intercept messages for "hot keys" or to use "translatemessage" to give you WM_CHAR and likewise are not reasonable unless they are explicit requirements of the VST specification.

The discrete message loop combined with FIFO mutex should in theory solve all issues, but clients shouldn't need to use this sort of work-around.

In my opinion any host that does not provide events to a window with the "edit" class is broken in a fundamental way. It is using win32 in a non-standard way which is incompatible with components of win32 itself. That is a bug.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

aciddose wrote: The discrete message loop combined with FIFO mutex should in theory solve all issues, but clients shouldn't need to use this sort of work-around.
You don't really need a custom FIFO or anything, just listen to the messages you want in the other thread, then map them to custom messages (the WM_APP range is safe) and PostMessage() back to the regular UI thread/window. While this doesn't save you from setting up another thread and window, you can at least process the messages normally then (just remapping back to the actual events in your windowproc).

Post Reply

Return to “DSP and Plugin Development”