1 // ProgressDialog.h 2 3 #ifndef __PROGRESS_DIALOG_H 4 #define __PROGRESS_DIALOG_H 5 6 #include "../../../Windows/Synchronization.h" 7 #include "../../../Windows/Thread.h" 8 9 #include "../../../Windows/Control/Dialog.h" 10 #include "../../../Windows/Control/ProgressBar.h" 11 12 #include "ProgressDialogRes.h" 13 14 class CProgressSync 15 { 16 NWindows::NSynchronization::CCriticalSection _cs; 17 bool _stopped; 18 bool _paused; 19 UInt64 _total; 20 UInt64 _completed; 21 public: CProgressSync()22 CProgressSync(): _stopped(false), _paused(false), _total(1), _completed(0) {} 23 24 HRESULT ProcessStopAndPause(); GetStopped()25 bool GetStopped() 26 { 27 NWindows::NSynchronization::CCriticalSectionLock lock(_cs); 28 return _stopped; 29 } SetStopped(bool value)30 void SetStopped(bool value) 31 { 32 NWindows::NSynchronization::CCriticalSectionLock lock(_cs); 33 _stopped = value; 34 } GetPaused()35 bool GetPaused() 36 { 37 NWindows::NSynchronization::CCriticalSectionLock lock(_cs); 38 return _paused; 39 } SetPaused(bool value)40 void SetPaused(bool value) 41 { 42 NWindows::NSynchronization::CCriticalSectionLock lock(_cs); 43 _paused = value; 44 } SetProgress(UInt64 total,UInt64 completed)45 void SetProgress(UInt64 total, UInt64 completed) 46 { 47 NWindows::NSynchronization::CCriticalSectionLock lock(_cs); 48 _total = total; 49 _completed = completed; 50 } SetPos(UInt64 completed)51 void SetPos(UInt64 completed) 52 { 53 NWindows::NSynchronization::CCriticalSectionLock lock(_cs); 54 _completed = completed; 55 } GetProgress(UInt64 & total,UInt64 & completed)56 void GetProgress(UInt64 &total, UInt64 &completed) 57 { 58 NWindows::NSynchronization::CCriticalSectionLock lock(_cs); 59 total = _total; 60 completed = _completed; 61 } 62 }; 63 64 class CU64ToI32Converter 65 { 66 UInt64 _numShiftBits; 67 public: Init(UInt64 range)68 void Init(UInt64 range) 69 { 70 // Windows CE doesn't like big number here. 71 for (_numShiftBits = 0; range > (1 << 15); _numShiftBits++) 72 range >>= 1; 73 } Count(UInt64 value)74 int Count(UInt64 value) { return int(value >> _numShiftBits); } 75 }; 76 77 class CProgressDialog: public NWindows::NControl::CModalDialog 78 { 79 private: 80 UINT_PTR _timer; 81 82 UString _title; 83 CU64ToI32Converter _converter; 84 UInt64 _peviousPos; 85 UInt64 _range; 86 NWindows::NControl::CProgressBar m_ProgressBar; 87 88 int _prevPercentValue; 89 90 bool _wasCreated; 91 bool _needClose; 92 bool _inCancelMessageBox; 93 bool _externalCloseMessageWasReceived; 94 95 bool OnTimer(WPARAM timerID, LPARAM callback); 96 void SetRange(UInt64 range); 97 void SetPos(UInt64 pos); 98 virtual bool OnInit(); 99 virtual void OnCancel(); 100 virtual void OnOK(); 101 NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; 102 #ifndef _SFX 103 void AddToTitle(LPCWSTR string); 104 #endif 105 bool OnButtonClicked(int buttonID, HWND buttonHWND); 106 WaitCreating()107 void WaitCreating() { _dialogCreatedEvent.Lock(); } 108 void CheckNeedClose(); 109 bool OnExternalCloseMessage(); 110 public: 111 CProgressSync Sync; 112 int IconID; 113 114 #ifndef _SFX 115 HWND MainWindow; 116 UString MainTitle; 117 UString MainAddTitle; 118 ~CProgressDialog(); 119 #endif 120 CProgressDialog()121 CProgressDialog(): _timer(0) 122 #ifndef _SFX 123 ,MainWindow(0) 124 #endif 125 { 126 IconID = -1; 127 _wasCreated = false; 128 _needClose = false; 129 _inCancelMessageBox = false; 130 _externalCloseMessageWasReceived = false; 131 132 if (_dialogCreatedEvent.Create() != S_OK) 133 throw 1334987; 134 } 135 136 INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0) 137 { 138 _title = title; 139 INT_PTR res = CModalDialog::Create(IDD_PROGRESS, wndParent); 140 thread.Wait(); 141 return res; 142 } 143 144 enum 145 { 146 kCloseMessage = WM_APP + 1 147 }; 148 149 virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); 150 ProcessWasFinished()151 void ProcessWasFinished() 152 { 153 WaitCreating(); 154 if (_wasCreated) 155 PostMsg(kCloseMessage); 156 else 157 _needClose = true; 158 }; 159 }; 160 161 162 class CProgressCloser 163 { 164 CProgressDialog *_p; 165 public: CProgressCloser(CProgressDialog & p)166 CProgressCloser(CProgressDialog &p) : _p(&p) {} ~CProgressCloser()167 ~CProgressCloser() { _p->ProcessWasFinished(); } 168 }; 169 170 #endif 171