// ProgressDialog.h #ifndef __PROGRESS_DIALOG_H #define __PROGRESS_DIALOG_H #include "../../../Windows/Synchronization.h" #include "../../../Windows/Thread.h" #include "../../../Windows/Control/Dialog.h" #include "../../../Windows/Control/ProgressBar.h" #include "ProgressDialogRes.h" class CProgressSync { NWindows::NSynchronization::CCriticalSection _cs; bool _stopped; bool _paused; UInt64 _total; UInt64 _completed; public: CProgressSync(): _stopped(false), _paused(false), _total(1), _completed(0) {} HRESULT ProcessStopAndPause(); 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 SetProgress(UInt64 total, UInt64 completed) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); _total = total; _completed = completed; } void SetPos(UInt64 completed) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); _completed = completed; } void GetProgress(UInt64 &total, UInt64 &completed) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); total = _total; completed = _completed; } }; 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); } }; class CProgressDialog: public NWindows::NControl::CModalDialog { private: UINT_PTR _timer; UString _title; CU64ToI32Converter _converter; UInt64 _peviousPos; UInt64 _range; NWindows::NControl::CProgressBar m_ProgressBar; int _prevPercentValue; bool _wasCreated; bool _needClose; bool _inCancelMessageBox; bool _externalCloseMessageWasReceived; bool OnTimer(WPARAM timerID, LPARAM callback); void SetRange(UInt64 range); void SetPos(UInt64 pos); virtual bool OnInit(); virtual void OnCancel(); virtual void OnOK(); NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; #ifndef _SFX void AddToTitle(LPCWSTR string); #endif bool OnButtonClicked(int buttonID, HWND buttonHWND); void WaitCreating() { _dialogCreatedEvent.Lock(); } void CheckNeedClose(); bool OnExternalCloseMessage(); public: CProgressSync Sync; int IconID; #ifndef _SFX HWND MainWindow; UString MainTitle; UString MainAddTitle; ~CProgressDialog(); #endif CProgressDialog(): _timer(0) #ifndef _SFX ,MainWindow(0) #endif { IconID = -1; _wasCreated = false; _needClose = false; _inCancelMessageBox = false; _externalCloseMessageWasReceived = false; if (_dialogCreatedEvent.Create() != S_OK) throw 1334987; } INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0) { _title = title; INT_PTR res = CModalDialog::Create(IDD_PROGRESS, wndParent); thread.Wait(); return res; } enum { kCloseMessage = WM_APP + 1 }; virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); void ProcessWasFinished() { WaitCreating(); if (_wasCreated) PostMsg(kCloseMessage); else _needClose = true; }; }; class CProgressCloser { CProgressDialog *_p; public: CProgressCloser(CProgressDialog &p) : _p(&p) {} ~CProgressCloser() { _p->ProcessWasFinished(); } }; #endif