[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