Comctl32 V6 adds three different states into the progress bar: Normal, Paused, and Error. These three states change the color of the bar based on the theme.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56352
-- v8: comctl32/progress: Add states for progress bar.
From: Jacob Czekalla jczekalla@codeweavers.com
--- dlls/comctl32/tests/progress.c | 99 +++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/tests/progress.c b/dlls/comctl32/tests/progress.c index b6716366498..5660d915f46 100644 --- a/dlls/comctl32/tests/progress.c +++ b/dlls/comctl32/tests/progress.c @@ -23,16 +23,26 @@ #include "winbase.h" #include "wingdi.h" #include "winuser.h" -#include "commctrl.h" +#include "commctrl.h" +#include "vssym32.h"
#include "wine/test.h" - #include "v6util.h" +#include "msg.h"
static HWND hProgressParentWnd; static const char progressTestClass[] = "ProgressBarTestClass"; static BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
+/* For message tests */ +enum seq_index +{ + CHILD_SEQ_INDEX, + NUM_MSG_SEQUENCES +}; + +static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; + static HWND create_progress(DWORD style) { return CreateWindowExA(0, PROGRESS_CLASSA, "", WS_VISIBLE | style, @@ -308,6 +318,89 @@ static void test_PBM_STEPIT(void) } }
+static WNDPROC old_proc; + +static const struct message paint_pbm_setstate_seq[] = +{ + {PBM_SETSTATE, sent}, + {WM_PAINT, sent}, + {WM_ERASEBKGND, sent | defwinproc}, + {0} +}; + +static const struct message pbm_setstate_seq[] = +{ + {PBM_SETSTATE, sent}, + {0} +}; + +static LRESULT WINAPI test_pbm_setstate_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) +{ + static int defwndproc_counter = 0; + struct message msg = {0}; + LRESULT ret; + + if (message == PBM_SETSTATE + || message == WM_PAINT + || message == WM_ERASEBKGND) + { + msg.message = message; + msg.flags = sent | wparam | lparam; + if (defwndproc_counter) + msg.flags |= defwinproc; + msg.wParam = wp; + msg.lParam = lp; + add_message(sequences, CHILD_SEQ_INDEX, &msg); + } + + ++defwndproc_counter; + ret = CallWindowProcA(old_proc, hwnd, message, wp, lp); + --defwndproc_counter; + return ret; +} + +void test_bar_states(void) +{ + HWND progress_bar; + int state; + + static const struct + { + DWORD state; + DWORD previous_state; + const struct message *expected_seq; + BOOL error; + } + tests[] = + { + {0, PBST_NORMAL, pbm_setstate_seq, 1}, + {PBST_NORMAL, PBST_NORMAL, pbm_setstate_seq, 0}, + {PBST_PAUSED, PBST_NORMAL, paint_pbm_setstate_seq, 0}, + {PBST_PAUSED, PBST_PAUSED, pbm_setstate_seq, 0}, + {PBST_ERROR, PBST_PAUSED, paint_pbm_setstate_seq, 0}, + {PBST_ERROR, PBST_ERROR, pbm_setstate_seq, 0}, + {PBFS_PARTIAL, PBST_ERROR, pbm_setstate_seq, 1} + }; + + progress_bar = create_progress(0); + + old_proc = (WNDPROC)SetWindowLongPtrA(progress_bar, GWLP_WNDPROC, (LONG_PTR)test_pbm_setstate_proc); + flush_events(); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + for (int i = 0; i < ARRAY_SIZE(tests); i++) + { + state = SendMessageA(progress_bar, PBM_SETSTATE, tests[i].state, 0); + flush_events(); + ok_sequence(sequences, CHILD_SEQ_INDEX, tests[i].expected_seq, "PBM_SETSTATE", TRUE); + todo_wine ok(state == (tests[i].error ? 0 : tests[i].previous_state), "Expected %ld, but got %d.\n", tests[i].previous_state, state); + state = SendMessageA(progress_bar, PBM_GETSTATE, 0, 0); + todo_wine ok(state == (tests[i].error ? tests[i].previous_state : tests[i].state), "Expected %ld, but got %d.\n", tests[i].state, state); + } + + DestroyWindow(progress_bar); +} + static void init_functions(void) { HMODULE hComCtl32 = LoadLibraryA("comctl32.dll"); @@ -337,9 +430,11 @@ START_TEST(progress)
if (!load_v6_module(&ctx_cookie, &hCtx)) return; + init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
test_setcolors(); test_PBM_STEPIT(); + test_bar_states();
unload_v6_module(ctx_cookie, hCtx);
From: Jacob Czekalla jczekalla@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56352 --- dlls/comctl32/progress.c | 28 ++++++++++++++++++++++------ dlls/comctl32/tests/progress.c | 6 +++--- dlls/comctl32/tests/taskdialog.c | 5 ++--- 3 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/dlls/comctl32/progress.c b/dlls/comctl32/progress.c index 6d556f10094..fcecd7bb293 100644 --- a/dlls/comctl32/progress.c +++ b/dlls/comctl32/progress.c @@ -53,6 +53,7 @@ typedef struct COLORREF ColorBar; /* Bar color */ COLORREF ColorBk; /* Background color */ HFONT Font; /* Handle to font (not unused) */ + UINT State; /* State of progress bar */ } PROGRESS_INFO;
/* Control configuration constants */ @@ -147,6 +148,7 @@ typedef struct tagProgressDrawInfo int ledW, ledGap; HTHEME theme; RECT bgRect; + UINT state; } ProgressDrawInfo;
typedef void (*ProgressDrawProc)(const ProgressDrawInfo* di, int start, int end); @@ -243,7 +245,7 @@ static void draw_theme_bar_H (const ProgressDrawInfo* di, int start, int end) r.top = di->rect.top; r.bottom = di->rect.bottom; r.right = di->rect.left + end; - DrawThemeBackground (di->theme, di->hdc, PP_CHUNK, 0, &r, NULL); + DrawThemeBackground (di->theme, di->hdc, PP_FILL, di->state, &r, NULL); }
/* draw themed vertical bar from 'start' to 'end' */ @@ -254,7 +256,7 @@ static void draw_theme_bar_V (const ProgressDrawInfo* di, int start, int end) r.right = di->rect.right; r.bottom = di->rect.bottom - start; r.top = di->rect.bottom - end; - DrawThemeBackground (di->theme, di->hdc, PP_CHUNKVERT, 0, &r, NULL); + DrawThemeBackground (di->theme, di->hdc, PP_FILLVERT, di->state, &r, NULL); }
/* draw themed horizontal background from 'start' to 'end' */ @@ -310,6 +312,7 @@ static LRESULT PROGRESS_Draw (PROGRESS_INFO *infoPtr, HDC hdc) TRACE("(infoPtr=%p, hdc=%p)\n", infoPtr, hdc);
pdi.hdc = hdc; + pdi.state = infoPtr->State; pdi.theme = GetWindowTheme (infoPtr->Self);
/* get the required bar brush */ @@ -522,6 +525,20 @@ static UINT PROGRESS_SetPos (PROGRESS_INFO *infoPtr, INT pos) } }
+static UINT PROGRESS_SetState (HWND hwnd, PROGRESS_INFO *infoPtr, UINT state) +{ + UINT prev_state = infoPtr->State; + + if (state == PBST_NORMAL || state == PBST_PAUSED || state == PBST_ERROR) + infoPtr->State = state; + else + return 0; + + if (state != prev_state) + InvalidateRect(hwnd, NULL, TRUE); + return prev_state; +} + /*********************************************************************** * ProgressWindowProc */ @@ -569,6 +586,7 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message, infoPtr->ColorBar = CLR_DEFAULT; infoPtr->ColorBk = CLR_DEFAULT; infoPtr->Font = 0; + infoPtr->State = PBST_NORMAL;
TRACE("Progress Ctrl creation, hwnd=%p\n", hwnd); return 0; @@ -711,12 +729,10 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message, return infoPtr->ColorBk;
case PBM_SETSTATE: - if(wParam != PBST_NORMAL) - FIXME("state %Ix not yet handled\n", wParam); - return PBST_NORMAL; + return PROGRESS_SetState(hwnd, infoPtr, wParam);
case PBM_GETSTATE: - return PBST_NORMAL; + return infoPtr->State;
case PBM_SETMARQUEE: if(wParam != 0) diff --git a/dlls/comctl32/tests/progress.c b/dlls/comctl32/tests/progress.c index 5660d915f46..092137985fb 100644 --- a/dlls/comctl32/tests/progress.c +++ b/dlls/comctl32/tests/progress.c @@ -392,10 +392,10 @@ void test_bar_states(void) { state = SendMessageA(progress_bar, PBM_SETSTATE, tests[i].state, 0); flush_events(); - ok_sequence(sequences, CHILD_SEQ_INDEX, tests[i].expected_seq, "PBM_SETSTATE", TRUE); - todo_wine ok(state == (tests[i].error ? 0 : tests[i].previous_state), "Expected %ld, but got %d.\n", tests[i].previous_state, state); + ok_sequence(sequences, CHILD_SEQ_INDEX, tests[i].expected_seq, "PBM_SETSTATE", FALSE); + ok(state == (tests[i].error ? 0 : tests[i].previous_state), "Expected %ld, but got %d.\n", tests[i].previous_state, state); state = SendMessageA(progress_bar, PBM_GETSTATE, 0, 0); - todo_wine ok(state == (tests[i].error ? tests[i].previous_state : tests[i].state), "Expected %ld, but got %d.\n", tests[i].state, state); + ok(state == (tests[i].error ? tests[i].previous_state : tests[i].state), "Expected %ld, but got %d.\n", tests[i].state, state); }
DestroyWindow(progress_bar); diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c index ef60a5953bd..5fbe5a65b1b 100644 --- a/dlls/comctl32/tests/taskdialog.c +++ b/dlls/comctl32/tests/taskdialog.c @@ -721,10 +721,9 @@ static HRESULT CALLBACK taskdialog_callback_proc_progress_bar(HWND hwnd, UINT no ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_STATE, PBST_PAUSED, 0); ok(ret == PBST_NORMAL, "Expect state: %d got state: %lx\n", PBST_NORMAL, ret); ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_STATE, PBST_ERROR, 0); - /* Progress bar has fixme on handling PBM_SETSTATE message */ - todo_wine ok(ret == PBST_PAUSED, "Expect state: %d got state: %lx\n", PBST_PAUSED, ret); + ok(ret == PBST_PAUSED, "Expect state: %d got state: %lx\n", PBST_PAUSED, ret); ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_STATE, PBST_NORMAL, 0); - todo_wine ok(ret == PBST_ERROR, "Expect state: %d got state: %lx\n", PBST_ERROR, ret); + ok(ret == PBST_ERROR, "Expect state: %d got state: %lx\n", PBST_ERROR, ret);
/* TDM_SET_PROGRESS_BAR_RANGE */ ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(0, 200));
This merge request was approved by Zhiyi Zhang.