Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

keyPreview and char capture

59 views
Skip to first unread message

Jerry Blumenthal

unread,
May 9, 2001, 12:56:45 AM5/9/01
to
1. Where do I find docs about vk_Next etc.?

2. How do I capture the Enter key? I've tried, in a FormKeyDown procedure
to use code like:

case key of
13 : ................
vk_home------
vk_up................

etc.

All the vk keys work, but not #13

Jerry Blumenthal


Antonio

unread,
May 9, 2001, 6:42:00 AM5/9/01
to
Jerry
Yu have to set KeyPreview to True in the Object Inspector.
VK_RETURN is the Enter Key.

rgs,
Antonio

"Jerry Blumenthal" <je...@blumenthalsoftware.com> escribió en el mensaje
news:3af8a349$1_1@dnews...

Peter Below (TeamB)

unread,
May 9, 2001, 3:13:38 PM5/9/01
to
In article <3af8a349$1_1@dnews>, Jerry Blumenthal wrote:
> 1. Where do I find docs about vk_Next etc.?

The D5 online help has a topic under "virtual key codes" in the index. For
older versions you can find a similar topic in the windows API helpfile.

> 2. How do I capture the Enter key? I've tried, in a FormKeyDown procedure
> to use code like:
>
> case key of
> 13 : ................
> vk_home------
> vk_up................
>
> etc.
>
> All the vk keys work, but not #13

Time for the Ol' sermon again <g>. The section below was written in response
to a question on how to handle the Tab key, but the principle is the same
for Enter.

The forms "preview" key handlers only see the keys the control with focus
also sees. But 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.
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 first 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 second
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, which is fired as part of the shortcut
processing.
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.


Peter Below (TeamB) 10011...@compuserve.com)
No e-mail responses, please, unless explicitly requested!
Note: I'm unable to visit the newsgroups every day at the moment,
so be patient if you don't get a reply immediately.

Jerry Blumenthal

unread,
May 10, 2001, 1:28:11 AM5/10/01
to
It's embarrasing. I suppose I should be able to use what you wrote, but I
dont know how to fit it into an actual program, into an actual form or vcl
event handler. Can you go the extra step and tell me what to DO?

Jerry (using D4)


"Peter Below (TeamB)" <10011...@compuXXserve.com> wrote in message
news:VA.00006fb...@antispam.compuserve.com...

Peter Below (TeamB)

unread,
May 10, 2001, 2:24:22 PM5/10/01
to
In article <3af9fc3b_1@dnews>, Jerry Blumenthal wrote:
> It's embarrasing. I suppose I should be able to use what you wrote, but I
> dont know how to fit it into an actual program, into an actual form or vcl
> event handler. Can you go the extra step and tell me what to DO?

Well, you start by stopping the full quoting of the message you reply to <g>.
See http://www.borland.com/newsgroups/ for the forum guidelines.


// form declaration, private section
Procedure CMDialogKey(Var Msg: TWMKey); message CM_DIALOGKEY;

Procedure TForm1.CMDialogKey(Var Msg: TWMKEY);
Begin
If not (ActiveControl Is TButton) Then
If Msg.Charcode = VK_RETURN Then
Msg.Charcode := VK_TAB;
inherited;
End;

That would effectively turn the enter key into Tab so you could navigate to
the next control in sequence by hitting Enter.

Jerry Blumenthal

unread,
May 14, 2001, 3:21:24 PM5/14/01
to
> 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.

Can you tell me how to do this? "handling CM_DIALOGKey would be the
correct choice"

What kind of code should I put into what event handler?

Jerry Blumenthal


Peter Below (TeamB)

unread,
May 14, 2001, 5:34:09 PM5/14/01
to
In article <3b000566_1@dnews>, Jerry Blumenthal wrote:
>
> Can you tell me how to do this? "handling CM_DIALOGKey would be the
> correct choice"
> What kind of code should I put into what event handler?

I gave an example in my reply to your last post in this thread.

0 new messages