[15/18] comctl32: TaskDialog - Set default button and add tests

Fabian Maurer dark.shadow4 at web.de
Fri Feb 24 14:04:09 CST 2017


Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>

# Conflicts:
#	dlls/comctl32/tests/taskdialog.c
---
 dlls/comctl32/taskdialog.c       | 17 ++++++--
 dlls/comctl32/tests/taskdialog.c | 92 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 106 insertions(+), 3 deletions(-)

diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index 864b616fb7..fcfc1fb243 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -414,7 +414,7 @@ static button_info make_button(HDC hdc, UINT dialog_width, int id, const WCHAR *
 }
 
 static UINT add_buttons(HDC hdc, const TASKDIALOGCONFIG *pTaskConfig, struct list *controls,
-                        UINT dialog_width, UINT dialog_height)
+                        UINT dialog_width, UINT dialog_height, int default_button)
 {
     static const WCHAR class_button[] = {'B','u','t','t','o','n',0};
     static const WCHAR text_ok[] = {'O','K',0};
@@ -426,6 +426,7 @@ static UINT add_buttons(HDC hdc, const TASKDIALOGCONFIG *pTaskConfig, struct lis
     UINT alignment = 40; /* minimum distance from the left dialog border */
     UINT location_x;
     BOOL first_row = TRUE;
+    BOOL found_default = FALSE; /* Whether the default button ID is valid or not */
     button_info *buttons;
     int count = 0;
     int i;
@@ -497,10 +498,20 @@ static UINT add_buttons(HDC hdc, const TASKDIALOGCONFIG *pTaskConfig, struct lis
             buttons[i].x += diff;
     }
 
+    for(i=0; i<count; i++)
+        if(buttons[i].id == default_button)
+            found_default = TRUE;
+
      /* Now that we got them all positioned, create all buttons */
     for(i=0; i<count; i++)
     {
-        controls_add(controls, buttons[i].id, class_button, buttons[i].text, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+        DWORD style = 0;
+        if((!found_default && i==0) || buttons[i].id == default_button)
+            style = BS_DEFPUSHBUTTON;
+        else
+            style = BS_PUSHBUTTON;
+
+        controls_add(controls, buttons[i].id, class_button, buttons[i].text, WS_CHILD | WS_VISIBLE | style,
                                buttons[i].x, buttons[i].y, buttons[i].width, 10);
     }
 
@@ -577,7 +588,7 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnBu
     }
 
     /* Create buttons */
-    dialog_height = add_buttons(dc_dummy, pTaskConfig, controls, dialog_width, dialog_height);
+    dialog_height = add_buttons(dc_dummy, pTaskConfig, controls, dialog_width, dialog_height, pTaskConfig->nDefaultButton);
 
     header.title = pTaskConfig->pszWindowTitle;
     if(!header.title)
diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
index f975a53de5..725bcd1b9a 100644
--- a/dlls/comctl32/tests/taskdialog.c
+++ b/dlls/comctl32/tests/taskdialog.c
@@ -33,6 +33,10 @@ static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, in
 /* For message checking we use a simplified version from the code used for user32 messages */
 
 #define TDN_NO_MORE_MESSAGES 0xffffffff
+#define ID_START 20 /* Lower IDs might be used by the system */
+
+#define ID_START_BUTTON (ID_START + 0)
+#define ID_START_RADIO (ID_START + 1000)
 
 /* How the message is sent to the dialog */
 typedef enum
@@ -84,6 +88,38 @@ static const message_data mes_cancel_button_press[] = {
     { TDN_NO_MORE_MESSAGES }
 };
 
+static const message_data mes_button_clicked_ok[] = {
+    { TDN_DIALOG_CONSTRUCTED, 0, 0 },
+    { TDN_CREATED, 0, 0 },
+    { TDN_BUTTON_CLICKED, IDOK, 0 },
+    { TDN_DESTROYED, 0, 0 },
+    { TDN_NO_MORE_MESSAGES }
+};
+
+static const message_data mes_button_clicked_custom1[] = {
+    { TDN_DIALOG_CONSTRUCTED, 0, 0 },
+    { TDN_CREATED, 0, 0 },
+    { TDN_BUTTON_CLICKED, ID_START_BUTTON, 0 },
+    { TDN_DESTROYED, 0, 0 },
+    { TDN_NO_MORE_MESSAGES }
+};
+
+static const message_data mes_button_clicked_retry[] = {
+    { TDN_DIALOG_CONSTRUCTED, 0, 0 },
+    { TDN_CREATED, 0, 0 },
+    { TDN_BUTTON_CLICKED, IDRETRY, 0 },
+    { TDN_DESTROYED, 0, 0 },
+    { TDN_NO_MORE_MESSAGES }
+};
+
+static const message_data mes_button_clicked_custom4[] = {
+    { TDN_DIALOG_CONSTRUCTED, 0, 0 },
+    { TDN_CREATED, 0, 0 },
+    { TDN_BUTTON_CLICKED, ID_START_BUTTON + 4, 0 },
+    { TDN_DESTROYED, 0, 0 },
+    { TDN_NO_MORE_MESSAGES }
+};
+
 /* Message lists to send */
 
 static const message_send_data mes_send_return[] = {
@@ -328,6 +364,31 @@ static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radi
     CloseHandle(event);
 }
 
+static const TASKDIALOG_BUTTON* buttons_make(int count)
+{
+    int i;
+    static const WCHAR str_format[] = {'%','d',0};
+    TASKDIALOG_BUTTON *ret = HeapAlloc(GetProcessHeap(), 0, count*sizeof(TASKDIALOG_BUTTON));
+
+    for(i=0; i<count; i++)
+    {
+        WCHAR *text = HeapAlloc(GetProcessHeap(), 0, 10*sizeof(WCHAR));
+        wsprintfW(text, str_format, i);
+        ret[i].pszButtonText = text;
+
+        ret[i].nButtonID = ID_START_BUTTON + i;
+    }
+    return ret;
+}
+
+static void buttons_destroy(int count, const TASKDIALOG_BUTTON *pButtons)
+{
+    int i;
+    for(i=0; i<count; i++)
+        HeapFree(GetProcessHeap(), 0, (void *)pButtons[i].pszButtonText);
+    HeapFree(GetProcessHeap(), 0, (void *)pButtons);
+}
+
 static void test_TaskDialogIndirect(void)
 {
     TASKDIALOGCONFIG info = {0};
@@ -345,6 +406,37 @@ static void test_TaskDialogIndirect(void)
 
     run_test(&info, IDOK, 0, 0, mes_simple_show, mes_send_return);
     run_test(&info, IDOK, 0, 0, mes_cancel_button_press, mes_send_3_click_button_ok);
+
+    /* Test nDefaultButton */
+
+    /* Test with all common buttons and invalid default ID */
+    info.nDefaultButton = 0; /* Should default to first created button */
+    info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
+                           | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
+    run_test(&info, IDOK, 0, 0, mes_button_clicked_ok, mes_send_return);
+
+    /* Test with all common and custom buttons and invalid default ID */
+    info.nDefaultButton = 0xff; /* Random ID, should also default to first created button */
+    info.cButtons = 10;
+    info.pButtons = buttons_make(info.cButtons);
+    run_test(&info, ID_START_BUTTON, 0, 0, mes_button_clicked_custom1, mes_send_return);
+
+    /* Test with only custom buttons and invalid default ID */
+    info.dwCommonButtons = 0;
+    run_test(&info, ID_START_BUTTON, 0, 0, mes_button_clicked_custom1, mes_send_return);
+
+    /* Test with common and custom buttons and valid default ID */
+    info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
+                               | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
+    info.nDefaultButton = IDRETRY;
+    run_test(&info, IDRETRY, 0, 0, mes_button_clicked_retry, mes_send_return);
+
+    /* Test with common and custom buttons and valid default ID */
+    info.nDefaultButton = ID_START_BUTTON + 4;
+    run_test(&info, ID_START_BUTTON + 4, 0, 0, mes_button_clicked_custom4, mes_send_return);
+
+
+    buttons_destroy(info.cButtons, info.pButtons);
 }
 
 START_TEST(taskdialog)
-- 
2.11.1




More information about the wine-patches mailing list