Solo para complementar la respuesta de Rob Kennedy, debe usar el SetThemeAppProperties
de esta manera.
uses
UxTheme;
procedure DisableThemesApp;
begin
SetThemeAppProperties(0);
SendMessage(Application.Handle,WM_THEMECHANGED,0,0);
SendMessage(Application.MainForm.Handle,CM_RECREATEWND,0,0);
end;
procedure EnableThemesApp;
begin
SetThemeAppProperties(STAP_ALLOW_NONCLIENT or STAP_ALLOW_CONTROLS or STAP_ALLOW_WEBCONTENT);
SendMessage(Application.Handle,WM_THEMECHANGED,0,0);
SendMessage(Application.MainForm.Handle,CM_RECREATEWND,0,0);
end;
y para determinar si los controles son temáticos o no puede utilizar la función GetThemeAppProperties
.
var
Flag : DWORD;
begin
Flag:=GetThemeAppProperties;
if (Flag and STAP_ALLOW_CONTROLS)<>0 then //if the controls are themed
begin
end;
end;
ACTUALIZACIÓN
Debido a los problemas descritos para usted, puedo comprobar el código de la unidad UxTheme
y veo el problema está relacionado con la función UseThemes
. así que escribí este pequeño parche (usando las funciones del parche HookProc
, UnHookProc
y GetActualAddr
desarrollado por Andreas Hausladen), que funciona bien en mis pruebas. déjame saber si funciona para ti también.
debe incluir el PatchUxTheme en su lista de usos. y llame a las funciones DisableThemesApp
y EnableThemesApp
.
unit PatchUxTheme;
interface
procedure EnableThemesApp;
procedure DisableThemesApp;
implementation
uses
Controls,
Forms,
Messages,
UxTheme,
Sysutils,
Windows;
type
TJumpOfs = Integer;
PPointer = ^Pointer;
PXRedirCode = ^TXRedirCode;
TXRedirCode = packed record
Jump: Byte;
Offset: TJumpOfs;
end;
PAbsoluteIndirectJmp = ^TAbsoluteIndirectJmp;
TAbsoluteIndirectJmp = packed record
OpCode: Word;
Addr: PPointer;
end;
var
UseThemesBackup: TXRedirCode;
function GetActualAddr(Proc: Pointer): Pointer;
begin
if Proc <> nil then
begin
if (Win32Platform = VER_PLATFORM_WIN32_NT) and (PAbsoluteIndirectJmp(Proc).OpCode = $25FF) then
Result := PAbsoluteIndirectJmp(Proc).Addr^
else
Result := Proc;
end
else
Result := nil;
end;
procedure HookProc(Proc, Dest: Pointer; var BackupCode: TXRedirCode);
var
n: DWORD;
Code: TXRedirCode;
begin
Proc := GetActualAddr(Proc);
Assert(Proc <> nil);
if ReadProcessMemory(GetCurrentProcess, Proc, @BackupCode, SizeOf(BackupCode), n) then
begin
Code.Jump := $E9;
Code.Offset := PAnsiChar(Dest) - PAnsiChar(Proc) - SizeOf(Code);
WriteProcessMemory(GetCurrentProcess, Proc, @Code, SizeOf(Code), n);
end;
end;
procedure UnhookProc(Proc: Pointer; var BackupCode: TXRedirCode);
var
n: Cardinal;
begin
if (BackupCode.Jump <> 0) and (Proc <> nil) then
begin
Proc := GetActualAddr(Proc);
Assert(Proc <> nil);
WriteProcessMemory(GetCurrentProcess, Proc, @BackupCode, SizeOf(BackupCode), n);
BackupCode.Jump := 0;
end;
end;
function UseThemesH:Boolean;
Var
Flag : DWORD;
begin
Flag:=GetThemeAppProperties;
if ((@IsAppThemed<>nil) and (@IsThemeActive<>nil)) then
Result := IsAppThemed and IsThemeActive and ((Flag and STAP_ALLOW_CONTROLS)<>0)
else
Result := False;
end;
procedure HookUseThemes;
begin
HookProc(@UxTheme.UseThemes, @UseThemesH, UseThemesBackup);
end;
procedure UnHookUseThemes;
begin
UnhookProc(@UxTheme.UseThemes, UseThemesBackup);
end;
Procedure DisableThemesApp;
begin
SetThemeAppProperties(0);
SendMessage(Application.Handle,WM_THEMECHANGED,0,0);
SendMessage(Application.MainForm.Handle,CM_RECREATEWND,0,0);
end;
Procedure EnableThemesApp;
begin
SetThemeAppProperties(STAP_ALLOW_NONCLIENT or STAP_ALLOW_CONTROLS or STAP_ALLOW_WEBCONTENT);
SendMessage(Application.Handle,WM_THEMECHANGED,0,0);
SendMessage(Application.MainForm.Handle,CM_RECREATEWND,0,0);
end;
initialization
HookUseThemes;
finalization
UnHookUseThemes;
end.
@RRUZ. Llegar allí, pero aún no ... Definitivamente, se necesitaba CM_RECREATEWND para ver cualquier cosa (aunque lo evitaría porque los desagradables efectos secundarios pueden provocar Combos, ListViews ...). Todavía hay problemas al eliminar el tema con ** SpeedButtons desapareciendo, PageControls no repintar cuando se cambia la pestaña, y Grids es un desorden de visualización **. Una de las razones podría ser porque ** 'IsAppThemed e IsThemeActive' ** aún devuelve' True', lo que confunde al VCL al intentar pintar ... –
@ François, ¿ve problemas similares si cambia la configuración del tema de forma global desde el ¿panel de control? –
@Rob. Muy buena pregunta. No es tan malo cuando se elimina el tema en el panel de control (a Windows Classic). El único problema en ese caso parece ser la pintura de las celdas de las rejillas. Los SpeedButtons y PageControls se comportan correctamente.Ahora la parte interesante es que cambiar en el Panel de Control Y cambiar en la aplicación con el código anterior funciona bien (todos parecen comportarse). –