Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/comctl32/taskdialog.c | 45 ++++++++++++++++++++++ dlls/comctl32/tests/taskdialog.c | 65 ++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+)
diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c index 91c8af019b..3c198df6d1 100644 --- a/dlls/comctl32/taskdialog.c +++ b/dlls/comctl32/taskdialog.c @@ -57,6 +57,7 @@ struct taskdialog_info HWND main_icon; HWND main_instruction; HWND content; + HWND progress_bar; HWND *buttons; INT button_count; HWND default_button; @@ -351,6 +352,17 @@ static void taskdialog_add_content(struct taskdialog_info *dialog_info) taskdialog_hyperlink_enabled(dialog_info)); }
+static void taskdialog_add_progress_bar(struct taskdialog_info *dialog_info) +{ + const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig; + DWORD style = PBS_SMOOTH | PBS_SMOOTHREVERSE | WS_CHILD | WS_VISIBLE; + + if (!(taskconfig->dwFlags & (TDF_SHOW_PROGRESS_BAR | TDF_SHOW_MARQUEE_PROGRESS_BAR))) return; + if (taskconfig->dwFlags & TDF_SHOW_MARQUEE_PROGRESS_BAR) style |= PBS_MARQUEE; + dialog_info->progress_bar = + CreateWindowW(PROGRESS_CLASSW, NULL, style, 0, 0, 0, 0, dialog_info->hwnd, NULL, 0, NULL); +} + static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *button, INT id, const WCHAR *text, BOOL custom_button) { @@ -464,6 +476,17 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info) /* Content */ taskdialog_label_layout(dialog_info, dialog_info->content, main_icon_right, dialog_width, &dialog_height, syslink);
+ /* Progress bar */ + if (dialog_info->progress_bar) + { + x = main_icon_right + h_spacing; + y = dialog_height + v_spacing; + size.cx = dialog_width - x - h_spacing; + size.cy = GetSystemMetrics(SM_CYVSCROLL); + SetWindowPos(dialog_info->progress_bar, 0, x, y, size.cx, size.cy, SWP_NOZORDER); + dialog_height = y + size.cy; + } + dialog_height = max(dialog_height, main_icon_bottom);
/* Common and custom buttons */ @@ -598,6 +621,7 @@ static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd) taskdialog_add_main_icon(dialog_info); taskdialog_add_main_instruction(dialog_info); taskdialog_add_content(dialog_info); + taskdialog_add_progress_bar(dialog_info); taskdialog_add_buttons(dialog_info);
/* Set default button */ @@ -621,6 +645,7 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR { static const WCHAR taskdialog_info_propnameW[] = {'T','a','s','k','D','i','a','l','o','g','I','n','f','o',0}; struct taskdialog_info *dialog_info; + LRESULT result;
TRACE("hwnd=%p msg=0x%04x wparam=%lx lparam=%lx\n", hwnd, msg, wParam, lParam);
@@ -635,6 +660,26 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR case TDM_ENABLE_BUTTON: taskdialog_enable_button(dialog_info, wParam, lParam); break; + case TDM_SET_MARQUEE_PROGRESS_BAR: + SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, 0); + break; + case TDM_SET_PROGRESS_BAR_STATE: + result = SendMessageW(dialog_info->progress_bar, PBM_SETSTATE, wParam, 0); + SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, result); + break; + case TDM_SET_PROGRESS_BAR_RANGE: + result = SendMessageW(dialog_info->progress_bar, PBM_SETRANGE, 0, lParam); + SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, result); + break; + case TDM_SET_PROGRESS_BAR_POS: + result = 0; + if (!(dialog_info->taskconfig->dwFlags & TDF_SHOW_MARQUEE_PROGRESS_BAR)) + result = SendMessageW(dialog_info->progress_bar, PBM_SETPOS, wParam, 0); + SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, result); + break; + case TDM_SET_PROGRESS_BAR_MARQUEE: + SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, lParam); + break; case WM_INITDIALOG: dialog_info = (struct taskdialog_info *)lParam;
diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c index cca700cd18..10cd3da794 100644 --- a/dlls/comctl32/tests/taskdialog.c +++ b/dlls/comctl32/tests/taskdialog.c @@ -373,6 +373,70 @@ static void test_timer(void) pTaskDialogIndirect(&info, NULL, NULL, NULL); }
+static HRESULT CALLBACK taskdialog_callback_proc_progress_bar(HWND hwnd, UINT notification, WPARAM wParam, + LPARAM lParam, LONG_PTR ref_data) +{ + unsigned long ret; + DWORD *flags = (DWORD *)ref_data; + if (notification == TDN_CREATED) + { + /* TDM_SET_PROGRESS_BAR_STATE */ + ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_STATE, PBST_NORMAL, 0); + ok(ret == PBST_NORMAL, "Expect state: %d got state: %lx\n", PBST_NORMAL, ret); + 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); + 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); + + /* TDM_SET_PROGRESS_BAR_RANGE */ + ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(0, 200)); + ok(ret == MAKELONG(0, 100), "Expect range:%x got:%lx\n", MAKELONG(0, 100), ret); + ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(0, 200)); + ok(ret == MAKELONG(0, 200), "Expect range:%x got:%lx\n", MAKELONG(0, 200), ret); + + /* TDM_SET_PROGRESS_BAR_POS */ + if (*flags & TDF_SHOW_MARQUEE_PROGRESS_BAR) + { + ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_POS, 1, 0); + ok(ret == 0, "Expect position:%x got:%lx\n", 0, ret); + ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_POS, 2, 0); + ok(ret == 0, "Expect position:%x got:%lx\n", 0, ret); + } + else + { + ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_POS, 1, 0); + ok(ret == 0, "Expect position:%x got:%lx\n", 0, ret); + ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_POS, 2, 0); + ok(ret == 1, "Expect position:%x got:%lx\n", 1, ret); + } + + SendMessageW(hwnd, TDM_CLICK_BUTTON, IDOK, 0); + } + + return S_OK; +} + +static void test_progress_bar(void) +{ + TASKDIALOGCONFIG info = {0}; + + info.cbSize = sizeof(TASKDIALOGCONFIG); + info.dwFlags = TDF_SHOW_PROGRESS_BAR; + info.pfCallback = taskdialog_callback_proc_progress_bar; + info.lpCallbackData = (LONG_PTR)&info.dwFlags; + info.dwCommonButtons = TDCBF_OK_BUTTON; + pTaskDialogIndirect(&info, NULL, NULL, NULL); + + info.dwFlags = TDF_SHOW_MARQUEE_PROGRESS_BAR; + pTaskDialogIndirect(&info, NULL, NULL, NULL); + + info.dwFlags = TDF_SHOW_PROGRESS_BAR | TDF_SHOW_MARQUEE_PROGRESS_BAR; + pTaskDialogIndirect(&info, NULL, NULL, NULL); +} + START_TEST(taskdialog) { ULONG_PTR ctx_cookie; @@ -411,6 +475,7 @@ START_TEST(taskdialog) test_buttons(); test_help(); test_timer(); + test_progress_bar();
unload_v6_module(ctx_cookie, hCtx); }
On 06/14/2018 11:02 AM, Zhiyi Zhang wrote:
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com
dlls/comctl32/taskdialog.c | 45 ++++++++++++++++++++++ dlls/comctl32/tests/taskdialog.c | 65 ++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+)
diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c index 91c8af019b..3c198df6d1 100644 --- a/dlls/comctl32/taskdialog.c +++ b/dlls/comctl32/taskdialog.c @@ -57,6 +57,7 @@ struct taskdialog_info HWND main_icon; HWND main_instruction; HWND content;
- HWND progress_bar; HWND *buttons; INT button_count; HWND default_button;
@@ -351,6 +352,17 @@ static void taskdialog_add_content(struct taskdialog_info *dialog_info) taskdialog_hyperlink_enabled(dialog_info)); }
+static void taskdialog_add_progress_bar(struct taskdialog_info *dialog_info) +{
- const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
- DWORD style = PBS_SMOOTH | PBS_SMOOTHREVERSE | WS_CHILD | WS_VISIBLE;
- if (!(taskconfig->dwFlags & (TDF_SHOW_PROGRESS_BAR | TDF_SHOW_MARQUEE_PROGRESS_BAR))) return;
- if (taskconfig->dwFlags & TDF_SHOW_MARQUEE_PROGRESS_BAR) style |= PBS_MARQUEE;
- dialog_info->progress_bar =
CreateWindowW(PROGRESS_CLASSW, NULL, style, 0, 0, 0, 0, dialog_info->hwnd, NULL, 0, NULL);
+}
- static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *button, INT id, const WCHAR *text, BOOL custom_button) {
@@ -464,6 +476,17 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info) /* Content */ taskdialog_label_layout(dialog_info, dialog_info->content, main_icon_right, dialog_width, &dialog_height, syslink);
/* Progress bar */
if (dialog_info->progress_bar)
{
x = main_icon_right + h_spacing;
y = dialog_height + v_spacing;
size.cx = dialog_width - x - h_spacing;
size.cy = GetSystemMetrics(SM_CYVSCROLL);
SetWindowPos(dialog_info->progress_bar, 0, x, y, size.cx, size.cy, SWP_NOZORDER);
dialog_height = y + size.cy;
}
dialog_height = max(dialog_height, main_icon_bottom); /* Common and custom buttons */
@@ -598,6 +621,7 @@ static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd) taskdialog_add_main_icon(dialog_info); taskdialog_add_main_instruction(dialog_info); taskdialog_add_content(dialog_info);
taskdialog_add_progress_bar(dialog_info); taskdialog_add_buttons(dialog_info);
/* Set default button */
@@ -621,6 +645,7 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR { static const WCHAR taskdialog_info_propnameW[] = {'T','a','s','k','D','i','a','l','o','g','I','n','f','o',0}; struct taskdialog_info *dialog_info;
LRESULT result;
TRACE("hwnd=%p msg=0x%04x wparam=%lx lparam=%lx\n", hwnd, msg, wParam, lParam);
@@ -635,6 +660,26 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR case TDM_ENABLE_BUTTON: taskdialog_enable_button(dialog_info, wParam, lParam); break;
case TDM_SET_MARQUEE_PROGRESS_BAR:
SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, 0);
break;
This appears to be wrong, it shouldn't just start/stop animation, but switch from marquee to regular mode and back, in our case flipping styles.
case TDM_SET_PROGRESS_BAR_POS:
result = 0;
if (!(dialog_info->taskconfig->dwFlags & TDF_SHOW_MARQUEE_PROGRESS_BAR))
result = SendMessageW(dialog_info->progress_bar, PBM_SETPOS, wParam, 0);
SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, result);
break;
Did you verify that Progress control handles this correctly, maybe flags check is not necessary?
case TDM_SET_PROGRESS_BAR_MARQUEE:
SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, lParam);
break; case WM_INITDIALOG: dialog_info = (struct taskdialog_info *)lParam;
diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c index cca700cd18..10cd3da794 100644 --- a/dlls/comctl32/tests/taskdialog.c +++ b/dlls/comctl32/tests/taskdialog.c @@ -373,6 +373,70 @@ static void test_timer(void) pTaskDialogIndirect(&info, NULL, NULL, NULL); }
+static HRESULT CALLBACK taskdialog_callback_proc_progress_bar(HWND hwnd, UINT notification, WPARAM wParam,
LPARAM lParam, LONG_PTR ref_data)
+{
- unsigned long ret;
- DWORD *flags = (DWORD *)ref_data;
You can pass flags by value.
On Thu 6 14 21:03, Nikolay Sivov wrote:
On 06/14/2018 11:02 AM, Zhiyi Zhang wrote:
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com
dlls/comctl32/taskdialog.c | 45 ++++++++++++++++++++++ dlls/comctl32/tests/taskdialog.c | 65 ++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+)
diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c index 91c8af019b..3c198df6d1 100644 --- a/dlls/comctl32/taskdialog.c +++ b/dlls/comctl32/taskdialog.c @@ -57,6 +57,7 @@ struct taskdialog_info HWND main_icon; HWND main_instruction; HWND content; + HWND progress_bar; HWND *buttons; INT button_count; HWND default_button; @@ -351,6 +352,17 @@ static void taskdialog_add_content(struct taskdialog_info *dialog_info) taskdialog_hyperlink_enabled(dialog_info)); } +static void taskdialog_add_progress_bar(struct taskdialog_info *dialog_info) +{ + const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig; + DWORD style = PBS_SMOOTH | PBS_SMOOTHREVERSE | WS_CHILD | WS_VISIBLE;
+ if (!(taskconfig->dwFlags & (TDF_SHOW_PROGRESS_BAR | TDF_SHOW_MARQUEE_PROGRESS_BAR))) return; + if (taskconfig->dwFlags & TDF_SHOW_MARQUEE_PROGRESS_BAR) style |= PBS_MARQUEE; + dialog_info->progress_bar = + CreateWindowW(PROGRESS_CLASSW, NULL, style, 0, 0, 0, 0, dialog_info->hwnd, NULL, 0, NULL); +}
static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *button, INT id, const WCHAR *text, BOOL custom_button) { @@ -464,6 +476,17 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info) /* Content */ taskdialog_label_layout(dialog_info, dialog_info->content, main_icon_right, dialog_width, &dialog_height, syslink); + /* Progress bar */ + if (dialog_info->progress_bar) + { + x = main_icon_right + h_spacing; + y = dialog_height + v_spacing; + size.cx = dialog_width - x - h_spacing; + size.cy = GetSystemMetrics(SM_CYVSCROLL); + SetWindowPos(dialog_info->progress_bar, 0, x, y, size.cx, size.cy, SWP_NOZORDER); + dialog_height = y + size.cy; + }
dialog_height = max(dialog_height, main_icon_bottom); /* Common and custom buttons */ @@ -598,6 +621,7 @@ static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd) taskdialog_add_main_icon(dialog_info); taskdialog_add_main_instruction(dialog_info); taskdialog_add_content(dialog_info); + taskdialog_add_progress_bar(dialog_info); taskdialog_add_buttons(dialog_info); /* Set default button */ @@ -621,6 +645,7 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR { static const WCHAR taskdialog_info_propnameW[] = {'T','a','s','k','D','i','a','l','o','g','I','n','f','o',0}; struct taskdialog_info *dialog_info; + LRESULT result; TRACE("hwnd=%p msg=0x%04x wparam=%lx lparam=%lx\n", hwnd, msg, wParam, lParam); @@ -635,6 +660,26 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR case TDM_ENABLE_BUTTON: taskdialog_enable_button(dialog_info, wParam, lParam); break; + case TDM_SET_MARQUEE_PROGRESS_BAR: + SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, 0); + break;
This appears to be wrong, it shouldn't just start/stop animation, but switch from marquee to regular mode and back, in our case flipping styles.
Thanks. In the end, turns out I still got it confused with TDM_SET_PROGRESS_BAR_MARQUEE, even though I noticed the easy confusion from the start :(
I sent a v2.
+ case TDM_SET_PROGRESS_BAR_POS: + result = 0; + if (!(dialog_info->taskconfig->dwFlags & TDF_SHOW_MARQUEE_PROGRESS_BAR)) + result = SendMessageW(dialog_info->progress_bar, PBM_SETPOS, wParam, 0); + SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, result); + break;
Did you verify that Progress control handles this correctly, maybe flags check is not necessary?
+ case TDM_SET_PROGRESS_BAR_MARQUEE: + SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, lParam); + break; case WM_INITDIALOG: dialog_info = (struct taskdialog_info *)lParam; diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c index cca700cd18..10cd3da794 100644 --- a/dlls/comctl32/tests/taskdialog.c +++ b/dlls/comctl32/tests/taskdialog.c @@ -373,6 +373,70 @@ static void test_timer(void) pTaskDialogIndirect(&info, NULL, NULL, NULL); } +static HRESULT CALLBACK taskdialog_callback_proc_progress_bar(HWND hwnd, UINT notification, WPARAM wParam, + LPARAM lParam, LONG_PTR ref_data) +{ + unsigned long ret; + DWORD *flags = (DWORD *)ref_data;
You can pass flags by value.
Sure.