Page 1 of 1

onKeyDown and window::defaultKeyDownHandling

Posted: 30 Apr 2019 17:02
by daveplummermd
I cant seem to capture a "onKeyDown" event.

I contstruct a simle form called "keyDown", that has both a "setKeyDownResponder" and a "setCharResponder"

Code: Select all

implement keyDown inherits formWindow     open core, vpiDomains   clauses     display(Parent) = Form :-         Form = new(Parent),         Form:show().   clauses     new(Parent) :-         formWindow::new(Parent),         generatedInitialize().   predicates     onKeyDown : window::keyDownResponder. clauses     onKeyDown(_Source, Key, _ShiftControlAlt) = window::defaultKeyDownHandling :-         stdio::write("\n", Key),         !.   predicates     onChar : window::charResponder. clauses     onChar(_Source, Char, _ShiftControlAlt) = window::defaultCharHandling :-         stdio::write("\n", Char),         !.   % This code is maintained automatically, do not update it manually. %  11:49:42-30.4.2019 predicates     generatedInitialize : (). clauses     generatedInitialize() :-         setText("keyDown"),         setRect(rct(50, 40, 290, 160)),         setState([wsf_ClipSiblings, wsf_ClipChildren]),         menuSet(noMenu),         setCharResponder(onChar),         setKeyDownResponder(onKeyDown). % end of automatic code   end implement keyDown
I expect the predicate "onKeyDown" to be triggered on any key push when the window is active, in focus. Even in debug, it is never triggered.
The onChar predicate does behave as expected and write the Char to the message window.

What am I missing?

thanks in advance

Dave

Re: onKeyDown and window::defaultKeyDownHandling

Posted: 30 Apr 2019 20:47
by Harrison Pratt
Controls capture the key actions before the form can act on them.

If you delete all controls on the form which might capture a key press (including OK and Cancel buttons) then you can see that the form itself can capture the keystrokes.

I haven't worked out how to handle having certain key actions be ignored by controls and pass onward to the form, though.

Re: onKeyDown and window::defaultKeyDownHandling

Posted: 1 May 2019 1:43
by daveplummermd
I understand that I can introduce a "addNativeMessageHandler(onNative)" and then detect and act on key presses that way...such as this code to detect a keydown and keyup events for the left shift key:

Code: Select all

implement keyDown inherits formWindow     open core, vpiDomains   clauses     display(Parent) = Form :-         Form = new(Parent),         Form:show().   clauses     new(Parent) :-         formWindow::new(Parent),         generatedInitialize(),         addNativeMessageHandler(onNative).   facts     shiftKeyIsPressed : boolean := false.   predicates     onNative : window::nativeMessageHandler. clauses     onNative(_Source, Message, WParam, LParam) = window::defaultNativeHandling() :-         if Message = 135 and shiftKeyIsPressed = false and not(toString(LParam) = "0000000000000000") then              shiftKeyIsPressed := true         elseif Message = 257 and toString(LParam) = "00000000C02A0001" then              shiftKeyIsPressed := false         end if,         !.
Is is just so messy dealing with the tin the representation of the nativeMessageHandler
nativeMessageHandler = (window Source, unsigned Message, gui_native::wParam WParam, gui_native::lParam LParam).

I am hoping for a more elegant and readable

Code: Select all

onKeyPress(vk_shift):-         blah,         blah.        
Am i missing something

Re: onKeyDown and window::defaultKeyDownHandling

Posted: 1 May 2019 10:00
by B.Hooijenga
Hello Dave,

I had the same problem.
I found this solution: I made a customControl in an formwindow.
In this customControl you can make an KeyDownResponder.
The customControl must have focus.
And then the KeydownResponder will work perfectly.

Ben

Re: onKeyDown and window::defaultKeyDownHandling

Posted: 1 May 2019 11:56
by Harrison Pratt
Another approach is to use an edit control and set the Visible property to False. That control will accumulate the keys pressed, so you can either use that "history" or clear the edit control after each key press.

Re: onKeyDown and window::defaultKeyDownHandling

Posted: 1 May 2019 13:40
by daveplummermd
Thanks Guys
I am going to experiment/play with both ideas

dave

Re: onKeyDown and window::defaultKeyDownHandling

Posted: 2 May 2019 10:22
by Thomas Linder Puls
Maybe it would be a good idea if you explain your problem on a higher level first: "When the user presses … then program/dialog/form should …".

And then a little clarification. At any time there is one (and only one) window that has focus. This window will receive the key up and down messages and char messages. Very often the focus window is a control nested in a dialog/form/.... In that case the control has focus, the dialog/form/... is active (but only the control has focus).

This is however only "surface" correct. In reality key up and down goes into one central "input thing" in Windows which then decides which message queue (~ application/thread) that should receive the messages, and then the relevant application will fetch and dispatch this message internally (normally corresponding to the "surface" behavior).

Due to this more complex setup, keys can be handled at windows level (ALT+TAB switches application, no application receive this keypress directly). Function keys are typically handled at application level, Alt+LETTER is handled on application using accelerator tables, etc. Keys that are not handled on one level is passed on to the next level (Windows -> application -> focus control).

But key events does not go to the dialog/form (unless this is the one that actually has focus (but if it contains an enabled visible control the dialog never has focus)).