From d4dc0cb54596f99b8fc40c90232823801b363cff Mon Sep 17 00:00:00 2001 From: Ethan Rodensky Date: Thu, 14 Mar 2024 14:00:52 -0400 Subject: [PATCH] [UXTHEME] Import DrawThemeTextEx() function from Wine (part of #6622) This is a Vista+ function, but it exists in Windows XP/2003 internally and used for drawing "Window Text" with a shadow in DrawNCPreview(). And DrawThemeText() now acts as wrapper on top of it. CORE-5991 --- dll/win32/uxtheme/draw.c | 62 ++++++++++++++++++++++++++++++++------ sdk/include/psdk/uxtheme.h | 53 ++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 9 deletions(-) diff --git a/dll/win32/uxtheme/draw.c b/dll/win32/uxtheme/draw.c index c18a5986c47..c50f9128189 100644 --- a/dll/win32/uxtheme/draw.c +++ b/dll/win32/uxtheme/draw.c @@ -1372,11 +1372,21 @@ typedef int (WINAPI * DRAWSHADOWTEXT)(HDC hdc, LPCWSTR pszText, UINT cch, RECT * COLORREF crText, COLORREF crShadow, int ixOffset, int iyOffset); /*********************************************************************** - * DrawThemeText (UXTHEME.@) + * DrawThemeTextEx (UXTHEME.@) */ -HRESULT WINAPI DrawThemeText(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, - LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, - DWORD dwTextFlags2, const RECT *pRect) +HRESULT +WINAPI +DrawThemeTextEx( + _In_ HTHEME hTheme, + _In_ HDC hdc, + _In_ int iPartId, + _In_ int iStateId, + _In_ LPCWSTR pszText, + _In_ int iCharCount, + _In_ DWORD dwTextFlags, + _Inout_ LPRECT pRect, + _In_ const DTTOPTS *options +) { HRESULT hr; HFONT hFont = NULL; @@ -1389,10 +1399,14 @@ HRESULT WINAPI DrawThemeText(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int oldBkMode; RECT rt; int iShadowType; + DWORD optFlags; - TRACE("%d %d: stub\n", iPartId, iStateId); if(!hTheme) return E_HANDLE; + if (!options) + return E_NOTIMPL; + + optFlags = options->dwFlags; hr = GetThemeFont(hTheme, hdc, iPartId, iStateId, TMT_FONT, &logfont); if(SUCCEEDED(hr)) @@ -1410,10 +1424,17 @@ HRESULT WINAPI DrawThemeText(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, oldBkMode = SetBkMode(hdc, TRANSPARENT); - if(dwTextFlags2 & DTT_GRAYED) - textColor = GetSysColor(COLOR_GRAYTEXT); - else { - if(FAILED(GetThemeColor(hTheme, iPartId, iStateId, TMT_TEXTCOLOR, &textColor))) + if (optFlags & DTT_TEXTCOLOR) + { + textColor = options->crText; + } + else + { + int textColorProp = TMT_TEXTCOLOR; + if (optFlags & DTT_COLORPROP) + textColorProp = options->iColorPropId; + + if (FAILED(GetThemeColor(hTheme, iPartId, iStateId, textColorProp, &textColor))) textColor = GetTextColor(hdc); } @@ -1473,6 +1494,29 @@ cleanup: return S_OK; } +/*********************************************************************** + * DrawThemeText (UXTHEME.@) + */ +HRESULT WINAPI DrawThemeText(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, + LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, + DWORD dwTextFlags2, const RECT *pRect) +{ + DTTOPTS opts = { 0 }; + RECT rt = *pRect; + + TRACE("(%p %p %d %d %s:%d 0x%08lx 0x%08lx %p)\n", hTheme, hdc, iPartId, iStateId, + debugstr_wn(pszText, iCharCount), iCharCount, dwTextFlags, dwTextFlags2, pRect); + + if (dwTextFlags2 & DTT_GRAYED) + { + opts.dwFlags = DTT_TEXTCOLOR; + opts.crText = GetSysColor(COLOR_GRAYTEXT); + } + opts.dwSize = sizeof(opts); + + return DrawThemeTextEx(hTheme, hdc, iPartId, iStateId, pszText, iCharCount, dwTextFlags, &rt, &opts); +} + /*********************************************************************** * GetThemeBackgroundContentRect (UXTHEME.@) */ diff --git a/sdk/include/psdk/uxtheme.h b/sdk/include/psdk/uxtheme.h index cd98a46ae19..2b9a4f32a37 100644 --- a/sdk/include/psdk/uxtheme.h +++ b/sdk/include/psdk/uxtheme.h @@ -15,6 +15,24 @@ extern "C" { #define DTBG_COMPUTINGREGION 0x00000010 #define DTBG_MIRRORDC 0x00000020 #define DTT_GRAYED 0x00000001 + +/* DTTOPTS.dwFlags bits */ +#define DTT_TEXTCOLOR 0x00000001 +#define DTT_BORDERCOLOR 0x00000002 +#define DTT_SHADOWCOLOR 0x00000004 +#define DTT_SHADOWTYPE 0x00000008 +#define DTT_SHADOWOFFSET 0x00000010 +#define DTT_BORDERSIZE 0x00000020 +#define DTT_FONTPROP 0x00000040 +#define DTT_COLORPROP 0x00000080 +#define DTT_STATEID 0x00000100 +#define DTT_CALCRECT 0x00000200 +#define DTT_APPLYOVERLAY 0x00000400 +#define DTT_GLOWSIZE 0x00000800 +#define DTT_CALLBACK 0x00001000 +#define DTT_COMPOSITED 0x00002000 +#define DTT_VALIDBITS 0x00003fff + #define ETDT_DISABLE 0x00000001 #define ETDT_ENABLE 0x00000002 #define ETDT_USETABTEXTURE 0x00000004 @@ -39,6 +57,7 @@ extern "C" { typedef HANDLE HPAINTBUFFER; typedef HANDLE HTHEME; +typedef int (WINAPI *DTT_CALLBACK_PROC)(HDC,LPWSTR,int,RECT*,UINT,LPARAM); typedef enum _BP_BUFFERFORMAT { @@ -90,6 +109,24 @@ typedef struct _MARGINS { int cyBottomHeight; } MARGINS, *PMARGINS; +typedef struct _DTTOPTS { + DWORD dwSize; + DWORD dwFlags; + COLORREF crText; + COLORREF crBorder; + COLORREF crShadow; + int iTextShadowType; + POINT ptShadowOffset; + int iBorderSize; + int iFontPropId; + int iColorPropId; + int iStateId; + BOOL fApplyOverlay; + int iGlowSize; + DTT_CALLBACK_PROC pfnDrawTextCallback; + LPARAM lParam; +} DTTOPTS, *PDTTOPTS; + HRESULT WINAPI CloseThemeData(HTHEME); HRESULT WINAPI DrawThemeBackground(HTHEME,HDC,int,int,const RECT*,const RECT*); HRESULT WINAPI DrawThemeBackgroundEx(HTHEME,HDC,int,int,const RECT*,const DTBGOPTS*); @@ -139,6 +176,22 @@ HTHEME WINAPI OpenThemeData(HWND,LPCWSTR); HTHEME WINAPI OpenThemeDataEx(HWND,LPCWSTR,DWORD); void WINAPI SetThemeAppProperties(DWORD); HRESULT WINAPI SetWindowTheme(HWND,LPCWSTR,LPCWSTR); + +/* Undocumented and not exported in Windows XP/2003 + * In public headers since Vista+ */ +HRESULT +WINAPI +DrawThemeTextEx( + _In_ HTHEME hTheme, + _In_ HDC hdc, + _In_ int iPartId, + _In_ int iStateId, + _In_ LPCWSTR pszText, + _In_ int iCharCount, + _In_ DWORD dwTextFlags, + _Inout_ LPRECT pRect, + _In_ const DTTOPTS *options +); #endif #ifdef __cplusplus