ProgressDialog.h revision cd66d540cead3f8200b0c73bad9c276d67896c3d
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
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  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
107  void WaitCreating() { _dialogCreatedEvent.Lock(); }
108  void CheckNeedClose();
109  bool OnExternalCloseMessage();
110public:
111  CProgressSync Sync;
112  int IconID;
113
114  #ifndef _SFX
115  HWND MainWindow;
116  UString MainTitle;
117  UString MainAddTitle;
118  ~CProgressDialog();
119  #endif
120
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
151  void ProcessWasFinished()
152  {
153    WaitCreating();
154    if (_wasCreated)
155      PostMessage(kCloseMessage);
156    else
157      _needClose = true;
158  };
159};
160
161
162class CProgressCloser
163{
164  CProgressDialog *_p;
165public:
166  CProgressCloser(CProgressDialog &p) : _p(&p) {}
167  ~CProgressCloser() { _p->ProcessWasFinished(); }
168};
169
170#endif
171