答案已更新!再次。
好吧,我不是很有经验VCL
的样式用户,但我会尝试解释如何避免你的问题。在您进一步阅读之前,我应该告诉您:没有办法取消注册任何样式。
风格与否 风格
首先,您必须知道VCL
's 样式使用内部FRegisteredStyles
字典来存储所有已注册的样式。TStyleManager.LoadFromFile(YourStyleName)
样式在被调用后被注册。不幸的是,风格永远不会从字典中删除。
不要使用UnregisterStyle
程序。它根本不会取消注册样式。只需从可用样式列表中删除指定样式。因此,在您调用后,UnregisterStyle(YourStyle)
您只是从内部列表中清除YourStyle
,而不是从前面提到的字典中清除,并且无法设置此样式。
调用成功后UnregisterStyle()
你可能会调用LoadFromFile()
方法,想知道应用程序为什么说:
样式“翡翠”已注册。
发生这种情况是因为LoadFromFile()
方法加载指定的样式并检查其是否存在于已注册样式的内部字典中。此检查始终返回true
,因为UnregisterStyle()
过程不会从字典中删除指定的样式。
同样的事情也与财产有关StyleNames
。此属性返回样式名称使用内部FRegisteredStyles
字典获取具有指定索引的样式名称。
如果你想知道我的意见,这种风格的行为很奇怪。方法UnregisterStyle()
还应该从字典中删除指定的样式。也许我错了,但这是一个真正的错误。另一方面,没有错误 - 您正在尝试使用未记录的方法。真相就在附近。
样式化结果
作为结论,我建议您使用直接访问样式来决定是否使用所选样式。请参阅下面的代码(假设您打开了应用程序的样式):
procedure TForm1.Button1Click(Sender: TObject);
begin
if Assigned(TStyleManager.Style['Emerald']) and TStyleManager.Style['Emerald'].Available then
// Do your code
else
ShowMessage('Specified style is not available!');
end;
如果你有资源,VCL.Themes
你可以很容易地检查我在这里写的东西的合理性。
高科技
我为此创建class-helper
了TStyleManager
允许检查样式文件是否已注册并在需要时取消注册。为了TStyleInfo
用样式文件中的真实值填充记录,我们需要将指定的样式保存到TMemoryStream
然后将流传递给IsValidStyle
函数。我们也可以使用物理路径来样式化 (fe C:\Embarcadero\Delphi\Styles\Emerald.vsf
) 而不是带有流的变体,但后者看起来更优雅。
不幸的是,根据Remy 的评论(我不知道如何创建链接),C++ Builder
(由 OP 使用)不支持class-helper
功能。唯一的解决方案是创建一个简单的单元,其中包含class-helper
. 要使用它,将这样的单元添加到uses
子句并调用适当的公共过程\函数就足够了。
本单元结构如下:
unit StyleManager_CH;
interface
uses
VCL.Themes;
function IsStyleRegistered_CH(var AStyle: TCustomStyleServices): Boolean;
procedure UnregisterStyleEx_CH(var AStyle: TCustomStyleServices);
implementation
uses
System.SysUtils, System.Classes, System.Generics.Collections;
type
TStyleManagerHelper = class helper for TStyleManager
public
class function IsStyleRegistered(var AStyle: TCustomStyleServices): Boolean;
class procedure UnregisterStyleEx(var AStyle: TCustomStyleServices);
end;
class function TStyleManagerHelper.IsStyleRegistered(var
AStyle: TCustomStyleServices): Boolean;
begin
Result := Assigned(AStyle) and
TStyleManager.FRegisteredStyles.ContainsKey(AStyle.Name);
end;
class procedure TStyleManagerHelper.UnregisterStyleEx(var
AStyle: TCustomStyleServices);
var
MS: TMemoryStream;
StyleInfo: TStyleInfo;
SourceInfo: VCL.Themes.TStyleManager.TSourceInfo;
begin
if Assigned(AStyle) then
begin
MS := TMemoryStream.Create;
try
AStyle.SaveToStream(MS);
MS.Position := 0;
if AStyle.IsValidStyle(MS, StyleInfo) then
begin
if TStyleManager.FRegisteredStyles.ContainsKey(StyleInfo.Name) then
begin
SourceInfo := TStyleManager.FRegisteredStyles.Items[StyleInfo.Name];
if Assigned(SourceInfo.Data) then
FreeAndNil(SourceInfo.Data);
TStyleManager.FStyles.Remove(AStyle);
TStyleManager.FRegisteredStyles.Remove(StyleInfo.Name);
FreeAndNil(AStyle);
end;
end;
finally
MS.Free;
end;
end;
end;
function IsStyleRegistered_CH(var AStyle: TCustomStyleServices): Boolean;
begin
Result := TStyleManager.IsStyleRegistered(AStyle);
end;
procedure UnregisterStyleEx_CH(var AStyle: TCustomStyleServices);
begin
TStyleManager.UnregisterStyleEx(AStyle);
end;
end.
附录_CH
代表class-helper
缩写。还修复了一些内存泄漏。
我不确定是否有另一种方法可以“即时”重新加载样式文件。