January 16th, 2026
0 reactions

How can I get the tab index number from a dialog box control?

A customer wanted to retrieve the TabIndex of a dialog box control. They were able to get its class name and control ID, but couldn’t figure out how to get its tab index.

There is no tab index, at least not as a number.

The customer was probably confused because some UI frameworks provide a numeric TabIndex property on a control. For example, HTML elements have a tabindex attribute. XAML Control elements have a TabIndex property. However, Win32 dialogs do not.

Despite the absence of numeric tab indexes in Win32 dialogs, that doesn’t stop some dialog designers from providing a pretend one anyway. However. these tab index numbers are a fabrication of the designer tool and are not actually part of the dialog manager.

Imagine you had a set of pages you have to put in order. Each pages has a sticky note labeled “priority” with a number, and you arrange the pages so they are sorted, with the smallest numeric priority as the first page, and the one with the largest property as the last page. Before you staple the pages together, you remove all of the sticky notes. If you receive the document, how can you figure out the original priorities of each page?

You can’t, because the priorities were used to collate the pages but are not actually part of the final document.

In the Win32 dialog manager, the tab index is determined by the order in which the controls are z-ordered as children of the dialog. (Only controls with the WS_TAB­STOP style participate in tabbing in the first place.) So you can infer that the topmost child of the dialog had the lowest tab index, and the bottommost one had the highest tab index, but you don’t know what the actual tab index was.

And if the dialog wasn’t authored by a tool that uses tab indexes, then there is no tab index to recover at all. (Maybe the order of the pages in the document is determined by some other way, say, by the order in which they were submitted for collation.)

You can walk through the controls in order by tab order by using Get­Window() with GW_CHILD to get the topmost child, and then GW_HWND­NEXT to get subsequent children. Ignore any windows that do not have the WS_TAB­STOP style.

I’m not sure what problem the customer was trying to solve, where they thought that the tab index was the solution. Maybe they wanted to reverse-generate the dialog template from a live running dialog. Or maybe they were trying to get the information to fit a schema that came with a TabIndex property. In that case, they can just arbitrarily assign a TabIndex of 1 to the first tab stop child, and then increasing integers to subsequent ones.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

1 comment

Sort by :
  • Antonio Rodríguez 57 minutes ago

    Maybe they were adding controls to the dialog at run time, and wanted to make sure that they were in the right tab order. For example, if I add items at the end of a radio group, the new items should be focused right after the existing ones (and prior to, say, the command buttons that sit at the bottom of the dialog). If you need to modify an attribute, a good way to get started is trying to read it at runtime; and in the case of this example, you need to know the tab index of the last...

    Read more