![]() |
![]() |
|||||
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
|
Q: Receive key events for the arrow keys or the TAB key.AnswerHave you ever tried to respond to the TAB key by writing an OnKeyPress handler for a control? You probably discovered that it doesn't work, at least not for most controls. The problem is that windows only sends keyboard events for the TAB key if the focused control specifically asks for them. The same holds true for the arrow keys. So how does the operating system know that the focused control wants to receive keyboard events for the TAB key? The OS sends the focused control a WM_GETDLGCODE message to ask the control what keys it wants to receive. The return value from this message determines what keystrokes will be sent to the control. The return value for WM_GETDLGCODE is a combination of these values:
To receive key events for the TAB key, the focused cotnrol must return DLGC_WANTTAB. To receive key events for the arrow keys, return DLGC_WANTARROWS. If you want to receive events for both the arrow keys and the TAB key, then bitwise OR DLGC_WANTARROWS with DLGC_WANTTAB and return that value. If you want to receive key events for all keys, then return DLGC_WANTALLKEYS. The VCL contains some good examples of how to use the WM_GETDLGCODE message. TToolBar responds to WM_GETDLGCODE so it can receive events for the arrow keys, and TCustomGrid uses WM_GETDLGCODE to request both the arrow keys and the TAB key. TMediaPlayer and TDBNavigator use WM_GETDLGCODE to request the arrow keys. Here are some code snippets from the VCL that demonstrate how they respond to the WM_GETDLGCODE message. I have converted code from pascal to C++ for readability. void __fastcall TToolBar::WMGetDlgCode(TMessage & Message) { // only want the arrow keys in some situations if(FInMenuLoop) Message.Result = DLGC_WANTARROWS; } void __fastcall TCustomGrid::WMGetDlgCode(TMessage & Message) { // always want the arrow keys Msg.Result := DLGC_WANTARROWS; ... // sometimes want the tab key if (Options.Contains(goTabs)) Msg.Result |= DLGC_WANTTAB; // sometimes want WM_CHAR messages if (Options.Contains(goEditing)) Msg.Result |= DLGC_WANTCHARS; } void __fastcall TMediaPlayer::WMGetDlgCode(TMessage &Message) { Message.Result = DLGC_WANTARROWS; } Note: Don't create a WM_GETDLGCODE handler for your form. You must write the WM_GETDLGCODE handler at the control level. Note: In VCL programs, the operating system is not actually the creator of the WM_GETDLGCODE message. The VCL synthesizes the message. Fortunately, this is an implementation detail that you can ignore. Simply write your WM_GETDLGCODE handler as if the OS was the creator of the message. | ||||||
All rights reserved. |