Delphi 如何初始化组件中活动主题的状态?

Delphi 如何初始化组件中活动主题的状态?,delphi,themes,delphi-2009,Delphi,Themes,Delphi 2009,我处理一个主题感知组件,当我创建它时,我必须使用IsThemeActive(来自UxTheme unit)设置初始状态。但是,如果我在组件构造函数中使用此函数,我会遇到访问冲突。在其他任何地方使用都可以。如果无法在OnCreate中设置初始状态,会发生什么情况?如何设置初始状态 我的组成单位: unit TestUnit; interface uses Classes, Windows, Controls, ComCtrls, StdCtrls, CommCtrl, Messages, Fo

我处理一个主题感知组件,当我创建它时,我必须使用
IsThemeActive
(来自UxTheme unit)设置初始状态。但是,如果我在组件
构造函数中使用此函数,我会遇到访问冲突。在其他任何地方使用都可以。如果无法在
OnCreate
中设置初始状态,会发生什么情况?如何设置初始状态

我的组成单位:

unit TestUnit;

interface

uses Classes, Windows, Controls, ComCtrls, StdCtrls, CommCtrl, Messages, Forms,
     SysUtils, Graphics, UxTheme;

type
  TSuperList = class(TListView)
  private
    FThemeEnabled: Boolean;
  public
    constructor Create(AOwner: TComponent); override;
  end;

implementation

constructor TSuperList.Create(AOwner: TComponent);
begin
 inherited;
 FThemeEnabled:= IsThemeActive;
end;

end.
在应用程序中使用它:

procedure TForm1.FormCreate(Sender: TObject);
begin
 List1:= TSuperList.Create(Form1);
 List1.Parent:= Form1;
end;

我找到了解决办法。我必须首先初始化主题库:

unit TestUnit;

interface

uses Classes, Windows, Controls, ComCtrls, StdCtrls, CommCtrl, Messages, Forms,
     SysUtils, Graphics, UxTheme;

type
  TSuperList = class(TListView)
  private
    FThemeEnabled: Boolean;
  public
    constructor Create(AOwner: TComponent); override;
  end;

implementation

var IsThemeEnabled: Boolean;

constructor TSuperList.Create(AOwner: TComponent);
begin
 inherited;
 FThemeEnabled:= IsThemeEnabled;
end;

initialization

 InitThemeLibrary;
 IsThemeEnabled:= IsThemeActive;

end.

我找到了解决办法。我必须首先初始化主题库:

unit TestUnit;

interface

uses Classes, Windows, Controls, ComCtrls, StdCtrls, CommCtrl, Messages, Forms,
     SysUtils, Graphics, UxTheme;

type
  TSuperList = class(TListView)
  private
    FThemeEnabled: Boolean;
  public
    constructor Create(AOwner: TComponent); override;
  end;

implementation

var IsThemeEnabled: Boolean;

constructor TSuperList.Create(AOwner: TComponent);
begin
 inherited;
 FThemeEnabled:= IsThemeEnabled;
end;

initialization

 InitThemeLibrary;
 IsThemeEnabled:= IsThemeActive;

end.

我已经用自己的自定义组件测试了这种情况,并且没有任何
AccessViolation
。可能是因为我使用的是Delphi Tokyo 10.2

1.获取主题状态 但作为一个想法:您可以重写
CreateWnd
过程来调用
IsThemeActive
函数,而不是在
constructor
部分中执行此操作

大概是这样的:

procedure TSuperList.CreateWnd;
begin
  Inherited CreateWnd;
  FThemeEnabled := UXTheme.IsThemeActive;
end;
不需要显式初始化主题库

2.正确处理主题的可访问性 此外,我还想指出,检查应用程序是否应用了视觉样式(-es)非常重要,因为操作系统现在可以使用视觉样式,但应用程序不能。因此,
IsThemeActive
函数在应用程序没有应用主题时返回
True
。这将导致将您的组件绘制为主题,而将其他组件绘制为非主题。 您可以使用
IsAppThemed
函数检查应用程序当前是否使用主题

IsAppThemed
的重要注意事项:

在Windows 8之前,可以在“控制面板”中关闭视觉样式,以便应用程序可以支持视觉样式,但在给定时间不应用视觉样式。 在Windows 8中,无法关闭视觉样式

您可能想知道:为什么这两个函数都返回
True
,即使我的应用程序在视觉上没有主题化,并且操作系统启用了主题

我对此没有答案。在
IsThemeActive
函数返回
True
IsAppThemed
函数返回
False
的情况下,只有一种情况是专门为您的应用程序禁用视觉外观。下图描述了如何实现这一点(略用俄语):


红线上方的复选框旨在“选中”以在操作系统激活主题时禁用应用程序主题化

下面的图片显示了
t表单在应用程序禁用视觉主题(通过上述方式,
IsAppThemed
返回
False
)和活动应用程序主题化(
IsAppThemed
返回
True
)的情况下将具有何种外观。 注意:左侧是标准的
notepad.exe
应用程序,它没有焦点,在这两种情况下都以主题为主题

因此,玩弄主题并不是一件小事

资料来源:


我用自己的自定义组件测试了这种情况,没有任何
访问冲突。可能是因为我使用的是Delphi Tokyo 10.2

1.获取主题状态 但作为一个想法:您可以重写
CreateWnd
过程来调用
IsThemeActive
函数,而不是在
constructor
部分中执行此操作

大概是这样的:

procedure TSuperList.CreateWnd;
begin
  Inherited CreateWnd;
  FThemeEnabled := UXTheme.IsThemeActive;
end;
不需要显式初始化主题库

2.正确处理主题的可访问性 此外,我还想指出,检查应用程序是否应用了视觉样式(-es)非常重要,因为操作系统现在可以使用视觉样式,但应用程序不能。因此,
IsThemeActive
函数在应用程序没有应用主题时返回
True
。这将导致将您的组件绘制为主题,而将其他组件绘制为非主题。 您可以使用
IsAppThemed
函数检查应用程序当前是否使用主题

IsAppThemed
的重要注意事项:

在Windows 8之前,可以在“控制面板”中关闭视觉样式,以便应用程序可以支持视觉样式,但在给定时间不应用视觉样式。 在Windows 8中,无法关闭视觉样式

您可能想知道:为什么这两个函数都返回
True
,即使我的应用程序在视觉上没有主题化,并且操作系统启用了主题

我对此没有答案。在
IsThemeActive
函数返回
True
IsAppThemed
函数返回
False
的情况下,只有一种情况是专门为您的应用程序禁用视觉外观。下图描述了如何实现这一点(略用俄语):


红线上方的复选框旨在“选中”以在操作系统激活主题时禁用应用程序主题化

下面的图片显示了
t表单在应用程序禁用视觉主题(通过上述方式,
IsAppThemed
返回
False
)和活动应用程序主题化(
IsAppThemed
返回
True
)的情况下将具有何种外观。 注意:左侧是标准的
notepad.exe
应用程序,它没有焦点,在这两种情况下都以主题为主题

因此,玩弄主题并不是一件小事

资料来源:


好的,所以我们可以确定它不能在构造函数中调用。。。现在,我应该在哪里称呼它,这样我就可以阅读初始状态了?@TomBrunberg,我用了最简单的例子更新了这个问题。我还尝试在
初始化
部分使用
IsThemeActive
。。。它也失败了!我不能,因为我的部件是d