• Welcome to PlanetSquires Forums.
 

_WM_KEYDOWN handler questions

Started by David Kenny, October 20, 2013, 06:11:45 PM

Previous topic - Next topic

David Kenny

This one has me puzzled...  ???

If I put only the following code into a _WM_KEYDOWN handler for a RichEdit (for instance):    Beep
    Function=%True

I get a beep for each keystroke and non-printable characters are blocked (a couple excepts mentioned below). So far, so good.  But then I do get all printable  characters (Ok, I didn't verify all, but all alpha, numeric, and many others including, "/.,?><":';" etc.

Shouldn't the "Function = %True" stop processing for all keystrokes in this scenario?

I actually tested two controls, and EditBox and a RichEdit.  Tab took me to the next control for both of them. Enter was blocked for the RichEdit, but made it to the EditBox. 

Any thoughts?

David

Eddy Van Esch

David,

In order to intercept (and 'swallow' ) some keystrokes entered in a control, I think you need to subclass that control.
If you do not subclass the control, keystrokes are passed to the controls form WndProc routine no matter what.
Someone please correct me if I'm wrong ...

Kind regards
Eddy

David Kenny

Thanks for the reply Eddy,

It's my understanding that FF is subclassing the controls for us.  That is why we have the option to use "Function = %True", to let FF know we don't want further processing on that message to occur (actually FF passes the flag along to let Windows know we don't want further processing done).  I also believe there are many messages that wouldn't be available to us unless FF was subclassing the controls.  Of course, I could be wrong on any one of these beliefs.  :-\

Paul Squires

Hi guys, I haven't tested any of this (not at development computer) but whenever I want to have full control over incoming messages to a Form or Control, I intercept them in the FF_PUMPHOOK handler. There you get the raw, unprocessed, incoming message and you can do anything with it. It has always worked great for me.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

David Kenny

Will give that a try... I've seen you give that advice before (not to me thankfully), so I should have thought of it.  I'll let you know how it turns out.

David Kenny

Works perfectly!  Thanks Paul!

That does seem to indicate that there is some bug in the FF message handlers though.

Best regards,

David

Paul Squires

Hi David,

I had occassion to do a lot of work today with key handling in one of my programs so I decided to use the message handlers rather than the PumpHook. In order to catch all of the keystrokes you need to handle WM_KEYDOWN, WM_CHAR and also %WM_GETDLGCODE. Works perfectly for me.

Here is a template that you can use.


'--------------------------------------------------------------------------------
Function FORM1_TEXT1_CUSTOM ( _
                            ControlIndex  As Long,  _  ' index in Control Array
                            hWndForm      As Dword, _  ' handle of Form
                            hWndControl   As Dword, _  ' handle of Control
                            wMsg          As Long,  _  ' type of message
                            wParam        As Dword, _  ' first message parameter
                            lParam        As Long   _  ' second message parameter
                            ) As Long

   Select Case wMsg
   
      Case %WM_CHAR
         Function = -1:  Exit Function
         
         ' Prevent the message beeps when Enter or Escape are pressed
         'Select Case wParam
         '   Case %VK_RETURN, %VK_ESCAPE
         '      Function = -1
         '      Exit Function
         'End Select
         
      Case %WM_KEYDOWN                     
         Function = -1:  Exit Function

         'Select Case wParam
         '   Case %VK_RETURN
         '      ' do something here in response to the ENTER key
         '      Function = -1
         '   Case %VK_ESCAPE
         '      ' do something here in response to the ESCAPE key
         '      Function = -1
         '      Exit Function   
         'End Select

      Case %WM_GETDLGCODE
         ' MS system responds irregular to Enter key - better handle it ourselves
          Local pMsg As TAGMSG Ptr
          Local iMsg As Long

          pMsg = lParam
          If pMsg > 0 Then
             iMsg = @pMsg.Message
             If (iMsg = %WM_KEYDOWN) Or (iMsg = %WM_CHAR) Then 
                Function = %DLGC_WANTALLKEYS
                Exit Function
             End If
          End If

   End Select
   
End Function


Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

David Kenny

Well, I must admit that I didn't try the custom message handler.  ???  But that's only because there is a dedicated handler for WM_CHAR and WM_KEYDOWN. ::)  Are those supposed to be used some other way? It's strange because I could see the FF routine hat called that handler pass the return code along to whatever called it.  I didn't try to follow it further up.

I didn't know about WM_GETDLGCODE.  Thanks for the tip and the template!

Paul Squires

I guess I could have broke the code out into the separate WM_CHAR and WM_KEYDOWN handlers but I would still have to use WM_GETDLGCODE in the Custom handler.... so, I decided to put it all in one place for the sake of togetherness. :)
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

David Kenny

I see what's going on now!  I reread my first post.  It was written poorly and my message was not so clear. :-[

Look at the attached project.

Compile and run the project and observe the control behavior when typing.  Remove the comment on the line in the pump hook and retest as before.  Notice the different behavior.

Best regards,

David



Paul Squires

It is not as easy/clear as you might expect. You should read up on how Windows handles key processing. It can be confusing. In FireFly, if you intercept WM_KEYDOWN in the PumpHook then the message never makes it to the TanslateMessage function that is in FireFly's message loop.

If the message makes it to TranslateMessage then it will get dispatched to the Form/Control and will also generate a WM_CHAR message. At that point you need to deal with WM_CHAR (regular alphanumeric kind of characters) and WM_KEYDOWN (for arrow keys, function keys, Jome/End, PgUp, PgDn, etc)

These links may help to explain things better than me:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646268(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/ms646276(v=vs.85).aspx
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

...and I shouldn't be using the %VK_ codes in WM_CHAR. I should be testing for character codes (eg. ENTER = 13, ESCAPE = 27, etc).
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

David Kenny

But why would FF translate it before calling the Control's WM_KEYDOWN message handler.  Shouldn't it be calling it after that message handler returns so that it can skip the TranslateMessage call if the handler returns a %True?

It's OK if the answer is that it couldn't be done any other way.  :)


Paul Squires

Quote from: David Kenny on October 26, 2013, 10:50:29 PM
But why would FF translate it before calling the Control's WM_KEYDOWN message handler.  Shouldn't it be calling it after that message handler returns so that it can skip the TranslateMessage call if the handler returns a %True?
I guess that it could have been done that way but it sure would have resulted in one hell of a large message pump. I would have to add code to preprocess every message handler for every form and every control in the application. Whereas, now the design of FireFly allows the messages for the form/control to be processed in the individual specific forms/controls Window Procedures. It makes for better modular code with no loss of functionality.

I guess that I implied that it is TranslateMessage that sends the keystroke messages to the form/control but it is actually DispatchMessage that does that work. TranslateMessage and DispatchMessage are usually paired together in the message pump.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

David Kenny

QuoteI guess that it could have been done that way but it sure would have resulted in one hell of a large message pump.
I can accept that.  I had always been operating under the assumption that code could be plucked from a case structure in a regular PB program and inserted into the appropriate FF message handler (and you can some 99% of the time ;D) and it would work the same.  But it's good to know the conditions that dictate when it needs to be handled differently.

I withdraw my assertion that there must be some bug in FF's message pump as it's more a limitation that I was unaware of.

Thanks Paul!