Board index » delphi » How to keep focus on a form to catch PgUp en PgDn keys

How to keep focus on a form to catch PgUp en PgDn keys

I am using Delphi 5 Enterprise

I do have a form with on it several buttons.
I do have a OnKeyDown event attached to the form.
When one of the buttons is activated I lose focus on the main form, so I
don't get anny PgDn or PgUp key events.
Is ther somewhere a property on the buttons or on the form so that I can
alway
catch OnKeyDown events ???

Rien Mulder

 

Re:How to keep focus on a form to catch PgUp en PgDn keys


Quote
Rien Mulder <m_mul...@dds.nl> wrote in message

news:3e5684f9@newsgroups.borland.com...
...

Quote
> I do have a OnKeyDown event attached to the form.
> When one of the buttons is activated I lose focus on
> the main form, so I don't get anny PgDn or PgUp key
> events.
> Is ther somewhere a property on the buttons or on the
> form so that I can alway catch OnKeyDown events ???

Set the form's KeyPreview property to True.  The form gets first crack at
any keys pressed.  Any keys that the form acts upon should be set to 0
afterwards (Key := 0) unless you want the focused control to act upon it as
well.

--
Ray Marron

Re:How to keep focus on a form to catch PgUp en PgDn keys


Quote
In article <3e568...@newsgroups.borland.com>, Rien Mulder wrote:
> I do have a form with on it several buttons.
> I do have a OnKeyDown event attached to the form.
> When one of the buttons is activated I lose focus on the main form, so I
> don't get anny PgDn or PgUp key events.

You have to understand how this key preview feature works. It only sees
keys the active control *wants* to see, and a button does not indicate any
interest in navigation keys. Try the OnShortcut event of the form, it
should see every key that comes along, since it is fired before the active
control is even asked whether it wants to see the key or not.

Here is an older post of mine that details the key processing going on in
a Delphi app. It's a bit hard to find in the newsgroup archives, so i'll
repost it:

<quote>
The control with focus will not receive all keys. The Windows/VCL key
handling mechanism works like this:

 1. you press a key.
 2. a WM_KEYDOWN or WM_SYSKEYDOWN message is put into the applications
    message queue.
 3. the message loop code retrieves the message and, after some checks
    for special treatments (e.g. for MDI) hands it to a VCL function.
 4. The function converts the message to a CN_KEYDOWN message and sends it
    to the control with focus.
 5. The handler for this message in TWinControl first checks if the key
    is a keyboard shortcut for a menu item on the controls popup menu (if
    any), if not it checks all the popup menus of the controls parent
    controls and finally the forms main menu (if any). During this process
    the forms IsShortcut method is called and fires the OnShortcut event.
    IsShortcut also asks all actionlists on the form if one of their
actions
    wants to handle the shortcut. IsShortcut and the OnShortcut event
    constitute the first chance to intercept the key at the form level.
 6. If it is not a menu shortcut the key event is next send as a
CM_CHILDKEY
    message to the control. The handler for this message in TWinControl
does
    nothing more than sending it to the controls parent. It will thus work
    its way up the parent chain until it finally reaches the form. This
    constitutes the second chance to trap the key event at the form level.
 7. If the CM_CHILDKEY message is not handled by any receiver (none sets
    msg.result to 1) the code in TWincontrol.CNKeyDown then asks the
control
    whether it wants to handle the key event. However, it does this only
if
    the key is one of the following: VK_TAB, VK_LEFT, VK_RIGHT, VK_UP,
    VK_DOWN, VK_RETURN, VK_EXECUTE, VK_ESCAPE, VK_CANCEL, all other keys
    will be delivered to the control without further checks.
    CNKeyDown sends two messages to the control for these keys:
 7a.CM_WANTSPECIALKEY    
 7b.WM_GETDLGCODE (which is the message Windows standard controls expect
    and handle).
 8. If the control does not express an interest in the key (Tedit controls
    do not want VK_TAB, for instance) a CM_DIALOGKEY message is send to
the
    form for these special keys. The default handler for this message in
    TCustomForm handles the navigation between controls in response to the
    key events and marks the message as handled. This message is the third
    opportunity to trap these keys on the form level. The default handler
    broadcasts the message to all TWinControls on the form, this is the
    way default and cancel buttons get aware of return and Escape key
    events even if they do not have the focus.
 9. If the key message is still not marked as handled (msg.result is still
0)
    the code path returns to the message loop and the message is finally
    handed to the API functions TranslateMessage (which generates a
WM_CHAR
    message if the key produces a character) and DispatchMessage (which
sends
    the key message to the controls window proc).
10. The controls handler for WM_KEYDOWN receives the message. The handler
in
    TWinControl calls the DOKeyDown method, passing the message
parameters.
11. DoKeyDown checks if the parent forms KeyPreview property is true, if
so
    it directly calls the DoKeyDown method of the form, which fires the
forms
    OnKeyDown event. If the Key is set to 0 there, no further processing
is
    performed.
12. DoKeyDown calls KeyDown (which is virtual and can thus be overriden),
    TWinControl.KeyDown fires the controls OnKeyDown event. Again, if Key
is
    set to 0 there, no further processing is done on it.
13. Code flow returns to TWinControl.WMKeyDown, which calls the inherited
    handler. The key event finally gets to the default window function
    this way and may cause a visible action in the control.

As you can see the path of a key message is quite complicated. If you
press the tab key in an edit control the message will get up to step 8 and
then be processed on the form level as CM_DIALOGKEY, it is marked as
handled there, so all the steps further down are not executed and the
control never sees the WM_KEYDOWN message for it, so its OnKeyDown handler
never fires for a Tab.

The process offers the following points of intervention on the form level:

a) Application.OnMessage
 This event is fired directly after the message has been retrieved from
 the message queue in step 3, before anything further is done for it.
 The event sees all messages that go through the message loop, not only
 key messages.
b) The forms OnShortcut event.
c) CM_CHILDKEY
 If you add a handler for this message to the form it will see all key
 events with the exeption of menu shortcuts. Such a handler would see
 all tab key events, but also many others.
d) CM_DIALOGKEY
 If you add a handler for this message it will see all the keys mentioned
 in step 7, unless the control wants to handle them itself. This handler
 would see VK_TAB if the active control is not a TMemo with WantTabs =
 True or a TRichedit or grid control, for instance. I think for your
 purpose handling CM_DIALOGKEY would be the correct choice. Do not forget
 to call the inherited handler or form navigation will cease to work.

</quote>

--
Peter Below (TeamB)  
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be

Other Threads