From: Johannes Anderwald Date: Mon, 26 Apr 2010 19:50:11 +0000 (+0000) Subject: [SHELL32] X-Git-Tag: backups/header-work@57446~33^2~42 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=42c28cc44f397363225de805fe8afb07ba408e80 [SHELL32] - Start implementing file copy / move / delete dialog - Not yet enabled svn path=/trunk/; revision=47043 --- diff --git a/reactos/dll/win32/shell32/lang/en-US.rc b/reactos/dll/win32/shell32/lang/en-US.rc index 6e8aef34ee0..04df98d1e60 100644 --- a/reactos/dll/win32/shell32/lang/en-US.rc +++ b/reactos/dll/win32/shell32/lang/en-US.rc @@ -373,6 +373,17 @@ BEGIN PUSHBUTTON "Cancel", 14006, 206, 236, 50, 14 END +IDD_SH_FILE_COPY DIALOGEX 0, 0, 264, 45 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION +CAPTION "Copying..." +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + PUSHBUTTON "Cancel", 14002, 195, 14, 60, 16 + CONTROL "", 14000, "MSCTLS_PROGRESS32", 0, 8, 20, 170, 10 + LTEXT "File", 14001, 8, 6, 169, 10 +END + + FOLDER_OPTIONS_GENERAL_DLG DIALOGEX 0, 0, 264, 256 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION CAPTION "General" diff --git a/reactos/dll/win32/shell32/shlfileop.c b/reactos/dll/win32/shell32/shlfileop.c index 6992d187ee4..defe95facd6 100644 --- a/reactos/dll/win32/shell32/shlfileop.c +++ b/reactos/dll/win32/shell32/shlfileop.c @@ -33,6 +33,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); #define IsDotDir(x) ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0)))) #define FO_MASK 0xF +#define WM_FILE (WM_USER + 1) +#define TIMER_ID (100) static const WCHAR wWildcardFile[] = {'*',0}; static const WCHAR wWildcardChars[] = {'*','?',0}; @@ -52,6 +54,40 @@ typedef struct BOOL bCancelled; } FILE_OPERATION; +#define ERROR_SHELL_INTERNAL_FILE_NOT_FOUND 1026 + +typedef struct +{ + DWORD attributes; + LPWSTR szDirectory; + LPWSTR szFilename; + LPWSTR szFullPath; + BOOL bFromWildcard; + BOOL bFromRelative; + BOOL bExists; +} FILE_ENTRY; + +typedef struct +{ + FILE_ENTRY *feFiles; + DWORD num_alloc; + DWORD dwNumFiles; + BOOL bAnyFromWildcard; + BOOL bAnyDirectories; + BOOL bAnyDontExist; +} FILE_LIST; + +typedef struct +{ + FILE_LIST * from; + FILE_LIST * to; + FILE_OPERATION * op; + DWORD Index; + HWND hDlgCtrl; + HWND hwndDlg; +}FILE_OPERATION_CONTEXT; + + /* 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}; @@ -514,6 +550,163 @@ static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest) return GetLastError(); } +static WINAPI DWORD SHOperationProgressRoutine(LARGE_INTEGER TotalFileSize, LARGE_INTEGER TotalBytesTransferred, LARGE_INTEGER StreamSize, LARGE_INTEGER StreamBytesTransferred, DWORD dwStreamNumber, DWORD dwCallbackReason, HANDLE hSourceFile, HANDLE hDestinationFile, LPVOID lpData) +{ + FILE_OPERATION_CONTEXT * Context; + LARGE_INTEGER Progress; + + /* get context */ + Context = (FILE_OPERATION_CONTEXT*)lpData; + + if (TotalBytesTransferred.QuadPart) + { + Progress.QuadPart = (TotalBytesTransferred.QuadPart * 100) / TotalFileSize.QuadPart; + } + else + { + Progress.QuadPart = 1; + } + + /* update progress bar */ + SendMessageW(Context->hDlgCtrl, PBM_SETPOS, (WPARAM)Progress.u.LowPart, 0); + + if (TotalBytesTransferred.QuadPart == TotalFileSize.QuadPart) + { + /* file was copied */ + Context->Index++; + PostMessageW(Context->hwndDlg, WM_FILE, 0, 0); + } + + return PROGRESS_CONTINUE; +} + +BOOL +QueueFile( + FILE_OPERATION_CONTEXT * Context) +{ + FILE_ENTRY * from, *to; + BOOL bRet = FALSE; + + if (Context->Index >= Context->from->dwNumFiles) + return FALSE; + + /* get current file */ + from = &Context->from->feFiles[Context->Index]; + + if (Context->op->req->fFlags != FO_DELETE) + to = &Context->to->feFiles[Context->Index]; + + /* update status */ + SendDlgItemMessageW(Context->hwndDlg, 14001, WM_SETTEXT, 0, (LPARAM)from->szFullPath); + + if (Context->op->req->wFunc == FO_COPY) + { + bRet = CopyFileExW(from->szFullPath, to->szFullPath, SHOperationProgressRoutine, (LPVOID)Context, &Context->op->bCancelled, 0); + } + else if (Context->op->req->wFunc == FO_MOVE) + { + //bRet = MoveFileWithProgressW(from->szFullPath, to->szFullPath, SHOperationProgressRoutine, (LPVOID)Context, MOVEFILE_COPY_ALLOWED); + } + else if (Context->op->req->wFunc == FO_DELETE) + { + bRet = DeleteFile(from->szFullPath); + } + + return bRet; +} + +static INT_PTR CALLBACK SHOperationDialog(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + FILE_OPERATION_CONTEXT * Context; + + Context = (FILE_OPERATION_CONTEXT*) GetWindowLongPtr(hwndDlg, DWLP_USER); + + switch(uMsg) + { + case WM_INITDIALOG: + SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)lParam); + + /* get context */ + Context = (FILE_OPERATION_CONTEXT*)lParam; + + /* store progress bar handle */ + Context->hDlgCtrl = GetDlgItem(hwndDlg, 14000); + + /* store window handle */ + Context->hwndDlg = hwndDlg; + + /* set progress bar range */ + (void)SendMessageW(Context->hDlgCtrl, (UINT) PBM_SETRANGE, 0, MAKELPARAM(0, 100)); + + /* start file queueing */ + SetTimer(hwndDlg, TIMER_ID, 1000, NULL); + //QueueFile(Context); + + return TRUE; + + case WM_CLOSE: + Context->op->bCancelled = TRUE; + EndDialog(hwndDlg, Context->op->bCancelled); + return TRUE; + case WM_COMMAND: + if (LOWORD(wParam) == 14002) + { + Context->op->bCancelled = TRUE; + EndDialog(hwndDlg, Context->op->bCancelled); + return TRUE; + } + break; + case WM_TIMER: + if (wParam == TIMER_ID) + { + QueueFile(Context); + KillTimer(hwndDlg, TIMER_ID); + } + break; + case WM_FILE: + if (!QueueFile(Context)) + EndDialog(hwndDlg, Context->op->bCancelled); + default: + break; + } + return FALSE; +} + +HRESULT +SHShowFileOperationDialog(FILE_OPERATION *op, FILE_LIST *flFrom, FILE_LIST *flTo) +{ + HWND hwnd; + BOOL bRet; + MSG msg; + FILE_OPERATION_CONTEXT Context; + + Context.from = flFrom; + Context.to = flTo; + Context.op = op; + Context.Index = 0; + Context.op->bCancelled = FALSE; + + hwnd = CreateDialogParam(shell32_hInstance, MAKEINTRESOURCE(IDD_SH_FILE_COPY), NULL, SHOperationDialog, (LPARAM)&Context); + if (hwnd == NULL) + { + ERR("Failed to create dialog\n"); + return E_FAIL; + } + ShowWindow(hwnd, SW_SHOWNORMAL); + + while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) + { + if (!IsWindow(hwnd) || !IsDialogMessage(hwnd, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + return NOERROR; +} + + /************************************************************************ * SHNotifyCopyFile [internal] * @@ -808,28 +1001,7 @@ int WINAPI SHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp) return retCode; } -#define ERROR_SHELL_INTERNAL_FILE_NOT_FOUND 1026 -typedef struct -{ - DWORD attributes; - LPWSTR szDirectory; - LPWSTR szFilename; - LPWSTR szFullPath; - BOOL bFromWildcard; - BOOL bFromRelative; - BOOL bExists; -} FILE_ENTRY; - -typedef struct -{ - FILE_ENTRY *feFiles; - DWORD num_alloc; - DWORD dwNumFiles; - BOOL bAnyFromWildcard; - BOOL bAnyDirectories; - BOOL bAnyDontExist; -} FILE_LIST; static void __inline grow_list(FILE_LIST *list) diff --git a/reactos/dll/win32/shell32/shresdef.h b/reactos/dll/win32/shell32/shresdef.h index 93b50975a07..43e409cbf44 100644 --- a/reactos/dll/win32/shell32/shresdef.h +++ b/reactos/dll/win32/shell32/shresdef.h @@ -193,6 +193,7 @@ #define IDD_TREEVIEW 0x3741 #define SHELL_EXTENDED_SHORTCUT_DLG 0x4000 #define OPEN_WITH_PROGRAMM_DLG 0x4001 +#define IDD_SH_FILE_COPY 0x4002 /* ID's of the ShellAbout controls */ // Part 1 - ID's identical to Windows Server 2003 SP1's shell32.dll