diff --git a/SystemInformer/delayhook.c b/SystemInformer/delayhook.c index 48f4d20307cf..3a2dc3f15626 100644 --- a/SystemInformer/delayhook.c +++ b/SystemInformer/delayhook.c @@ -32,6 +32,10 @@ static BOOLEAN PhDefaultEnableStreamerMode = FALSE; static BOOLEAN PhDefaultEnableThemeAcrylicWindowSupport = FALSE; static BOOLEAN PhDefaultEnableThemeAnimation = FALSE; +BOOL(WINAPI* PhIsDarkModeAllowedForWindow_I)( + _In_ HWND WindowHandle + ) = NULL; + LRESULT CALLBACK PhMenuWindowHookProcedure( _In_ HWND WindowHandle, _In_ UINT WindowMessage, @@ -234,7 +238,7 @@ LRESULT CALLBACK PhStaticWindowHookProcedure( { RECT rectClient; GetClientRect(WindowHandle, &rectClient); - InflateRect(&rectClient, 2, 2); + PhInflateRect(&rectClient, 2, 2); MapWindowRect(WindowHandle, ParentHandle, &rectClient); InvalidateRect(ParentHandle, &rectClient, TRUE); // fix the annoying white border left by the previous active control } @@ -925,40 +929,35 @@ LRESULT CALLBACK PhHeaderWindowHookProcedure( { CREATESTRUCT* createStruct = (CREATESTRUCT*)lParam; - // Don't apply header theme for unsupported dialogs: Advanced Security and Digital Signature Details (Dart Vanya) - if (!FindWindowEx(GetAncestor(WindowHandle, GA_ROOT), NULL, L"DirectUIHWND", NULL) && - !FindWindowEx(GetParent(createStruct->hwndParent), NULL, L"NativeFontCtl", NULL)) + if (createStruct->hwndParent) { - if (createStruct->hwndParent) - { - WCHAR windowClassName[MAX_PATH]; + WCHAR windowClassName[MAX_PATH]; - if (!GetClassName(createStruct->hwndParent, windowClassName, RTL_NUMBER_OF(windowClassName))) - windowClassName[0] = UNICODE_NULL; + if (!GetClassName(createStruct->hwndParent, windowClassName, RTL_NUMBER_OF(windowClassName))) + windowClassName[0] = UNICODE_NULL; - if (PhEqualStringZ(windowClassName, L"PhTreeNew", FALSE)) - { - LONG_PTR windowStyle = PhGetWindowStyle(createStruct->hwndParent); + if (PhEqualStringZ(windowClassName, L"PhTreeNew", FALSE)) + { + LONG_PTR windowStyle = PhGetWindowStyle(createStruct->hwndParent); - if (BooleanFlagOn(windowStyle, TN_STYLE_CUSTOM_HEADERDRAW)) - { - PhSetControlTheme(WindowHandle, L"DarkMode_ItemsView"); + if (BooleanFlagOn(windowStyle, TN_STYLE_CUSTOM_HEADERDRAW)) + { + PhSetControlTheme(WindowHandle, L"DarkMode_ItemsView"); - return CallWindowProc(PhDefaultHeaderWindowProcedure, WindowHandle, WindowMessage, wParam, lParam); - } + return CallWindowProc(PhDefaultHeaderWindowProcedure, WindowHandle, WindowMessage, wParam, lParam); } } + } - context = PhAllocateZero(sizeof(PHP_THEME_WINDOW_HEADER_CONTEXT)); - context->ThemeHandle = PhOpenThemeData(WindowHandle, VSCLASS_HEADER, PhGetWindowDpi(WindowHandle)); - context->CursorPos.x = LONG_MIN; - context->CursorPos.y = LONG_MIN; - PhSetWindowContext(WindowHandle, LONG_MAX, context); + context = PhAllocateZero(sizeof(PHP_THEME_WINDOW_HEADER_CONTEXT)); + context->ThemeHandle = PhOpenThemeData(WindowHandle, VSCLASS_HEADER, PhGetWindowDpi(WindowHandle)); + context->CursorPos.x = LONG_MIN; + context->CursorPos.y = LONG_MIN; + PhSetWindowContext(WindowHandle, LONG_MAX, context); - PhSetControlTheme(WindowHandle, L"DarkMode_ItemsView"); + PhSetControlTheme(WindowHandle, L"DarkMode_ItemsView"); - InvalidateRect(WindowHandle, NULL, FALSE); - } + InvalidateRect(WindowHandle, NULL, FALSE); } else { @@ -1043,6 +1042,17 @@ LRESULT CALLBACK PhHeaderWindowHookProcedure( break; case WM_PAINT: { + // Don't apply header theme for unsupported dialogs: Advanced Security, Digital Signature Details, etc. (Dart Vanya) + if (!PhIsDarkModeAllowedForWindow_I(GetParent(WindowHandle))) + { + PhRemoveWindowContext(WindowHandle, LONG_MAX); + if (context->ThemeHandle) + PhCloseThemeData(context->ThemeHandle); + PhFree(context); + PhSetControlTheme(WindowHandle, L"Explorer"); + break; + } + //PAINTSTRUCT ps; //HDC BufferedHDC; //HPAINTBUFFER BufferedPaint; @@ -1312,6 +1322,12 @@ static HRESULT(WINAPI* PhDefaultGetThemeColor)( _Out_ COLORREF* pColor ) = NULL; +// uxtheme.dll ordinal 49 +static HTHEME(WINAPI* PhDefaultOpenNcThemeData)( + _In_ HWND hwnd, + _In_ LPCWSTR pszClassList + ) = NULL; + static BOOL (WINAPI* PhDefaultSystemParametersInfo)( _In_ UINT uiAction, _In_ UINT uiParam, @@ -1769,6 +1785,20 @@ HRESULT PhGetThemeColorHook( return retVal; } +HTHEME PhOpenNcThemeDataHook( + _In_ HWND hwnd, + _In_ LPCWSTR pszClassList + ) +{ + if (PhEqualStringZ((PWSTR)pszClassList, VSCLASS_SCROLLBAR, TRUE) && + PhIsDarkModeAllowedForWindow_I(hwnd)) + { + return PhDefaultOpenNcThemeData(NULL, L"Explorer::ScrollBar"); + } + + return PhDefaultOpenNcThemeData(hwnd, pszClassList); +} + BOOLEAN CALLBACK PhInitializeTaskDialogTheme( _In_ HWND WindowHandle, _In_opt_ PVOID CallbackData @@ -1987,6 +2017,8 @@ VOID PhRegisterDetoursHooks( PhDefaultDrawThemeText = PhGetDllBaseProcedureAddress(baseAddress, "DrawThemeText", 0); PhDefaultDrawThemeTextEx = PhGetDllBaseProcedureAddress(baseAddress, "DrawThemeTextEx", 0); PhDefaultGetThemeColor = PhGetDllBaseProcedureAddress(baseAddress, "GetThemeColor", 0); + PhIsDarkModeAllowedForWindow_I = PhGetDllBaseProcedureAddress(baseAddress, NULL, 137); + PhDefaultOpenNcThemeData = PhGetDllBaseProcedureAddress(baseAddress, NULL, 49); } if (baseAddress = PhGetLoaderEntryDllBaseZ(L"Comctl32.dll")) @@ -2014,6 +2046,8 @@ VOID PhRegisterDetoursHooks( goto CleanupExit; if (!NT_SUCCESS(status = DetourAttach((PVOID)&PhDefaultGetThemeColor, (PVOID)PhGetThemeColorHook))) goto CleanupExit; + if (!NT_SUCCESS(status = DetourAttach((PVOID)&PhDefaultOpenNcThemeData, (PVOID)PhOpenNcThemeDataHook))) + goto CleanupExit; if (!NT_SUCCESS(status = DetourAttach((PVOID)&PhDefaultTaskDialogIndirect, (PVOID)PhTaskDialogIndirectHook))) goto CleanupExit; } diff --git a/phlib/theme.c b/phlib/theme.c index 9f7a4f59ec85..e065725142c8 100644 --- a/phlib/theme.c +++ b/phlib/theme.c @@ -202,6 +202,7 @@ VOID PhInitializeWindowTheme( AllowDarkModeForWindow_I = PhGetDllBaseProcedureAddress(baseAddress, NULL, 133); SetPreferredAppMode_I = PhGetDllBaseProcedureAddress(baseAddress, NULL, 135); //FlushMenuThemes_I = PhGetDllBaseProcedureAddress(baseAddress, NULL, 136); + IsDarkModeAllowedForWindow_I = PhGetDllBaseProcedureAddress(baseAddress, NULL, 137); } if (SetPreferredAppMode_I) @@ -240,8 +241,17 @@ VOID PhInitializeWindowTheme( if (defaultWindowProc != PhpThemeWindowSubclassProc) { + WCHAR windowClassName[MAX_PATH]; PhSetWindowContext(WindowHandle, LONG_MAX, defaultWindowProc); SetWindowLongPtr(WindowHandle, GWLP_WNDPROC, (LONG_PTR)PhpThemeWindowSubclassProc); + + if (!GetClassName(WindowHandle, windowClassName, RTL_NUMBER_OF(windowClassName))) + windowClassName[0] = UNICODE_NULL; + if ((PhEqualStringZ(windowClassName, L"PhTreeNew", FALSE) || PhEqualStringZ(windowClassName, WC_LISTVIEW, FALSE)) && + WindowsVersion >= WINDOWS_10_RS5) + { + AllowDarkModeForWindow_I(WindowHandle, TRUE); // HACK for dynamically generated plugin tabs + } } PhEnumChildWindows( @@ -742,7 +752,9 @@ BOOLEAN CALLBACK PhpThemeWindowEnumChildWindows( // PhSetControlTheme(tooltipWindow, L""); // break; //case 1: // Old colors - PhWindowThemeSetDarkMode(WindowHandle, TRUE); + //PhWindowThemeSetDarkMode(WindowHandle, TRUE); + AllowDarkModeForWindow_I(WindowHandle, TRUE); + PhSetControlTheme(WindowHandle, L"DarkMode_ItemsView"); PhWindowThemeSetDarkMode(tooltipWindow, TRUE); } @@ -821,6 +833,7 @@ BOOLEAN CALLBACK PhpThemeWindowEnumChildWindows( //case 1: // Old colors PhWindowThemeSetDarkMode(tooltipWindow, TRUE); PhWindowThemeSetDarkMode(WindowHandle, TRUE); + AllowDarkModeForWindow_I(WindowHandle, TRUE); } if (PhEnableThemeListviewBorder) @@ -3270,12 +3283,11 @@ LRESULT CALLBACK PhpThemeWindowACLUISubclassProc( { HDC hdc = GetDC(WindowHandle); RECT rectControl = customDraw->rc; - InflateRect(&rectControl, 2, 2); + PhInflateRect(&rectControl, 2, 2); MapWindowRect(customDraw->hdr.hwndFrom, WindowHandle, &rectControl); FillRect(hdc, &rectControl, PhThemeWindowBackgroundBrush); // fix the annoying white border left by the previous active control ReleaseDC(WindowHandle, hdc); } - return CDRF_DODEFAULT; } } } diff --git a/tools/peview/delayhook.c b/tools/peview/delayhook.c index 27d2abdf6ce1..1bc60cd4993c 100644 --- a/tools/peview/delayhook.c +++ b/tools/peview/delayhook.c @@ -32,6 +32,10 @@ static BOOLEAN PhDefaultEnableStreamerMode = FALSE; static BOOLEAN PhDefaultEnableThemeAcrylicWindowSupport = FALSE; static BOOLEAN PhDefaultEnableThemeAnimation = FALSE; +BOOL(WINAPI* PhIsDarkModeAllowedForWindow_I)( + _In_ HWND WindowHandle + ) = NULL; + LRESULT CALLBACK PhMenuWindowHookProcedure( _In_ HWND WindowHandle, _In_ UINT WindowMessage, @@ -925,40 +929,35 @@ LRESULT CALLBACK PhHeaderWindowHookProcedure( { CREATESTRUCT* createStruct = (CREATESTRUCT*)lParam; - // Don't apply header theme for unsupported dialogs: Advanced Security and Digital Signature Details (Dart Vanya) - if (!FindWindowEx(GetAncestor(WindowHandle, GA_ROOT), NULL, L"DirectUIHWND", NULL) && - !FindWindowEx(GetParent(createStruct->hwndParent), NULL, L"NativeFontCtl", NULL)) + if (createStruct->hwndParent) { - if (createStruct->hwndParent) - { - WCHAR windowClassName[MAX_PATH]; + WCHAR windowClassName[MAX_PATH]; - if (!GetClassName(createStruct->hwndParent, windowClassName, RTL_NUMBER_OF(windowClassName))) - windowClassName[0] = UNICODE_NULL; + if (!GetClassName(createStruct->hwndParent, windowClassName, RTL_NUMBER_OF(windowClassName))) + windowClassName[0] = UNICODE_NULL; - if (PhEqualStringZ(windowClassName, L"PhTreeNew", FALSE)) - { - LONG_PTR windowStyle = PhGetWindowStyle(createStruct->hwndParent); + if (PhEqualStringZ(windowClassName, L"PhTreeNew", FALSE)) + { + LONG_PTR windowStyle = PhGetWindowStyle(createStruct->hwndParent); - if (BooleanFlagOn(windowStyle, TN_STYLE_CUSTOM_HEADERDRAW)) - { - PhSetControlTheme(WindowHandle, L"DarkMode_ItemsView"); + if (BooleanFlagOn(windowStyle, TN_STYLE_CUSTOM_HEADERDRAW)) + { + PhSetControlTheme(WindowHandle, L"DarkMode_ItemsView"); - return CallWindowProc(PhDefaultHeaderWindowProcedure, WindowHandle, WindowMessage, wParam, lParam); - } + return CallWindowProc(PhDefaultHeaderWindowProcedure, WindowHandle, WindowMessage, wParam, lParam); } } + } - context = PhAllocateZero(sizeof(PHP_THEME_WINDOW_HEADER_CONTEXT)); - context->ThemeHandle = PhOpenThemeData(WindowHandle, VSCLASS_HEADER, PhGetWindowDpi(WindowHandle)); - context->CursorPos.x = LONG_MIN; - context->CursorPos.y = LONG_MIN; - PhSetWindowContext(WindowHandle, LONG_MAX, context); + context = PhAllocateZero(sizeof(PHP_THEME_WINDOW_HEADER_CONTEXT)); + context->ThemeHandle = PhOpenThemeData(WindowHandle, VSCLASS_HEADER, PhGetWindowDpi(WindowHandle)); + context->CursorPos.x = LONG_MIN; + context->CursorPos.y = LONG_MIN; + PhSetWindowContext(WindowHandle, LONG_MAX, context); - PhSetControlTheme(WindowHandle, L"DarkMode_ItemsView"); + PhSetControlTheme(WindowHandle, L"DarkMode_ItemsView"); - InvalidateRect(WindowHandle, NULL, FALSE); - } + InvalidateRect(WindowHandle, NULL, FALSE); } else { @@ -1043,6 +1042,17 @@ LRESULT CALLBACK PhHeaderWindowHookProcedure( break; case WM_PAINT: { + // Don't apply header theme for unsupported dialogs: Advanced Security, Digital Signature Details, etc. (Dart Vanya) + if (!PhIsDarkModeAllowedForWindow_I(GetParent(WindowHandle))) + { + PhRemoveWindowContext(WindowHandle, LONG_MAX); + if (context->ThemeHandle) + PhCloseThemeData(context->ThemeHandle); + PhFree(context); + PhSetControlTheme(WindowHandle, L"Explorer"); + break; + } + //PAINTSTRUCT ps; //HDC BufferedHDC; //HPAINTBUFFER BufferedPaint; @@ -1312,6 +1322,12 @@ static HRESULT(WINAPI* PhDefaultGetThemeColor)( _Out_ COLORREF* pColor ) = NULL; +// uxtheme.dll ordinal 49 +static HTHEME(WINAPI* PhDefaultOpenNcThemeData)( + _In_ HWND hwnd, + _In_ LPCWSTR pszClassList + ) = NULL; + static BOOL (WINAPI* PhDefaultSystemParametersInfo)( _In_ UINT uiAction, _In_ UINT uiParam, @@ -1754,6 +1770,20 @@ HRESULT PhGetThemeColorHook( return retVal; } +HTHEME PhOpenNcThemeDataHook( + _In_ HWND hwnd, + _In_ LPCWSTR pszClassList +) +{ + if (PhEqualStringZ((PWSTR)pszClassList, VSCLASS_SCROLLBAR, TRUE) && + PhIsDarkModeAllowedForWindow_I(hwnd)) + { + return PhDefaultOpenNcThemeData(NULL, L"Explorer::ScrollBar"); + } + + return PhDefaultOpenNcThemeData(hwnd, pszClassList); +} + BOOLEAN CALLBACK PhInitializeTaskDialogTheme( _In_ HWND WindowHandle, _In_opt_ PVOID CallbackData @@ -1972,6 +2002,8 @@ VOID PhRegisterDetoursHooks( PhDefaultDrawThemeText = PhGetDllBaseProcedureAddress(baseAddress, "DrawThemeText", 0); PhDefaultDrawThemeTextEx = PhGetDllBaseProcedureAddress(baseAddress, "DrawThemeTextEx", 0); PhDefaultGetThemeColor = PhGetDllBaseProcedureAddress(baseAddress, "GetThemeColor", 0); + PhIsDarkModeAllowedForWindow_I = PhGetDllBaseProcedureAddress(baseAddress, NULL, 137); + PhDefaultOpenNcThemeData = PhGetDllBaseProcedureAddress(baseAddress, NULL, 49); } if (baseAddress = PhGetLoaderEntryDllBaseZ(L"Comctl32.dll")) @@ -1999,6 +2031,8 @@ VOID PhRegisterDetoursHooks( goto CleanupExit; if (!NT_SUCCESS(status = DetourAttach((PVOID)&PhDefaultGetThemeColor, (PVOID)PhGetThemeColorHook))) goto CleanupExit; + if (!NT_SUCCESS(status = DetourAttach((PVOID)&PhDefaultOpenNcThemeData, (PVOID)PhOpenNcThemeDataHook))) + goto CleanupExit; if (!NT_SUCCESS(status = DetourAttach((PVOID)&PhDefaultTaskDialogIndirect, (PVOID)PhTaskDialogIndirectHook))) goto CleanupExit; }