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