1

I'm looking to control runtime themes in a way that is friendly for version control tools. Be it programmatically, or by some configuration such as a text based manifest file (but not the DPROJ file through the GUI project options).

Is there any such way?

For clarification: The DPROJ is not committed to git because it is auto edited by Delphi for no apparent reason, and contains the command line parameters that anyone can modify daily.

AmigoJack
  • 5,234
  • 1
  • 15
  • 31
Khorkhe
  • 1,024
  • 1
  • 11
  • 26
  • One option to reduce changes to the dproj file: https://www.uweraabe.de/Blog/2017/01/18/dproj-changed-or-not-changed/ – Brian Apr 19 '22 at 17:26
  • Oh that's great! It would likely work for most of my projects, but in the main one, cmdline params are extensively used to point to input files. Saving those into SCM would still be a pain, and would still prefer to keep it out of the way if possible – Khorkhe Apr 19 '22 at 18:18
  • Create a separate `.manifest` file, and then refer to it as an `RT_MANIFEST` (24) resource type in a `.rc` script file that is compiled with a [`{$R}`](https://docwiki.embarcadero.com/RADStudio/en/Resource_file_(Delphi)) directive in your code. – Remy Lebeau Apr 19 '22 at 19:11
  • @RemyLebeau would you happen to have a pointer to some manifest docs, when it comes to runtime themes syntax? I had looked up the MSDN, but it had nothing about themes – Khorkhe Apr 19 '22 at 19:16
  • 1
    @Khorkhe "*[MSDN] had nothing about themes*" - yes, it does. See [Enabling Visual Styles](https://learn.microsoft.com/en-us/windows/win32/controls/cookbook-overview). – Remy Lebeau Apr 19 '22 at 19:21
  • seems my google-fu failed, thanks for the pointer! – Khorkhe Apr 19 '22 at 19:28
  • 3
    @Brian that link points to an outdated plugin. Uwe merged this and another one into Project Magician already a few years ago https://www.uweraabe.de/Blog/downloads/download-info/project-magician/ – Delphi Coder Apr 19 '22 at 21:07

1 Answers1

0

Thanks to @Remy's pointers, this is the code responsible for disabling themes using a custom manifest:

<dependency>
  <dependentAssembly>
    <assemblyIdentity
      type="win32"
      name="Microsoft.Windows.Common-Controls"
      version="5.82.0.0"
      processorArchitecture="*"
      publicKeyToken="6595b64144ccf1df"
      language="*"
    />
  </dependentAssembly>
</dependency>

The critical parameter is which version of Common Controls is used:

  • version="5.82.0.0" will disable themes
  • version="6.0.0.0" and above will enable them
AmigoJack
  • 5,234
  • 1
  • 15
  • 31
Khorkhe
  • 1,024
  • 1
  • 11
  • 26
  • Funny, I've never seen someone use a manifest to go back to the older version of `ComCtl32.dll`. If you omit the manifest from the executable, Windows will default to v5. But even so, just know that going back to v5 will affect more than just Theming, as `ComCtl32.dll` v6 does implement other things, too. So, various modern UI elements/behaviors may be different/lost by going back to v5. – Remy Lebeau Apr 19 '22 at 21:26
  • 1
    That said, there is another option to control in code which `ComCtl32.dll` version is used, on a per-window basis - [Activation Contexts](https://docs.microsoft.com/en-us/windows/win32/sbscs/activation-contexts) (which is what Windows uses for you when a manifest is used). See [How can you use both versions 5 and 6 of the common controls within the same module?](https://devblogs.microsoft.com/oldnewthing/20140508-00/?p=1043). So, you could let the app use v6 normally, but setup a v5 AC for any window you want to disable Themes for. Of course, you could just use `SetWindowTheme()` instead... – Remy Lebeau Apr 19 '22 at 21:26
  • 1
    One advantage of disabled themes is: background colors of controls (f.e. `TGroupBox`) are rendered. Themes don't allow that anymore, as if too many people in the past overdid so. – AmigoJack Apr 19 '22 at 22:01
  • @Remy yes the search box loses its icons. As AmigoJack says, the project has lots of custom coloring, such as backgrounds, checkbox font colors etc, all of which are non-modifiable with themes. Worse yet, edit boxes having their borders "cut" as if truncated, until Ctl3D is checked, which I'm not sure is the right solution yet, but that's the subject of another question. As for SetWindowTheme, i tried to test it in the OnCreate event of a form to disable a button's theme but it did not take effect. Can it be done per control, or must it be entire form? Finally, in which function to call it? – Khorkhe Apr 20 '22 at 03:20
  • Since SetWindowTheme takes a handle, in theory any window control can be disabled. Maybe there's a constraint at which point it should be invoked? – Khorkhe Apr 20 '22 at 03:40
  • No: [as per the docs](https://learn.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-setwindowtheme) it's for whole windows only. Which explains the "_Window_" part in its name (which must not be confused with the product name _Windows_). – AmigoJack Apr 20 '22 at 07:49