Delphi XE2:如何从文件重新加载自定义的VCL样式?

8

我正在使用以下方法从文件加载自定义样式:

TStyleManager.LoadFromFile(filename)

当文件被更改时,我希望能够重新加载它。但是,如果我尝试这样做,会出现“EDuplicateStyleException”异常,因为该样式已经被注册。
有没有一种方法可以卸载样式,以便我可以再次加载它?典型的情况是,您正在对自定义样式进行更改,并希望在不重新启动整个应用程序的情况下看到它的效果。
5个回答

7

在扫描源代码后,我猜这不可能用一种直截了当的方式实现。你唯一的机会可能是实现一些肮脏的技巧。

无论你做什么,你都应该为此编写一个质量控制程序。Embarcadero可以实现重新加载文件,如果样式已经存在,而不是引发异常。对我来说,那看起来像是一种自然的行为。


1
看起来他们删除了错误报告:“要么没有报告#98852”。 - Gabriel
1
功能请求不见了,这是怎么回事? - James Johnston
无论出于什么原因,该报告在公共场合下都不可见。但是,它已经关闭了,解决方案评论中提到该问题已在XE3中得到修复。 - Uwe Raabe
@UweRaabe - 实际上不是这样的。我现在正在尝试在C ++ Tokyo中重新加载vsf文件。如果您调用LoadFromFile然后SetStyle,它会告诉您样式已经注册。 - Gabriel
1
我同意。这就是为什么我会尝试发布一段可行的代码(我已经发布了一些内容,但UnRegisterStyle存在问题)。其他人将从中受益更多:1.他们不必等待Emba修复它(如果有修复的话)。2.他们不必购买错误修复。换句话说,我认为我们最好在这里解决这个问题,而不是依赖Embarcadero。 - Gabriel
显示剩余5条评论

4

请查看这个项目vcl styles utils,其中一个提供的功能是卸载vcl风格。只需要在您的项目中包含Vcl.Styles.Ext单元,然后使用以下代码。

 TStyleManager.RemoveStyle('Carbon');

3
另一个想法:这可能会起作用。为简单起见,以下是部分代码。在下面的代码中,您首先获取对已注册样式的句柄。然后,我猜您可以处理并重新分配指向从文件加载的指针。我认为异常仅在尝试应用样式时显示,而不是在加载样式时显示。如果我错了,请原谅我。
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;

你的概念是正确的,但不会起作用,因为文件名称没有空格,而样式名称有空格。例如,IcebergClassic.vsf是样式文件名,样式名称是“Iceberg Classico”。因此,进行小的变通以添加空格,你的代码就可以正常工作了。 - Nix

1

试试这个:

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;

注意:我从未编译过代码。但它应该可以工作。
无论如何,你应该使用RRuz的库。他对这些VCL样式非常了解。

0

你可以在另一个文件中复制每个样式,并使用不同的名称。然后,你可以加载它的副本作为解决方法。如果你真的需要原始样式,那么你可以在加载副本之后再加载它。


谢谢,这是一个想法,但在样式中进行大量更改并希望在每次更改后进行测试时并不是非常实用。每次保存"MyStyle_copy_nr_442"等,并记得同时更改样式名称属性,需要输入很多文字,这使得重新启动应用程序更快。 - Ville Krumlinde

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接