From bb9cc13c1fd3f76f1252f8afd32216078ba8fffc Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Mon, 9 Feb 2015 22:29:23 +0000 Subject: [PATCH] [BROWSEUI] - Implement CProgressDialog based on wine - Patch by Huw Campbell, improved by me CORE-4476 svn path=/trunk/; revision=66212 --- reactos/dll/win32/browseui/CMakeLists.txt | 1 + .../dll/win32/browseui/CProgressDialog.cpp | 453 ++++++++++++++++++ reactos/dll/win32/browseui/CProgressDialog.h | 101 ++++ reactos/dll/win32/browseui/browseui.cpp | 1 + reactos/dll/win32/browseui/browseui.rc | 1 + reactos/dll/win32/browseui/lang/en-US.rc | 19 + reactos/dll/win32/browseui/precomp.h | 2 + .../dll/win32/browseui/res/progressdialog.rgs | 13 + reactos/dll/win32/browseui/resource.h | 8 + 9 files changed, 599 insertions(+) create mode 100644 reactos/dll/win32/browseui/CProgressDialog.cpp create mode 100644 reactos/dll/win32/browseui/CProgressDialog.h create mode 100644 reactos/dll/win32/browseui/res/progressdialog.rgs diff --git a/reactos/dll/win32/browseui/CMakeLists.txt b/reactos/dll/win32/browseui/CMakeLists.txt index 370d2951e23..016fa4826b7 100644 --- a/reactos/dll/win32/browseui/CMakeLists.txt +++ b/reactos/dll/win32/browseui/CMakeLists.txt @@ -28,6 +28,7 @@ list(APPEND SOURCE toolsband.cpp travellog.cpp utility.cpp + CProgressDialog.cpp precomp.h) add_library(browseui SHARED diff --git a/reactos/dll/win32/browseui/CProgressDialog.cpp b/reactos/dll/win32/browseui/CProgressDialog.cpp new file mode 100644 index 00000000000..19d5fd5a004 --- /dev/null +++ b/reactos/dll/win32/browseui/CProgressDialog.cpp @@ -0,0 +1,453 @@ +/* + * Progress dialog + * + * Copyright 2007 Mikolaj Zalewski + * Copyright 2014 Huw Campbell + * + * this library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * this library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#define COBJMACROS + +#define CANCEL_MSG_LINE 2 + +/* Note: to avoid a deadlock we don't want to send messages to the dialog + * with the critical section held. Instead we only mark what fields should be + * updated and the dialog proc does the update */ +#define UPDATE_PROGRESS 0x1 +#define UPDATE_TITLE 0x2 +#define UPDATE_LINE1 0x4 +#define UPDATE_LINE2 (UPDATE_LINE1<<1) +#define UPDATE_LINE3 (UPDATE_LINE1<<2) + + +#define WM_DLG_UPDATE (WM_APP+1) /* set to the dialog when it should update */ +#define WM_DLG_DESTROY (WM_APP+2) /* DestroyWindow must be called from the owning thread */ + +#define ID_3SECONDS 101 + +CProgressDialog::CProgressDialog() +{ + ULONG cb = 32 *sizeof(WCHAR); + this->lines[0] = (LPWSTR) heap_alloc_zero(cb); + this->lines[1] = (LPWSTR) heap_alloc_zero(cb); + this->lines[2] = (LPWSTR) heap_alloc_zero(cb); + this->cancelMsg = (LPWSTR) heap_alloc_zero(cb); + this->title = (LPWSTR) heap_alloc_zero(cb); + + this->clockHand = -1; + this->progressClock[29].ullMark = 0ull; + this->dwStartTime = GetTickCount(); + + InitializeCriticalSection(&this->cs); + this->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ProgressDialog.cs"); +} + +CProgressDialog::~CProgressDialog() +{ + if (this->hwnd) + this->end_dialog(); + heap_free(this->lines[0]); + heap_free(this->lines[1]); + heap_free(this->lines[2]); + heap_free(this->cancelMsg); + heap_free(this->title); + this->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&this->cs); +} + +static void set_buffer(LPWSTR *buffer, LPCWSTR string) +{ + static const WCHAR empty_string[] = {0}; + ULONG len; + + if (string == NULL) + string = empty_string; + len = (wcslen(string) + 1)*sizeof(WCHAR); + + LPWSTR tmp = (LPWSTR) heap_realloc(*buffer, len); + if (tmp) + *buffer = tmp; + else + len = wcslen(*buffer) + 1; + + StringCchCopyW(*buffer, len, string); +} + +struct create_params +{ + CProgressDialog *This; + HANDLE hEvent; + HWND hwndParent; +}; + +static LPWSTR load_string(HINSTANCE hInstance, UINT uiResourceId) +{ + WCHAR string[256]; + LPWSTR ret; + + LoadStringW(hInstance, uiResourceId, string, sizeof(string)/sizeof(string[0])); + ret = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, (wcslen(string) + 1) * sizeof(WCHAR)); + StrCpyW(ret, string); + return ret; +} + +void CProgressDialog::set_progress_marquee() +{ + HWND hProgress = GetDlgItem(this->hwnd, IDC_PROGRESS_BAR); + SetWindowLongW(hProgress, GWL_STYLE, + GetWindowLongW(hProgress, GWL_STYLE)|PBS_MARQUEE); +} + +void CProgressDialog::update_dialog(DWORD dwUpdate) +{ + WCHAR empty[] = {0}; + + if (dwUpdate & UPDATE_TITLE) + SetWindowTextW(this->hwnd, this->title); + + if (dwUpdate & UPDATE_LINE1) + SetDlgItemTextW(this->hwnd, IDC_TEXT_LINE, (this->isCancelled ? empty : this->lines[0])); + if (dwUpdate & UPDATE_LINE2) + SetDlgItemTextW(this->hwnd, IDC_TEXT_LINE+1, (this->isCancelled ? empty : this->lines[1])); + if (dwUpdate & UPDATE_LINE3) + SetDlgItemTextW(this->hwnd, IDC_TEXT_LINE+2, (this->isCancelled ? this->cancelMsg : this->lines[2])); + + if (dwUpdate & UPDATE_PROGRESS) + { + ULONGLONG ullTotal = this->ullTotal; + ULONGLONG ullCompleted = this->ullCompleted; + + /* progress bar requires 32-bit coordinates */ + while (ullTotal >> 32) + { + ullTotal >>= 1; + ullCompleted >>= 1; + } + + SendDlgItemMessageW(this->hwnd, IDC_PROGRESS_BAR, PBM_SETRANGE32, 0, (DWORD)ullTotal); + SendDlgItemMessageW(this->hwnd, IDC_PROGRESS_BAR, PBM_SETPOS, (DWORD)ullCompleted, 0); + } +} + +void CProgressDialog::end_dialog() +{ + SendMessageW(this->hwnd, WM_DLG_DESTROY, 0, 0); + /* native doesn't re-enable the window? */ + if (this->hwndDisabledParent) + EnableWindow(this->hwndDisabledParent, TRUE); + this->hwnd = NULL; +} + +static INT_PTR CALLBACK dialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CProgressDialog *This = (CProgressDialog *)GetWindowLongPtrW(hwnd, DWLP_USER); + + switch (msg) + { + case WM_INITDIALOG: + { + struct create_params *params = (struct create_params *)lParam; + + /* Note: until we set the hEvent, the object is protected by + * the critical section held by StartProgress */ + SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)params->This); + This = params->This; + This->hwnd = hwnd; + + if (This->dwFlags & PROGDLG_NOPROGRESSBAR) + ShowWindow(GetDlgItem(hwnd, IDC_PROGRESS_BAR), SW_HIDE); + if (This->dwFlags & PROGDLG_NOCANCEL) + ShowWindow(GetDlgItem(hwnd, IDCANCEL), SW_HIDE); + if (This->dwFlags & PROGDLG_MARQUEEPROGRESS) + This->set_progress_marquee(); + if (This->dwFlags & PROGDLG_NOMINIMIZE) + SetWindowLongW(hwnd, GWL_STYLE, GetWindowLongW(hwnd, GWL_STYLE) & (~WS_MINIMIZEBOX)); + + This->update_dialog(0xffffffff); + This->dwUpdate = 0; + This->isCancelled = FALSE; + + SetTimer(hwnd, ID_3SECONDS, 3 * 1000, NULL); + + SetEvent(params->hEvent); + return TRUE; + } + + case WM_DLG_UPDATE: + EnterCriticalSection(&This->cs); + This->update_dialog(This->dwUpdate); + This->dwUpdate = 0; + LeaveCriticalSection(&This->cs); + return TRUE; + + case WM_DLG_DESTROY: + DestroyWindow(hwnd); + PostThreadMessageW(GetCurrentThreadId(), WM_NULL, 0, 0); /* wake up the GetMessage */ + KillTimer(hwnd, ID_3SECONDS); + + return TRUE; + + case WM_CLOSE: + case WM_COMMAND: + if (msg == WM_CLOSE || wParam == IDCANCEL) + { + EnterCriticalSection(&This->cs); + This->isCancelled = TRUE; + + if (!This->cancelMsg[0]) { + heap_free(This->cancelMsg); + This->cancelMsg = load_string(_AtlBaseModule.GetResourceInstance(), IDS_CANCELLING); + } + + This->set_progress_marquee(); + EnableWindow(GetDlgItem(This->hwnd, IDCANCEL), FALSE); + This->update_dialog(UPDATE_LINE1|UPDATE_LINE2|UPDATE_LINE3); + LeaveCriticalSection(&This->cs); + } + return TRUE; + + case WM_TIMER: + EnterCriticalSection(&This->cs); + if (This->progressClock[29].ullMark != 0ull) { + // We have enough info to take a guess + ULONGLONG sizeDiff = This->progressClock[This->clockHand].ullMark - + This->progressClock[(This->clockHand + 29) % 30].ullMark; + DWORD timeDiff = This->progressClock[This->clockHand].dwTime - + This->progressClock[(This->clockHand + 29) % 30].dwTime; + DWORD runDiff = This->progressClock[This->clockHand].dwTime - + This->dwStartTime; + ULONGLONG sizeLeft = This->ullTotal - This->progressClock[This->clockHand].ullMark; + + // A guess for time remaining based on the recent slope. + DWORD timeLeftD = (DWORD) timeDiff * ((double) sizeLeft) / ((double) sizeDiff); + // A guess for time remaining based on the start time and current position + DWORD timeLeftI = (DWORD) runDiff * ((double) sizeLeft) / ((double) This->progressClock[This->clockHand].ullMark); + + heap_realloc(&This->lines[2], 128); + StrFromTimeIntervalW(This->lines[2], 128, timeLeftD * 0.3 + timeLeftI * 0.7 , 2); + This->update_dialog( UPDATE_LINE1 << 2 ); + } + LeaveCriticalSection(&This->cs); + + return TRUE; + } + return FALSE; +} + +static DWORD WINAPI dialog_thread(LPVOID lpParameter) +{ + /* Note: until we set the hEvent in WM_INITDIALOG, the ProgressDialog object + * is protected by the critical section held by StartProgress */ + struct create_params *params = (struct create_params *) lpParameter; + HWND hwnd; + MSG msg; + + hwnd = CreateDialogParamW(_AtlBaseModule.GetResourceInstance(), + MAKEINTRESOURCEW(IDD_PROGRESS_DLG), + params->hwndParent, + dialog_proc, + (LPARAM)params); + + while (GetMessageW(&msg, NULL, 0, 0) > 0) + { + if (!IsWindow(hwnd)) + break; + if(!IsDialogMessageW(hwnd, &msg)) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + + return 0; +} + +HRESULT WINAPI CProgressDialog::StartProgressDialog(HWND hwndParent, IUnknown *punkEnableModeless, DWORD dwFlags, LPCVOID reserved) +{ + static const INITCOMMONCONTROLSEX init = { sizeof(init), ICC_ANIMATE_CLASS }; + + struct create_params params; + HANDLE hThread; + + // TRACE("(%p, %p, %x, %p)\n", this, punkEnableModeless, dwFlags, reserved); + if (punkEnableModeless || reserved) + FIXME("Reserved parameters not null (%p, %p)\n", punkEnableModeless, reserved); + if (dwFlags & PROGDLG_AUTOTIME) + FIXME("Flags PROGDLG_AUTOTIME not supported\n"); + if (dwFlags & PROGDLG_NOTIME) + FIXME("Flags PROGDLG_NOTIME not supported\n"); + + InitCommonControlsEx( &init ); + + EnterCriticalSection(&this->cs); + + if (this->hwnd) + { + LeaveCriticalSection(&this->cs); + return S_OK; /* as on XP */ + } + this->dwFlags = dwFlags; + params.This = this; + params.hwndParent = hwndParent; + params.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + + hThread = CreateThread(NULL, 0, dialog_thread, ¶ms, 0, NULL); + WaitForSingleObject(params.hEvent, INFINITE); + CloseHandle(params.hEvent); + CloseHandle(hThread); + + this->hwndDisabledParent = NULL; + if (hwndParent && (dwFlags & PROGDLG_MODAL)) + { + HWND hwndDisable = GetAncestor(hwndParent, GA_ROOT); + if (EnableWindow(hwndDisable, FALSE)) + this->hwndDisabledParent = hwndDisable; + } + + LeaveCriticalSection(&this->cs); + + return S_OK; +} + +HRESULT WINAPI CProgressDialog::StopProgressDialog() +{ + EnterCriticalSection(&this->cs); + if (this->hwnd) + this->end_dialog(); + LeaveCriticalSection(&this->cs); + + return S_OK; +} + +HRESULT WINAPI CProgressDialog::SetTitle(LPCWSTR pwzTitle) +{ + HWND hwnd; + + EnterCriticalSection(&this->cs); + set_buffer(&this->title, pwzTitle); + this->dwUpdate |= UPDATE_TITLE; + hwnd = this->hwnd; + LeaveCriticalSection(&this->cs); + + if (hwnd) + SendMessageW(hwnd, WM_DLG_UPDATE, 0, 0); + + return S_OK; +} + +HRESULT WINAPI CProgressDialog::SetAnimation(HINSTANCE hInstance, UINT uiResourceId) +{ + return S_OK; +} + +BOOL WINAPI CProgressDialog::HasUserCancelled() +{ + return this->isCancelled; +} + +HRESULT WINAPI CProgressDialog::SetProgress64(ULONGLONG ullCompleted, ULONGLONG ullTotal) +{ + HWND hwnd; + + EnterCriticalSection(&this->cs); + this->ullTotal = ullTotal; + this->ullCompleted = ullCompleted; + + if (GetTickCount() - this->progressClock[(this->clockHand + 29) % 30].dwTime > 20) { + this->clockHand = (this->clockHand + 1) % 30; + this->progressClock[this->clockHand].ullMark = ullCompleted; + this->progressClock[this->clockHand].dwTime = GetTickCount(); + } + + this->dwUpdate |= UPDATE_PROGRESS; + hwnd = this->hwnd; + LeaveCriticalSection(&this->cs); + + if (hwnd) + SendMessageW(hwnd, WM_DLG_UPDATE, 0, 0); + + return S_OK; /* Windows sometimes returns S_FALSE */ +} + +HRESULT WINAPI CProgressDialog::SetProgress(DWORD dwCompleted, DWORD dwTotal) +{ + return this->SetProgress64(dwCompleted, dwTotal); +} + +HRESULT WINAPI CProgressDialog::SetLine(DWORD dwLineNum, LPCWSTR pwzLine, BOOL bPath, LPCVOID reserved) +{ + HWND hwnd; + + if (reserved) + FIXME("reserved pointer not null (%p)\n", reserved); + + dwLineNum--; + if (dwLineNum >= 3) /* Windows seems to do something like that */ + dwLineNum = 0; + + EnterCriticalSection(&this->cs); + set_buffer(&this->lines[dwLineNum], pwzLine); + this->dwUpdate |= UPDATE_LINE1 << dwLineNum; + hwnd = (this->isCancelled ? NULL : this->hwnd); /* no sense to send the message if window cancelled */ + LeaveCriticalSection(&this->cs); + + if (hwnd) + SendMessageW(hwnd, WM_DLG_UPDATE, 0, 0); + + return S_OK; +} + +HRESULT WINAPI CProgressDialog::SetCancelMsg(LPCWSTR pwzMsg, LPCVOID reserved) +{ + HWND hwnd; + + if (reserved) + FIXME("reserved pointer not null (%p)\n", reserved); + + EnterCriticalSection(&this->cs); + set_buffer(&this->cancelMsg, pwzMsg); + this->dwUpdate |= UPDATE_LINE1 << CANCEL_MSG_LINE; + hwnd = (this->isCancelled ? this->hwnd : NULL); /* no sense to send the message if window not cancelled */ + LeaveCriticalSection(&this->cs); + + if (hwnd) + SendMessageW(hwnd, WM_DLG_UPDATE, 0, 0); + + return S_OK; +} + +HRESULT WINAPI CProgressDialog::Timer(DWORD dwTimerAction, LPCVOID reserved) +{ + if (reserved) + FIXME("Reserved field not NULL but %p\n", reserved); + + return S_OK; +} + +HRESULT WINAPI CProgressDialog::GetWindow(HWND* phwnd) +{ + EnterCriticalSection(&this->cs); + *phwnd = this->hwnd; + LeaveCriticalSection(&this->cs); + return S_OK; +} + +HRESULT WINAPI CProgressDialog::ContextSensitiveHelp(BOOL fEnterMode) +{ + return E_NOTIMPL; +} diff --git a/reactos/dll/win32/browseui/CProgressDialog.h b/reactos/dll/win32/browseui/CProgressDialog.h new file mode 100644 index 00000000000..ed4646956ee --- /dev/null +++ b/reactos/dll/win32/browseui/CProgressDialog.h @@ -0,0 +1,101 @@ +/* + * Progress dialog + * + * Copyright 2014 Huw Campbell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _PROGRESSDIALOG_H_ +#define _PROGRESSDIALOG_H_ + +class CProgressDialog : + public CComCoClass, + public CComObjectRootEx, + public IProgressDialog, + public IOleWindow +{ +public: + CRITICAL_SECTION cs; + HWND hwnd; + DWORD dwFlags; + DWORD dwUpdate; + LPWSTR lines[3]; + LPWSTR cancelMsg; + LPWSTR title; + BOOL isCancelled; + ULONGLONG ullCompleted; + ULONGLONG ullTotal; + HWND hwndDisabledParent; + void set_progress_marquee(); + void update_dialog(DWORD dwUpdate); + void end_dialog(); + + UINT clockHand; + struct progressMark { + ULONGLONG ullMark; + DWORD dwTime; + }; + progressMark progressClock[30]; + DWORD dwStartTime; + + CProgressDialog(); + ~CProgressDialog(); + + // IProgressDialog + virtual HRESULT WINAPI StartProgressDialog(HWND hwndParent, IUnknown *punkEnableModeless, DWORD dwFlags, LPCVOID reserved); + virtual HRESULT WINAPI StopProgressDialog(); + virtual HRESULT WINAPI SetTitle(LPCWSTR pwzTitle); + virtual HRESULT WINAPI SetAnimation(HINSTANCE hInstance, UINT uiResourceId); + virtual BOOL WINAPI HasUserCancelled(); + virtual HRESULT WINAPI SetProgress64(ULONGLONG ullCompleted, ULONGLONG ullTotal); + virtual HRESULT WINAPI SetProgress(DWORD dwCompleted, DWORD dwTotal); + virtual HRESULT WINAPI SetLine(DWORD dwLineNum, LPCWSTR pwzLine, BOOL bPath, LPCVOID reserved); + virtual HRESULT WINAPI SetCancelMsg(LPCWSTR pwzMsg, LPCVOID reserved); + virtual HRESULT WINAPI Timer(DWORD dwTimerAction, LPCVOID reserved); + + //////// IOleWindow + virtual HRESULT WINAPI GetWindow(HWND* phwnd); + virtual HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode); + +DECLARE_REGISTRY_RESOURCEID(IDR_PROGRESSDIALOG) +DECLARE_NOT_AGGREGATABLE(CProgressDialog) + +DECLARE_PROTECT_FINAL_CONSTRUCT() + +BEGIN_COM_MAP(CProgressDialog) + COM_INTERFACE_ENTRY_IID(IID_IProgressDialog, IProgressDialog) + COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) +END_COM_MAP() +}; + +static inline void *heap_alloc(size_t size) +{ + return HeapAlloc(GetProcessHeap(), 0, size); +} +static inline void *heap_alloc_zero(size_t size) +{ + return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); +} +static inline void *heap_realloc(void *mem, size_t size) +{ + return mem ? HeapReAlloc(GetProcessHeap(), 0, mem, size) : heap_alloc(size); +} +static inline BOOL heap_free(void *mem) +{ + return HeapFree(GetProcessHeap(), 0, mem); +} + +#endif /* _PROGRESSDIALOG_H_ */ diff --git a/reactos/dll/win32/browseui/browseui.cpp b/reactos/dll/win32/browseui/browseui.cpp index 77bf0101e06..c7bd50cfd51 100644 --- a/reactos/dll/win32/browseui/browseui.cpp +++ b/reactos/dll/win32/browseui/browseui.cpp @@ -39,6 +39,7 @@ OBJECT_ENTRY(CLSID_GlobalFolderSettings, CGlobalFolderSettings) OBJECT_ENTRY(CLSID_InternetToolbar, CInternetToolbar) OBJECT_ENTRY(CLSID_CRegTreeOptions, CRegTreeOptions) OBJECT_ENTRY(CLSID_ExplorerBand, CExplorerBand) +OBJECT_ENTRY(CLSID_ProgressDialog, CProgressDialog) END_OBJECT_MAP() CBrowseUIModule gModule; diff --git a/reactos/dll/win32/browseui/browseui.rc b/reactos/dll/win32/browseui/browseui.rc index e70ff04d0f7..09efb0d47f7 100644 --- a/reactos/dll/win32/browseui/browseui.rc +++ b/reactos/dll/win32/browseui/browseui.rc @@ -42,6 +42,7 @@ IDR_GLOBALFOLDERSETTINGS REGISTRY "res/globalfoldersettings.rgs" IDR_INTERNETTOOLBAR REGISTRY "res/internettoolbar.rgs" IDR_REGTREEOPTIONS REGISTRY "res/regtreeoptions.rgs" IDR_EXPLORERBAND REGISTRY "res/explorerband.rgs" +IDR_PROGRESSDIALOG REGISTRY "res/progressdialog.rgs" /* * Everything specific to any language goes diff --git a/reactos/dll/win32/browseui/lang/en-US.rc b/reactos/dll/win32/browseui/lang/en-US.rc index 4ba0f50eec0..f21b9c19a89 100644 --- a/reactos/dll/win32/browseui/lang/en-US.rc +++ b/reactos/dll/win32/browseui/lang/en-US.rc @@ -108,6 +108,19 @@ END /* Dialogs */ +IDD_PROGRESS_DLG DIALOG 0, 0, 260, 85 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU +CAPTION "" +FONT 8, "MS Shell Dlg" +{ + CONTROL "", IDC_ANIMATION, ANIMATE_CLASSA, 0, 12, 10, 236, 25 /* TODO: style */ + LTEXT "", IDC_TEXT_LINE, 7, 45, 250, 10, SS_LEFT|SS_NOPREFIX + LTEXT "", IDC_TEXT_LINE + 1, 7, 55, 250, 10, SS_LEFT|SS_NOPREFIX + LTEXT "", IDC_TEXT_LINE + 2, 7, 75, 190, 10, SS_LEFT|SS_NOPREFIX + CONTROL "", IDC_PROGRESS_BAR, PROGRESS_CLASSA, WS_BORDER, 7, 65, 190, 8 + PUSHBUTTON "Cancel", IDCANCEL, 205, 65, 50, 15, WS_GROUP | WS_TABSTOP | WS_VISIBLE +} + IDD_CUSTOMIZETOOLBAREX DIALOGEX 0, 0, 357, 33 STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CAPTION FONT 8, "MS Shell Dlg", 0, 0, 0x1 @@ -139,6 +152,12 @@ END /* Strings */ +STRINGTABLE +BEGIN + IDS_CANCELLING "Canceling..." + IDS_REMAINING "Remaining" +END + STRINGTABLE BEGIN 800 "Contains commands for manipulating the selected items." diff --git a/reactos/dll/win32/browseui/precomp.h b/reactos/dll/win32/browseui/precomp.h index 7863e0320fd..09bcdc88fc6 100644 --- a/reactos/dll/win32/browseui/precomp.h +++ b/reactos/dll/win32/browseui/precomp.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,7 @@ #include "globalfoldersettings.h" #include "regtreeoptions.h" #include "explorerband.h" +#include "CProgressDialog.h" #include WINE_DEFAULT_DEBUG_CHANNEL(browseui); diff --git a/reactos/dll/win32/browseui/res/progressdialog.rgs b/reactos/dll/win32/browseui/res/progressdialog.rgs new file mode 100644 index 00000000000..1451d259a1f --- /dev/null +++ b/reactos/dll/win32/browseui/res/progressdialog.rgs @@ -0,0 +1,13 @@ +HKCR +{ + NoRemove CLSID + { + ForceRemove {F8383852-FCD3-11D1-A6B9-006097DF5BD4} = s 'Progress Dialog' + { + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Apartment' + } + } + } +} diff --git a/reactos/dll/win32/browseui/resource.h b/reactos/dll/win32/browseui/resource.h index d0911fe3a15..bfc7e95c1b6 100644 --- a/reactos/dll/win32/browseui/resource.h +++ b/reactos/dll/win32/browseui/resource.h @@ -83,6 +83,7 @@ #define IDR_GLOBALFOLDERSETTINGS 137 #define IDR_REGTREEOPTIONS 138 #define IDR_EXPLORERBAND 139 +#define IDR_PROGRESSDIALOG 140 #define IDS_SMALLICONS 12301 #define IDS_LARGEICONS 12302 @@ -100,6 +101,13 @@ #define IDS_BACK 58689 #define IDS_FORWARD 58690 +#define IDS_CANCELLING 16 +#define IDS_REMAINING 17 +#define IDC_ANIMATION 100 +#define IDC_PROGRESS_BAR 102 +#define IDC_TEXT_LINE 103 +#define IDD_PROGRESS_DLG 100 + #define IDR_ACCELERATORS 256 #define IDI_CABINET 103