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