【问题标题】:Delphi XE2: Reloading a custom VCL style from file?Delphi XE2:从文件重新加载自定义 VCL 样式?
【发布时间】:2011-09-12 09:49:47
【问题描述】:

我正在从文件中加载自定义样式:

TStyleManager.LoadFromFile(filename)

当文件更改时,我想再次加载它。但如果我尝试得到EDuplicateStyleException,因为样式已经注册。

有没有办法卸载样式以便我可以再次加载它?这种情况的典型情况是您正在对自定义样式进行更改,并希望在不重新启动整个应用程序的情况下看到它的实际效果。

【问题讨论】:

    标签: delphi delphi-xe2 vcl-styles


    【解决方案1】:

    在扫描了源代码后,我想这是不可能的。您唯一的机会可能是实施一些肮脏的黑客行为。

    无论你做什么,你都应该为此写一个 QC。如果样式已经存在,Embarcadero 可以实现重新加载文件,而不是引发异常。这对我来说是一种自然的行为。

    【讨论】:

    • 谢谢 Uwe,我在这里发布了一个功能请求:qc.embarcadero.com/wc/qcmain.aspx?d=98852
    • 看起来他们删除了错误报告:“要么没有报告#98852”
    • 功能请求消失了。那是怎么回事?
    • 无论出于何种原因,该报告都无法公开显示。尽管如此,它已关闭,解决意见中提到了 XE3 中正在修复的问题。
    • 我同意。这就是为什么我会尝试发布一段有效的代码(我已经发布了一些内容,但 UnRegisterStyle 存在问题)。其他人将从中受益更多: 1. 他们不必等待 Emba 修复它(如果曾经修复)。 2. 他们不必购买错误修复程序。换句话说,我认为我们在这里解决这个问题而不是依赖 Embarcadero 会更好。
    【解决方案2】:

    查看这个项目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;
      

      【讨论】:

      • 你的概念是对的,但它不起作用,因为文件名没有空格,样式名有空格。 IE。 IcebergClassic.vsf 是样式文件名,样式名称是“Iceberg Classico”。添加空格的小解决方法,您的代码将起作用。
      【解决方案4】:

      试试这个:

      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 风格非常了解。

      【讨论】:

        【解决方案5】:

        您可以将每个样式复制到另一个文件中,并使用不同的样式名称。然后你可以加载它的副本作为一种解决方法。如果您确实需要原件,则可以在加载副本后加载。

        【讨论】:

        • 谢谢,这是一个想法,但在对样式进行大量更改并希望在每次更改后进行测试时不太实用。保存“MyStyle_copy_nr_442”等并记住每次都更改样式名称属性需要大量输入,这使得重新启动应用程序变得更快。
        猜你喜欢
        • 1970-01-01
        • 2012-02-26
        • 2012-08-25
        • 2013-10-26
        • 2013-05-18
        • 2012-04-17
        • 1970-01-01
        • 2012-04-18
        • 2011-12-04
        相关资源
        最近更新 更多