shell32[2/3]: add a confirmation dialog with a "Yes to All" option
Mikołaj Zalewski
mikolaj at zalewski.pl
Fri Feb 9 09:59:43 CST 2007
This will be helpful for overwrite file confirmations. The current
confirmation are changed to use this dialog so they have the buttons
right-aligned like on Windows.
-------------- next part --------------
From 9fcd77a6e66355f4e474fd698cbbed2ba00d3782 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Miko=C5=82aj_Zalewski?= <mikolaj at zalewski.pl>
Date: Thu, 8 Feb 2007 23:25:35 +0100
Subject: [PATCH] shell32: add a confirmation dialog with a "Yes to All" option
---
dlls/shell32/shell32_En.rc | 13 ++++
dlls/shell32/shlfileop.c | 143 ++++++++++++++++++++++++++++++++++++++++----
dlls/shell32/shresdef.h | 5 ++
3 files changed, 150 insertions(+), 11 deletions(-)
diff --git a/dlls/shell32/shell32_En.rc b/dlls/shell32/shell32_En.rc
index 7c7caaa..09530c6 100644
--- a/dlls/shell32/shell32_En.rc
+++ b/dlls/shell32/shell32_En.rc
@@ -104,6 +104,19 @@ FONT 8, "MS Shell Dlg"
4, 40, 180, 120
}
+SHELL_YESTOALL_MSGBOX DIALOG 200, 100, 280, 90
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Message"
+FONT 8, "MS Shell Dlg"
+{
+ DEFPUSHBUTTON "&Yes", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Yes to &all", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&No", IDNO, 162, 69, 53, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Cancel", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP
+ ICON "", IDD_ICON, 10, 10, 16, 16
+ LTEXT "", IDD_MESSAGE, 40, 10, 238, 52, 0
+}
+
SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 210, 152
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "About %s"
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c
index ac38957..d1ea475 100644
--- a/dlls/shell32/shlfileop.c
+++ b/dlls/shell32/shlfileop.c
@@ -65,6 +65,135 @@ static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest);
static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bFailIfExists);
static DWORD SHFindAttrW(LPCWSTR pName, BOOL fileOnly);
+/* Confirm dialogs with an optional "Yes To All" as used in file operations confirmations
+ */
+static const WCHAR CONFIRM_MSG_PROP[] = {'W','I','N','E','_','C','O','N','F','I','R','M',0};
+
+struct confirm_msg_info
+{
+ LPWSTR lpszText;
+ LPWSTR lpszCaption;
+ HICON hIcon;
+ BOOL bYesToAll;
+};
+
+/* as some buttons may be hidden and the dialog height may change we may need
+ * to move the controls */
+static void confirm_msg_move_button(HWND hDlg, INT iId, INT *xPos, INT yOffset, BOOL bShow)
+{
+ HWND hButton = GetDlgItem(hDlg, iId);
+ RECT r;
+
+ if (bShow) {
+ POINT pt;
+ int width;
+
+ GetWindowRect(hButton, &r);
+ width = r.right - r.left;
+ pt.x = r.left;
+ pt.y = r.top;
+ ScreenToClient(hDlg, &pt);
+ MoveWindow(hButton, *xPos - width, pt.y - yOffset, width, r.bottom - r.top, FALSE);
+ *xPos -= width + 5;
+ }
+ else
+ ShowWindow(hButton, SW_HIDE);
+}
+
+/* Note: we paint the text manually and don't use the static control to make
+ * sure the text has the same height as the one computed in WM_INITDIALOG
+ */
+static INT_PTR CALLBACK ConfirmMsgBox_Paint(HWND hDlg)
+{
+ PAINTSTRUCT ps;
+ HFONT hOldFont;
+ RECT r;
+ HDC hdc;
+
+ BeginPaint(hDlg, &ps);
+ hdc = ps.hdc;
+
+ GetClientRect(GetDlgItem(hDlg, IDD_MESSAGE), &r);
+ /* this will remap the rect to dialog coords */
+ MapWindowPoints(GetDlgItem(hDlg, IDD_MESSAGE), hDlg, (LPPOINT)&r, 2);
+ hOldFont = SelectObject(hdc, (HFONT)SendDlgItemMessageW(hDlg, IDD_MESSAGE, WM_GETFONT, 0, 0));
+ DrawTextW(hdc, (LPWSTR)GetPropW(hDlg, CONFIRM_MSG_PROP), -1, &r, DT_NOPREFIX | DT_PATH_ELLIPSIS | DT_WORDBREAK);
+ SelectObject(hdc, hOldFont);
+ EndPaint(hDlg, &ps);
+ return TRUE;
+}
+
+static INT_PTR CALLBACK ConfirmMsgBox_Init(HWND hDlg, LPARAM lParam)
+{
+ struct confirm_msg_info *info = (struct confirm_msg_info *)lParam;
+ INT xPos, yOffset;
+ int width, height;
+ HFONT hOldFont;
+ HDC hdc;
+ RECT r;
+
+ SetWindowTextW(hDlg, info->lpszCaption);
+ ShowWindow(GetDlgItem(hDlg, IDD_MESSAGE), SW_HIDE);
+ SetPropW(hDlg, CONFIRM_MSG_PROP, (HANDLE)info->lpszText);
+ SendDlgItemMessageW(hDlg, IDD_ICON, STM_SETICON, (WPARAM)info->hIcon, 0);
+
+ /* compute the text height and resize the dialog */
+ GetClientRect(GetDlgItem(hDlg, IDD_MESSAGE), &r);
+ hdc = GetDC(hDlg);
+ yOffset = r.bottom;
+ hOldFont = SelectObject(hdc, (HFONT)SendDlgItemMessageW(hDlg, IDD_MESSAGE, WM_GETFONT, 0, 0));
+ DrawTextW(hdc, info->lpszText, -1, &r, DT_NOPREFIX | DT_PATH_ELLIPSIS | DT_WORDBREAK | DT_CALCRECT);
+ SelectObject(hdc, hOldFont);
+ yOffset -= r.bottom;
+ yOffset = min(yOffset, 35); /* don't make the dialog too small */
+ ReleaseDC(hDlg, hdc);
+
+ GetClientRect(hDlg, &r);
+ xPos = r.right - 7;
+ GetWindowRect(hDlg, &r);
+ width = r.right - r.left;
+ height = r.bottom - r.top - yOffset;
+ MoveWindow(hDlg, (GetSystemMetrics(SM_CXSCREEN) - width)/2,
+ (GetSystemMetrics(SM_CYSCREEN) - height)/2, width, height, FALSE);
+
+ confirm_msg_move_button(hDlg, IDCANCEL, &xPos, yOffset, info->bYesToAll);
+ confirm_msg_move_button(hDlg, IDNO, &xPos, yOffset, TRUE);
+ confirm_msg_move_button(hDlg, IDD_YESTOALL, &xPos, yOffset, info->bYesToAll);
+ confirm_msg_move_button(hDlg, IDYES, &xPos, yOffset, TRUE);
+ return TRUE;
+}
+
+static INT_PTR CALLBACK ConfirmMsgBoxProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ return ConfirmMsgBox_Init(hDlg, lParam);
+ case WM_PAINT:
+ return ConfirmMsgBox_Paint(hDlg);
+ case WM_COMMAND:
+ EndDialog(hDlg, wParam);
+ break;
+ case WM_CLOSE:
+ EndDialog(hDlg, IDCANCEL);
+ break;
+ }
+ return FALSE;
+}
+
+static int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll)
+{
+ static const WCHAR wszTemplate[] = {'S','H','E','L','L','_','Y','E','S','T','O','A','L','L','_','M','S','G','B','O','X',0};
+ struct confirm_msg_info info;
+
+ info.lpszText = lpszText;
+ info.lpszCaption = lpszCaption;
+ info.hIcon = hIcon;
+ info.bYesToAll = bYesToAll;
+ return DialogBoxParamW(shell32_hInstance, wszTemplate, hWnd, ConfirmMsgBoxProc, (LPARAM)&info);
+}
+
+/* confirmation dialogs content */
typedef struct
{
HINSTANCE hIconInstance;
@@ -132,8 +261,8 @@ BOOL SHELL_ConfirmDialogW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir)
{
WCHAR szCaption[255], szText[255], szBuffer[MAX_PATH + 256];
SHELL_ConfirmIDstruc ids;
- MSGBOXPARAMSW params;
DWORD_PTR args[1];
+ HICON hIcon;
if (!SHELL_ConfirmIDs(nKindOfDialog, &ids))
return FALSE;
@@ -144,17 +273,9 @@ BOOL SHELL_ConfirmDialogW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir)
args[0] = (DWORD_PTR)szDir;
FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
szText, 0, 0, szBuffer, sizeof(szBuffer), (va_list*)args);
+ hIcon = LoadIconW(ids.hIconInstance, (LPWSTR)MAKEINTRESOURCE(ids.icon_resource_id));
- ZeroMemory(¶ms, sizeof(params));
- params.cbSize = sizeof(MSGBOXPARAMSW);
- params.hwndOwner = hWnd;
- params.hInstance = ids.hIconInstance;
- params.lpszText = szBuffer;
- params.lpszCaption = szCaption;
- params.lpszIcon = (LPWSTR)MAKEINTRESOURCE(ids.icon_resource_id);
- params.dwStyle = MB_YESNO | MB_USERICON;
-
- return (IDYES == MessageBoxIndirectW(¶ms));
+ return (IDYES == SHELL_ConfirmMsgBox(hWnd, szBuffer, szCaption, hIcon, FALSE));
}
static DWORD SHELL32_AnsiToUnicodeBuf(LPCSTR aPath, LPWSTR *wPath, DWORD minChars)
diff --git a/dlls/shell32/shresdef.h b/dlls/shell32/shresdef.h
index 422acc4..b9a7bad 100644
--- a/dlls/shell32/shresdef.h
+++ b/dlls/shell32/shresdef.h
@@ -96,6 +96,11 @@
/* Note: this string is referenced from the registry*/
#define IDS_RECYCLEBIN_FOLDER_NAME 8964
+#define IDD_ICON 0x4300
+#define IDD_MESSAGE 0x4301
+
+/* these IDs are the same as on native */
+#define IDD_YESTOALL 0x3207
/* browse for folder dialog box */
#define IDD_STATUS 0x3743
#define IDD_TITLE 0x3742
--
1.4.4.2
More information about the wine-patches
mailing list