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