Module: wine Branch: master Commit: c55277c7e15f56d3c421c948e17338a1c22f560d URL: http://source.winehq.org/git/wine.git/?a=commit;h=c55277c7e15f56d3c421c948e1...
Author: Mikołaj Zalewski mikolaj@zalewski.pl Date: Fri Feb 9 16:59:43 2007 +0100
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..0a64531 100644 --- a/dlls/shell32/shlfileop.c +++ b/dlls/shell32/shlfileop.c @@ -65,6 +65,135 @@ static DWORD SHNotifyMoveFileW(LPCWSTR s 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 { 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 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