{"id":23663,"date":"2008-01-29T07:00:00","date_gmt":"2008-01-29T15:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2008\/01\/29\/the-history-of-the-windows-xp-common-controls\/"},"modified":"2008-01-29T07:00:00","modified_gmt":"2008-01-29T15:00:00","slug":"the-history-of-the-windows-xp-common-controls","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20080129-00\/?p=23663","title":{"rendered":"The history of the Windows XP common controls"},"content":{"rendered":"<p>\nIn the beginning, there was one control library,\nnamely <code>USER<\/code>,\nthe window manager itself,\nwhich provided buttons, static controls, edit controls,\nscroll bars, list boxes, and combo boxes.\nThese controls were under the purview of the window manager team.\n<\/p>\n<p>\nIn Windows&nbsp;3.1\na second control library known as the shell common controls was added,\nbut the library really didn&#8217;t come into it own until Windows&nbsp;95,\nwhere it consisted\nof the list view, header, tree view, tooltip,\ntoolbar, status bar, track bar, tab, updown, progress, hotkey,\nand animation controls.\nThese controls were originally custom controls\nwritten by the shell team for use in Explorer,\nbut since they seemed to be generally useful,\ntime was budgeted to do the\nextra work to make the controls more suitable for general use,\ntesting the controls in combinations and scenarios\nthat Explorer itself didn&#8217;t use,\nand putting together formal documentation.\n<\/p>\n<p>\nThe shell common controls library underwent many changes over\nthe years, whereas the core intrinsic controls in the window manager\nchanged much more conservatively.\n<\/p>\n<p>\nWith Windows&nbsp;XP, the visual design team wanted to give the\nlook of Windows a new life.\nChanging the non-client area (such as the window frame) was comparatively\nstraightforward, since programs didn&#8217;t have much\ncontrol over that part of the window anyway.\nAs a result, they get the Windows&nbsp;XP look &#8220;for free&#8221;.\n<\/p>\n<p>\nThe client area is another story.\nPrograms are in control of their client area,\nwhere they can place controls that come with Windows,\ntheir own custom controls,\nor controls obtained from a third party library.\nMaking major changes to the core controls or the common controls\nwould be a high-risk endeavor\nsince there are thousands upon thousands of Windows program that\nnot only use them,\nbut use them in all sorts of crazy ways.\n<\/p>\n<p>\nThe initial stab at resolving these two conflicting goals\n(making major changes to these controls to increase visual appeal\nand functionality\nwhile simultaneously not changing them to maintain compatibility)\nwas to create a new DLL that would contain the &#8220;fancy new version&#8221;\nof the core controls as well as the shell common controls.\nThe old DLLs <code>USER32<\/code> and <code>COMCTL32<\/code> stayed\nwhere they were, so that old programs continued to get the behavior\nthey were expecting,\nand the new XP-style controls were placed in a DLL named\n<code>UXCTRL.DLL<\/code>.\nUX stands for <i>user experience<\/i>,\nwhich was the hot new buzzword at the time.\nTo avoid name collision with the old style controls,\nthe new controls got new names beginning with Ux.\nFor example, the <code>UXCTRL<\/code> version of the button control\nwas called UxButton.\n<\/p>\n<p>\nNew features could be added to these new Ux controls with wild abandon\nwithout heed for backward compatibility since they were brand new controls.\nThere was nothing they had to be compatible with.\nExplorer was changed to use these new controls instead of the old stodgy\ncontrols,\nand everything worked great.\n<\/p>\n<p>\nOr so it seemed.\n<\/p>\n<p>\nWe thought we had cleverly sidestepped the backward compatibility problem\nby creating entirely new controls,\nbut doing that created <i>a whole new category<\/i> of compatibility bugs.\nEven though it&#8217;s completely undocumented and unsupported,\nprograms like to\ngrovel into the internal data structures of other programs\nor otherwise\nmanipulate those programs&#8217; windows.\nIn Explorer&#8217;s case, it turns out that a lot of programs like to\ngo spelunking around Explorer&#8217;s window hierarchy and use functions\nlike <code>FindWindow<\/code> and\n<code>EnumChildWindows<\/code>\nto find the object of their affections.\nFor example, a program might use <code>EnumChildWindows<\/code> to\nenumerate all the child windows of an Explorer browser,\nand then use <code>GetClassName<\/code>\nand <code>lstrcmpi(szClassName, TEXT(\"button\"))<\/code>\nto look for a specific control.\nIn this example, the target was a button,\nbut it could have been a list view or a tool bar.\nSince all the new XP-style controls were named\nthings like UxButton and UxListView,\nthese programs which looked for a button by comparing against\nthe string <code>\"button\"<\/code> stopped working.\n<\/p>\n<p>\nOf course, there was no guarantee that Explorer would even use\nbuttons at all;\nExplorer was completely within its rights to revamp its user interface.\nBut that&#8217;s not much consolation to the customers who paid good money\nfor these programs,\nespecially since magazine columnists are the types of people most\nlikely to be running (or indeed even writing!)\n<a HREF=\"http:\/\/www.pcmag.com\/article2\/0,2704,1159395,00.asp\">\nstrange off-the-wall programs that pull these\nsorts of nasty stunts in the first place<\/a>.\n<\/p>\n<p>\nOkay, so it is now a compatibility requirement that all the new window\nclasses have the same names as their old counterparts.\nThis created an impasse, since these controls needed to be created\nby dialog boxes, and therefore they had to be globally-registered\nwindow classes.\nBut you can&#8217;t have two global window classes with the same name,\nbecause that would create ambiguity over which one the caller was\nasking for.\n<\/p>\n<p>\nMore brainstorming ensued, and a Plan&nbsp;C emerged.\nThe common controls library would take advantage of\n<a HREF=\"http:\/\/msdn2.microsoft.com\/en-gb\/library\/aa375193.aspx\">\nside-by-side assemblies<\/a>\nand use the application manifest to control which\nDLL a given window class name would resolve to.\nThus was born a new DLL also called <code>COMCTL32<\/code>,\nbut with a new version number&mdash;version&nbsp;6.\nOld programs would get version&nbsp;5.82 just like they did\nin Windows&nbsp;2000.\nNew programs would have to use a manifest to specify that they wanted\nversion&nbsp;6.\n<\/p>\n<p>\nOnce again, the solution came with a new problem.\nSince the entire <code>COMCTL32<\/code> library got split\ninto two versions,\nthis meant that there were two versions of the image list code.\nWhole new scenarios emerged, such as\n<a HREF=\"http:\/\/forums.microsoft.com\/MSDN\/ShowPost.aspx?PostID=965968\">\nputting a version&nbsp;5 image list in a\nversion&nbsp;6 tree view<\/a>, or vice versa.\n(As the linked thread notes illustrates, not all of the problems with\ncross-version scenarios were caught in the initial release and had\nto wait for a service pack for the fix to become available.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Stepping forward while looking back.<\/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":[2],"class_list":["post-23663","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>Stepping forward while looking back.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/23663","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=23663"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/23663\/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=23663"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=23663"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=23663"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}