1 // ProgressDialog2.h 2 3 #ifndef __PROGRESS_DIALOG_2_H 4 #define __PROGRESS_DIALOG_2_H 5 6 #include "../../../Common/MyCom.h" 7 8 #include "../../../Windows/ErrorMsg.h" 9 #include "../../../Windows/Synchronization.h" 10 #include "../../../Windows/Thread.h" 11 12 #include "../../../Windows/Control/Dialog.h" 13 #include "../../../Windows/Control/ListView.h" 14 #include "../../../Windows/Control/ProgressBar.h" 15 16 #include "MyWindowsNew.h" 17 18 struct CProgressMessageBoxPair 19 { 20 UString Title; 21 UString Message; 22 }; 23 24 struct CProgressFinalMessage 25 { 26 CProgressMessageBoxPair ErrorMessage; 27 CProgressMessageBoxPair OkMessage; 28 ThereIsMessageCProgressFinalMessage29 bool ThereIsMessage() const { return !ErrorMessage.Message.IsEmpty() || !OkMessage.Message.IsEmpty(); } 30 }; 31 32 class CProgressSync 33 { 34 bool _stopped; 35 bool _paused; 36 37 public: 38 bool _bytesProgressMode; 39 UInt64 _totalBytes; 40 UInt64 _completedBytes; 41 UInt64 _totalFiles; 42 UInt64 _curFiles; 43 UInt64 _inSize; 44 UInt64 _outSize; 45 46 UString _titleFileName; 47 UString _status; 48 UString _filePath; 49 bool _isDir; 50 51 UStringVector Messages; 52 CProgressFinalMessage FinalMessage; 53 54 NWindows::NSynchronization::CCriticalSection _cs; 55 56 CProgressSync(); 57 Get_Stopped()58 bool Get_Stopped() 59 { 60 NWindows::NSynchronization::CCriticalSectionLock lock(_cs); 61 return _stopped; 62 } Set_Stopped(bool val)63 void Set_Stopped(bool val) 64 { 65 NWindows::NSynchronization::CCriticalSectionLock lock(_cs); 66 _stopped = val; 67 } 68 69 bool Get_Paused(); Set_Paused(bool val)70 void Set_Paused(bool val) 71 { 72 NWindows::NSynchronization::CCriticalSectionLock lock(_cs); 73 _paused = val; 74 } 75 Set_BytesProgressMode(bool bytesProgressMode)76 void Set_BytesProgressMode(bool bytesProgressMode) 77 { 78 NWindows::NSynchronization::CCriticalSectionLock lock(_cs); 79 _bytesProgressMode = bytesProgressMode; 80 } 81 82 HRESULT CheckStop(); 83 HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const UString &fileName, bool isDir = false); 84 85 void Set_NumFilesTotal(UInt64 val); 86 void Set_NumBytesTotal(UInt64 val); 87 void Set_NumFilesCur(UInt64 val); 88 HRESULT Set_NumBytesCur(const UInt64 *val); 89 HRESULT Set_NumBytesCur(UInt64 val); 90 void Set_Ratio(const UInt64 *inSize, const UInt64 *outSize); 91 92 void Set_TitleFileName(const UString &fileName); 93 void Set_Status(const UString &s); 94 void Set_FilePath(const UString &path, bool isDir = false); 95 96 void AddError_Message(const wchar_t *message); 97 void AddError_Message_Name(const wchar_t *message, const wchar_t *name); 98 void AddError_Code_Name(DWORD systemError, const wchar_t *name); 99 ThereIsMessage()100 bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); } 101 }; 102 103 class CProgressDialog: public NWindows::NControl::CModalDialog 104 { 105 UString _titleFileName; 106 UString _filePath; 107 UString _status; 108 bool _isDir; 109 110 UString _background_String; 111 UString _backgrounded_String; 112 UString _foreground_String; 113 UString _pause_String; 114 UString _continue_String; 115 UString _paused_String; 116 117 int _buttonSizeX; 118 int _buttonSizeY; 119 120 UINT_PTR _timer; 121 122 UString _title; 123 124 class CU64ToI32Converter 125 { 126 unsigned _numShiftBits; 127 UInt64 _range; 128 public: CU64ToI32Converter()129 CU64ToI32Converter(): _numShiftBits(0), _range(1) {} Init(UInt64 range)130 void Init(UInt64 range) 131 { 132 _range = range; 133 // Windows CE doesn't like big number for ProgressBar. 134 for (_numShiftBits = 0; range >= ((UInt32)1 << 15); _numShiftBits++) 135 range >>= 1; 136 } Count(UInt64 val)137 int Count(UInt64 val) 138 { 139 int res = (int)(val >> _numShiftBits); 140 if (val == _range) 141 res++; 142 return res; 143 } 144 }; 145 146 CU64ToI32Converter _progressConv; 147 UInt64 _progressBar_Pos; 148 UInt64 _progressBar_Range; 149 150 NWindows::NControl::CProgressBar m_ProgressBar; 151 NWindows::NControl::CListView _messageList; 152 153 int _numMessages; 154 155 #ifdef __ITaskbarList3_INTERFACE_DEFINED__ 156 CMyComPtr<ITaskbarList3> _taskbarList; 157 #endif 158 HWND _hwndForTaskbar; 159 160 UInt32 _prevTime; 161 UInt64 _elapsedTime; 162 163 UInt64 _prevPercentValue; 164 UInt64 _prevElapsedSec; 165 UInt64 _prevRemainingSec; 166 167 UInt64 _totalBytes_Prev; 168 UInt64 _processed_Prev; 169 UInt64 _packed_Prev; 170 UInt64 _ratio_Prev; 171 UString _filesStr_Prev; 172 173 unsigned _prevSpeed_MoveBits; 174 UInt64 _prevSpeed; 175 176 bool _foreground; 177 178 unsigned _numReduceSymbols; 179 180 bool _wasCreated; 181 bool _needClose; 182 183 unsigned _numPostedMessages; 184 UInt32 _numAutoSizeMessages; 185 186 bool _errorsWereDisplayed; 187 188 bool _waitCloseByCancelButton; 189 bool _cancelWasPressed; 190 191 bool _inCancelMessageBox; 192 bool _externalCloseMessageWasReceived; 193 194 195 #ifdef __ITaskbarList3_INTERFACE_DEFINED__ SetTaskbarProgressState(TBPFLAG tbpFlags)196 void SetTaskbarProgressState(TBPFLAG tbpFlags) 197 { 198 if (_taskbarList && _hwndForTaskbar) 199 _taskbarList->SetProgressState(_hwndForTaskbar, tbpFlags); 200 } 201 #endif 202 void SetTaskbarProgressState(); 203 204 void UpdateStatInfo(bool showAll); 205 bool OnTimer(WPARAM timerID, LPARAM callback); 206 void SetProgressRange(UInt64 range); 207 void SetProgressPos(UInt64 pos); 208 virtual bool OnInit(); 209 virtual bool OnSize(WPARAM wParam, int xSize, int ySize); 210 virtual void OnCancel(); 211 virtual void OnOK(); 212 NWindows::NSynchronization::CManualResetEvent _createDialogEvent; 213 NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; 214 #ifndef _SFX 215 void AddToTitle(LPCWSTR string); 216 #endif 217 218 void SetPauseText(); 219 void SetPriorityText(); 220 void OnPauseButton(); 221 void OnPriorityButton(); 222 bool OnButtonClicked(int buttonID, HWND buttonHWND); 223 bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); 224 225 void SetTitleText(); 226 void ShowSize(int id, UInt64 val, UInt64 &prev); 227 228 void UpdateMessagesDialog(); 229 230 void AddMessageDirect(LPCWSTR message, bool needNumber); 231 void AddMessage(LPCWSTR message); 232 233 bool OnExternalCloseMessage(); 234 void EnableErrorsControls(bool enable); 235 236 void ShowAfterMessages(HWND wndParent); 237 238 void CheckNeedClose(); 239 public: 240 CProgressSync Sync; 241 bool CompressingMode; 242 bool WaitMode; 243 bool ShowCompressionInfo; 244 bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages. 245 int IconID; 246 247 HWND MainWindow; 248 #ifndef _SFX 249 UString MainTitle; 250 UString MainAddTitle; 251 ~CProgressDialog(); 252 #endif 253 254 CProgressDialog(); WaitCreating()255 void WaitCreating() 256 { 257 _createDialogEvent.Set(); 258 _dialogCreatedEvent.Lock(); 259 } 260 261 INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0); 262 263 void ProcessWasFinished(); 264 }; 265 266 267 class CProgressCloser 268 { 269 CProgressDialog *_p; 270 public: CProgressCloser(CProgressDialog & p)271 CProgressCloser(CProgressDialog &p) : _p(&p) {} ~CProgressCloser()272 ~CProgressCloser() { _p->ProcessWasFinished(); } 273 }; 274 275 class CProgressThreadVirt 276 { 277 FString ErrorPath1; 278 FString ErrorPath2; 279 protected: 280 CProgressFinalMessage FinalMessage; 281 282 // error if any of HRESULT, ErrorMessage, ErrorPath 283 virtual HRESULT ProcessVirt() = 0; 284 void Process(); 285 public: 286 HRESULT Result; 287 bool ThreadFinishedOK; // if there is no fatal exception 288 CProgressDialog ProgressDialog; 289 MyThreadFunction(void * param)290 static THREAD_FUNC_DECL MyThreadFunction(void *param) 291 { 292 CProgressThreadVirt *p = (CProgressThreadVirt *)param; 293 try 294 { 295 p->Process(); 296 p->ThreadFinishedOK = true; 297 } 298 catch (...) { p->Result = E_FAIL; } 299 return 0; 300 } 301 SetErrorPath1(const FString & path)302 void SetErrorPath1(const FString &path) { ErrorPath1 = path; } SetErrorPath2(const FString & path)303 void SetErrorPath2(const FString &path) { ErrorPath2 = path; } 304 305 HRESULT Create(const UString &title, HWND parentWindow = 0); CProgressThreadVirt()306 CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {} 307 GetMessagePair(bool isError)308 CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; } 309 310 }; 311 312 UString HResultToMessage(HRESULT errorCode); 313 314 #endif 315