1370b324cSopenharmony_ci// ProgressDialog2.h
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#ifndef ZIP7_INC_PROGRESS_DIALOG_2_H
4370b324cSopenharmony_ci#define ZIP7_INC_PROGRESS_DIALOG_2_H
5370b324cSopenharmony_ci
6370b324cSopenharmony_ci#include "../../../Common/MyCom.h"
7370b324cSopenharmony_ci
8370b324cSopenharmony_ci#include "../../../Windows/ErrorMsg.h"
9370b324cSopenharmony_ci#include "../../../Windows/Synchronization.h"
10370b324cSopenharmony_ci#include "../../../Windows/Thread.h"
11370b324cSopenharmony_ci
12370b324cSopenharmony_ci#include "../../../Windows/Control/Dialog.h"
13370b324cSopenharmony_ci#include "../../../Windows/Control/ListView.h"
14370b324cSopenharmony_ci#include "../../../Windows/Control/ProgressBar.h"
15370b324cSopenharmony_ci
16370b324cSopenharmony_ci#include "MyWindowsNew.h"
17370b324cSopenharmony_ci
18370b324cSopenharmony_cistruct CProgressMessageBoxPair
19370b324cSopenharmony_ci{
20370b324cSopenharmony_ci  UString Title;
21370b324cSopenharmony_ci  UString Message;
22370b324cSopenharmony_ci};
23370b324cSopenharmony_ci
24370b324cSopenharmony_cistruct CProgressFinalMessage
25370b324cSopenharmony_ci{
26370b324cSopenharmony_ci  CProgressMessageBoxPair ErrorMessage;
27370b324cSopenharmony_ci  CProgressMessageBoxPair OkMessage;
28370b324cSopenharmony_ci
29370b324cSopenharmony_ci  bool ThereIsMessage() const { return !ErrorMessage.Message.IsEmpty() || !OkMessage.Message.IsEmpty(); }
30370b324cSopenharmony_ci};
31370b324cSopenharmony_ci
32370b324cSopenharmony_ciclass CProgressSync
33370b324cSopenharmony_ci{
34370b324cSopenharmony_ci  bool _stopped;
35370b324cSopenharmony_ci  bool _paused;
36370b324cSopenharmony_ci
37370b324cSopenharmony_cipublic:
38370b324cSopenharmony_ci  bool _bytesProgressMode;
39370b324cSopenharmony_ci  bool _isDir;
40370b324cSopenharmony_ci  UInt64 _totalBytes;
41370b324cSopenharmony_ci  UInt64 _completedBytes;
42370b324cSopenharmony_ci  UInt64 _totalFiles;
43370b324cSopenharmony_ci  UInt64 _curFiles;
44370b324cSopenharmony_ci  UInt64 _inSize;
45370b324cSopenharmony_ci  UInt64 _outSize;
46370b324cSopenharmony_ci
47370b324cSopenharmony_ci  UString _titleFileName;
48370b324cSopenharmony_ci  UString _status;
49370b324cSopenharmony_ci  UString _filePath;
50370b324cSopenharmony_ci
51370b324cSopenharmony_ci  UStringVector Messages;
52370b324cSopenharmony_ci  CProgressFinalMessage FinalMessage;
53370b324cSopenharmony_ci
54370b324cSopenharmony_ci  NWindows::NSynchronization::CCriticalSection _cs;
55370b324cSopenharmony_ci
56370b324cSopenharmony_ci  CProgressSync();
57370b324cSopenharmony_ci
58370b324cSopenharmony_ci  bool Get_Stopped()
59370b324cSopenharmony_ci  {
60370b324cSopenharmony_ci    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
61370b324cSopenharmony_ci    return _stopped;
62370b324cSopenharmony_ci  }
63370b324cSopenharmony_ci  void Set_Stopped(bool val)
64370b324cSopenharmony_ci  {
65370b324cSopenharmony_ci    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
66370b324cSopenharmony_ci    _stopped = val;
67370b324cSopenharmony_ci  }
68370b324cSopenharmony_ci
69370b324cSopenharmony_ci  bool Get_Paused();
70370b324cSopenharmony_ci  void Set_Paused(bool val)
71370b324cSopenharmony_ci  {
72370b324cSopenharmony_ci    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
73370b324cSopenharmony_ci    _paused = val;
74370b324cSopenharmony_ci  }
75370b324cSopenharmony_ci
76370b324cSopenharmony_ci  void Set_BytesProgressMode(bool bytesProgressMode)
77370b324cSopenharmony_ci  {
78370b324cSopenharmony_ci    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
79370b324cSopenharmony_ci    _bytesProgressMode = bytesProgressMode;
80370b324cSopenharmony_ci  }
81370b324cSopenharmony_ci
82370b324cSopenharmony_ci  HRESULT CheckStop();
83370b324cSopenharmony_ci  HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir = false);
84370b324cSopenharmony_ci
85370b324cSopenharmony_ci  HRESULT Set_NumFilesTotal(UInt64 val);
86370b324cSopenharmony_ci  void Set_NumBytesTotal(UInt64 val);
87370b324cSopenharmony_ci  void Set_NumFilesCur(UInt64 val);
88370b324cSopenharmony_ci  HRESULT Set_NumBytesCur(const UInt64 *val);
89370b324cSopenharmony_ci  HRESULT Set_NumBytesCur(UInt64 val);
90370b324cSopenharmony_ci  void Set_Ratio(const UInt64 *inSize, const UInt64 *outSize);
91370b324cSopenharmony_ci
92370b324cSopenharmony_ci  void Set_TitleFileName(const UString &fileName);
93370b324cSopenharmony_ci  void Set_Status(const UString &s);
94370b324cSopenharmony_ci  HRESULT Set_Status2(const UString &s, const wchar_t *path, bool isDir = false);
95370b324cSopenharmony_ci  void Set_FilePath(const wchar_t *path, bool isDir = false);
96370b324cSopenharmony_ci
97370b324cSopenharmony_ci  void AddError_Message(const wchar_t *message);
98370b324cSopenharmony_ci  void AddError_Message_Name(const wchar_t *message, const wchar_t *name);
99370b324cSopenharmony_ci  // void AddError_Code_Name(DWORD systemError, const wchar_t *name);
100370b324cSopenharmony_ci  void AddError_Code_Name(HRESULT systemError, const wchar_t *name);
101370b324cSopenharmony_ci
102370b324cSopenharmony_ci  bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); }
103370b324cSopenharmony_ci};
104370b324cSopenharmony_ci
105370b324cSopenharmony_ciclass CProgressDialog: public NWindows::NControl::CModalDialog
106370b324cSopenharmony_ci{
107370b324cSopenharmony_ci  UString _titleFileName;
108370b324cSopenharmony_ci  UString _filePath;
109370b324cSopenharmony_ci  UString _status;
110370b324cSopenharmony_ci  bool _isDir;
111370b324cSopenharmony_ci
112370b324cSopenharmony_ci  UString _background_String;
113370b324cSopenharmony_ci  UString _backgrounded_String;
114370b324cSopenharmony_ci  UString _foreground_String;
115370b324cSopenharmony_ci  UString _pause_String;
116370b324cSopenharmony_ci  UString _continue_String;
117370b324cSopenharmony_ci  UString _paused_String;
118370b324cSopenharmony_ci
119370b324cSopenharmony_ci  int _buttonSizeX;
120370b324cSopenharmony_ci  int _buttonSizeY;
121370b324cSopenharmony_ci
122370b324cSopenharmony_ci  UINT_PTR _timer;
123370b324cSopenharmony_ci
124370b324cSopenharmony_ci  UString _title;
125370b324cSopenharmony_ci
126370b324cSopenharmony_ci  class CU64ToI32Converter
127370b324cSopenharmony_ci  {
128370b324cSopenharmony_ci    unsigned _numShiftBits;
129370b324cSopenharmony_ci    UInt64 _range;
130370b324cSopenharmony_ci  public:
131370b324cSopenharmony_ci    CU64ToI32Converter(): _numShiftBits(0), _range(1) {}
132370b324cSopenharmony_ci    void Init(UInt64 range)
133370b324cSopenharmony_ci    {
134370b324cSopenharmony_ci      _range = range;
135370b324cSopenharmony_ci      // Windows CE doesn't like big number for ProgressBar.
136370b324cSopenharmony_ci      for (_numShiftBits = 0; range >= ((UInt32)1 << 15); _numShiftBits++)
137370b324cSopenharmony_ci        range >>= 1;
138370b324cSopenharmony_ci    }
139370b324cSopenharmony_ci    int Count(UInt64 val)
140370b324cSopenharmony_ci    {
141370b324cSopenharmony_ci      int res = (int)(val >> _numShiftBits);
142370b324cSopenharmony_ci      if (val == _range)
143370b324cSopenharmony_ci        res++;
144370b324cSopenharmony_ci      return res;
145370b324cSopenharmony_ci    }
146370b324cSopenharmony_ci  };
147370b324cSopenharmony_ci
148370b324cSopenharmony_ci  CU64ToI32Converter _progressConv;
149370b324cSopenharmony_ci  UInt64 _progressBar_Pos;
150370b324cSopenharmony_ci  UInt64 _progressBar_Range;
151370b324cSopenharmony_ci
152370b324cSopenharmony_ci  NWindows::NControl::CProgressBar m_ProgressBar;
153370b324cSopenharmony_ci  NWindows::NControl::CListView _messageList;
154370b324cSopenharmony_ci
155370b324cSopenharmony_ci  unsigned _numMessages;
156370b324cSopenharmony_ci  UStringVector _messageStrings;
157370b324cSopenharmony_ci
158370b324cSopenharmony_ci  // #ifdef __ITaskbarList3_INTERFACE_DEFINED__
159370b324cSopenharmony_ci  CMyComPtr<ITaskbarList3> _taskbarList;
160370b324cSopenharmony_ci  // #endif
161370b324cSopenharmony_ci  HWND _hwndForTaskbar;
162370b324cSopenharmony_ci
163370b324cSopenharmony_ci  UInt32 _prevTime;
164370b324cSopenharmony_ci  UInt64 _elapsedTime;
165370b324cSopenharmony_ci
166370b324cSopenharmony_ci  UInt64 _prevPercentValue;
167370b324cSopenharmony_ci  UInt64 _prevElapsedSec;
168370b324cSopenharmony_ci  UInt64 _prevRemainingSec;
169370b324cSopenharmony_ci
170370b324cSopenharmony_ci  UInt64 _totalBytes_Prev;
171370b324cSopenharmony_ci  UInt64 _processed_Prev;
172370b324cSopenharmony_ci  UInt64 _packed_Prev;
173370b324cSopenharmony_ci  UInt64 _ratio_Prev;
174370b324cSopenharmony_ci
175370b324cSopenharmony_ci  UString _filesStr_Prev;
176370b324cSopenharmony_ci  UString _filesTotStr_Prev;
177370b324cSopenharmony_ci
178370b324cSopenharmony_ci  unsigned _prevSpeed_MoveBits;
179370b324cSopenharmony_ci  UInt64 _prevSpeed;
180370b324cSopenharmony_ci
181370b324cSopenharmony_ci  bool _foreground;
182370b324cSopenharmony_ci
183370b324cSopenharmony_ci  unsigned _numReduceSymbols;
184370b324cSopenharmony_ci
185370b324cSopenharmony_ci  bool _wasCreated;
186370b324cSopenharmony_ci  bool _needClose;
187370b324cSopenharmony_ci
188370b324cSopenharmony_ci  unsigned _numPostedMessages;
189370b324cSopenharmony_ci  UInt32 _numAutoSizeMessages;
190370b324cSopenharmony_ci
191370b324cSopenharmony_ci  bool _errorsWereDisplayed;
192370b324cSopenharmony_ci
193370b324cSopenharmony_ci  bool _waitCloseByCancelButton;
194370b324cSopenharmony_ci  bool _cancelWasPressed;
195370b324cSopenharmony_ci
196370b324cSopenharmony_ci  bool _inCancelMessageBox;
197370b324cSopenharmony_ci  bool _externalCloseMessageWasReceived;
198370b324cSopenharmony_ci
199370b324cSopenharmony_ci
200370b324cSopenharmony_ci  // #ifdef __ITaskbarList3_INTERFACE_DEFINED__
201370b324cSopenharmony_ci  void SetTaskbarProgressState(TBPFLAG tbpFlags)
202370b324cSopenharmony_ci  {
203370b324cSopenharmony_ci    if (_taskbarList && _hwndForTaskbar)
204370b324cSopenharmony_ci      _taskbarList->SetProgressState(_hwndForTaskbar, tbpFlags);
205370b324cSopenharmony_ci  }
206370b324cSopenharmony_ci  // #endif
207370b324cSopenharmony_ci  void SetTaskbarProgressState();
208370b324cSopenharmony_ci
209370b324cSopenharmony_ci  void UpdateStatInfo(bool showAll);
210370b324cSopenharmony_ci  void SetProgressRange(UInt64 range);
211370b324cSopenharmony_ci  void SetProgressPos(UInt64 pos);
212370b324cSopenharmony_ci  virtual bool OnTimer(WPARAM timerID, LPARAM callback) Z7_override;
213370b324cSopenharmony_ci  virtual bool OnInit() Z7_override;
214370b324cSopenharmony_ci  virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override;
215370b324cSopenharmony_ci  virtual void OnCancel() Z7_override;
216370b324cSopenharmony_ci  virtual void OnOK() Z7_override;
217370b324cSopenharmony_ci  virtual bool OnNotify(UINT /* controlID */, LPNMHDR header) Z7_override;
218370b324cSopenharmony_ci  void CopyToClipboard();
219370b324cSopenharmony_ci
220370b324cSopenharmony_ci  NWindows::NSynchronization::CManualResetEvent _createDialogEvent;
221370b324cSopenharmony_ci  NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent;
222370b324cSopenharmony_ci  #ifndef Z7_SFX
223370b324cSopenharmony_ci  void AddToTitle(LPCWSTR string);
224370b324cSopenharmony_ci  #endif
225370b324cSopenharmony_ci
226370b324cSopenharmony_ci  void SetPauseText();
227370b324cSopenharmony_ci  void SetPriorityText();
228370b324cSopenharmony_ci  void OnPauseButton();
229370b324cSopenharmony_ci  void OnPriorityButton();
230370b324cSopenharmony_ci  bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override;
231370b324cSopenharmony_ci  bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override;
232370b324cSopenharmony_ci
233370b324cSopenharmony_ci  void SetTitleText();
234370b324cSopenharmony_ci  void ShowSize(unsigned id, UInt64 val, UInt64 &prev);
235370b324cSopenharmony_ci
236370b324cSopenharmony_ci  void UpdateMessagesDialog();
237370b324cSopenharmony_ci
238370b324cSopenharmony_ci  void AddMessageDirect(LPCWSTR message, bool needNumber);
239370b324cSopenharmony_ci  void AddMessage(LPCWSTR message);
240370b324cSopenharmony_ci
241370b324cSopenharmony_ci  bool OnExternalCloseMessage();
242370b324cSopenharmony_ci  void EnableErrorsControls(bool enable);
243370b324cSopenharmony_ci
244370b324cSopenharmony_ci  void ShowAfterMessages(HWND wndParent);
245370b324cSopenharmony_ci
246370b324cSopenharmony_ci  void CheckNeedClose();
247370b324cSopenharmony_cipublic:
248370b324cSopenharmony_ci  CProgressSync Sync;
249370b324cSopenharmony_ci  bool CompressingMode;
250370b324cSopenharmony_ci  bool WaitMode;
251370b324cSopenharmony_ci  bool ShowCompressionInfo;
252370b324cSopenharmony_ci  bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages.
253370b324cSopenharmony_ci  int IconID;
254370b324cSopenharmony_ci
255370b324cSopenharmony_ci  HWND MainWindow;
256370b324cSopenharmony_ci  #ifndef Z7_SFX
257370b324cSopenharmony_ci  UString MainTitle;
258370b324cSopenharmony_ci  UString MainAddTitle;
259370b324cSopenharmony_ci  ~CProgressDialog() Z7_DESTRUCTOR_override;
260370b324cSopenharmony_ci  #endif
261370b324cSopenharmony_ci
262370b324cSopenharmony_ci  CProgressDialog();
263370b324cSopenharmony_ci  void WaitCreating()
264370b324cSopenharmony_ci  {
265370b324cSopenharmony_ci    _createDialogEvent.Set();
266370b324cSopenharmony_ci    _dialogCreatedEvent.Lock();
267370b324cSopenharmony_ci  }
268370b324cSopenharmony_ci
269370b324cSopenharmony_ci  INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = NULL);
270370b324cSopenharmony_ci
271370b324cSopenharmony_ci
272370b324cSopenharmony_ci  /* how it works:
273370b324cSopenharmony_ci     1) the working thread calls ProcessWasFinished()
274370b324cSopenharmony_ci        that sends kCloseMessage message to CProgressDialog (GUI) thread
275370b324cSopenharmony_ci     2) CProgressDialog (GUI) thread receives kCloseMessage message and
276370b324cSopenharmony_ci        calls ProcessWasFinished_GuiVirt();
277370b324cSopenharmony_ci        So we can implement ProcessWasFinished_GuiVirt() and show special
278370b324cSopenharmony_ci        results window in GUI thread with CProgressDialog as parent window
279370b324cSopenharmony_ci  */
280370b324cSopenharmony_ci
281370b324cSopenharmony_ci  void ProcessWasFinished();
282370b324cSopenharmony_ci  virtual void ProcessWasFinished_GuiVirt() {}
283370b324cSopenharmony_ci};
284370b324cSopenharmony_ci
285370b324cSopenharmony_ci
286370b324cSopenharmony_ciclass CProgressCloser
287370b324cSopenharmony_ci{
288370b324cSopenharmony_ci  CProgressDialog *_p;
289370b324cSopenharmony_cipublic:
290370b324cSopenharmony_ci  CProgressCloser(CProgressDialog &p) : _p(&p) {}
291370b324cSopenharmony_ci  ~CProgressCloser() { _p->ProcessWasFinished(); }
292370b324cSopenharmony_ci};
293370b324cSopenharmony_ci
294370b324cSopenharmony_ci
295370b324cSopenharmony_ciclass CProgressThreadVirt: public CProgressDialog
296370b324cSopenharmony_ci{
297370b324cSopenharmony_ciprotected:
298370b324cSopenharmony_ci  FStringVector ErrorPaths;
299370b324cSopenharmony_ci  CProgressFinalMessage FinalMessage;
300370b324cSopenharmony_ci
301370b324cSopenharmony_ci  // error if any of HRESULT, ErrorMessage, ErrorPath
302370b324cSopenharmony_ci  virtual HRESULT ProcessVirt() = 0;
303370b324cSopenharmony_cipublic:
304370b324cSopenharmony_ci  HRESULT Result;
305370b324cSopenharmony_ci  bool ThreadFinishedOK; // if there is no fatal exception
306370b324cSopenharmony_ci
307370b324cSopenharmony_ci  void Process();
308370b324cSopenharmony_ci  void AddErrorPath(const FString &path) { ErrorPaths.Add(path); }
309370b324cSopenharmony_ci
310370b324cSopenharmony_ci  HRESULT Create(const UString &title, HWND parentWindow = NULL);
311370b324cSopenharmony_ci  CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {}
312370b324cSopenharmony_ci
313370b324cSopenharmony_ci  CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; }
314370b324cSopenharmony_ci};
315370b324cSopenharmony_ci
316370b324cSopenharmony_ciUString HResultToMessage(HRESULT errorCode);
317370b324cSopenharmony_ci
318370b324cSopenharmony_ci/*
319370b324cSopenharmony_cihow it works:
320370b324cSopenharmony_ci
321370b324cSopenharmony_ciclient code inherits CProgressThreadVirt and calls
322370b324cSopenharmony_ciCProgressThreadVirt::Create()
323370b324cSopenharmony_ci{
324370b324cSopenharmony_ci  it creates new thread that calls CProgressThreadVirt::Process();
325370b324cSopenharmony_ci  it creates modal progress dialog window with ProgressDialog.Create()
326370b324cSopenharmony_ci}
327370b324cSopenharmony_ci
328370b324cSopenharmony_ciCProgressThreadVirt::Process()
329370b324cSopenharmony_ci{
330370b324cSopenharmony_ci  {
331370b324cSopenharmony_ci    Result = ProcessVirt(); // virtual function that must implement real work
332370b324cSopenharmony_ci  }
333370b324cSopenharmony_ci  if (exceptions) or FinalMessage.ErrorMessage.Message
334370b324cSopenharmony_ci  {
335370b324cSopenharmony_ci    set message to ProgressDialog.Sync.FinalMessage.ErrorMessage.Message
336370b324cSopenharmony_ci  }
337370b324cSopenharmony_ci  else if (FinalMessage.OkMessage.Message)
338370b324cSopenharmony_ci  {
339370b324cSopenharmony_ci    set message to ProgressDialog.Sync.FinalMessage.OkMessage
340370b324cSopenharmony_ci  }
341370b324cSopenharmony_ci
342370b324cSopenharmony_ci  PostMsg(kCloseMessage);
343370b324cSopenharmony_ci}
344370b324cSopenharmony_ci
345370b324cSopenharmony_ci
346370b324cSopenharmony_ciCProgressDialog::OnExternalCloseMessage()
347370b324cSopenharmony_ci{
348370b324cSopenharmony_ci  if (ProgressDialog.Sync.FinalMessage)
349370b324cSopenharmony_ci  {
350370b324cSopenharmony_ci    WorkWasFinishedVirt();
351370b324cSopenharmony_ci    Show (ProgressDialog.Sync.FinalMessage)
352370b324cSopenharmony_ci    MessagesDisplayed = true;
353370b324cSopenharmony_ci  }
354370b324cSopenharmony_ci}
355370b324cSopenharmony_ci
356370b324cSopenharmony_ci*/
357370b324cSopenharmony_ci
358370b324cSopenharmony_ci#endif
359