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
18struct CProgressMessageBoxPair
19{
20  UString Title;
21  UString Message;
22};
23
24struct CProgressFinalMessage
25{
26  CProgressMessageBoxPair ErrorMessage;
27  CProgressMessageBoxPair OkMessage;
28
29  bool ThereIsMessage() const { return !ErrorMessage.Message.IsEmpty() || !OkMessage.Message.IsEmpty(); }
30};
31
32class CProgressSync
33{
34  bool _stopped;
35  bool _paused;
36
37public:
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
58  bool Get_Stopped()
59  {
60    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
61    return _stopped;
62  }
63  void Set_Stopped(bool val)
64  {
65    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
66    _stopped = val;
67  }
68
69  bool Get_Paused();
70  void Set_Paused(bool val)
71  {
72    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
73    _paused = val;
74  }
75
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
100  bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); }
101};
102
103class 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:
129    CU64ToI32Converter(): _numShiftBits(0), _range(1) {}
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    }
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__
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();
239public:
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();
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
267class CProgressCloser
268{
269  CProgressDialog *_p;
270public:
271  CProgressCloser(CProgressDialog &p) : _p(&p) {}
272  ~CProgressCloser() { _p->ProcessWasFinished(); }
273};
274
275class CProgressThreadVirt
276{
277  FString ErrorPath1;
278  FString ErrorPath2;
279protected:
280  CProgressFinalMessage FinalMessage;
281
282  // error if any of HRESULT, ErrorMessage, ErrorPath
283  virtual HRESULT ProcessVirt() = 0;
284  void Process();
285public:
286  HRESULT Result;
287  bool ThreadFinishedOK; // if there is no fatal exception
288  CProgressDialog ProgressDialog;
289
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
302  void SetErrorPath1(const FString &path) { ErrorPath1 = path; }
303  void SetErrorPath2(const FString &path) { ErrorPath2 = path; }
304
305  HRESULT Create(const UString &title, HWND parentWindow = 0);
306  CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {}
307
308  CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; }
309
310};
311
312UString HResultToMessage(HRESULT errorCode);
313
314#endif
315