How should I create controls on my dialog box that has a tab control?

Raymond Chen

The tab control from the shell common controls provides the tab selector control that is popular in tabbed dialogs. You’d be tempted to create the content of the tab control’s display area as children of the tab control, but that’s the wrong thing to do.

You should create them as siblings of the tab control.

What you want to do is create your tab control to cover the portion of the dialog box that you want to be tabbed. You then use the TCM_ADJUST­RECT message (or the equivalent TabCtrl_AdjustRect macro) to determine the display area of the tab control. Inside that display area, you can place your content, but do it with the dialog box as the parent, not the tab control.

  Dialog  
   
       
Tab control   Content 1   Content 2

Depending on which tab in the tab control is selected, you show exactly one of the content windows and hide the others.

If you think about how focus works in dialog boxes, you’ll realize that it has to be this way.

The tab control itself is focusable, and presumably you want to be able to put focus on your content, too. Now consider what happens if you create the content as children of the tab control:

  Dialog  
   
  Tab control  
   
           
  Content 1   Content 2  

By default, the tab order in a dialog box follows the dialog box’s immediate children. In this case, it means that the tab control can receive focus, but the content cannot, since they are not immediate children of the dialog box.

You can alter this behavior with the WS_EX_CONTROL­PARENT extended window style, which means “I’m just a container. My children are the things that can get focus, not me.” So let’s try that and put the WS_EX_CONTROL­PARENT extended window style on the tab control.

  Dialog  
   
  Tab control  
   
           
  Content 1   Content 2  

This time, the tab control drops out of the tab order, and its children, the content controls, join in.

With this window hierarchy, no amount of fiddling with the WS_EX_CONTROL­PARENT extended window style will allow the tab control and its children to all be part of the tab order. Because a window and its children cannot both be part of the tab order.

The only solution is to move the content controls out, so they aren’t children of the tab control. Making them siblings of the tab control, as they are in the original diagram, allows all three to participate in the tab order.

Bonus chatter: The content windows are typically nested dialogs which are marked with the WS_EX_CONTROL­PARENT extended window style. This permits the children of the nested dialogs to participate in the tab order, but keeping them inside a nested dialog lets you hide and show the controls in bulk by hiding and showing the nested dialog.