Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/comctl32/taskdialog.c | 476 +++++++++++++++++++++----------------
1 file changed, 268 insertions(+), 208 deletions(-)
diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index 1ab9e133da..4fdea1e889 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -2,6 +2,7 @@
* Task dialog control
*
* Copyright 2017 Fabian Maurer
+ * Copyright 2018 Zhiyi Zhang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -71,37 +72,23 @@ struct taskdialog_button_desc
struct taskdialog_template_desc
{
const TASKDIALOGCONFIG *taskconfig;
- unsigned int dialog_height;
- unsigned int dialog_width;
struct list controls;
WORD control_count;
- LONG x_baseunit;
- LONG y_baseunit;
- HFONT font;
- struct taskdialog_button_desc *default_button;
};
struct taskdialog_info
{
HWND hwnd;
- PFTASKDIALOGCALLBACK callback;
- LONG_PTR callback_data;
+ const TASKDIALOGCONFIG *taskconfig;
+ LONG x_baseunit;
+ LONG y_baseunit;
+ HFONT hfont;
};
-static void pixels_to_dialogunits(const struct taskdialog_template_desc *desc, LONG *width, LONG *height)
+static void dialogunits_to_pixels(const struct taskdialog_info *dialog_info, LONG *width, LONG *height)
{
- if (width)
- *width = MulDiv(*width, 4, desc->x_baseunit);
- if (height)
- *height = MulDiv(*height, 8, desc->y_baseunit);
-}
-
-static void dialogunits_to_pixels(const struct taskdialog_template_desc *desc, LONG *width, LONG *height)
-{
- if (width)
- *width = MulDiv(*width, desc->x_baseunit, 4);
- if (height)
- *height = MulDiv(*height, desc->y_baseunit, 8);
+ if (width) *width = MulDiv(*width, dialog_info->x_baseunit, 4);
+ if (height) *height = MulDiv(*height, dialog_info->y_baseunit, 8);
}
static void template_write_data(char **ptr, const void *src, unsigned int size)
@@ -110,66 +97,54 @@ static void template_write_data(char **ptr, const void *src, unsigned int size)
*ptr += size;
}
-/* used to calculate size for the controls */
-static void taskdialog_get_text_extent(const struct taskdialog_template_desc *desc, const WCHAR *text,
- BOOL user_resource, SIZE *sz)
+static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notification, WPARAM wparam, LPARAM lparam)
+{
+ const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
+ return taskconfig->pfCallback
+ ? taskconfig->pfCallback(dialog_info->hwnd, notification, wparam, lparam, taskconfig->lpCallbackData)
+ : S_OK;
+}
+
+const WCHAR *taskdialog_loadstring(const WCHAR *text, BOOL user_resource, HINSTANCE hinstance, LONG *length)
{
- RECT rect = { 0, 0, desc->dialog_width - DIALOG_SPACING * 2, 0}; /* padding left and right of the control */
- const WCHAR *textW = NULL;
static const WCHAR nulW;
- unsigned int length;
- HFONT oldfont;
- HDC hdc;
+ const WCHAR *textW = NULL;
if (IS_INTRESOURCE(text))
{
- if (!(length = LoadStringW(user_resource ? desc->taskconfig->hInstance : COMCTL32_hModule,
- (UINT_PTR)text, (WCHAR *)&textW, 0)))
+ if (!(*length = LoadStringW(user_resource ? hinstance : COMCTL32_hModule, (UINT_PTR)text, (WCHAR *)&textW, 0)))
{
WARN("Failed to load text\n");
textW = &nulW;
- length = 0;
+ *length = 0;
}
}
else
{
textW = text;
- length = strlenW(textW);
+ *length = strlenW(textW);
}
- hdc = GetDC(0);
- oldfont = SelectObject(hdc, desc->font);
-
- dialogunits_to_pixels(desc, &rect.right, NULL);
- DrawTextW(hdc, textW, length, &rect, DT_LEFT | DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK);
- pixels_to_dialogunits(desc, &rect.right, &rect.bottom);
-
- SelectObject(hdc, oldfont);
- ReleaseDC(0, hdc);
-
- sz->cx = rect.right - rect.left;
- sz->cy = rect.bottom - rect.top;
+ return textW;
}
static unsigned int taskdialog_add_control(struct taskdialog_template_desc *desc, WORD id, const WCHAR *class,
- HINSTANCE hInstance, const WCHAR *text, DWORD style, short x, short y, short cx, short cy)
+ HINSTANCE hInstance, const WCHAR *text, DWORD style)
{
struct taskdialog_control *control = Alloc(sizeof(*control));
unsigned int size, class_size, text_size;
DLGITEMTEMPLATE *template;
static const WCHAR nulW;
const WCHAR *textW;
+ LONG length;
char *ptr;
class_size = (strlenW(class) + 1) * sizeof(WCHAR);
- if (IS_INTRESOURCE(text))
- text_size = LoadStringW(hInstance, (UINT_PTR)text, (WCHAR *)&textW, 0) * sizeof(WCHAR);
- else
- {
- textW = text;
- text_size = strlenW(textW) * sizeof(WCHAR);
- }
+ if (!text) text = &nulW;
+
+ textW = taskdialog_loadstring(text, TRUE, hInstance, &length);
+ text_size = length * sizeof(WCHAR);
size = sizeof(DLGITEMTEMPLATE);
size += class_size;
@@ -180,11 +155,6 @@ static unsigned int taskdialog_add_control(struct taskdialog_template_desc *desc
control->template_size = size;
template->style = WS_VISIBLE | style;
- template->dwExtendedStyle = 0;
- template->x = x;
- template->y = y;
- template->cx = cx;
- template->cy = cy;
template->id = id;
ptr = (char *)(template + 1);
template_write_data(&ptr, class, class_size);
@@ -198,19 +168,8 @@ static unsigned int taskdialog_add_control(struct taskdialog_template_desc *desc
static unsigned int taskdialog_add_static_label(struct taskdialog_template_desc *desc, WORD id, const WCHAR *str)
{
- unsigned int size;
- SIZE sz;
-
- if (!str)
- return 0;
-
- taskdialog_get_text_extent(desc, str, TRUE, &sz);
-
- desc->dialog_height += DIALOG_SPACING;
- size = taskdialog_add_control(desc, id, WC_STATICW, desc->taskconfig->hInstance, str, 0, DIALOG_SPACING,
- desc->dialog_height, sz.cx, sz.cy);
- desc->dialog_height += sz.cy + DIALOG_SPACING;
- return size;
+ if (!str) return 0;
+ return taskdialog_add_control(desc, id, WC_STATICW, desc->taskconfig->hInstance, str, 0);
}
static unsigned int taskdialog_add_main_instruction(struct taskdialog_template_desc *desc)
@@ -223,97 +182,214 @@ static unsigned int taskdialog_add_content(struct taskdialog_template_desc *desc
return taskdialog_add_static_label(desc, ID_CONTENT, desc->taskconfig->pszContent);
}
-static void taskdialog_init_button(struct taskdialog_button_desc *button, struct taskdialog_template_desc *desc,
- int id, const WCHAR *text, BOOL custom_button)
+static unsigned int taskdialog_add_buttons(struct taskdialog_template_desc *desc)
{
- SIZE sz;
-
- taskdialog_get_text_extent(desc, text, custom_button, &sz);
+ const TASKDIALOGCONFIG *taskconfig = desc->taskconfig;
+ DWORD style, flags = taskconfig->dwCommonButtons;
+ struct taskdialog_button_desc *buttons;
+ unsigned int max_count, count = 0, i, size = 0;
+ int default_id = 0;
- button->id = id;
- button->text = text;
- button->width = max(DIALOG_BUTTON_WIDTH, sz.cx + DIALOG_SPACING * 2);
- button->line = 0;
- button->hinst = custom_button ? desc->taskconfig->hInstance : COMCTL32_hModule;
+ /* Allocate enough memory for the custom and the default buttons. Maximum 6
+ * default buttons possible. */
+ max_count = 6;
- if (id == desc->taskconfig->nDefaultButton)
- desc->default_button = button;
-}
+ if (taskconfig->cButtons && taskconfig->pButtons) max_count += taskconfig->cButtons;
-static void taskdialog_init_common_buttons(struct taskdialog_template_desc *desc, struct taskdialog_button_desc *buttons,
- unsigned int *button_count)
-{
- DWORD flags = desc->taskconfig->dwCommonButtons;
+ buttons = Alloc(max_count * sizeof(*buttons));
+ if (!buttons) return 0;
-#define TASKDIALOG_INIT_COMMON_BUTTON(id) \
- do { \
- taskdialog_init_button(&buttons[(*button_count)++], desc, ID##id, MAKEINTRESOURCEW(IDS_BUTTON_##id), FALSE); \
- } while(0)
+ if (taskconfig->cButtons && taskconfig->pButtons)
+ for (count = 0; count < taskconfig->cButtons; count++)
+ {
+ buttons[count].id = taskconfig->pButtons[count].nButtonID;
+ buttons[count].text = taskconfig->pButtons[count].pszButtonText;
+ buttons[count].hinst = taskconfig->hInstance;
+ }
- if (flags & TDCBF_OK_BUTTON)
- TASKDIALOG_INIT_COMMON_BUTTON(OK);
+ if (flags & TDCBF_OK_BUTTON
+ || (count == 0 && !(flags & (TDCBF_YES_BUTTON | TDCBF_NO_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CANCEL_BUTTON | TDCBF_CLOSE_BUTTON))))
+ {
+ buttons[count].id = IDOK;
+ buttons[count++].text = MAKEINTRESOURCEW(IDS_BUTTON_OK);
+ }
if (flags & TDCBF_YES_BUTTON)
- TASKDIALOG_INIT_COMMON_BUTTON(YES);
+ {
+ buttons[count].id = IDYES;
+ buttons[count++].text = MAKEINTRESOURCEW(IDS_BUTTON_YES);
+ }
if (flags & TDCBF_NO_BUTTON)
- TASKDIALOG_INIT_COMMON_BUTTON(NO);
+ {
+ buttons[count].id = IDNO;
+ buttons[count++].text = MAKEINTRESOURCEW(IDS_BUTTON_NO);
+ }
if (flags & TDCBF_RETRY_BUTTON)
- TASKDIALOG_INIT_COMMON_BUTTON(RETRY);
+ {
+ buttons[count].id = IDRETRY;
+ buttons[count++].text = MAKEINTRESOURCEW(IDS_BUTTON_RETRY);
+ }
if (flags & TDCBF_CANCEL_BUTTON)
- TASKDIALOG_INIT_COMMON_BUTTON(CANCEL);
+ {
+ buttons[count].id = IDCANCEL;
+ buttons[count++].text = MAKEINTRESOURCEW(IDS_BUTTON_CANCEL);
+ }
if (flags & TDCBF_CLOSE_BUTTON)
- TASKDIALOG_INIT_COMMON_BUTTON(CLOSE);
+ {
+ buttons[count].id = IDCLOSE;
+ buttons[count++].text = MAKEINTRESOURCEW(IDS_BUTTON_CLOSE);
+ }
+
+ for (i = 0; i < count; i++)
+ if (buttons[i].id == taskconfig->nDefaultButton) default_id = buttons[i].id;
+
+ if (!default_id) default_id = buttons[0].id;
+
+ for (i = 0; i < count; i++)
+ {
+ style = buttons[i].id == default_id ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON;
+ size += taskdialog_add_control(desc, buttons[i].id, WC_BUTTONW,
+ buttons[i].hinst ? buttons[i].hinst : COMCTL32_hModule, buttons[i].text, style);
+ }
-#undef TASKDIALOG_INIT_COMMON_BUTTON
+ Free(buttons);
+ return size;
}
-static unsigned int taskdialog_add_buttons(struct taskdialog_template_desc *desc)
+static unsigned int taskdialog_get_reference_rect(struct taskdialog_info *dialog_info, RECT *ret)
{
- unsigned int count = 0, buttons_size, i, line_count, size = 0;
- unsigned int location_x, *line_widths, alignment = ~0u;
- const TASKDIALOGCONFIG *taskconfig = desc->taskconfig;
+ const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
+ HMONITOR monitor = MonitorFromWindow(taskconfig->hwndParent ? taskconfig->hwndParent : GetActiveWindow(),
+ MONITOR_DEFAULTTOPRIMARY);
+ MONITORINFO info;
+
+ info.cbSize = sizeof(info);
+ GetMonitorInfoW(monitor, &info);
+
+ if (taskconfig->dwFlags & TDF_POSITION_RELATIVE_TO_WINDOW && taskconfig->hwndParent)
+ GetWindowRect(taskconfig->hwndParent, ret);
+ else
+ *ret = info.rcWork;
+
+ return info.rcWork.right - info.rcWork.left;
+}
+
+static void taskdialog_get_label_size(HWND hwnd, LONG max_width, SIZE *size)
+{
+ HFONT hfont, old_hfont;
+ HDC hdc;
+ RECT rect = {0};
+ WCHAR text[1024];
+ INT text_length;
+
+ hfont = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0);
+ text_length = GetWindowTextW(hwnd, text, ARRAY_SIZE(text));
+ hdc = GetDC(hwnd);
+ old_hfont = SelectObject(hdc, hfont);
+ rect.right = max_width;
+ size->cy = DrawTextW(hdc, text, text_length, &rect, DT_LEFT | DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK);
+ size->cx = min(max_width, rect.right - rect.left);
+ if(old_hfont) SelectObject(hdc, old_hfont);
+ ReleaseDC(hwnd, hdc);
+}
+
+static void taskdialog_resize(struct taskdialog_info *dialog_info)
+{
+ const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
+ static BOOL first_time = TRUE;
+ RECT ref_rect, window_rect;
+ LONG screen_width;
+ LONG dialog_width, dialog_height = 0;
+ LONG x, y;
+ SIZE size;
+ LONG horizontal_spacing, vertical_spacing;
+ HWND hwnd;
+ DWORD flags = taskconfig->dwCommonButtons;
+ LONG buttons_max_size, button_min_width, button_count = 0, line_count;
+ LONG *line_widths, alignment;
struct taskdialog_button_desc *buttons;
+ INT i;
- /* Allocate enough memory for the custom and the default buttons. Maximum 6 default buttons possible. */
- buttons_size = 6;
- if (taskconfig->cButtons && taskconfig->pButtons)
- buttons_size += taskconfig->cButtons;
+ screen_width = taskdialog_get_reference_rect(dialog_info, &ref_rect);
- if (!(buttons = Alloc(buttons_size * sizeof(*buttons))))
- return 0;
+ dialog_width = max(taskconfig->cxWidth, DIALOG_MIN_WIDTH);
+ dialogunits_to_pixels(dialog_info, &dialog_width, 0);
+ dialog_width = min(dialog_width, screen_width);
- /* Custom buttons */
- if (taskconfig->cButtons && taskconfig->pButtons)
- for (i = 0; i < taskconfig->cButtons; i++)
- taskdialog_init_button(&buttons[count++], desc, taskconfig->pButtons[i].nButtonID,
- taskconfig->pButtons[i].pszButtonText, TRUE);
+ horizontal_spacing = DIALOG_SPACING;
+ vertical_spacing = DIALOG_SPACING;
- /* Common buttons */
- taskdialog_init_common_buttons(desc, buttons, &count);
+ dialogunits_to_pixels(dialog_info, &horizontal_spacing, &vertical_spacing);
- /* There must be at least one button */
- if (count == 0)
- taskdialog_init_button(&buttons[count++], desc, IDOK, MAKEINTRESOURCEW(IDS_BUTTON_OK), FALSE);
+ /* Main instruction */
+ hwnd = GetDlgItem(dialog_info->hwnd, ID_MAIN_INSTRUCTION);
+ if (hwnd)
+ {
+ x = horizontal_spacing;
+ y = dialog_height + vertical_spacing;
+ size.cx = dialog_width - x - horizontal_spacing;
+ taskdialog_get_label_size(hwnd, size.cx, &size);
+ MoveWindow(hwnd, x, y, size.cx, size.cy, TRUE);
+ dialog_height = y + size.cy;
+ }
+
+ /* Main content */
+ hwnd = GetDlgItem(dialog_info->hwnd, ID_CONTENT);
+ if (hwnd)
+ {
+ x = horizontal_spacing;
+ y = dialog_height + vertical_spacing;
+ size.cx = dialog_width - x - horizontal_spacing;
+ taskdialog_get_label_size(hwnd, size.cx, &size);
+ MoveWindow(hwnd, x, y, size.cx, size.cy, TRUE);
+ dialog_height = y + size.cy;
+ }
+
+ /* Common Buttons and Custom Buttons */
+ /* Allocate enough memory for the custom and the default buttons. Maximum 6 default buttons possible. */
+ buttons_max_size = 6;
+ /* Custom buttons */
+ if (taskconfig->cButtons && taskconfig->pButtons) buttons_max_size += taskconfig->cButtons;
- if (!desc->default_button)
- desc->default_button = &buttons[0];
+ /* For easy handling just allocate as many lines as buttons, the worst case. s*/
+ buttons = Alloc(buttons_max_size * sizeof(*buttons));
+ line_widths = Alloc(buttons_max_size * sizeof(*line_widths));
- /* For easy handling just allocate as many lines as buttons, the worst case. */
- line_widths = Alloc(count * sizeof(*line_widths));
+ if (taskconfig->cButtons && taskconfig->pButtons)
+ for (button_count = 0; button_count < taskconfig->cButtons; button_count++)
+ buttons[button_count].id = taskconfig->pButtons[button_count].nButtonID;
+
+ /* Ok button may be added if no button is specified in taskconfig */
+ if (GetDlgItem(dialog_info->hwnd, IDOK)) buttons[button_count++].id = IDOK;
+ if (flags & TDCBF_YES_BUTTON) buttons[button_count++].id = IDYES;
+ if (flags & TDCBF_NO_BUTTON) buttons[button_count++].id = IDNO;
+ if (flags & TDCBF_RETRY_BUTTON) buttons[button_count++].id = IDRETRY;
+ if (flags & TDCBF_CANCEL_BUTTON) buttons[button_count++].id = IDCANCEL;
+ if (flags & TDCBF_CLOSE_BUTTON) buttons[button_count++].id = IDCLOSE;
+
+ button_min_width = DIALOG_BUTTON_WIDTH;
+ dialogunits_to_pixels(dialog_info, &button_min_width, 0);
+ for (i = 0; i < button_count; i++)
+ {
+ hwnd = GetDlgItem(dialog_info->hwnd, buttons[i].id);
+ taskdialog_get_label_size(hwnd, dialog_width - horizontal_spacing, &size);
+ buttons[i].width = max(size.cx, button_min_width);
+ buttons[i].line = 0;
+ }
/* Separate buttons into lines */
- location_x = DIALOG_SPACING;
- for (i = 0, line_count = 0; i < count; i++)
+ x = horizontal_spacing;
+ for (i = 0, line_count = 0; i < button_count; i++)
{
- if (location_x + buttons[i].width + DIALOG_SPACING > desc->dialog_width)
+ if (x + buttons[i].width + horizontal_spacing >= dialog_width)
{
- location_x = DIALOG_SPACING;
+ x = horizontal_spacing;
line_count++;
}
buttons[i].line = line_count;
- location_x += buttons[i].width + DIALOG_SPACING;
- line_widths[line_count] += buttons[i].width + DIALOG_SPACING;
+ x += buttons[i].width + horizontal_spacing;
+ line_widths[line_count] += buttons[i].width + horizontal_spacing;
}
line_count++;
@@ -324,9 +400,8 @@ static unsigned int taskdialog_add_buttons(struct taskdialog_template_desc *desc
unsigned int j, last_button = 0;
int diff_changed;
- for (j = 0; j < count; j++)
- if (buttons[j].line == i - 1)
- last_button = j;
+ for (j = 0; j < button_count; j++)
+ if (buttons[j].line == i - 1) last_button = j;
/* Difference in length of both lines if we wrapped the last button from the last line into this one */
diff_changed = abs(2 * buttons[last_button].width + line_widths[i] - line_widths[i - 1]);
@@ -340,38 +415,58 @@ static unsigned int taskdialog_add_buttons(struct taskdialog_template_desc *desc
}
/* Calculate left alignment so all lines are as far right as possible. */
+ alignment = dialog_width;
for (i = 0; i < line_count; i++)
{
- int new_alignment = desc->dialog_width - line_widths[i];
- if (new_alignment < alignment)
- alignment = new_alignment;
+ int new_alignment = dialog_width - line_widths[i];
+ if (new_alignment < alignment) alignment = new_alignment;
}
- /* Now that we got them all positioned, create all buttons */
- location_x = alignment;
- for (i = 0; i < count; i++)
+ /* Now that we got them all positioned, move all buttons */
+ x = alignment;
+ size.cy = DIALOG_BUTTON_HEIGHT;
+ dialogunits_to_pixels(dialog_info, NULL, &size.cy);
+ for (i = 0; i < button_count; i++)
{
- DWORD style = &buttons[i] == desc->default_button ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON;
-
- if (i > 0 && buttons[i].line != buttons[i - 1].line) /* New line */
+ /* New line */
+ if (i > 0 && buttons[i].line != buttons[i - 1].line)
{
- location_x = alignment;
- desc->dialog_height += DIALOG_BUTTON_HEIGHT + DIALOG_SPACING;
+ x = alignment;
+ dialog_height += size.cy + vertical_spacing;
}
- size += taskdialog_add_control(desc, buttons[i].id, WC_BUTTONW, buttons[i].hinst, buttons[i].text, style,
- location_x, desc->dialog_height, buttons[i].width, DIALOG_BUTTON_HEIGHT);
-
- location_x += buttons[i].width + DIALOG_SPACING;
+ y = dialog_height + vertical_spacing;
+ size.cx = buttons[i].width;
+ hwnd = GetDlgItem(dialog_info->hwnd, buttons[i].id);
+ MoveWindow(hwnd, x, y, size.cx, size.cy, TRUE);
+ x += buttons[i].width + horizontal_spacing;
}
- /* Add height for last row and spacing */
- desc->dialog_height += DIALOG_BUTTON_HEIGHT + DIALOG_SPACING;
+ /* Add height for last row button and spacing */
+ dialog_height += size.cy + vertical_spacing;
Free(line_widths);
Free(buttons);
- return size;
+ /* Add height for spacing, title height and frame height */
+ dialog_height += vertical_spacing;
+ dialog_height += GetSystemMetrics(SM_CYCAPTION);
+ dialog_height += GetSystemMetrics(SM_CXDLGFRAME);
+
+ if (first_time)
+ {
+ x = (ref_rect.left + ref_rect.right + dialog_width) / 2;
+ y = (ref_rect.top + ref_rect.bottom + dialog_height) / 2;
+ first_time = FALSE;
+ }
+ else
+ {
+ GetWindowRect(dialog_info->hwnd, &window_rect);
+ x = window_rect.left;
+ y = window_rect.top;
+ }
+
+ MoveWindow(dialog_info->hwnd, x, y, dialog_width, dialog_height, TRUE);
}
static void taskdialog_clear_controls(struct list *controls)
@@ -386,28 +481,6 @@ static void taskdialog_clear_controls(struct list *controls)
}
}
-static unsigned int taskdialog_get_reference_rect(const struct taskdialog_template_desc *desc, RECT *ret)
-{
- HMONITOR monitor = MonitorFromWindow(desc->taskconfig->hwndParent ? desc->taskconfig->hwndParent : GetActiveWindow(),
- MONITOR_DEFAULTTOPRIMARY);
- MONITORINFO info;
-
- info.cbSize = sizeof(info);
- GetMonitorInfoW(monitor, &info);
-
- if (desc->taskconfig->dwFlags & TDF_POSITION_RELATIVE_TO_WINDOW && desc->taskconfig->hwndParent)
- GetWindowRect(desc->taskconfig->hwndParent, ret);
- else
- *ret = info.rcWork;
-
- pixels_to_dialogunits(desc, &ret->left, &ret->top);
- pixels_to_dialogunits(desc, &ret->right, &ret->bottom);
-
- pixels_to_dialogunits(desc, &info.rcWork.left, &info.rcWork.top);
- pixels_to_dialogunits(desc, &info.rcWork.right, &info.rcWork.bottom);
- return info.rcWork.right - info.rcWork.left;
-}
-
static WCHAR *taskdialog_get_exe_name(const TASKDIALOGCONFIG *taskconfig, WCHAR *name, DWORD length)
{
DWORD len = GetModuleFileNameW(NULL, name, length);
@@ -425,17 +498,14 @@ static WCHAR *taskdialog_get_exe_name(const TASKDIALOGCONFIG *taskconfig, WCHAR
static DLGTEMPLATE *create_taskdialog_template(const TASKDIALOGCONFIG *taskconfig)
{
struct taskdialog_control *control, *control2;
- unsigned int size, title_size, screen_width;
+ unsigned int size, title_size;
struct taskdialog_template_desc desc;
static const WORD fontsize = 0x7fff;
static const WCHAR emptyW[] = { 0 };
const WCHAR *titleW = NULL;
DLGTEMPLATE *template;
- NONCLIENTMETRICSW ncm;
WCHAR pathW[MAX_PATH];
- RECT ref_rect;
char *ptr;
- HDC hdc;
/* Window title */
if (!taskconfig->pszWindowTitle)
@@ -459,22 +529,6 @@ static DLGTEMPLATE *create_taskdialog_template(const TASKDIALOGCONFIG *taskconfi
desc.taskconfig = taskconfig;
desc.control_count = 0;
- ncm.cbSize = sizeof(ncm);
- SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
- desc.font = CreateFontIndirectW(&ncm.lfMessageFont);
-
- hdc = GetDC(0);
- SelectObject(hdc, desc.font);
- desc.x_baseunit = GdiGetCharDimensions(hdc, NULL, &desc.y_baseunit);
- ReleaseDC(0, hdc);
-
- screen_width = taskdialog_get_reference_rect(&desc, &ref_rect);
-
- desc.dialog_height = 0;
- desc.dialog_width = max(taskconfig->cxWidth, DIALOG_MIN_WIDTH);
- desc.dialog_width = min(desc.dialog_width, screen_width);
- desc.default_button = NULL;
-
size += taskdialog_add_main_instruction(&desc);
size += taskdialog_add_content(&desc);
size += taskdialog_add_buttons(&desc);
@@ -483,16 +537,11 @@ static DLGTEMPLATE *create_taskdialog_template(const TASKDIALOGCONFIG *taskconfi
if (!template)
{
taskdialog_clear_controls(&desc.controls);
- DeleteObject(desc.font);
return NULL;
}
template->style = DS_MODALFRAME | DS_SETFONT | WS_CAPTION | WS_VISIBLE | WS_SYSMENU;
template->cdit = desc.control_count;
- template->x = (ref_rect.left + ref_rect.right + desc.dialog_width) / 2;
- template->y = (ref_rect.top + ref_rect.bottom + desc.dialog_height) / 2;
- template->cx = desc.dialog_width;
- template->cy = desc.dialog_height;
ptr = (char *)(template + 1);
ptr += 2; /* menu */
@@ -513,22 +562,32 @@ static DLGTEMPLATE *create_taskdialog_template(const TASKDIALOGCONFIG *taskconfi
Free(control);
}
- DeleteObject(desc.font);
return template;
}
-static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notification, WPARAM wparam, LPARAM lparam)
-{
- return dialog_info->callback ? dialog_info->callback(dialog_info->hwnd, notification, wparam, lparam,
- dialog_info->callback_data) : S_OK;
-}
-
static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, WORD command_id)
{
if (taskdialog_notify(dialog_info, TDN_BUTTON_CLICKED, command_id, 0) == S_OK)
EndDialog(dialog_info->hwnd, command_id);
}
+static void taskdialog_init_dialog_info(struct taskdialog_info *dialog_info, HWND hwnd)
+{
+ NONCLIENTMETRICSW ncm;
+ HDC hdc;
+
+ dialog_info->hwnd = hwnd;
+
+ ncm.cbSize = sizeof(ncm);
+ SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
+ dialog_info->hfont = CreateFontIndirectW(&ncm.lfMessageFont);
+
+ hdc = GetDC(0);
+ SelectObject(hdc, dialog_info->hfont);
+ dialog_info->x_baseunit = GdiGetCharDimensions(hdc, NULL, &dialog_info->y_baseunit);
+ ReleaseDC(0, hdc);
+}
+
static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static const WCHAR taskdialog_info_propnameW[] = {'T','a','s','k','D','i','a','l','o','g','I','n','f','o',0};
@@ -546,8 +605,10 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
break;
case WM_INITDIALOG:
dialog_info = (struct taskdialog_info *)lParam;
- dialog_info->hwnd = hwnd;
+ taskdialog_init_dialog_info(dialog_info, hwnd);
+
SetPropW(hwnd, taskdialog_info_propnameW, dialog_info);
+ taskdialog_resize(dialog_info);
taskdialog_notify(dialog_info, TDN_DIALOG_CONSTRUCTED, 0, 0);
break;
@@ -584,8 +645,7 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *taskconfig, int *butto
if (!taskconfig || taskconfig->cbSize != sizeof(TASKDIALOGCONFIG))
return E_INVALIDARG;
- dialog_info.callback = taskconfig->pfCallback;
- dialog_info.callback_data = taskconfig->lpCallbackData;
+ dialog_info.taskconfig = taskconfig;
template = create_taskdialog_template(taskconfig);
ret = (short)DialogBoxIndirectParamW(taskconfig->hInstance, template, taskconfig->hwndParent,
--
2.17.0