From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/comctl32/progress.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/dlls/comctl32/progress.c b/dlls/comctl32/progress.c index 93f85bbbb32..178e76dff09 100644 --- a/dlls/comctl32/progress.c +++ b/dlls/comctl32/progress.c @@ -145,7 +145,6 @@ typedef struct tagProgressDrawInfo HBRUSH hbrBar; HBRUSH hbrBk; int ledW, ledGap; - HTHEME theme; } ProgressDrawInfo;
typedef void (*ProgressDrawProc)(const ProgressDrawInfo* di, int start, int end); @@ -333,6 +332,16 @@ static BOOL PROGRESS_IsSmooth(HWND hwnd) return GetWindowLongW(hwnd, GWL_STYLE) & PBS_SMOOTH; }
+static const ProgressDrawProc *PROGRESS_GetDrawProcs(HWND hwnd, BOOL smooth, DWORD style) +{ + int proc_idx = (smooth ? 0 : 4) + ((style & PBS_VERTICAL) ? 2 : 0); + + if (GetWindowTheme(hwnd)) + return &drawProcThemed[proc_idx]; + + return &drawProcClassic[proc_idx]; +} + /*********************************************************************** * PROGRESS_Draw * Draws the progress bar. @@ -349,7 +358,6 @@ static LRESULT PROGRESS_Draw (PROGRESS_INFO *infoPtr, HDC hdc)
pdi.infoPtr = infoPtr; pdi.hdc = hdc; - pdi.theme = GetWindowTheme (infoPtr->Self);
/* get the required bar brush */ if (infoPtr->ColorBar == CLR_DEFAULT) @@ -371,8 +379,7 @@ static LRESULT PROGRESS_Draw (PROGRESS_INFO *infoPtr, HDC hdc)
/* compute some drawing parameters */ barSmooth = PROGRESS_IsSmooth(infoPtr->Self); - drawProcs = &((pdi.theme ? drawProcThemed : drawProcClassic)[(barSmooth ? 0 : 4) - + ((dwStyle & PBS_VERTICAL) ? 2 : 0)]); + drawProcs = PROGRESS_GetDrawProcs(infoPtr->Self, barSmooth, dwStyle); barSize = get_bar_size( dwStyle, &pdi.rect );
if (!barSmooth)
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/comctl32/progress.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/progress.c b/dlls/comctl32/progress.c index 178e76dff09..3c44f052fc9 100644 --- a/dlls/comctl32/progress.c +++ b/dlls/comctl32/progress.c @@ -586,7 +586,7 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message, theme = OpenThemeData (hwnd, themeClass);
dwExStyle &= ~(WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE); - if (!theme) dwExStyle |= WS_EX_STATICEDGE; + if (!COMCTL32_IsThemed (hwnd)) dwExStyle |= WS_EX_STATICEDGE; SetWindowLongW (hwnd, GWL_EXSTYLE, dwExStyle); /* Force recalculation of a non-client area */ SetWindowPos(hwnd, 0, 0, 0, 0, 0, @@ -654,7 +654,7 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message, theme = OpenThemeData (hwnd, themeClass);
/* WS_EX_STATICEDGE disappears when the control is themed */ - if (theme) + if (COMCTL32_IsThemed (hwnd)) dwExStyle &= ~WS_EX_STATICEDGE; else dwExStyle |= WS_EX_STATICEDGE;
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/comctl32/progress.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/dlls/comctl32/progress.c b/dlls/comctl32/progress.c index 3c44f052fc9..16f4b29c6fd 100644 --- a/dlls/comctl32/progress.c +++ b/dlls/comctl32/progress.c @@ -561,6 +561,24 @@ static UINT PROGRESS_SetState (HWND hwnd, PROGRESS_INFO *infoPtr, UINT state) return prev_state; }
+static LRESULT PROGRESS_ThemeChanged(HWND hwnd) +{ + DWORD style = GetWindowLongW(hwnd, GWL_EXSTYLE); + + CloseThemeData(GetWindowTheme(hwnd)); + OpenThemeData(hwnd, L"Progress"); + + /* WS_EX_STATICEDGE disappears when the control is themed */ + if (COMCTL32_IsThemed(hwnd)) + style &= ~WS_EX_STATICEDGE; + else + style |= WS_EX_STATICEDGE; + SetWindowLongW(hwnd, GWL_EXSTYLE, style); + + InvalidateRect(hwnd, NULL, TRUE); + return 0; +} + /*********************************************************************** * ProgressWindowProc */ @@ -646,23 +664,7 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message, return 0;
case WM_THEMECHANGED: - { - DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE); - - theme = GetWindowTheme (hwnd); - CloseThemeData (theme); - theme = OpenThemeData (hwnd, themeClass); - - /* WS_EX_STATICEDGE disappears when the control is themed */ - if (COMCTL32_IsThemed (hwnd)) - dwExStyle &= ~WS_EX_STATICEDGE; - else - dwExStyle |= WS_EX_STATICEDGE; - SetWindowLongW (hwnd, GWL_EXSTYLE, dwExStyle); - - InvalidateRect (hwnd, NULL, TRUE); - return 0; - } + return PROGRESS_ThemeChanged (hwnd);
case PBM_DELTAPOS: {
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/comctl32/progress.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/dlls/comctl32/progress.c b/dlls/comctl32/progress.c index 16f4b29c6fd..9b7a1617e20 100644 --- a/dlls/comctl32/progress.c +++ b/dlls/comctl32/progress.c @@ -65,6 +65,7 @@ typedef struct static inline int get_led_size ( const PROGRESS_INFO *infoPtr, LONG style, const RECT* rect ) { +#if __WINE_COMCTL32_VERSION == 6 HTHEME theme = GetWindowTheme (infoPtr->Self); if (theme) { @@ -72,6 +73,7 @@ static inline int get_led_size ( const PROGRESS_INFO *infoPtr, LONG style, if (SUCCEEDED( GetThemeInt( theme, 0, 0, TMT_PROGRESSCHUNKSIZE, &chunkSize ))) return chunkSize; } +#endif
if (style & PBS_VERTICAL) return MulDiv (rect->right - rect->left, 2, 3); @@ -82,6 +84,7 @@ static inline int get_led_size ( const PROGRESS_INFO *infoPtr, LONG style, /* Helper to obtain gap between progress bar chunks */ static inline int get_led_gap ( const PROGRESS_INFO *infoPtr ) { +#if __WINE_COMCTL32_VERSION == 6 HTHEME theme = GetWindowTheme (infoPtr->Self); if (theme) { @@ -89,6 +92,7 @@ static inline int get_led_gap ( const PROGRESS_INFO *infoPtr ) if (SUCCEEDED( GetThemeInt( theme, 0, 0, TMT_PROGRESSSPACESIZE, &spaceSize ))) return spaceSize; } +#endif
return LED_GAP; } @@ -96,16 +100,21 @@ static inline int get_led_gap ( const PROGRESS_INFO *infoPtr ) /* Get client rect. Takes into account that theming needs no adjustment. */ static inline void get_client_rect (HWND hwnd, RECT* rect) { +#if __WINE_COMCTL32_VERSION == 6 HTHEME theme = GetWindowTheme (hwnd); - GetClientRect (hwnd, rect); - if (!theme) - InflateRect(rect, -1, -1); - else + + if (theme) { DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE); int part = (dwStyle & PBS_VERTICAL) ? PP_BARVERT : PP_BAR; + GetClientRect (hwnd, rect); GetThemeBackgroundContentRect (theme, 0, part, 0, rect, rect); + return; } +#endif + + GetClientRect (hwnd, rect); + InflateRect (rect, -1, -1); }
/* Compute the extend of the bar */ @@ -233,6 +242,7 @@ static const ProgressDrawProc drawProcClassic[8] = { draw_chunk_bar_V, draw_solid_bkg_V, };
+#if __WINE_COMCTL32_VERSION == 6 /* draw themed horizontal bar from 'start' to 'end' */ static void draw_theme_bar_H (const ProgressDrawInfo* di, int start, int end) { @@ -298,9 +308,11 @@ static const ProgressDrawProc drawProcThemed[8] = { /* Vertical */ draw_theme_bar_V, draw_theme_bkg_V, }; +#endif /* __WINE_COMCTL32_VERSION == 6 */
static void PROGRESS_DrawBackground (const PROGRESS_INFO *infoPtr, HDC hdc, ProgressDrawInfo *pdi) { +#if __WINE_COMCTL32_VERSION == 6 HTHEME theme = GetWindowTheme (infoPtr->Self);
if (theme) @@ -319,6 +331,7 @@ static void PROGRESS_DrawBackground (const PROGRESS_INFO *infoPtr, HDC hdc, Prog pdi->rect = content_rect; return; } +#endif
FrameRect (hdc, &pdi->rect, pdi->hbrBk); InflateRect (&pdi->rect, -1, -1); @@ -326,8 +339,10 @@ static void PROGRESS_DrawBackground (const PROGRESS_INFO *infoPtr, HDC hdc, Prog
static BOOL PROGRESS_IsSmooth(HWND hwnd) { +#if __WINE_COMCTL32_VERSION == 6 if (GetWindowTheme(hwnd)) return FALSE; +#endif
return GetWindowLongW(hwnd, GWL_STYLE) & PBS_SMOOTH; } @@ -336,8 +351,10 @@ static const ProgressDrawProc *PROGRESS_GetDrawProcs(HWND hwnd, BOOL smooth, DWO { int proc_idx = (smooth ? 0 : 4) + ((style & PBS_VERTICAL) ? 2 : 0);
+#if __WINE_COMCTL32_VERSION == 6 if (GetWindowTheme(hwnd)) return &drawProcThemed[proc_idx]; +#endif
return &drawProcClassic[proc_idx]; } @@ -563,6 +580,7 @@ static UINT PROGRESS_SetState (HWND hwnd, PROGRESS_INFO *infoPtr, UINT state)
static LRESULT PROGRESS_ThemeChanged(HWND hwnd) { +#if __WINE_COMCTL32_VERSION == 6 DWORD style = GetWindowLongW(hwnd, GWL_EXSTYLE);
CloseThemeData(GetWindowTheme(hwnd)); @@ -577,6 +595,9 @@ static LRESULT PROGRESS_ThemeChanged(HWND hwnd)
InvalidateRect(hwnd, NULL, TRUE); return 0; +#else + return DefWindowProcW(hwnd, WM_THEMECHANGED, 0, 0); +#endif }
/*********************************************************************** @@ -586,8 +607,6 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PROGRESS_INFO *infoPtr; - static const WCHAR themeClass[] = L"Progress"; - HTHEME theme;
TRACE("hwnd %p, msg %04x, wparam %Ix, lParam %Ix\n", hwnd, message, wParam, lParam);
@@ -601,7 +620,7 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message, { DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
- theme = OpenThemeData (hwnd, themeClass); + COMCTL32_OpenThemeForWindow (hwnd, L"Progress");
dwExStyle &= ~(WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE); if (!COMCTL32_IsThemed (hwnd)) dwExStyle |= WS_EX_STATICEDGE; @@ -636,8 +655,7 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message, TRACE("Progress Ctrl destruction, hwnd=%p\n", hwnd); Free (infoPtr); SetWindowLongPtrW(hwnd, 0, 0); - theme = GetWindowTheme (hwnd); - CloseThemeData (theme); + COMCTL32_CloseThemeForWindow (hwnd); return 0;
case WM_ERASEBKGND:
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/comctl32/propsheet.c | 3 +++ dlls/comctl32/tests/propsheet.c | 1 - 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/comctl32/propsheet.c b/dlls/comctl32/propsheet.c index da15385f496..de369f60580 100644 --- a/dlls/comctl32/propsheet.c +++ b/dlls/comctl32/propsheet.c @@ -1630,8 +1630,11 @@ static BOOL PROPSHEET_CreatePage(HWND hwndParent, { SetWindowSubclass(hwndPage, PROPSHEET_WizardSubclassProc, 1, 0); } + +#if __WINE_COMCTL32_VERSION == 6 if (!(psInfo->ppshheader.dwFlags & INTRNL_ANY_WIZARD)) EnableThemeDialogTexture (hwndPage, ETDT_ENABLETAB); +#endif
return TRUE; } diff --git a/dlls/comctl32/tests/propsheet.c b/dlls/comctl32/tests/propsheet.c index ba9e9be030c..812f6530478 100644 --- a/dlls/comctl32/tests/propsheet.c +++ b/dlls/comctl32/tests/propsheet.c @@ -1292,7 +1292,6 @@ static void test_page_dialog_texture(void)
/* Test that theme dialog texture is enabled for comctl32 v6, even when theming is off */ ret = pIsThemeDialogTextureEnabled(sheethwnd); - todo_wine_if(!is_v6) ok(ret == is_v6, "Wrong theme dialog texture status.\n");
hwnd = CreateWindowA(WC_EDITA, "child", WS_POPUP | WS_VISIBLE, 1, 2, 50, 50, 0, 0, 0, NULL);
Nikolay Sivov (@nsivov) commented about dlls/comctl32/progress.c:
return GetWindowLongW(hwnd, GWL_STYLE) & PBS_SMOOTH;}
+static const ProgressDrawProc *PROGRESS_GetDrawProcs(HWND hwnd, BOOL smooth, DWORD style) +{
- int proc_idx = (smooth ? 0 : 4) + ((style & PBS_VERTICAL) ? 2 : 0);
It's en existing thing, but I still want to mention it. This is not going to use all 8 drawing functions, any idea why we have 8 of them? If all we need is 4 states, this should be made more obvious, for example
drawProcThemed[!!smooth][!!(style & PBS_VERTICAL)]
any idea why we have 8 of them?
There are 4 states. Then, for each state, there is a function to draw the progress bar and another one to draw the background. For example, draw_theme_bar_H() and draw_theme_bkg_H().
Then, they're called like the following. ``` drawProcs[0]( &pdi, 0, gapStart); /* Draw progress bar */ drawProcs[1]( &pdi, gapStart, gapEnd); /* Draw background */ drawProcs[0]( &pdi, gapEnd, barSize); /* Draw progress bar */ ```
On Mon Nov 10 09:50:18 2025 +0000, Zhiyi Zhang wrote:
any idea why we have 8 of them?
There are 4 states. Then, for each state, there is a function to draw the progress bar and another one to draw the background. For example, draw_theme_bar_H() and draw_theme_bkg_H(). Then, they're called like the following.
drawProcs[0]( &pdi, 0, gapStart); /* Draw progress bar */ drawProcs[1]( &pdi, gapStart, gapEnd); /* Draw background */ drawProcs[0]( &pdi, gapEnd, barSize); /* Draw progress bar */
Ah, ok, thanks.
On Mon Nov 10 09:51:23 2025 +0000, Nikolay Sivov wrote:
Ah, ok, thanks.
Obviously, they should be separated into two function groups. One for drawing the progress bar and the other one for the background. It would be much more intuitive this way. It can be done in a later patch though. I am trying not to introduce too many changes in this series.
On Mon Nov 10 11:30:24 2025 +0000, Zhiyi Zhang wrote:
Obviously, they should be separated into two function groups. One for drawing the progress bar and the other one for the background. It would be much more intuitive this way. It can be done in a later patch though. I am trying not to introduce too many changes in this series.
No, no need to do anything about that in this MR. We can improve it sometime later.
This merge request was approved by Nikolay Sivov.