通过在运行时添加应用程序清单,可以在运行时进行“运行时主题"的可选切换吗? [英] Possible to do runtime optional toggling of **runtime themes** by adding an application manifest at runtime?
问题描述
Possible Duplicate:
How to switch an Application between Themed and not Themed at run-time?
我创建了一个运行时主题选项设置为未启用的GUI应用程序,并且需要该选项来在应用程序初始化期间手动启用嵌入式清单.
I create a GUI App with runtime themes option set to not enabled and need the option to manually enable an embedded Manifest during App initialization.
问题:
VCL是否允许扩展点实现这一点?
Does the VCL allow an extension point to implement that?
让我解释一下:
- 自定义清单作为字符串常量嵌入在二进制文件中.
- 使用命令行参数开关启用运行时主题,例如:
MyApp.exe -themeOn
我已经深入研究Forms.TApplication,希望找到一个句柄,但是没有发现任何指向前进方向的有趣信息.
I have delved into Forms.TApplication in hope to find a handle but found nothing of interest pointing to a direction to go.
推荐答案
我会反过来做.我将通过在项目设置中启用运行时主题来包括标准comctl v6清单.然后,我会在启动时从 SetThemeAppProperties
.dpr文件,以在必要时禁用运行时主题.
I would do this the other way around. I would include the standard comctl v6 manifest by enabling runtime themes in the project settings. Then I would call SetThemeAppProperties
at startup, from the .dpr file, to disable runtime themes if necessary.
procedure DisableRuntimeThemes;
begin
InitThemeLibrary;
if Assigned(SetThemeAppProperties) then
SetThemeAppProperties(STAP_ALLOW_NONCLIENT);
end;
begin
if not FindCmdLineSwitch('themeOn') then
DisableRuntimeThemes;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.
您需要确保UxTheme
在.dpr使用子句中,或者甚至更好地将该函数移至其自己的专用单元中.
You'll need to make sure that UxTheme
is in the .dpr uses clause, or even better move that function to its own dedicated unit.
将清单文件作为正常名称包含进去,然后禁用运行时主题会更容易.启用运行时主题的另一种方法是涉及激活上下文,而不是这种方法.
It's easier to include the manifest as normal and then disable runtime themes. The alternative of enabling runtime themes involves activation contexts which is rather more involved than this approach.
说过比使用激活上下文要容易,我决定看看其中涉及了什么.这是我想出的:
Having said it was easier than using the activation context, I decided to see what was involved in that. And here's what I came up with:
unit ActivateRuntimeThemes;
interface
implementation
uses
Windows, SysUtils;
type
TActivationContext = class
private
FActCtxHandle: THandle;
FCreateActCtx: function(var pActCtx: TActCtx): THandle; stdcall;
FActivateActCtx: function(hActCtx: THandle; var lpCookie: LongWord): BOOL; stdcall;
FDeactivateActCtx: function(dwFlags: DWORD; ulCookie: LongWord): BOOL; stdcall;
FReleaseActCtx: procedure(hActCtx: THandle); stdcall;
FCookie: LongWord;
FSucceeded: Boolean;
public
constructor Create;
destructor Destroy; override;
end;
constructor TActivationContext.Create;
var
ActCtx: TActCtx;
hKernel32: HMODULE;
begin
inherited;
hKernel32 := GetModuleHandle(kernel32);
FCreateActCtx := GetProcAddress(hKernel32, 'CreateActCtxW');
if Assigned(FCreateActCtx) then
begin
FReleaseActCtx := GetProcAddress(hKernel32, 'ReleaseActCtx');
FActivateActCtx := GetProcAddress(hKernel32, 'ActivateActCtx');
FDeactivateActCtx := GetProcAddress(hKernel32, 'DeactivateActCtx');
ZeroMemory(@ActCtx, SizeOf(ActCtx));
ActCtx.cbSize := SizeOf(ActCtx);
ActCtx.lpSource := 'C:\desktop\comctlv6.manifest.txt';
FActCtxHandle := FCreateActCtx(ActCtx);
FSucceeded := (FActCtxHandle<>INVALID_HANDLE_VALUE) and FActivateActCtx(FActCtxHandle, FCookie);
end
else
FActCtxHandle := INVALID_HANDLE_VALUE;
end;
destructor TActivationContext.Destroy;
begin
if FSucceeded then
FDeactivateActCtx(0, FCookie);
if FActCtxHandle<>INVALID_HANDLE_VALUE then
FReleaseActCtx(FActCtxHandle);
inherited;
end;
var
ActivationContext: TActivationContext;
procedure FinaliseActivationContext;
begin
ActivationContext.Free;
end;
initialization
if FindCmdLineSwitch('themeOn') then
ActivationContext := TActivationContext.Create;
finalization
ActivationContext.Free;
end.
您应尽早在.dpr文件中包括该单元.在任何内存管理器之后,但在任何RTL/VCL单元之前.在项目设置中将运行时主题设置为无.您可能希望将清单文件包含为资源,但是为了方便起见,我在此处将其作为文件包含.
You should include this unit as early as possible in your .dpr file. After any memory managers, but before any RTL/VCL units. Set runtime themes to None in the project settings. You'd probably want to include the manifest file as a resource, but I've done it as a file here for my convenience.
这篇关于通过在运行时添加应用程序清单,可以在运行时进行“运行时主题"的可选切换吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!