XylemFlow 8 Posted June 1, 2023 (edited) I'm trying to create a 'Dark Mode' for my Windows application, but I want to keep the basic style of the controls and just change the colours. I have downloaded a VCL style (Windows 10 Charcoal) and converted it to an FMX style using the Bitmap Style Designer. It looks mostly ok. However, there are some annoying differences. The main one being that there's a thicker border around the forms. There are a few other issues with some controls. I can open the Style Designer to edit the parameters, but it's difficult to know what to change. I'd like to compare the parameters with the default style to see what's different, but how do I do that? The default style seems to be hardcoded and not visible in the Style Designer. Edited June 1, 2023 by XylemFlow Windows Share this post Link to post
programmerdelphi2k 237 Posted June 1, 2023 did you try save in disk using "WriteComponent" function? Share this post Link to post
XylemFlow 8 Posted June 7, 2023 On 6/1/2023 at 11:13 PM, programmerdelphi2k said: did you try save in disk using "WriteComponent" function? I'm not sure what you mean. The style object for my normal mode doesn't contain anything because only hard coded styles are used. Attached is a basic example of the issues I'm having. I build it in Delphi 11.2 for Windows 32-bit. When run you can click the checkbox to switch between styles. I have 2 issues when in Dark Mode. The borders of the form change. All the components on the form shift because of this. I'd like only the colours to change. I assume that I need to change some parameters in windowborderstyle in the Style Designer, but playing around with those parameters hasn't helped much. The main menu behaves differently. In normal light mode I can click File for example and then move the cursor over Edit and Edit will automatically open and File will close. However, that doesn't happen in Dark Mode. File just stays open. I don't know what to change in the style to fix it. If I had all the parameters of the default style (light) then I could compare with the parameters of the dark style to try to work out what the differences are and maybe fix these issues. But I don't know how to do that? Dark Mode Demo.zip Share this post Link to post
programmerdelphi2k 237 Posted June 7, 2023 (edited) @XylemFlow Here I am RAD 11.3/FMX and using StyleBook 2: 1 StyleBook Default = Empty 1 StyleBook Dark = Win10ModernDark.Style Unfortunately, some components store their properties in Hexadecimal values, so it's not possible to see the values directly, you'll need to convert them. This usually happens for properties with "images", value trees, etc... The "WriteComponent" function is found in TStream subclasses such as TMemoryStream etc... as well as "ReadComponent". Here I will try to demonstrate a way to do it, note that using "MEMO" or any other class that makes use of "TStrings", together with "themes/skins/styles", will be very painful in general, because there is much more involved than just change the skin of the component! NOTE: if you dont need show nothing in "memo", for example, the process is very quickly!!! type TForm1 = class(TForm) mmResourceBin: TMemo; BtnStyleLight: TButton; BtnStyleDark: TButton; stylebookDefault: TStyleBook; stylebookDark: TStyleBook; BtnWriteComponentOnMemo: TButton; BtnHexaToText: TButton; Layout1: TLayout; mmHexaToString: TMemo; mmObjectToText: TMemo; procedure BtnStyleLightClick(Sender: TObject); procedure BtnStyleDarkClick(Sender: TObject); procedure BtnWriteComponentOnMemoClick(Sender: TObject); procedure BtnHexaToTextClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.BtnStyleLightClick(Sender: TObject); begin mmObjectToText.Lines.Clear; mmResourceBin.Lines.Clear; mmHexaToString.Lines.Clear; // Self.StyleBook := stylebookDefault; end; procedure TForm1.BtnStyleDarkClick(Sender: TObject); begin mmObjectToText.Lines.Clear; mmResourceBin.Lines.Clear; mmHexaToString.Lines.Clear; // Self.StyleBook := stylebookDark; end; procedure TForm1.BtnWriteComponentOnMemoClick(Sender: TObject); var LMemoryStream : TMemoryStream; LStringStream : TStringStream; LText : string; LBeginPosition: integer; // int64... LEndPosition : integer; // "" LOffSet : integer; begin if (Self.StyleBook = nil) then begin mmObjectToText.Text := '"StyleBook = nil"'; // exit; end; // LMemoryStream := TMemoryStream.Create; try LStringStream := TStringStream.Create(LText); try LMemoryStream.WriteComponent(Self.StyleBook); LMemoryStream.Position := 0; // ObjectBinaryToText(LMemoryStream, LStringStream); LStringStream.Position := 0; // // LBeginPosition := -1; LEndPosition := -1; LOffSet := 'ResourcesBin = {'.Length; LBeginPosition := Pos('ResourcesBin = {', LStringStream.DataString); // if (LBeginPosition > 0) then begin LBeginPosition := LBeginPosition + LOffSet + 1; LEndPosition := Pos('}', Copy(LStringStream.DataString, LBeginPosition)) - 1; // if (LEndPosition > LBeginPosition) then begin // trying avoid slow ... mmObjectToText.BeginUpdate; try mmObjectToText.Text := LStringStream.DataString; finally mmObjectToText.EndUpdate; end; // mmResourceBin.BeginUpdate; try mmResourceBin.Text := Copy(LStringStream.DataString, LBeginPosition, LEndPosition).Trim finally mmResourceBin.EndUpdate; end; end else mmResourceBin.Text := '"}" was not found!'; end else mmResourceBin.Text := '"ResourcesBin = {" was not found!'; finally LStringStream.Free; end; finally LMemoryStream.Free; end; end; procedure TForm1.BtnHexaToTextClick(Sender: TObject); var LHexaString: string; LBytes : string; LIndex : integer; LNewText : string; begin LHexaString := mmResourceBin.Text.Replace(slinebreak, '').Replace(' ', ''); LIndex := 0; // if (LHexaString.Length = 0) then begin mmHexaToString.Text := 'mmResourceBin normalized is empty!'; // exit; end; // try for var i: integer := 0 to (LHexaString.Length - 1) div 2 do begin LIndex := (i * 2) + 1; // LBytes := LBytes + ',' + StrToInt('$' + Copy(LHexaString, LIndex, 2)).ToString; end; // for var V in LBytes.Remove(0, 1).Split([',']) do LNewText := LNewText + Chr(StrToInt(V)); // mmHexaToString.BeginUpdate; try mmHexaToString.Text := LNewText; finally mmHexaToString.EndUpdate; end; except on E: Exception do mmHexaToString.Text := E.Message; end; end; Edited June 7, 2023 by programmerdelphi2k Share this post Link to post
XylemFlow 8 Posted June 8, 2023 (edited) 14 hours ago, programmerdelphi2k said: @XylemFlow Here I am RAD 11.3/FMX and using StyleBook 2: 1 StyleBook Default = Empty 1 StyleBook Dark = Win10ModernDark.Style Unfortunately, some components store their properties in Hexadecimal values, so it's not possible to see the values directly, you'll need to convert them. This usually happens for properties with "images", value trees, etc... The "WriteComponent" function is found in TStream subclasses such as TMemoryStream etc... as well as "ReadComponent". Here I will try to demonstrate a way to do it, note that using "MEMO" or any other class that makes use of "TStrings", together with "themes/skins/styles", will be very painful in general, because there is much more involved than just change the skin of the component! Thanks for sharing that. But your stylebookDefault shows nothing as I expected. That's my issue. I can see all the parameters of the dark style but not the parameters of the default style to compare against. Edited June 8, 2023 by XylemFlow Share this post Link to post