{"id":1306,"date":"2011-10-30T21:55:52","date_gmt":"2011-10-30T19:55:52","guid":{"rendered":"https:\/\/alax.info\/blog\/?p=1306"},"modified":"2011-10-30T21:55:52","modified_gmt":"2011-10-30T19:55:52","slug":"common-controls-versions-compatibility-wtl","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/1306","title":{"rendered":"Common Controls: Versions, Compatibility, WTL"},"content":{"rendered":"<p>An application appears to be not working in Windows XP in a weird way: <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/bb774373%28v=vs.85%29.aspx\">rebar control<\/a> appeared to fail showing up.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1310\" title=\"Rebar Failed\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/10\/Image003.png\" alt=\"\" width=\"640\" height=\"238\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/10\/Image003.png 640w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/10\/Image003-320x119.png 320w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<p>Where the application is expected to look much nicer with rebar control as a container for menu (implemented as command bar WTL control) and toolbar with buttons:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1309\" title=\"Rebar Succeeded\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/10\/Image0022.png\" alt=\"\" width=\"640\" height=\"238\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/10\/Image0022.png 640w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/10\/Image0022-320x119.png 320w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<p>A WTL sample project generated by a Visual Studio wizard would never give such effect, and the bug was a combination of factors:<\/p>\n<ol>\n<li>An application built with a newer version of Windows SDK, which includes support for features (Windows Vista+ Common Controls) that are more recent than production environment (Windows XP); the application targets to Windows Vista+ environment too (<em>_WIN32_WINNT<\/em> &gt;= <em>0x0600<\/em>)<\/li>\n<li>Compatibility issues of Common Controls library<\/li>\n<li>WTL version (7.5), which did not yet include a workaround for the problem<\/li>\n<\/ol>\n<p>The problem, which caused the bug directly was the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/bb774393%28v=vs.85%29.aspx\">REBARBANDINFO structure<\/a> and its use as an argument with Common Controls API. As MSDN shows, the structure was amended twice with additional fields.<\/p>\n<p>One of the way to support multiple versions of the structure definition, and to resolve compatibility issues, is to embed structure size into structure payload. In fact, <em>REBARBANDINFO::cbSize<\/em> member is there exactly for this reason.<\/p>\n<p>The application is normally filling <em>cbSize<\/em> with the maximal known structure size and fills the rest of the fields respectively. The API is expected to be checking <em>cbSize<\/em> member and be detecting API version compatibility scenarios:<\/p>\n<ol>\n<li><em>cbSize<\/em> holds exactly the value the API expects (that is, the maximal value known\/defined to the API) &#8211; the simplest scenario where the API and the application are on the same page, both are using the same versions of the &#8220;protocol&#8221;\/interface.<\/li>\n<li><em>cbSize<\/em> is smaller than API can support &#8211; the API sees that it is dealing with a sort of legacy application which cannot utilize all available features, and the API acts respectively supporting the older part of the protocol, and keeping defaults or &#8220;old look&#8221; for the rest of implementation. This addresses backward compatibility: the newer API works with apps designed for older version of the API<\/li>\n<li><em>cbSize<\/em> is greater then API can support &#8211; the API sees that the application is already aware of newer version API and is possibly requesting some of the missing features. The API might be ignoring the unsupported part in assumption that API evolution tool place keeping some compatibility in mind, and still do the best it can with the existing implementation. Or, the API might just fail to work.<\/li>\n<\/ol>\n<p>The latter item #3 is the scenario here with rebar control. The application is using Windows Vista version of <em>REBARBANDINFO<\/em> structure and Windows XP implementation choses to completely fail.<\/p>\n<p>While it does not seem to be directly a bug, this attitude is definitely not developer friendly: there is no reason for the control to not work in its best and default way. Having API acting this way, each developer using the API needs to take care of the situation explicitly: whenever Windows Vista enabled application needs to be able to run in Windows XP system, the code around\u00c2\u00a0<em>REBARBANDINFO<\/em> would look like this:<\/p>\n<pre style=\"color: #000000; background: #ffffff;\">REBARBANDINFO BandInformation <span style=\"color: #808030;\">=<\/span> <span style=\"color: #800080;\">{<\/span> <span style=\"color: #800000; font-weight: bold;\">sizeof<\/span> BandInformation<span style=\"color: #808030;\">,<\/span> RBBIM_LPARAM <span style=\"color: #800080;\">}<\/span><span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #004a43;\">#<\/span><span style=\"color: #004a43;\">if<\/span><span style=\"color: #004a43;\"> _WIN32_WINNT <\/span><span style=\"color: #808030;\">&gt;<\/span><span style=\"color: #808030;\">=<\/span><span style=\"color: #004a43;\"> 0x0600<\/span>\r\n<span style=\"color: #800000; font-weight: bold;\">if<\/span><span style=\"color: #808030;\">(<\/span>GetOsVersion<span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">)<\/span> <span style=\"color: #808030;\">&lt;<\/span> <span style=\"color: #008000;\">0x00060000<\/span> <span style=\"color: #808030;\">|<\/span><span style=\"color: #808030;\">|<\/span> GetCommCtrlVersion<span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">)<\/span> <span style=\"color: #808030;\">&lt;<\/span> <span style=\"color: #008000;\">0x00060000<\/span><span style=\"color: #808030;\">)<\/span> <span style=\"color: #696969;\">\/\/ pre-Vista, Common Controls pre-6.0<\/span>\r\n    BandInformation<span style=\"color: #808030;\">.<\/span>cbSize <span style=\"color: #808030;\">=<\/span> REBARBANDINFO_V6_SIZE<span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #004a43;\">#<\/span><span style=\"color: #004a43;\">endif<\/span><span style=\"color: #696969;\">\/\/ _WIN32_WINNT &gt;= 0x0600<\/span>\r\n<span style=\"color: #800000; font-weight: bold;\">const<\/span> <span style=\"color: #603000;\">BOOL<\/span> bGetBandInfoResult <span style=\"color: #808030;\">=<\/span> Rebar<span style=\"color: #808030;\">.<\/span>GetBandInfo<span style=\"color: #808030;\">(<\/span><span style=\"color: #008c00;\">0<\/span><span style=\"color: #808030;\">,<\/span> <span style=\"color: #808030;\">&amp;<\/span>BandInformation<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span><\/pre>\n<p>If the API was nicer to developers, the code would be plain and simple:<\/p>\n<pre style=\"color: #000000; background: #ffffff;\">REBARBANDINFO BandInformation <span style=\"color: #808030;\">=<\/span> <span style=\"color: #800080;\">{<\/span> <span style=\"color: #800000; font-weight: bold;\">sizeof<\/span> BandInformation<span style=\"color: #808030;\">,<\/span> RBBIM_LPARAM <span style=\"color: #800080;\">}<\/span><span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #800000; font-weight: bold;\">const<\/span> <span style=\"color: #603000;\">BOOL<\/span> bGetBandInfoResult <span style=\"color: #808030;\">=<\/span> Rebar<span style=\"color: #808030;\">.<\/span>GetBandInfo<span style=\"color: #808030;\">(<\/span><span style=\"color: #008c00;\">0<\/span><span style=\"color: #808030;\">,<\/span> <span style=\"color: #808030;\">&amp;<\/span>BandInformation<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span><\/pre>\n<p>To address this problem, <a href=\"http:\/\/wtl.sourceforge.net\/\">WTL<\/a> 8.0 comes up with <em>RunTimeHelper<\/em> namespace and its <em>SizeOf_REBARBANDINFO<\/em> function. It takes care of details for the developer choosing the proper size of the structure on runtime. The code is being taken back to a simpler shape:<\/p>\n<pre style=\"color: #000000; background: #ffffff;\">REBARBANDINFO BandInformation <span style=\"color: #808030;\">=<\/span> <span style=\"color: #800080;\">{<\/span> RunTimeHelper<span style=\"color: #800080;\">::<\/span>SizeOf_REBARBANDINFO<span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #808030;\">,<\/span> RBBIM_LPARAM <span style=\"color: #800080;\">}<\/span><span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #800000; font-weight: bold;\">const<\/span> <span style=\"color: #603000;\">BOOL<\/span> bGetBandInfoResult <span style=\"color: #808030;\">=<\/span> Rebar<span style=\"color: #808030;\">.<\/span>GetBandInfo<span style=\"color: #808030;\">(<\/span><span style=\"color: #008c00;\">0<\/span><span style=\"color: #808030;\">,<\/span> <span style=\"color: #808030;\">&amp;<\/span>BandInformation<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span><\/pre>\n<p>All in all:<\/p>\n<ul>\n<li>be aware of compatibility issues (same scenario exists with other SDK structures: <em>LVGROUP<\/em>, <em>LVTILEINFO<\/em>, <em>MCHITTESTINFO<\/em>, <em>NONCLIENTMETRICS<\/em> and other).<\/li>\n<li>use latest version of WTL to have things worked around for you where Microsoft developers were not kid enough to provide perfect API<\/li>\n<li>be aware and take advantage of WTL&#8217;s <em>RunTimeHelper<\/em> class<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>An application appears to be not working in Windows XP in a weird way: rebar control appeared to fail showing up. Where the application is expected to look much nicer with rebar control as a container for menu (implemented as command bar WTL control) and toolbar with buttons: A WTL sample project generated by a&hellip; <\/p>\n<p><a class=\"moretag\" href=\"https:\/\/alax.info\/blog\/1306\">Read the full article<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[63,38,356,150,489],"class_list":["post-1306","post","type-post","status-publish","format-standard","hentry","category-wtl","tag-bug","tag-c","tag-compatibility","tag-windows","tag-wtl"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1306","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/comments?post=1306"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1306\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=1306"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=1306"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=1306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}