[PATCH 4/5] comctl32/taskdialog: Add support for hyperlink.

Zhiyi Zhang zzhang at codeweavers.com
Thu Jun 14 03:01:56 CDT 2018


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/comctl32/taskdialog.c | 51 ++++++++++++++++++++++++++++++--------
 1 file changed, 41 insertions(+), 10 deletions(-)

diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index 59a915977c..91c8af019b 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -222,7 +222,13 @@ static WCHAR *taskdialog_gettext(struct taskdialog_info *dialog_info, BOOL user_
     return ret;
 }
 
-static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND hwnd, LONG max_width, SIZE *size)
+static BOOL taskdialog_hyperlink_enabled(struct taskdialog_info *dialog_info)
+{
+    return dialog_info->taskconfig->dwFlags & TDF_ENABLE_HYPERLINKS;
+}
+
+static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND hwnd, LONG max_width, SIZE *size,
+                                      BOOL syslink)
 {
     DWORD style = DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK;
     HFONT hfont, old_hfont;
@@ -231,6 +237,12 @@ static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND
     WCHAR text[1024];
     INT text_length;
 
+    if (syslink)
+    {
+        SendMessageW(hwnd, LM_GETIDEALSIZE, max_width, (LPARAM)size);
+        return;
+    }
+
     if (dialog_info->taskconfig->dwFlags & TDF_RTL_LAYOUT)
         style |= DT_RIGHT | DT_RTLREADING;
     else
@@ -296,15 +308,19 @@ static void taskdialog_add_main_icon(struct taskdialog_info *dialog_info)
     taskdialog_set_icon(dialog_info, TDIE_ICON_MAIN, dialog_info->taskconfig->u.hMainIcon);
 }
 
-static HWND taskdialog_create_label(struct taskdialog_info *dialog_info, const WCHAR *text, HFONT font)
+static HWND taskdialog_create_label(struct taskdialog_info *dialog_info, const WCHAR *text, HFONT font, BOOL syslink)
 {
     WCHAR *textW;
     HWND hwnd;
+    const WCHAR *class;
+    DWORD style = WS_CHILD | WS_VISIBLE;
 
     if (!text) return NULL;
 
+    class = syslink ? WC_LINK : WC_STATICW;
+    if (syslink) style |= WS_TABSTOP;
     textW = taskdialog_gettext(dialog_info, TRUE, text);
-    hwnd = CreateWindowW(WC_STATICW, textW, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, dialog_info->hwnd, NULL, 0, NULL);
+    hwnd = CreateWindowW(class, textW, style, 0, 0, 0, 0, dialog_info->hwnd, NULL, 0, NULL);
     if (textW) Free(textW);
 
     SendMessageW(hwnd, WM_SETFONT, (WPARAM)font, 0);
@@ -326,12 +342,13 @@ static void taskdialog_add_main_instruction(struct taskdialog_info *dialog_info)
     dialog_info->main_instruction_font = CreateFontIndirectW(&ncm.lfMessageFont);
 
     dialog_info->main_instruction =
-        taskdialog_create_label(dialog_info, taskconfig->pszMainInstruction, dialog_info->main_instruction_font);
+        taskdialog_create_label(dialog_info, taskconfig->pszMainInstruction, dialog_info->main_instruction_font, FALSE);
 }
 
 static void taskdialog_add_content(struct taskdialog_info *dialog_info)
 {
-    dialog_info->content = taskdialog_create_label(dialog_info, dialog_info->taskconfig->pszContent, dialog_info->font);
+    dialog_info->content = taskdialog_create_label(dialog_info, dialog_info->taskconfig->pszContent, dialog_info->font,
+                                                   taskdialog_hyperlink_enabled(dialog_info));
 }
 
 static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *button, INT id, const WCHAR *text,
@@ -387,7 +404,7 @@ static void taskdialog_add_buttons(struct taskdialog_info *dialog_info)
 }
 
 static void taskdialog_label_layout(struct taskdialog_info *dialog_info, HWND hwnd, INT start_x, LONG dialog_width,
-                                    LONG *dialog_height)
+                                    LONG *dialog_height, BOOL syslink)
 {
     LONG x, y, max_width;
     SIZE size;
@@ -397,7 +414,7 @@ static void taskdialog_label_layout(struct taskdialog_info *dialog_info, HWND hw
     x = start_x + dialog_info->m.h_spacing;
     y = *dialog_height + dialog_info->m.v_spacing;
     max_width = dialog_width - x - dialog_info->m.h_spacing;
-    taskdialog_get_label_size(dialog_info, hwnd, max_width, &size);
+    taskdialog_get_label_size(dialog_info, hwnd, max_width, &size, syslink);
     SetWindowPos(hwnd, 0, x, y, size.cx, size.cy, SWP_NOZORDER);
     *dialog_height = y + size.cy;
 }
@@ -405,6 +422,7 @@ static void taskdialog_label_layout(struct taskdialog_info *dialog_info, HWND hw
 static void taskdialog_layout(struct taskdialog_info *dialog_info)
 {
     const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
+    BOOL syslink = taskdialog_hyperlink_enabled(dialog_info);
     static BOOL first_time = TRUE;
     RECT ref_rect;
     LONG screen_width, dialog_width, dialog_height = 0;
@@ -440,10 +458,11 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info)
     }
 
     /* Main instruction */
-    taskdialog_label_layout(dialog_info, dialog_info->main_instruction, main_icon_right, dialog_width, &dialog_height);
+    taskdialog_label_layout(dialog_info, dialog_info->main_instruction, main_icon_right, dialog_width, &dialog_height,
+                            FALSE);
 
     /* Content */
-    taskdialog_label_layout(dialog_info, dialog_info->content, main_icon_right, dialog_width, &dialog_height);
+    taskdialog_label_layout(dialog_info, dialog_info->content, main_icon_right, dialog_width, &dialog_height, syslink);
 
     dialog_height = max(dialog_height, main_icon_bottom);
 
@@ -456,7 +475,7 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info)
     taskdialog_du_to_px(dialog_info, &button_min_width, &button_height);
     for (i = 0; i < dialog_info->button_count; i++)
     {
-        taskdialog_get_label_size(dialog_info, dialog_info->buttons[i], dialog_width - h_spacing * 2, &size);
+        taskdialog_get_label_size(dialog_info, dialog_info->buttons[i], dialog_width - h_spacing * 2, &size, FALSE);
         button_layout_infos[i].width = max(size.cx, button_min_width);
     }
 
@@ -643,6 +662,18 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
                     dialog_info->last_timer_tick = GetTickCount();
             }
             break;
+        case WM_NOTIFY:
+        {
+            PNMLINK pnmLink = (PNMLINK)lParam;
+            HWND hwndFrom = pnmLink->hdr.hwndFrom;
+            if ((taskdialog_hyperlink_enabled(dialog_info)) && (hwndFrom == dialog_info->content)
+                && (pnmLink->hdr.code == NM_CLICK || pnmLink->hdr.code == NM_RETURN))
+            {
+                taskdialog_notify(dialog_info, TDN_HYPERLINK_CLICKED, 0, (LPARAM)pnmLink->item.szUrl);
+                break;
+            }
+            return FALSE;
+        }
         case WM_DESTROY:
             taskdialog_notify(dialog_info, TDN_DESTROYED, 0, 0);
             RemovePropW(hwnd, taskdialog_info_propnameW);
-- 
2.17.1





More information about the wine-devel mailing list