【问题标题】:How can I intitalize the status of the active theme in my component?如何初始化组件中活动主题的状态?
【发布时间】:2020-02-16 16:41:52
【问题描述】:

我在一个主题感知组件上工作,当我创建它时,我必须使用IsThemeActive(来自 UxTheme 单元)设置初始状态。但是如果我在组件constructor 中使用此功能,我会遇到访问冲突。在其他任何地方使用它都可以正常工作。发生了什么,如果我不能在 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;

【问题讨论】:

  • 好的,所以我们确定它不能在构造函数中调用...现在,我应该在哪里调用它,这样我才能读取初始状态?
  • @TomBrunberg,我用最小的例子更新了这个问题。
  • 我也尝试在initialization部分使用IsThemeActive...它也失败了!
  • 我不能,因为我的组件没有OnShow 事件。但是我发现出了什么问题!我必须先打电话给InitThemeLibrary... :)

标签: delphi themes delphi-2009


【解决方案1】:

我找到了解决方案。我必须先初始化主题库:

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.

【讨论】:

    【解决方案2】:

    我已经用我自己的自定义组件测试过这种情况,并且没有任何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 函数返回TrueIsAppThemed 函数返回False 的情况下,只有一种情况是视觉外观被禁用专门为您的应用程序。下图描述了如何实现这一点(有点俄语):


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

    下图显示TForm 在禁用应用程序视觉主题(通过上述方式,即IsAppThemed 返回False)和活动应用程序主题(IsAppThemed 返回@987654347)将具有什么样的外观@)。 注意:左侧是标准notepad.exe 应用程序,它没有焦点并且在两种情况下都是主题。

    因此,玩主题并非易事。

    来源:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-26
      • 2023-03-08
      • 1970-01-01
      • 2019-05-08
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      相关资源
      最近更新 更多