「ダークモード対応」の版間の差分

提供: MeryWiki
ナビゲーションに移動 検索に移動
編集の要約なし
編集の要約なし
6行目: 6行目:
Windows 10 1809 ではいくつかの非公開 API の存在が確認されており、これらを呼び出すことで Win32 アプリケーションでもダークモードに対応できる可能性が見えてきました。
Windows 10 1809 ではいくつかの非公開 API の存在が確認されており、これらを呼び出すことで Win32 アプリケーションでもダークモードに対応できる可能性が見えてきました。


==Windows 10 のダークモードの隠し API 研究==
下記は Delphi でダークモードの API を呼び出す実験で作成したソースコード (雑) です。
下記は Delphi でダークモードの API を呼び出す実験で作成したソースコード (雑) です。


==Windows 10 のダークモードの隠し API 研究==
アプリケーションの起動時に 1 度、AllowDarkModeForApp を呼び出しておけばメインメニューなどは Windows 10 のダークモードの設定の ON・OFF に連動して色が変わるようになりました。
 
また、AllowDarkModeForWindow を使用すれば TButton や TComboBox などに対してもダークモードを有効にできるらしいのですが、私の環境ではうまく動きませんでした。
 
<source lang="delphi">
<source lang="delphi">
unit DarkModeClasses;
unit DarkModeClasses;
84行目: 88行目:


end.
end.
</source>
==TButton や TComboBox などをダークモードに対応させるには?==
SetWindowTheme メソッドを使用してダークモードのテーマを割り当ててやることで、一部のコンポーネントはダークモードに対応させることができるようです。
<source lang="delphi">
SetWindowTheme(Handle, 'DarkMode_Explorer', nil);
</source>
</source>

2019年3月28日 (木) 21:43時点における版

Windows 10 のダークモードに対応するためには?

現時点 (Windows 10 1809) では、Windows 10 のダークモードに対応するためには UWP アプリケーションである必要があります。

しかし、Windows 10 1809 では explorer.exe がダークモードに対応したことで、Win32 アプリケーションのダークモード対応も徐々に開発されているような気がします。

Windows 10 1809 ではいくつかの非公開 API の存在が確認されており、これらを呼び出すことで Win32 アプリケーションでもダークモードに対応できる可能性が見えてきました。

Windows 10 のダークモードの隠し API 研究

下記は Delphi でダークモードの API を呼び出す実験で作成したソースコード (雑) です。

アプリケーションの起動時に 1 度、AllowDarkModeForApp を呼び出しておけばメインメニューなどは Windows 10 のダークモードの設定の ON・OFF に連動して色が変わるようになりました。

また、AllowDarkModeForWindow を使用すれば TButton や TComboBox などに対してもダークモードを有効にできるらしいのですが、私の環境ではうまく動きませんでした。

unit DarkModeClasses;

interface

uses
{$IF CompilerVersion > 22.9}
  Winapi.Windows, System.SysUtils;
{$ELSE}
  Windows, SysUtils;
{$IFEND}


resourcestring
  SDllLoadError = '%s をロードできません';

const
  THEME_LIB = 'uxtheme.dll';

type
  TShouldAppsUseDarkMode = function: BOOL; cdecl;
  TAllowDarkModeForWindow = function(hwnd: HWND; allow: BOOL): BOOL; cdecl;
  TAllowDarkModeForApp = function(allow: BOOL): BOOL; cdecl;
  TFlushMenuThemes = procedure; cdecl;
  TRefreshImmersiveColorPolicyState = procedure; cdecl;

var
  FHandle: THandle;
  FLoaded: Boolean;
  RefreshImmersiveColorPolicyState: TRefreshImmersiveColorPolicyState;
  ShouldAppsUseDarkMode: TShouldAppsUseDarkMode;
  AllowDarkModeForWindow: TAllowDarkModeForWindow;
  AllowDarkModeForApp: TAllowDarkModeForApp;
  FlushMenuThemes: TFlushMenuThemes;
  DarkModeSupported: Boolean;

implementation

function DarkModeLoadLibrary: Boolean;
begin
  if CheckWin32Version(10) and (TOSVersion.Build >= 17763) then
    FHandle := LoadLibrary(PChar(THEME_LIB));
  Result := FHandle <> 0;
  if Result then
  begin
    @RefreshImmersiveColorPolicyState := GetProcAddress(FHandle, MakeIntResource(104));
    @ShouldAppsUseDarkMode := GetProcAddress(FHandle, MakeIntResource(132));
    @AllowDarkModeForWindow := GetProcAddress(FHandle, MakeIntResource(133));
    @AllowDarkModeForApp := GetProcAddress(FHandle, MakeIntResource(135));
    @FlushMenuThemes := GetProcAddress(FHandle, MakeIntResource(136));
    if (@RefreshImmersiveColorPolicyState <> nil) and
      (@ShouldAppsUseDarkMode <> nil) and (@AllowDarkModeForWindow <> nil) and
      (@AllowDarkModeForApp <> nil) and (@FlushMenuThemes <> nil) then
      DarkModeSupported := True;
  end;
end;

procedure DarkModeFreeLibrary;
begin
  if FHandle <> 0 then
    FreeLibrary(FHandle);
  FHandle := 0;
end;

initialization

if not FLoaded then
  FLoaded := DarkModeLoadLibrary;

finalization

if FLoaded then
  DarkModeFreeLibrary;

end.

TButton や TComboBox などをダークモードに対応させるには?

SetWindowTheme メソッドを使用してダークモードのテーマを割り当ててやることで、一部のコンポーネントはダークモードに対応させることができるようです。

SetWindowTheme(Handle, 'DarkMode_Explorer', nil);
スポンサーリンク