Zhiyi Zhang : comctl32/taskdialog: Add support for progress bar.

Alexandre Julliard julliard at winehq.org
Fri Jun 15 15:41:00 CDT 2018


Module: wine
Branch: master
Commit: 1671ab53454e5ff545f46f6ab6a3424a4e34509a
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1671ab53454e5ff545f46f6ab6a3424a4e34509a

Author: Zhiyi Zhang <yi.gd.cn at gmail.com>
Date:   Fri Jun 15 11:07:49 2018 +0800

comctl32/taskdialog: Add support for progress bar.

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/comctl32/taskdialog.c       | 55 +++++++++++++++++++++++++++++++++
 dlls/comctl32/tests/taskdialog.c | 67 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 122 insertions(+)

diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index 07c031b..1a5fad1 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_PTR 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,36 @@ 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:
+        {
+            BOOL marquee = wParam;
+            LONG style;
+            if(!dialog_info->progress_bar) break;
+            style = GetWindowLongW(dialog_info->progress_bar, GWL_STYLE);
+            style = marquee ? style | PBS_MARQUEE : style & (~PBS_MARQUEE);
+            SetWindowLongW(dialog_info->progress_bar, GWL_STYLE, style);
+            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->progress_bar)
+            {
+                LONG style = GetWindowLongW(dialog_info->progress_bar, GWL_STYLE);
+                if (!(style & PBS_MARQUEE)) 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 cca700c..e91a878 100644
--- a/dlls/comctl32/tests/taskdialog.c
+++ b/dlls/comctl32/tests/taskdialog.c
@@ -373,6 +373,72 @@ 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;
+    LONG flags = (LONG)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;
+    info.lpCallbackData = (LONG_PTR)info.dwFlags;
+    pTaskDialogIndirect(&info, NULL, NULL, NULL);
+
+    info.dwFlags = TDF_SHOW_PROGRESS_BAR | TDF_SHOW_MARQUEE_PROGRESS_BAR;
+    info.lpCallbackData = (LONG_PTR)info.dwFlags;
+    pTaskDialogIndirect(&info, NULL, NULL, NULL);
+}
+
 START_TEST(taskdialog)
 {
     ULONG_PTR ctx_cookie;
@@ -411,6 +477,7 @@ START_TEST(taskdialog)
     test_buttons();
     test_help();
     test_timer();
+    test_progress_bar();
 
     unload_v6_module(ctx_cookie, hCtx);
 }




More information about the wine-cvs mailing list