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