{"id":111991,"date":"2026-01-16T07:00:00","date_gmt":"2026-01-16T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=111991"},"modified":"2026-01-16T08:38:01","modified_gmt":"2026-01-16T16:38:01","slug":"20260116-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20260116-00\/?p=111991","title":{"rendered":"How can I get the tab index number from a dialog box control?"},"content":{"rendered":"<p>A customer wanted to retrieve the <code>TabIndex<\/code> of a dialog box control. They were able to <a href=\"https:\/\/learn.microsoft.com\/windows\/win32\/api\/winuser\/nf-winuser-getclassnamew\"> get its class name<\/a> and <a title=\"Why are timer IDs and dialog control IDs 64-bit values on 64-bit Windows? Did you really expect people to create more than 4 billion timers or dialog controls?\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20191010-00\/?p=102978\"> control ID<\/a>, but couldn&#8217;t figure out how to get its tab index.<\/p>\n<p>There is no tab index, at least not as a number.<\/p>\n<p>The customer was probably confused because some UI frameworks provide a numeric TabIndex property on a control. For example, HTML elements have a <code>tabindex<\/code> attribute. XAML Control elements have a <code>TabIndex<\/code> property. However, Win32 dialogs do not.<\/p>\n<p>Despite the absence of numeric tab indexes in Win32 dialogs, that doesn&#8217;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.<\/p>\n<p>Imagine you had a set of pages you have to put in order. Each pages has a sticky note labeled &#8220;priority&#8221; 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?<\/p>\n<p>You can&#8217;t, because the priorities were used to collate the pages but are not actually part of the final document.<\/p>\n<p>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 <code>WS_<wbr \/>TAB\u00adSTOP<\/code> 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&#8217;t know what the actual tab index was.<\/p>\n<p>And if the dialog wasn&#8217;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.)<\/p>\n<p>You can walk through the controls in order by tab order by using <code>Get\u00adWindow()<\/code> with <code>GW_CHILD<\/code> to get the topmost child, and then <code>GW_HWND\u00adNEXT<\/code> to get subsequent children. Ignore any windows that do not have the <code>WS_<wbr \/>TAB\u00adSTOP<\/code> style.<\/p>\n<p>I&#8217;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 <code>TabIndex<\/code> property. In that case, they can just arbitrarily assign a <code>TabIndex<\/code> of 1 to the first tab stop child, and then increasing integers to subsequent ones.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The tab index number is an authoring concept, not a runtime concept.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-111991","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The tab index number is an authoring concept, not a runtime concept.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/111991","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=111991"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/111991\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=111991"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=111991"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=111991"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}