[PATCH 06/18] comctl32: TaskDialog - Implement main and content text controls

Fabian Maurer dark.shadow4 at web.de
Sat Feb 25 10:01:34 CST 2017


The dialog also now autosizes to fit the text.

v2: Don't crash if text is an integer resource

Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
 dlls/comctl32/taskdialog.c | 81 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 79 insertions(+), 2 deletions(-)

diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index f87ddf72a5..20d4e1ba32 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -59,7 +59,14 @@ typedef struct
 }dialog_header;
 
 #define MEMCPY_MOVEPTR(target, source, size) memcpy(target, source, size); target += size;
+
 #define STR_SIZE(str) ((lstrlenW(str) + 1) * sizeof(WCHAR))
+#define STR_EMPTY(str) (str == NULL || str[0] == 0)
+
+#define ID_START 0xF000
+
+static const int ID_TEXTMAIN    = ID_START + 1;
+static const int ID_TEXTCONTENT = ID_START + 2;
 
 /* Roughly fitting TaskDialog size */
 static const UINT DIALOG_DEFAULT_WIDTH = 180;
@@ -200,8 +207,24 @@ static void controls_add(struct list *controls, WORD id, const WCHAR *class, con
     list_add_tail(controls, &data->entry);
 }
 
+/* used to calculate size for the static controls */
+static RECT text_get_rect(HDC hdc, const WCHAR *text, UINT dialog_width)
+{
+    RECT rect = {0, 0, dialog_width - 10}; /* A padding of 5 left and right of the control */
+
+    dialogunits_to_pixels(&rect.right, NULL);
+
+    DrawTextW(hdc, text, -1, &rect, DT_LEFT | DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK);
+
+    pixels_to_dialogunits(&rect.right, &rect.bottom);
+
+    return rect;
+}
+
 /* FIXME: Make thread safe? */
 static const TASKDIALOGCONFIG *task_config = 0;
+static HFONT font_default, font_main;
+
 static HRESULT callback(HWND hwnd, UINT uNotification, WPARAM wParam, LPARAM lParam)
 {
     if(task_config->pfCallback)
@@ -216,9 +239,23 @@ static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA
     switch (uMsg)
     {
         case WM_INITDIALOG:
+            PostMessageW(GetDlgItem(hwndDlg, ID_TEXTMAIN), WM_SETFONT, (WPARAM)font_main, TRUE);
+            PostMessageW(GetDlgItem(hwndDlg, ID_TEXTCONTENT), WM_SETFONT, (WPARAM)font_default, TRUE);
             callback(hwndDlg, TDN_DIALOG_CONSTRUCTED, 0, 0);
             callback(hwndDlg, TDN_CREATED, 0, 0);
+
             return TRUE;
+        case WM_CTLCOLORSTATIC:
+               if((HWND)lParam == GetDlgItem(hwndDlg, ID_TEXTMAIN))
+               {
+                   HDC hdc = (HDC) wParam;
+
+                   SetTextColor(hdc, RGB(50,50,220));
+                   SetBkColor(hdc, GetSysColor(COLOR_3DFACE));
+
+                   return (INT_PTR)GetSysColorBrush(COLOR_3DFACE);
+               }
+               break;
         case WM_COMMAND:
             if(HIWORD(wParam) == BN_CLICKED)
             {
@@ -245,7 +282,9 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnBu
                                   int *pnRadioButton, BOOL *pfVerificationFlagChecked)
 {
     static const WCHAR empty_string[] = {0};
+    static const WCHAR font_name[] = {'T','a','h','o','m','a',0};
     static const WCHAR class_button[] = {'B','u','t','t','o','n',0};
+    static const WCHAR class_static[] = {'S','t','a','t','i','c',0};
     static const WCHAR text_ok[] = {'O','K',0};
     RECT desktop;
     UINT dialog_width; /* In dialog units */
@@ -253,6 +292,7 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnBu
     LPDLGTEMPLATEW template_data;
     dialog_header header = {0};
     struct list *controls;
+    HDC dc_dummy;
 
     TRACE("%p, %p, %p, %p\n", pTaskConfig, pnButton, pnRadioButton, pfVerificationFlagChecked);
 
@@ -263,8 +303,16 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnBu
 
     controls_init(&controls);
 
+    font_default = CreateFontW (16, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
+                                DEFAULT_CHARSET, 0, 0, CLEARTYPE_QUALITY,  FF_DONTCARE, font_name);
+    font_main = CreateFontW (19, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
+                                DEFAULT_CHARSET, 0, 0, CLEARTYPE_QUALITY,  FF_DONTCARE, font_name);
+
+    dc_dummy = CreateCompatibleDC(NULL);
+    SelectObject(dc_dummy, font_default);
+
     get_desktop_size(&desktop, pTaskConfig->hwndParent);
-    dialog_height = 100;
+    dialog_height = 5;
     dialog_width = pTaskConfig->cxWidth;
 
     /* Dialog can't be smaller than default size and not bigger than screen
@@ -276,7 +324,33 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnBu
 
     /* Start creating controls */
 
-    controls_add(controls, IDOK, class_button, text_ok, WS_CHILD | WS_VISIBLE, 105, 85, 40, 10);
+    if(!IS_INTRESOURCE(pTaskConfig->pszMainInstruction) && !STR_EMPTY(pTaskConfig->pszMainInstruction))
+    {
+        RECT rect;
+
+        SelectObject(dc_dummy, font_main);
+        rect = text_get_rect(dc_dummy, pTaskConfig->pszMainInstruction, dialog_width);
+
+        controls_add(controls, ID_TEXTMAIN, class_static, pTaskConfig->pszMainInstruction,
+                     WS_CHILD | WS_VISIBLE, 5, dialog_height + 5, rect.right, rect.bottom);
+
+        dialog_height += rect.bottom + 10;
+        SelectObject(dc_dummy, font_default);
+    }
+
+    if(!IS_INTRESOURCE(pTaskConfig->pszContent) && !STR_EMPTY(pTaskConfig->pszContent))
+    {
+        RECT rect = text_get_rect(dc_dummy, pTaskConfig->pszContent, dialog_width);
+
+        controls_add(controls, ID_TEXTCONTENT, class_static, pTaskConfig->pszContent,
+                     WS_CHILD | WS_VISIBLE, 5, dialog_height + 5, rect.right, rect.bottom);
+
+        dialog_height += rect.bottom + 10;
+    }
+
+    controls_add(controls, IDOK, class_button, text_ok,
+                 WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, dialog_width - 40 - 10, dialog_height + 5, 40, 10);
+    dialog_height += 10 + 10;
 
     header.title = pTaskConfig->pszWindowTitle;
     if(!header.title)
@@ -297,6 +371,9 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnBu
 
     /* Cleanup */
 
+    DeleteDC(dc_dummy);
+    DeleteObject(font_main);
+    DeleteObject(font_default);
     dialog_template_destroy(template_data);
     controls_destroy(controls);
 
-- 
2.12.0




More information about the wine-patches mailing list