From: Joachim Priesner Subject: [4/5] comctl32: Task dialog: Add main icon (try 3) Message-Id: <201502261658.07045.joachim.priesner@web.de> Date: Thu, 26 Feb 2015 16:58:04 +0100 --- dlls/comctl32/comctl32.h | 1 + dlls/comctl32/comctl32.rc | 1 + dlls/comctl32/taskdialog.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ include/commctrl.h | 5 ++++ 4 files changed, 68 insertions(+) diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h index 84b8fa0..2bc3507 100644 --- a/dlls/comctl32/comctl32.h +++ b/dlls/comctl32/comctl32.h @@ -68,6 +68,7 @@ extern HBRUSH COMCTL32_hPattern55AABrush DECLSPEC_HIDDEN; /* Task dialog */ #define IDD_TASKDIALOG 510 +#define IDC_MAIN_ICON 511 #define IDC_MAIN_INSTRUCTION 512 #define IDC_CONTENT 513 diff --git a/dlls/comctl32/comctl32.rc b/dlls/comctl32/comctl32.rc index fa8f7ea..0450a36 100644 --- a/dlls/comctl32/comctl32.rc +++ b/dlls/comctl32/comctl32.rc @@ -96,6 +96,7 @@ END IDD_TASKDIALOG DIALOG 100, 80, 216, 168 STYLE DS_MODALFRAME | DS_NOIDLEMSG | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU BEGIN + ICON "", IDC_MAIN_ICON, 8, 20, 16, 16, WS_CHILD | WS_VISIBLE LTEXT "", IDC_MAIN_INSTRUCTION, 32, 4, 176, 48, WS_CHILD | WS_VISIBLE | WS_GROUP | SS_NOPREFIX LTEXT "", IDC_CONTENT, 32, 4, 176, 48, WS_CHILD | WS_VISIBLE | WS_GROUP | SS_NOPREFIX PUSHBUTTON "OK", IDOK, 16, 56, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c index fe6822c..8fdf78b 100644 --- a/dlls/comctl32/taskdialog.c +++ b/dlls/comctl32/taskdialog.c @@ -29,6 +29,33 @@ WINE_DEFAULT_DEBUG_CHANNEL(commctrl); +#define IMAGERES_QUESTION_ICON MAKEINTRESOURCEW(0x63) +#define IMAGERES_ERROR_ICON MAKEINTRESOURCEW(0x62) +#define IMAGERES_WARNING_ICON MAKEINTRESOURCEW(0x54) +#define IMAGERES_INFORMATION_ICON MAKEINTRESOURCEW(0x51) + +/* Retrieves a main icon for the task dialog from the specified instance and icon identifier. */ +HICON TASKDIALOG_GetMainIcon(HINSTANCE instance, const WCHAR* icon) +{ + /* If instance is NULL and icon is not one if the TD_*_ICON constants, the icon is taken + * from the system's image resources (imageres.dll). This is documented in the MSDN + * documentation for the TDM_UPDATE_ICON message. Until imageres.dll is implemented, + * hard-code some of the offsets for standard icons in imageres.dll so at least some + * of the icons are displayed correctly. */ + if (icon == TD_ERROR_ICON || (instance == NULL && icon == IMAGERES_ERROR_ICON)) + return LoadIconW(NULL, (LPWSTR)IDI_ERROR); + else if (icon == TD_WARNING_ICON || (instance == NULL && icon == IMAGERES_WARNING_ICON)) + return LoadIconW(NULL, (LPWSTR)IDI_WARNING); + else if (icon == TD_INFORMATION_ICON || (instance == NULL && icon == IMAGERES_INFORMATION_ICON)) + return LoadIconW(NULL, (LPWSTR)IDI_INFORMATION); + else if (icon == TD_SHIELD_ICON) + return LoadIconW(NULL, (LPWSTR)IDI_SHIELD); + else if (instance == NULL && icon == IMAGERES_QUESTION_ICON) + return LoadIconW(NULL, (LPWSTR)IDI_QUESTION); + else + return LoadIconW(instance, icon); +} + /* Returns a pointer to the string specified by "text", which may be a resource identifier. */ static const WCHAR* TASKDIALOG_GetText(HINSTANCE instance, const WCHAR *text) { @@ -84,11 +111,13 @@ static void TASKDIALOG_OnInit(HWND hwnd, TASKDIALOGCONFIG *config) HDC hdc; HMONITOR monitor = 0; MONITORINFO monitorInfo; + HICON mainIcon = 0; int nButtons = 0; int i, currentX, currentY; int buttonWidth, buttonAreaWidth, buttonHeight; int windowClientWidth, windowClientHeight, windowLeft, windowTop; int windowBorderHeight, windowBorderWidth; + int mainIconHeight, mainIconLeft, mainIconWidth; int mainAreaTextLeft, mainAreaTextWidth; int contentTextWidth, contentTextHeight; int mainInstructionWidth, mainInstructionHeight; @@ -179,6 +208,28 @@ static void TASKDIALOG_OnInit(HWND hwnd, TASKDIALOGCONFIG *config) DestroyWindow(GetDlgItem(hwnd, IDOK)); else nButtons++; + /* Set the main icon. */ + if (config->dwFlags & TDF_USE_HICON_MAIN) + mainIcon = config->hMainIcon; + else + mainIcon = TASKDIALOG_GetMainIcon(config->hInstance, config->pszMainIcon); + + if (mainIcon) + { + SendDlgItemMessageW(hwnd, IDC_MAIN_ICON, STM_SETICON, (WPARAM)mainIcon, 0); + GetWindowRect(GetDlgItem(hwnd, IDC_MAIN_ICON), &rect); + MapWindowPoints(0, hwnd, (LPPOINT)&rect, 2); + mainIconHeight = rect.bottom - rect.top; + mainIconWidth = rect.right - rect.left; + mainIconLeft = spacing; + } + else + { + mainIconHeight = 0; + mainIconWidth = 0; + mainIconLeft = 0; + } + /* Position everything. */ GetWindowRect(hwnd, &rect); windowBorderHeight = rect.bottom - rect.top; @@ -222,6 +273,7 @@ static void TASKDIALOG_OnInit(HWND hwnd, TASKDIALOGCONFIG *config) buttonAreaWidth = (buttonWidth + spacing) * nButtons - spacing; mainAreaTextLeft = spacing; + if (mainIconWidth) mainAreaTextLeft += mainIconWidth + spacing; /* Calculate main area text size. The texts are at least as wide as the button area. */ GetClientRect(GetDlgItem(hwnd, IDC_MAIN_INSTRUCTION), &rect); @@ -253,6 +305,12 @@ static void TASKDIALOG_OnInit(HWND hwnd, TASKDIALOGCONFIG *config) /* Position everything from top to bottom. */ currentY = spacing; + /* Position the main icon. */ + if (mainIcon) + SetWindowPos(GetDlgItem(hwnd, IDC_MAIN_ICON), 0, mainIconLeft, currentY, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW); + else DestroyWindow(GetDlgItem(hwnd, IDC_MAIN_ICON)); + /* Position the texts in the main area. */ if (mainInstructionHeight) { @@ -272,6 +330,9 @@ static void TASKDIALOG_OnInit(HWND hwnd, TASKDIALOGCONFIG *config) } else DestroyWindow(GetDlgItem(hwnd, IDC_CONTENT)); + if (mainIconHeight) + currentY = max(currentY, spacing + mainIconHeight + spacing); + /* Position the buttons: right-aligned */ currentX = windowClientWidth - spacing - buttonAreaWidth; for (i = 0; i < (sizeof(commonButtons) / sizeof(commonButtons[0])); i++) diff --git a/include/commctrl.h b/include/commctrl.h index 0bcaeb6..af60ad3 100644 --- a/include/commctrl.h +++ b/include/commctrl.h @@ -5087,6 +5087,11 @@ static const WCHAR WC_SCROLLBARW[] = { 'S','c','r','o','l','l','B','a','r',0 }; #include +#define TD_WARNING_ICON MAKEINTRESOURCEW(-1) +#define TD_ERROR_ICON MAKEINTRESOURCEW(-2) +#define TD_INFORMATION_ICON MAKEINTRESOURCEW(-3) +#define TD_SHIELD_ICON MAKEINTRESOURCEW(-4) + enum _TASKDIALOG_FLAGS { TDF_ENABLE_HYPERLINKS = 0x0001, -- 1.8.4.5