{"id":555,"date":"2019-01-16T21:43:05","date_gmt":"2019-01-16T08:43:05","guid":{"rendered":"http:\/\/www.paradicesoftware.com\/blog\/?p=555"},"modified":"2025-01-01T19:01:57","modified_gmt":"2025-01-01T06:01:57","slug":"obtaining-the-users-windows-10-accent-colour-in-freepascal","status":"publish","type":"post","link":"http:\/\/www.paradicesoftware.com\/blog\/2019\/01\/obtaining-the-users-windows-10-accent-colour-in-freepascal\/","title":{"rendered":"Obtaining the user&#8217;s Windows 10 Accent colour in FreePascal"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">I&#8217;m currently designing a minimalistic user interface in FPC (Freepascal), and I wanted it to blend in with the existing Windows desktop. So naturally, I started looking for how to obtain the user&#8217;s chosen accent color (I&#8217;m deliberately alternating American and British spelling of colour\/color to help anyone that needs this to be able to google it successfully!) <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Knowing Microsoft, I knew obtaining this probably wasn&#8217;t going to be as easy as back in the old Win32 days, where there was a simple API<strong> <\/strong>like <em>GetSysColor(COLOR_ACTIVECAPTION)<\/em>,&nbsp;but&nbsp;I still had hopes that it wasn&#8217;t going to be too difficult. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As is often the case, the best reference I could find on how to do this was in <a href=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20170405-00\/?p=95905\">Raymond Chen&#8217;s blog.<\/a> Helpfully, he even demonstrates how to obtain this value in &#8220;raw C++&#8221;, which is the closest equivalent we can expect to doing so in FPC. Here&#8217;s the sample:<\/p>\n\n\n\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nnamespace abi_vm = ABI::Windows::UI::ViewManagement;\nnamespace wrl = Microsoft::WRL;\nnamespace wf = Windows::Foundation;\n\nvoid GetAccentColor()\n{\n    wrl::ComPtr&amp;lt;abi_vm::IUISettings&amp;gt; settings;\n    wf::ActivateInstance(wrl::Wrappers::HStringReference(\n     RuntimeClass_Windows_UI_ViewManagement_UISettings).Get(), &amp;amp;settings);\n    ABI::Windows::UI::Color color;\n    settings-&amp;gt;GetColorValue(abi_vm::UIColorType::Accent, &amp;amp;color);\n}\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">OK; it looks manageable, except in FPC, we don&#8217;t have access to any of those <em>namespace<\/em> compiler definitions. Which are leveraged for everything. So this isn&#8217;t going to be straightforward. Someone else must have solved this problem though, right? If not for FPC, then for Delphi? After an hour of Googling&#8230; no, I don&#8217;t think the source code exists for this in Pascal anywhere on the internet.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Breaking it down<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s look at what this code actually does, then we can hopefully rewrite it in FPC, step-by-step:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Define a COM interface to <em>UISettings<\/em><\/li><li>Figure out what that <em>HStringReference<\/em> wrapper does<\/li><li>Call a function called <em>ActivateInstance()<\/em><\/li><li>Call <em>UISettings.GetColorValue()<\/em> to obtain colour<\/li><li>Tidying up<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Allright. I&#8217;ve used COM before. So let&#8217;s get started! I&#8217;ll go into a lot of detail, because there&#8217;s a good chance there&#8217;s someone out there that wants to take this code and port it to yet another language that has no code sample! For those that just want the results, download the source code at the end.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Define a COM interface to UISettings<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">First problem with this: I don&#8217;t know what the <em>UISettings<\/em> interface looks like, and I&#8217;m going to need to write a complete definition of the interface (as well as the GUID) in order to use it correctly. There&#8217;s no real way to &#8216;discover&#8217; this, either. You just have to search for an existing definition in any language, and translate it. Fortunately, there&#8217;s a handy definition available on <a href=\"https:\/\/github.com\/tpn\/winsdk-10\/blob\/master\/Include\/10.0.16299.0\/winrt\/windows.ui.viewmanagement.idl\">Github<\/a>. From there, it was relatively straightforward to translate it into the Pascal dialect. But first! <em>IUISettings<\/em> derives from <em>IInspectable<\/em>, which seems to be common to all of the WinRT APIs. So we have to translate that first:<\/p>\n\n\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\ntype\n   IInspectable = interface (IUnknown)\n   &#x5B;&amp;#039;{AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90}&amp;#039;]\n      function GetIIDs (out iidCount: Cardinal; out IIDs: PGUID): HRESULT; stdcall;\n      function GetRuntimeClassName (out ClassName: HSTRING): HRESULT; stdcall;\n      function GetTrustLevel (out Trust: TrustLevel): HRESULT; stdcall;\n   end;\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And you can see from there, we also need definitions for HSTRING, and for an enum called TrustLevel (while we&#8217;re here, I&#8217;ll add other types we need later too):<\/p>\n\n\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\ntype\n   HSTRING    = type THandle;\n   TrustLevel = (BaseTrust, PartialTrust, FullTrust);\n   PCNZWCH    = PWideChar;\n   RO_INIT_TYPE = (RO_INIT_SINGLETHREADED, RO_INIT_MULTITHREADED);\t\n   TUIColorType = (Background=0,Foreground=1,AccentDark3=2,AccentDark2=3,AccentDark1=4,Accent=5,AccentLight1=6,AccentLight2=7,AccentLight3=8,Complement=9,Force_Dword=$7fffffff);\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here, for the first time, I actually got lucky. The <em>IUISettings<\/em> interface contains a whole bunch of functions and new types (you can see them <a href=\"https:\/\/github.com\/tpn\/winsdk-10\/blob\/master\/Include\/10.0.16299.0\/winrt\/windows.ui.viewmanagement.idl\">here&nbsp;on&nbsp;Github<\/a>, starting at line 699), and normally to define the interface you need to translate all of them. However, Microsoft added extra functionality in newer versions of the interface, <em>IUISettings2<\/em>,<em> IUISettings3 <\/em>and <em>IUISettings4<\/em>, and it so happens that the only function we need <em>GetColorValue<\/em>, is in IUISettings3 &#8211; and it&#8217;s the only function in that interface! This makes translation trivial, and we now have all the definitions we need.<\/p>\n\n\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\ntype\n   IUISettings3 = interface (IInspectable)\n      &#x5B;&amp;#039;{03021BE4-5254-4781-8194-5168F7D06D7B}&amp;#039;]\n      function GetColorValue (desiredColor: TUIColorType; out Value: UINT32): HRESULT; stdcall;\n   end;\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"mce_40\">2. Figure out what that HStringReference wrapper does<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Well, obviously it&#8217;s a wrapper for an HSTRING. What&#8217;s an HSTRING? It&#8217;s how the Windows Runtime manages strings (because there weren&#8217;t enough string types already). For FPC&#8217;s purposes, they&#8217;re equivalent to Handles. The function we need to call in step 3, <em>ActivateInstance()<\/em>, takes an HSTRING as it&#8217;s first parameter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It turns out we can manipulate HSTRINGs using the <em>WindowsCreateString()<\/em> and <em>WindowsDeleteString()<\/em> functions in the Windows Runtime. Of course, FPC has no idea about HSTRINGs or about the Windows Runtime in general. Additionally, we don&#8217;t want to make our program dependent on the Windows Runtime (Windows 8+) unnecessarily &#8211; not being able to acquire the user&#8217;s accent color is a really poor reason to prevent an application from executing on earlier Windows versions. So we need to use dynamic linking. The key code you need to dynamically link against the Windows Runtime (for our purposes) is as follows:<\/p>\n\n\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\nconst\n   WINRTSTRING_DLL = &amp;#039;api-ms-win-core-winrt-string-l1-1-0.dll&amp;#039;;\ntype\n   TWindowsCreateString = function (sourceString: PCNZWCH; Length: UINT32; out Str: HSTRING): HRESULT; stdcall;\n   TWindowsDeleteString = function (Str: HSTRING): HRESULT; stdcall;\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For space, I&#8217;ll leave out the usual calls to<em> LoadLibrary <\/em>and<em> GetProcAddress<\/em>; they&#8217;re included in the full downloadable source code at the end of this article. Now we have some functions we can use to obtain HSTRINGs from PWideChar strings (which are FPC-native), what do we actually populate the HSTRING with? What&#8217;s this &#8211; <em>RuntimeClass_Windows_UI_ViewManagement_UISettings<\/em>&nbsp;?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">OK, that one&#8217;s easy. It&#8217;s just a constant string:<\/p>\n\n\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\nconst\nRunTimeClass_UISettings = WideString(&amp;#039;Windows.UI.ViewManagement.UISettings&amp;#039;)\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3. Call a function called ActivateInstance()<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Getting closer to the action&#8230; now we&#8217;ve got the HSTRING, and we&#8217;ve got the interfaces we want to populate. But what is this <em>wf::ActivateInstance()<\/em> call?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This function is defined in the Windows Runtime too, and it&#8217;s how we actually instantiate the UISettings interface. But before we do so, and similarly to how normal COM works, we need to initialize (and eventually uninitialize) the runtime itself before we can instantiate interfaces from it. As before, here are the types you need for dynamic linking:<\/p>\n\n\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\nconst\n   WINRTCORE_DLL   = &amp;#039;api-ms-win-core-winrt-l1-1-0.dll&amp;#039;;\ntype\n   TRoInitialize        = function (InitType: RO_INIT_TYPE): HRESULT; stdcall;\n   TRoUninitialize      = procedure; stdcall;\n   TRoActivateInstance  = function (activatableClassId: HSTRING; out Instance: IInspectable): HRESULT; stdcall;\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And finally, here is how we put it all together to finally obtain a usable IUISettings3 interface instance:<\/p>\n\n\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\n\/\/ ALL ERROR checking omitted - refer to source code at end of article!\nvar\n   Hstr : HSTRING;\n   Inspectable : IInspectable;\n   UISettings : IUISettings3;\nbegin\n   RoInitialize(RO_INIT_MULTITHREADED);\n   WindowsCreateString(RunTimeClass_UISettings\n      ,Length(RunTimeClass_UISettings),hstr);\n   RoActivateInstance(hstr,Inspectable);\n   UISettings := Inspectable as IUISettings3;\n   \/\/ ..use our UISettings object!\n   UISettings := nil;\n   Inspectable := nil;\n   WindowsDeleteString(hstr);\n   RoUninitialize; \/\/ more on this below\nend;\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"mce_61\">4. Call UISettings.GetColorValue() to obtain  colour<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">After all the setup work to get to this point, this part is trivially easy:<\/p>\n\n\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\nvar\n   color : dword;\nbegin\n   UISettings.GetColorValue(Accent,color);\nend;\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Accent is the <em>TUIColorType<\/em> enum we defined earlier; if you&#8217;re lazy, you can replace this with the magic integer 5. Color is the same type as Windows&#8217; GDI Color: a dword, in BRGA format. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"mce_69\">5. Tidying up<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you&#8217;ve been following along, you should be able to build a working sample from the above code, but if you run it, it won&#8217;t be quite perfect. It&#8217;ll work, and you&#8217;ll get an actual color value, BUT your program will exception out with an Access Violation when your IUISettings interface variable leaves scope.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is an unfortunate consequence of FPC not having a native understanding of the types we&#8217;re working with; even though we explicitly set <em>UISettings<\/em> and <em>Inspectable<\/em> to nil, the compiler still believes we&#8217;re holding a reference, and finalizes it when the variables leave scope. Unfortunately, if that&#8217;s *after* we&#8217;ve called <em>RoUninitialize<\/em>, we&#8217;ll take an access violation. I&#8217;ve tried various methods to try and figure out where FPC thinks the extra reference is, or alternatively to try and tell it *not* to be smart about finalization, but I&#8217;ve only found three methods that work reliably:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Just don&#8217;t call RoUninitialize<\/li><li>Make sure the variable&#8217;s scope ends before calling RoUninitialize<\/li><li>Move RoInitialize and RoUninitialize to unit initialization\/finalization seconds<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Of the three, the second is my preferred option &#8211; and the way you&#8217;ll find it laid out in the attached source code. FPC doesn&#8217;t quite have the fine-grained scope control of C++, but you can simply wrap a nested procedure or function to do the same job. In pseudocode:<\/p>\n\n\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\nbegin\n   RoInitialize(RO_INIT_MULTITHREADED);\n   DoActualWork;\n   RoUninitialize;\nend.\n\nprocedure DoActualWork;\nvar\n   UISettings: IUISettings3;\nbegin\n    \/\/ ... etc\nend;\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Option 3 (using an FPC Unit&#8217;s initialization\/finalization sections) works just fine too &#8211; and I&#8217;d probably use that if I was going to statically link to the WinRT DLLs; but with Dynamic Linking, I chose to keep everything self-contained within a function instead.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Side note: If you have a smarter way of trying to prevent FPC from generating the spurious finalization call, I&#8217;d love to hear it!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"mce_74\">Source Code and demo<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Because I couldn&#8217;t find an FPC version of this code anywhere else on the internet, I&#8217;ve made the smallest possible working code sample available too (tested with FPC 3.0.4). <a href=\"http:\/\/www.paradicesoftware.com\/specs\/Win10RT_FPC_Accent.zip\">Here&#8217;s the source code and a compiled demo download<\/a>. (18.6KB).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m currently designing a minimalistic user interface in FPC (Freepascal), and I wanted it to blend in with the existing Windows desktop. So naturally, I started looking for how to obtain the user&#8217;s chosen accent color (I&#8217;m deliberately alternating American and British spelling of colour\/color to help anyone that needs this to be able to<\/p>\n","protected":false},"author":2722,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,18],"tags":[83,35,4,21,80],"class_list":["post-555","post","type-post","status-publish","format-standard","hentry","category-code","category-good-coding-guidelines","tag-accent","tag-fpc","tag-freepascal","tag-ui","tag-windows-runtime"],"_links":{"self":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts\/555","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/users\/2722"}],"replies":[{"embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/comments?post=555"}],"version-history":[{"count":32,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts\/555\/revisions"}],"predecessor-version":[{"id":730,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts\/555\/revisions\/730"}],"wp:attachment":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/media?parent=555"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/categories?post=555"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/tags?post=555"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}