delphivcldelphi-xe3vcl-styles

TSaveTextFileDialog and Vcl Styles


I'm using the TSaveTextFileDialog component in Delphi XE3, but when a VCL Style is enabled, the encoding combobox is drawn using the current VCL style.

Delphi TSaveTextFileDialog

How can I fix this, I mean disable the VCL style for the combobox?


Solution

  • The parent class (TOpenTextFileDialog) of the TSaveTextFileDialog component adds a set of Vcl components to implement the Encodings and EncodingIndex properties, you can disable the Vcl styles on these Vcl controls using the StyleElements property. unfortunately these components are private so you need a little hack in order to gain access and disable the Vcl Styles.

    Here you have two options.

    Using a class helper.

    You can introduce a helper function to get the Panel component which contains the Vcl controls of the dialog.

    type
     TOpenTextFileDialogHelper=class helper for TOpenTextFileDialog
      function GetPanel : TPanel;
     end;
    
    function TOpenTextFileDialogHelper.GetPanel: TPanel;
    begin
      Result:=Self.FPanel;
    end;
    

    then you can write a method to disable the Vcl Styles, like so :

    procedure DisableVclStyles(const Control : TControl);
    var
      i : Integer;
    begin
      if Control=nil then
        Exit;
       Control.StyleElements:=[];
    
      if Control is TWinControl then
        for i := 0 to TWinControl(Control).ControlCount-1 do
          DisableVclStyles(TWinControl(Control).Controls[i]);
    end;
    

    And finally use on this way

      DisableVclStyles(SaveTextFileDialog1.GetPanel);
      SaveTextFileDialog1.Execute;
    

    RTTI

    Another option is use the RTTI to access the private Vcl components.

    var
      LRttiContext : TRttiContext;
      LRttiField :TRttiField;
    begin
      LRttiContext:=TRttiContext.Create;
      for LRttiField in LRttiContext.GetType(SaveTextFileDialog1.ClassType).GetFields do
       if LRttiField.FieldType.IsInstance and LRttiField.FieldType.AsInstance.MetaclassType.ClassNameIs('TPanel') then
        DisableVclStyles(TPanel(LRttiField.GetValue(SaveTextFileDialog1).AsObject));
    
      SaveTextFileDialog1.Execute;
    end;