comctl32: Display icon (if possible) and all supplied texts in TaskDialogIndirect
Joachim Priesner
joachim.priesner at web.de
Tue Sep 30 08:21:27 CDT 2014
The TaskDialogIndirect function takes three texts: content, main instruction, and footer. The current implementation would only display the main instruction. Now all texts are displayed, concatenated by two newlines if necessary.
Also, if the requested icon is one that is supported by MessageBoxW (error, warning, question, information), that icon is displayed.
Tested on openSuse 13.1 and Windows 8.1 x64.
---
dlls/comctl32/commctrl.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++-
include/commctrl.h | 5 ++++
2 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c
index 4f4e2b1..f69a23d 100644
--- a/dlls/comctl32/commctrl.c
+++ b/dlls/comctl32/commctrl.c
@@ -68,6 +68,7 @@
#include "shlwapi.h"
#include "comctl32.h"
#include "wine/debug.h"
+#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
@@ -92,6 +93,9 @@ static const WCHAR strCC32SubclassInfo[] = {
'C','C','3','2','S','u','b','c','l','a','s','s','I','n','f','o',0
};
+static const WCHAR strTwoNewlines[] = {
+ '\r','\n','\r','\n',0
+};
/***********************************************************************
* DllMain [Internal]
@@ -1607,6 +1611,8 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnBu
{
UINT uType = 0;
INT ret;
+ UINT mainInstructionLength, contentLength, footerLength, totalLength;
+ WCHAR *buffer;
FIXME("%p, %p, %p, %p\n", pTaskConfig, pnButton, pnRadioButton, pfVerificationFlagChecked);
if (pTaskConfig->dwCommonButtons & TDCBF_YES_BUTTON &&
@@ -1628,8 +1634,71 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnBu
else
if (pTaskConfig->dwCommonButtons & TDCBF_OK_BUTTON)
uType |= MB_OK;
- ret = MessageBoxW(pTaskConfig->hwndParent, pTaskConfig->pszMainInstruction,
+
+ TRACE("flags=%#x, hInstance=%p, icon=%s\n", pTaskConfig->dwFlags, pTaskConfig->hInstance,
+ debugstr_w(pTaskConfig->pszMainIcon));
+
+ if (!(pTaskConfig->dwFlags & TDF_USE_HICON_MAIN))
+ {
+ /* If hInstance is NULL, but pszMainIcon is not one of TD_*_ICON, the icon is taken from
+ * the system's image resources (imageres.dll). This is not really documented, but mentioned
+ * in the documentation for the TDM_UPDATE_ICON message. As a workaround, the values for the
+ * symbols that MessageBoxW supports are hard-coded here. */
+ if (pTaskConfig->pszMainIcon == TD_ERROR_ICON ||
+ (pTaskConfig->hInstance == NULL && pTaskConfig->pszMainIcon == MAKEINTRESOURCEW(0x62)))
+ uType |= MB_ICONERROR;
+ else
+ if (pTaskConfig->pszMainIcon == TD_WARNING_ICON ||
+ (pTaskConfig->hInstance == NULL && pTaskConfig->pszMainIcon == MAKEINTRESOURCEW(0x54)))
+ uType |= MB_ICONWARNING;
+ else
+ if (pTaskConfig->pszMainIcon == TD_INFORMATION_ICON ||
+ (pTaskConfig->hInstance == NULL && pTaskConfig->pszMainIcon == MAKEINTRESOURCEW(0x51)))
+ uType |= MB_ICONINFORMATION;
+ else
+ if (pTaskConfig->hInstance == NULL && pTaskConfig->pszMainIcon == MAKEINTRESOURCEW(0x63))
+ uType |= MB_ICONQUESTION;
+ else
+ if (pTaskConfig->pszMainIcon == TD_SHIELD_ICON)
+ FIXME("TD_SHIELD_ICON not implemented yet\n");
+ }
+
+ /* Concatenate main instruction, content and footer by two newlines each
+ * to simulate the layout of the task dialog. */
+ mainInstructionLength = pTaskConfig->pszMainInstruction == NULL ? 0 : lstrlenW(pTaskConfig->pszMainInstruction);
+ contentLength = pTaskConfig->pszContent == NULL ? 0 : lstrlenW(pTaskConfig->pszContent);
+ footerLength = pTaskConfig->pszFooter == NULL ? 0 : lstrlenW(pTaskConfig->pszFooter);
+
+ totalLength = mainInstructionLength;
+ if (contentLength > 0)
+ totalLength += (totalLength == 0 ? 0 : 4) + contentLength;
+ if (footerLength > 0)
+ totalLength += (totalLength == 0 ? 0 : 4) + footerLength;
+
+ buffer = HeapAlloc(GetProcessHeap(), 0, (totalLength + 1) * sizeof(WCHAR));
+ if (!buffer)
+ return E_OUTOFMEMORY;
+ buffer[0] = '\0';
+ if (mainInstructionLength > 0)
+ {
+ strcatW(buffer, pTaskConfig->pszMainInstruction);
+ }
+ if (contentLength > 0)
+ {
+ if (buffer[0] != '\0')
+ strcatW(buffer, strTwoNewlines);
+ strcatW(buffer, pTaskConfig->pszContent);
+ }
+ if (footerLength > 0)
+ {
+ if (buffer[0] != '\0')
+ strcatW(buffer, strTwoNewlines);
+ strcatW(buffer, pTaskConfig->pszFooter);
+ }
+
+ ret = MessageBoxW(pTaskConfig->hwndParent, buffer,
pTaskConfig->pszWindowTitle, uType);
+ HeapFree(GetProcessHeap(), 0, buffer);
FIXME("dwCommonButtons=%x uType=%x ret=%x\n", pTaskConfig->dwCommonButtons, uType, ret);
if (pnButton) *pnButton = ret;
diff --git a/include/commctrl.h b/include/commctrl.h
index 9993ec7..73cc136 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -5086,6 +5086,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