// ProgressDialog2.h #ifndef __PROGRESS_DIALOG2_H #define __PROGRESS_DIALOG2_H #include "Windows/Synchronization.h" #include "Windows/Thread.h" #include "Windows/Control/Dialog.h" #include "Windows/Control/ListView.h" #include "Windows/Control/ProgressBar.h" class CProgressSync { bool _stopped; bool _paused; bool _bytesProgressMode; UInt64 _totalBytes; UInt64 _curBytes; UInt64 _totalFiles; UInt64 _curFiles; UInt64 _inSize; UInt64 _outSize; UString _titleFileName; UString _currentFileName; public: UStringVector Messages; UString ErrorMessage; UString ErrorMessageTitle; UString OkMessage; UString OkMessageTitle; NWindows::NSynchronization::CCriticalSection _cs; CProgressSync(): _stopped(false), _paused(false), _totalBytes((UInt64)(Int64)-1), _curBytes(0), _totalFiles((UInt64)(Int64)-1), _curFiles(0), _inSize((UInt64)(Int64)-1), _outSize((UInt64)(Int64)-1), _bytesProgressMode(true) {} bool GetStopped() { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); return _stopped; } void SetStopped(bool value) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); _stopped = value; } bool GetPaused() { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); return _paused; } void SetPaused(bool value) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); _paused = value; } void SetBytesProgressMode(bool bytesProgressMode) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); _bytesProgressMode = bytesProgressMode; } void SetProgress(UInt64 total, UInt64 completed) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); _totalBytes = total; _curBytes = completed; } void SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); if (inSize) _inSize = *inSize; if (outSize) _outSize = *outSize; } void SetPos(UInt64 completed) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); _curBytes = completed; } void SetNumBytesTotal(UInt64 value) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); _totalBytes = value; } void SetNumFilesTotal(UInt64 value) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); _totalFiles = value; } void SetNumFilesCur(UInt64 value) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); _curFiles = value; } HRESULT ProcessStopAndPause(); HRESULT SetPosAndCheckPaused(UInt64 completed); void GetProgress(UInt64 &total, UInt64 &completed, UInt64 &totalFiles, UInt64 &curFiles, UInt64 &inSize, UInt64 &outSize, bool &bytesProgressMode) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); total = _totalBytes; completed = _curBytes; totalFiles = _totalFiles; curFiles = _curFiles; inSize = _inSize; outSize = _outSize; bytesProgressMode = _bytesProgressMode; } void SetTitleFileName(const UString &fileName) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); _titleFileName = fileName; } void GetTitleFileName(UString &fileName) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); fileName = _titleFileName; } void SetCurrentFileName(const UString &fileName) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); _currentFileName = fileName; } void GetCurrentFileName(UString &fileName) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); fileName = _currentFileName; } void AddErrorMessage(LPCWSTR message) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); Messages.Add(message); } void SetErrorMessage(const UString &message) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); ErrorMessage = message; } void SetOkMessage(const UString &message) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); OkMessage = message; } void SetOkMessageTitle(const UString &title) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); OkMessageTitle = title; } void SetErrorMessageTitle(const UString &title) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); ErrorMessageTitle = title; } bool ThereIsMessage() const { return !Messages.IsEmpty() || !ErrorMessage.IsEmpty() || !OkMessage.IsEmpty(); } }; class CU64ToI32Converter { UInt64 _numShiftBits; public: void Init(UInt64 range) { // Windows CE doesn't like big number here. for (_numShiftBits = 0; range > (1 << 15); _numShiftBits++) range >>= 1; } int Count(UInt64 value) { return int(value >> _numShiftBits); } }; enum ESpeedMode { kSpeedBytes, kSpeedKBytes, kSpeedMBytes }; class CProgressDialog: public NWindows::NControl::CModalDialog { UString _prevFileName; UString _prevTitleName; private: UString backgroundString; UString backgroundedString; UString foregroundString; UString pauseString; UString continueString; UString pausedString; int buttonSizeX; int buttonSizeY; UINT_PTR _timer; UString _title; CU64ToI32Converter _converter; UInt64 _previousPos; UInt64 _range; NWindows::NControl::CProgressBar m_ProgressBar; NWindows::NControl::CListView _messageList; UInt32 _prevPercentValue; UInt32 _prevTime; UInt32 _elapsedTime; UInt32 _prevElapsedSec; UInt64 _prevRemainingSec; ESpeedMode _prevMode; UInt64 _prevSpeed; bool _foreground; int _numReduceSymbols; bool _wasCreated; bool _needClose; UInt32 _numPostedMessages; UInt32 _numAutoSizeMessages; bool _errorsWereDisplayed; bool _waitCloseByCancelButton; bool _cancelWasPressed; bool _inCancelMessageBox; bool _externalCloseMessageWasReceived; void UpdateStatInfo(bool showAll); bool OnTimer(WPARAM timerID, LPARAM callback); void SetRange(UInt64 range); void SetPos(UInt64 pos); virtual bool OnInit(); virtual bool OnSize(WPARAM wParam, int xSize, int ySize); virtual void OnCancel(); virtual void OnOK(); NWindows::NSynchronization::CManualResetEvent _createDialogEvent; NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; #ifndef _SFX void AddToTitle(LPCWSTR string); #endif void SetPauseText(); void SetPriorityText(); void OnPauseButton(); void OnPriorityButton(); bool OnButtonClicked(int buttonID, HWND buttonHWND); void SetTitleText(); void ShowSize(int id, UInt64 value); void UpdateMessagesDialog(); void AddMessageDirect(LPCWSTR message); void AddMessage(LPCWSTR message); bool OnExternalCloseMessage(); void EnableErrorsControls(bool enable); void ShowAfterMessages(HWND wndParent); void CheckNeedClose(); public: CProgressSync Sync; bool CompressingMode; bool WaitMode; bool ShowCompressionInfo; bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages. int IconID; #ifndef _SFX HWND MainWindow; UString MainTitle; UString MainAddTitle; ~CProgressDialog(); #endif CProgressDialog(); void WaitCreating() { _createDialogEvent.Set(); _dialogCreatedEvent.Lock(); } INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0); virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); void ProcessWasFinished(); }; class CProgressCloser { CProgressDialog *_p; public: CProgressCloser(CProgressDialog &p) : _p(&p) {} ~CProgressCloser() { _p->ProcessWasFinished(); } }; class CProgressThreadVirt { protected: UString ErrorMessage; UString ErrorPath1; UString ErrorPath2; UString OkMessage; UString OkMessageTitle; // error if any of HRESULT, ErrorMessage, ErrorPath virtual HRESULT ProcessVirt() = 0; void Process(); public: HRESULT Result; bool ThreadFinishedOK; // if there is no fatal exception CProgressDialog ProgressDialog; static THREAD_FUNC_DECL MyThreadFunction(void *param) { CProgressThreadVirt *p = (CProgressThreadVirt *)param; try { p->Process(); p->ThreadFinishedOK = true; } catch (...) { p->Result = E_FAIL; } return 0; } HRESULT Create(const UString &title, HWND parentWindow = 0); CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {} }; UString HResultToMessage(HRESULT errorCode); #endif