[4/5] comctl32: Task dialog: Add main icon (try 2)

Joachim Priesner joachim.priesner at web.de
Mon Feb 23 06:42:51 CST 2015


---
 dlls/comctl32/comctl32.h   |  1 +
 dlls/comctl32/comctl32.rc  |  1 +
 dlls/comctl32/taskdialog.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++
 include/commctrl.h         |  5 ++++
 4 files changed, 69 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 4921a5f..a9053a3 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -29,6 +29,34 @@
 
 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 an icon for the task dialog from the specified instance and icon identifier. */
+HICON TASKDIALOG_GetIcon(HINSTANCE instance, PCWSTR 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 if (instance)
+        return LoadIconW(instance, icon);
+    return 0;
+}
+
 /* Fills "result" with a pointer to the string specified by "text", which may be a resource identifier. */
 static HRESULT TASKDIALOG_GetText(const WCHAR *text, HINSTANCE instance, const WCHAR **result)
 {
@@ -88,11 +116,13 @@ static void TASKDIALOG_OnInit(HWND hwnd, TASKDIALOGCONFIG *config)
     HMONITOR monitor = 0;
     HRESULT result;
     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;
@@ -193,6 +223,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_GetIcon(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;
@@ -236,6 +288,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);
@@ -267,6 +320,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)
     {
@@ -286,6 +345,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 <pshpack1.h>
 
+#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




More information about the wine-patches mailing list