corneliusdavid 214 Posted September 10 I've got a Delphi 12.1 VCL application where, by default, there is no style applied. If the user wants, they can switch to a dark mode at which point, I load a pre-selected .vsf file and all is good. If the user wants to switch back, I simply set the style to 'Windows' and it switches back to the default style. It all still works. Because there will be several programs with this same functionality and option, I don't store the style file in the application but load it dynamically at runtime. And if, down the road, I want to replace the style file with a different one, I can because it's named simply "DarkMode.vsf" even though the internal style name could be "CopperDark" or "Windows10 BlackPearl" for example. With the overloaded TStyleManager.SetStyle procedure that can take either a string (the style name) or a TStyleServicesHandle (returned from LoadFromFile), I figured I could use either one interchangeably; therefore, it's simplest in my code to refer to the loaded file by its handle and not it's name but when changing back to the default style, I simply use the standard 'Windows' string name, leading to these procedures: procedure TMainForm.LoadThemeFiles; begin // save handle to dark style for later FDarkStyleServicesHandle := TStyleManager.LoadFromFile(TPath.Combine(ThemePath, 'DarkMode.vsf')); end; procedure TsMainForm.SetDarkTheme; begin TStyleManager.SetStyle(FDarkStyleServicesHandle); end; procedure TcssMainForm.ClearTheme; begin TStyleManager.SetStyle('Windows'); end; However, I found that once SetDarkTheme has been called followed by ClearTheme, SetDarkTheme will no longer work (as in the case the user switches DarkMode off then tries to turn it back on). I've attached a small program to demonstrate this; I've tried it in both Delphi 11.3 and 12.1. I've submitted a bug report but also have a work-around. Since SetStyle(string-name) works consistently, I've changed the LoadThemeFiles procedure to get and save the name of the style. The TStyleManager has a list of all registered style names, including 'Windows' so if I load one style, TStyleManager should have two style names: procedure TsMainForm.LoadThemeFiles; var StyNames: TArray<string>; begin TStyleManager.LoadFromFile(TPath.Combine(ThemePath, 'DarkMode.vsf')); StyNames := TStyleManager.StyleNames; // reminder not to load any styles into the project if Length(StyNames) > 2 then raise EProgrammerNotFound.Create('Styles should not be defined in the project!'); for var sn in StyNames do begin if not SameText(sn, 'Windows') then begin // save the dark-mode style name FDarkStyleName := sn; Break; end; end; end; After that, the change to SetDarkMode procedure is pretty obvious: procedure TcssMainForm.SetDarkTheme; begin TStyleManager.SetStyle(FDarkStyleName); end; I looked at the VCL source for the two SetStyle procedures and the string version simply looks through the list of registered style names and calls the TStyleServicesHandle version. So why does the first method fail? VclStyleToggle.zip Share this post Link to post
Pat Foley 51 Posted September 10 (edited) Delete Edited September 10 by Pat Foley Not working Share this post Link to post