[v3 PATCH 2/2] comctl32/taskdialog: Add support for TDN_TIMER notification.

Nikolay Sivov nsivov at codeweavers.com
Sat May 19 10:28:19 CDT 2018


From: Zhiyi Zhang <zzhang at codeweavers.com>

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---

v3: extended the test with S_FALSE case, some formatting changes.

 dlls/comctl32/taskdialog.c       | 22 ++++++++++++++
 dlls/comctl32/tests/taskdialog.c | 52 ++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index 644f60fbb8..ec0448558b 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -48,10 +48,13 @@ static const UINT DIALOG_MIN_WIDTH = 240;
 static const UINT DIALOG_SPACING = 5;
 static const UINT DIALOG_BUTTON_WIDTH = 50;
 static const UINT DIALOG_BUTTON_HEIGHT = 14;
+static const UINT DIALOG_TIMER_MS = 200;
 
 static const UINT ID_MAIN_INSTRUCTION = 0xf000;
 static const UINT ID_CONTENT          = 0xf001;
 
+static const UINT ID_TIMER = 1;
+
 struct taskdialog_control
 {
     struct list entry;
@@ -85,6 +88,7 @@ struct taskdialog_info
 {
     HWND hwnd;
     const TASKDIALOGCONFIG *taskconfig;
+    DWORD last_timer_tick;
 };
 
 static void pixels_to_dialogunits(const struct taskdialog_template_desc *desc, LONG *width, LONG *height)
@@ -535,7 +539,15 @@ static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, WORD
 
 static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd)
 {
+    const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
+
     dialog_info->hwnd = hwnd;
+
+    if (taskconfig->dwFlags & TDF_CALLBACK_TIMER)
+    {
+        SetTimer(hwnd, ID_TIMER, DIALOG_TIMER_MS, NULL);
+        dialog_info->last_timer_tick = GetTickCount();
+    }
 }
 
 static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -574,9 +586,19 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
         case WM_HELP:
             taskdialog_notify(dialog_info, TDN_HELP, 0, 0);
             break;
+        case WM_TIMER:
+            if (ID_TIMER == wParam)
+            {
+                DWORD elapsed = GetTickCount() - dialog_info->last_timer_tick;
+                if (taskdialog_notify(dialog_info, TDN_TIMER, elapsed, 0) == S_FALSE)
+                    dialog_info->last_timer_tick = GetTickCount();
+            }
+            break;
         case WM_DESTROY:
             taskdialog_notify(dialog_info, TDN_DESTROYED, 0, 0);
             RemovePropW(hwnd, taskdialog_info_propnameW);
+            if (dialog_info->taskconfig->dwFlags & TDF_CALLBACK_TIMER)
+                KillTimer(hwnd, ID_TIMER);
             break;
         default:
             return FALSE;
diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
index ad455554b2..432b89bd15 100644
--- a/dlls/comctl32/tests/taskdialog.c
+++ b/dlls/comctl32/tests/taskdialog.c
@@ -323,6 +323,57 @@ static void test_help(void)
     run_test(&info, IDOK, msg_got_tdn_help, "send f1");
 }
 
+struct timer_notification_data
+{
+    DWORD last_elapsed_ms;
+    DWORD num_fired;
+};
+
+static HRESULT CALLBACK taskdialog_callback_proc_timer(HWND hwnd, UINT notification,
+        WPARAM wParam, LPARAM lParam, LONG_PTR ref_data)
+{
+    struct timer_notification_data *data = (struct timer_notification_data *)ref_data;
+
+    if (notification == TDN_TIMER)
+    {
+        DWORD elapsed_ms;
+        int delta;
+
+        elapsed_ms = (DWORD)wParam;
+
+        if (data->num_fired == 3)
+            ok(data->last_elapsed_ms > elapsed_ms, "Expected reference time update.\n");
+        else
+        {
+            delta = elapsed_ms - data->last_elapsed_ms;
+            ok(delta > 0, "Expected positive time tick difference.\n");
+        }
+        data->last_elapsed_ms = elapsed_ms;
+
+        if (data->num_fired == 3)
+            PostMessageW(hwnd, TDM_CLICK_BUTTON, IDOK, 0);
+
+        ++data->num_fired;
+        return data->num_fired == 3 ? S_FALSE : S_OK;
+    }
+
+    return S_OK;
+}
+
+static void test_timer(void)
+{
+    struct timer_notification_data data = { 0 };
+    TASKDIALOGCONFIG info = { 0 };
+
+    info.cbSize = sizeof(TASKDIALOGCONFIG);
+    info.pfCallback = taskdialog_callback_proc_timer;
+    info.lpCallbackData = (LONG_PTR)&data;
+    info.dwFlags = TDF_CALLBACK_TIMER;
+    info.dwCommonButtons = TDCBF_OK_BUTTON;
+
+    pTaskDialogIndirect(&info, NULL, NULL, NULL);
+}
+
 START_TEST(taskdialog)
 {
     ULONG_PTR ctx_cookie;
@@ -360,6 +411,7 @@ START_TEST(taskdialog)
     test_callback();
     test_buttons();
     test_help();
+    test_timer();
 
     unload_v6_module(ctx_cookie, hCtx);
 }
-- 
2.17.0




More information about the wine-devel mailing list