Link to home
Start Free TrialLog in
Avatar of TropicalFish
TropicalFish

asked on

Tab with OnKeyDown

I have a form without any components on it in BCB4. I use the OnKeyDown event to respond to keyboard events. It works for all keys I need it for but the Tab key. How can I capture the Tab key using OnKeyDown?

Thanks
Avatar of AlexVirochovsky
AlexVirochovsky

Most of the time the tab key is handled by Windows and your program
doesn't see it. There are couple of ways to go about getting at the tab key,
both involve responding to Windows messages. Have a look at the links below:

http://www.temporaldoorway.com/programming/cbuilder/advancedissue/oddkeys.htm 
And
http://www.bcbdev.com/faqs/faq78.htm 

void OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags)
{
   if  (nChar == VK_TAB) //for the tab key
      //do your work

    //call the base class
     CWnd::OnKeyDown(nChar,nRepCnt,nFlags);
}
sniipet from http://www.bcbdev.com/faqs/faq78.htm 
...
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.
...
I hope, it helps. Alex

 
Avatar of TropicalFish

ASKER

Yes, I've read that before, but isn't that only for capturing tab in different components and not directly on a form? The note sais not to create a WM_GETDLGCODE handler for your form. This doesn't seem to work:

void __fastcall TForm::WMGetDlgCode(TMessage &Message)
{
   Message.Result = DLGC_WANTTAB;
}
ASKER CERTIFIED SOLUTION
Avatar of AlexVirochovsky
AlexVirochovsky

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Great, thanks!