Why doesn't the TAB key work on controls I've marked as WS_TABSTOP?

Raymond Chen

Raymond

A customer had a programming problem regarding tab stops:

I create a parent window (child of main frame) as below

// Create the popup window that holds the toolbar.
if (!CreateEx(
        WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT | WS_EX_LAYERED,
        _T("ToolbarPopupWindow"),
        _T(""),
        WS_POPUP | WS_CLIPSIBLINGS,
        0, 0, 0, 0,
        pParentWnd->GetSafeHwnd(),
        NULL))

This window hosts 2 toolbar windows.
Each toolbar window
has the WS_TABSTOP style set using
SetWindowLong.

// Set tab stop for accessibility
DWORD dwStyles = ::GetWindowLong(GetSafeHwnd(), GWL_STYLE);
::SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyles | WS_TABSTOP);

MSDN states

WS_EX_CONTROLPARENT
Allows the user to navigate among the child windows of the window
by using the TAB key.

But I am not able to use TAB to navigate to second toolbar.
I tried handling WM_GETDLGCODE and return
DLGC_WANTTAB. But this message is not sent to parent.

I can try subclassing the toolbar to handle TAB key, but if
I do that, then what’s the point of the WS_TABSTOP
and WS_EX_CONTROLPARENT styles?

You already know how to solve this customer’s problem.
The quoted documentation comes

from the MFC documentation on extended window styles
.
You may find that

the documentation in the Platform SDK to be a bit better
.
Which is not unexpected,
since extended window styles are a Platform SDK
feature; MFC is merely surfacing the underlying Win32 functionality
in its own framework.

Final clue:
Look at

this old blog entry
,
but come to it with a different point of view.

I used my psychic powers to solve this one.
A close reading of the description of the problem reveals
that the window in question is not part of a dialog box,
which means that the standard dialog message loop is not active.
Which means that a crucial step is missing.

Did you remember to
call IsDialogMessage in your message loop?

The customer confirmed that this was the missing step.

You are right, my window is not a dialog box.
Handling IsDialogMessage solved the issue.

Raymond Chen
Raymond Chen

Follow Raymond