api - tablacus/TablacusDark GitHub Wiki
ダークモード関連の非公開API
非公開APIは名前が無い場合が多いのでその時は数値でGetProcAddressします。
ShouldAppsUseDarkMode @uxtheme.dll,132
アプリがダークモードが有効か調べる。
※ハイコントラストの場合はダークモード関係ないのでハイコントラストのテーマかも調べましょう。
AllowDarkModeForWindow @uxtheme.dll,133
ウインドウやコントロールにダークモードを設定する。 TRUEをセットすると
SetWindowTheme(hwnd, L"explorer", NULL);
が
SetWindowTheme(hwnd, L"darkmode_explorer", NULL);
と同じ感じになる(SysListView32だけ例外あり)
SetPreferredAppMode @uxtheme.dll,135
そのアプリがダークモードか否かを設定。 とりあえず、これを設定するだけでメニューはダークモードになる。(カスタムドローしている場合は除く)
APPMODE_DEFAULT = 0,
APPMODE_ALLOWDARK = 1,
APPMODE_FORCEDARK = 2,
APPMODE_FORCELIGHT = 3,
今は APPMODE_FORCEDARK や APPMODE_FORCELIGHT を一度使うとずーとダークモード、ライトモードになり、ライトモード/ダークモードの切り替えができなくなる。
だから、ライトモードは APPMODE_DEFAULT 、ダークモードは APPMODE_ALLOWDARK にするのがお勧め。
RefreshImmersiveColorPolicyState @uxtheme.dll,104
ダークモード切替後に呼ぶと良いようだ。
IsDarkModeAllowedForWindow @uxtheme.dll,137
ウインドウがダークモードかどうか調べる。SetPreferredAppMode もダークモードになってないと取得できなかった。
SetWindowCompositionAttribute @user32.dll,"SetWindowCompositionAttribute"
DwmSetWindowAttribute @dwmapi.dll,"DwmSetWindowAttribute"
タイトルバーをダークモード化するのに使う。途中で仕様が変わったので SetWindowCompositionAttribute が使えたら SetWindowCompositionAttribute 使えなかったら DwmSetWindowAttribute を使う
#ifndef PreferredAppMode
enum PreferredAppMode
{
APPMODE_DEFAULT = 0,
APPMODE_ALLOWDARK = 1,
APPMODE_FORCEDARK = 2,
APPMODE_FORCELIGHT = 3,
APPMODE_MAX = 4
};
#endif
#ifndef WINCOMPATTRDATA
struct WINCOMPATTRDATA
{
DWORD dwAttrib;
PVOID pvData;
SIZE_T cbData;
};
#endif
typedef PreferredAppMode (WINAPI* LPFNSetPreferredAppMode)(PreferredAppMode appMode);
typedef bool (WINAPI* LPFNAllowDarkModeForWindow)(HWND hwnd, BOOL allow);
typedef bool (WINAPI* LPFNShouldAppsUseDarkMode)();
typedef void (WINAPI* LPFNRefreshImmersiveColorPolicyState)();
typedef bool (WINAPI* LPFNIsDarkModeAllowedForWindow)(HWND hwnd);
typedef BOOL(WINAPI* LPFNSetWindowCompositionAttribute)(HWND hWnd, WINCOMPATTRDATA*);
typedef HRESULT (STDAPICALLTYPE * LPFNDwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
LPFNSetPreferredAppMode _SetPreferredAppMode = NULL;
LPFNAllowDarkModeForWindow _AllowDarkModeForWindow = NULL;
LPFNShouldAppsUseDarkMode _ShouldAppsUseDarkMode = NULL;
LPFNRefreshImmersiveColorPolicyState _RefreshImmersiveColorPolicyState = NULL;
LPFNIsDarkModeAllowedForWindow _IsDarkModeAllowedForWindow = NULL;
LPFNSetWindowCompositionAttribute _SetWindowCompositionAttribute = NULL;
LPFNDwmSetWindowAttribute _DwmSetWindowAttribute = NULL;
if (hDll = LoadLibraryA("uxtheme.dll")) {
*(FARPROC *)&_ShouldAppsUseDarkMode = GetProcAddress(hDll, MAKEINTRESOURCEA(132));
*(FARPROC *)&_AllowDarkModeForWindow = GetProcAddress(hDll, MAKEINTRESOURCEA(133));
*(FARPROC *)&_SetPreferredAppMode = GetProcAddress(hDll, MAKEINTRESOURCEA(135));
*(FARPROC *)&_RefreshImmersiveColorPolicyState = GetProcAddress(hDll, MAKEINTRESOURCEA(104));
*(FARPROC *)&_IsDarkModeAllowedForWindow = GetProcAddress(hDll, MAKEINTRESOURCEA(137));
FreeLibrary(hDll);
}
if (hDll = LoadLibraryA("user32.dll")) {
*(FARPROC *)&_SetWindowCompositionAttribute = GetProcAddress(hDll, "SetWindowCompositionAttribute");
FreeLibrary(hDll);
}
if (!_SetWindowCompositionAttribute) {
if (hDll = LoadLibraryA("dwmapi.dll")) {
*(FARPROC *)&_DwmSetWindowAttribute = GetProcAddress(hDll, "DwmSetWindowAttribute");
FreeLibrary(hDll);
}
}