Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi XE2: Reloading a custom VCL style from file?

I'm loading a custom style from file using:

TStyleManager.LoadFromFile(filename)

When the file is changed I want to load it again. But if I try that I get a EDuplicateStyleException because the style is already registered.

Is there a way to unload a style so I can load it again? The typical case for this is that you are making changes to a custom style and want to see it in action without restarting the whole application.

like image 430
Ville Krumlinde Avatar asked Sep 12 '11 09:09

Ville Krumlinde


4 Answers

After scanning the sources I guess that is not possible in a straight forward way. Your only chance might be to implement some dirty hack.

Whatever you do, you should write a QC for this. Embarcadero could implement to reload the file if the style already exists instead of raising an exception. That would look like a natural behaviour to me.

like image 133
Uwe Raabe Avatar answered Nov 13 '22 14:11

Uwe Raabe


Check this project vcl styles utils, one of the features exposed is the capacity of unload a vcl style. Just include the Vcl.Styles.Ext unit in your project and then use this code.

 TStyleManager.RemoveStyle('Carbon');
like image 45
RRUZ Avatar answered Nov 13 '22 16:11

RRUZ


Another idea: This might work. Partial code for simplicity. In the code below, you first get a handle to the already registered Style. I guess then, you can dispose and re-assign the pointer with the one you loaded from the file. I believe the exception only show when you try to apply the style, not when you load it. Forgive me if I am wrong.

var
  StyleName: String;
  Style    : TStyleManager.TStyleServicesHandle;
  FileName : String;

begin

  StyleName := 'Obsidian';       // or another style name
  FileName  := 'obsidian.vsf';   // or any other valid style file name

  Style     := TStyleManager.Style[ StyleName];

  if Assigned( Style) then   // style already registered
  begin
    TStyleManager.TrySetStyle( StyleName);
    // insert other processing here

  end
  else // style not registered
  begin 
    if TStyleManager.IsValidStyle( FileName) then
    begin
      Style := TStyleManager.LoadFromFile( FileName);
      if Assigned( Style) then
      begin   
        // insert other processing here, such as
        // TStyleManager.SetStyle( Style);

      end;
    end;
  end;

end;
like image 3
Anthony Streets Avatar answered Nov 13 '22 14:11

Anthony Streets


Try this:

procedure TfrmMain.Button11Click(TObject *Sender);    
 var
    MyStyle TCustomStyleServices;
 const
    usStylePath= 'c:\Users\Public\Documents\Embarcadero\Studio\19.0\Styles\vcl\MINE.vsf';
begin
 if TStyleManager.IsValidStyle(usStylePath)
    begin
    // Get current style
    MyStyle:= TStyleManager.Style["Emerald"];   // this will return a TCustomStyleServices obj

    if (MyStyle <> NULL)
       begin
       // Set default Windows style (no style)
       TStyleManager.SetStyle(TStyleManager.SystemStyle);

       // Remove it
       TStyleManager.UnRegisterStyle(MyStyle);
       end;

    // Load style from disk
    TStyleManager.LoadFromFile(usStylePath);
    TStyleManager.SetStyle(Emerald");
    end;
end;

Note: I never complied the code. But it should work.

Anyway, you should use RRuz's library. He knows a lot about these VCL styles.

like image 1
Server Overflow Avatar answered Nov 13 '22 15:11

Server Overflow