1 // ProgressDialog.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../../Common/IntToString.h"
6
7 #include "resource.h"
8
9 #include "ProgressDialog.h"
10
11 using namespace NWindows;
12
13 extern HINSTANCE g_hInstance;
14
15 static const UINT_PTR kTimerID = 3;
16 static const UINT kTimerElapse = 100;
17
18 #ifdef Z7_LANG
19 #include "LangUtils.h"
20 #endif
21
ProcessStopAndPause()22 HRESULT CProgressSync::ProcessStopAndPause()
23 {
24 for (;;)
25 {
26 if (GetStopped())
27 return E_ABORT;
28 if (!GetPaused())
29 break;
30 ::Sleep(100);
31 }
32 return S_OK;
33 }
34
35 #ifndef Z7_SFX
~CProgressDialog()36 CProgressDialog::~CProgressDialog()
37 {
38 AddToTitle(L"");
39 }
AddToTitle(LPCWSTR s)40 void CProgressDialog::AddToTitle(LPCWSTR s)
41 {
42 if (MainWindow != 0)
43 MySetWindowText(MainWindow, UString(s) + MainTitle);
44 }
45 #endif
46
47
48 #define UNDEFINED_VAL ((UInt64)(Int64)-1)
49
OnInit()50 bool CProgressDialog::OnInit()
51 {
52 _range = UNDEFINED_VAL;
53 _prevPercentValue = UNDEFINED_VAL;
54
55 _wasCreated = true;
56 _dialogCreatedEvent.Set();
57
58 #ifdef Z7_LANG
59 LangSetDlgItems(*this, NULL, 0);
60 #endif
61
62 m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
63
64 if (IconID >= 0)
65 {
66 HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IconID));
67 SetIcon(ICON_BIG, icon);
68 }
69
70 _timer = SetTimer(kTimerID, kTimerElapse);
71 SetText(_title);
72 CheckNeedClose();
73 return CModalDialog::OnInit();
74 }
75
OnCancel()76 void CProgressDialog::OnCancel() { Sync.SetStopped(true); }
OnOK()77 void CProgressDialog::OnOK() { }
78
SetRange(UInt64 range)79 void CProgressDialog::SetRange(UInt64 range)
80 {
81 _range = range;
82 _peviousPos = (UInt64)(Int64)-1;
83 _converter.Init(range);
84 m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100%
85 }
86
SetPos(UInt64 pos)87 void CProgressDialog::SetPos(UInt64 pos)
88 {
89 bool redraw = true;
90 if (pos < _range && pos > _peviousPos)
91 {
92 UInt64 posDelta = pos - _peviousPos;
93 if (posDelta < (_range >> 10))
94 redraw = false;
95 }
96 if (redraw)
97 {
98 m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100%
99 _peviousPos = pos;
100 }
101 }
102
OnTimer(WPARAM,LPARAM)103 bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
104 {
105 if (Sync.GetPaused())
106 return true;
107
108 CheckNeedClose();
109
110 UInt64 total, completed;
111 Sync.GetProgress(total, completed);
112 if (total != _range)
113 SetRange(total);
114 SetPos(completed);
115
116 if (total == 0)
117 total = 1;
118
119 const UInt64 percentValue = completed * 100 / total;
120 if (percentValue != _prevPercentValue)
121 {
122 wchar_t s[64];
123 ConvertUInt64ToString(percentValue, s);
124 UString title = s;
125 title += "% ";
126 SetText(title + _title);
127 #ifndef Z7_SFX
128 AddToTitle(title + MainAddTitle);
129 #endif
130 _prevPercentValue = percentValue;
131 }
132 return true;
133 }
134
OnMessage(UINT message,WPARAM wParam,LPARAM lParam)135 bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
136 {
137 switch (message)
138 {
139 case kCloseMessage:
140 {
141 if (_timer)
142 {
143 KillTimer(kTimerID);
144 _timer = 0;
145 }
146 if (_inCancelMessageBox)
147 {
148 _externalCloseMessageWasReceived = true;
149 break;
150 }
151 return OnExternalCloseMessage();
152 }
153 /*
154 case WM_SETTEXT:
155 {
156 if (_timer == 0)
157 return true;
158 }
159 */
160 }
161 return CModalDialog::OnMessage(message, wParam, lParam);
162 }
163
OnButtonClicked(unsigned buttonID,HWND buttonHWND)164 bool CProgressDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND)
165 {
166 switch (buttonID)
167 {
168 case IDCANCEL:
169 {
170 bool paused = Sync.GetPaused();
171 Sync.SetPaused(true);
172 _inCancelMessageBox = true;
173 int res = ::MessageBoxW(*this, L"Are you sure you want to cancel?", _title, MB_YESNOCANCEL);
174 _inCancelMessageBox = false;
175 Sync.SetPaused(paused);
176 if (res == IDCANCEL || res == IDNO)
177 {
178 if (_externalCloseMessageWasReceived)
179 OnExternalCloseMessage();
180 return true;
181 }
182 break;
183 }
184 }
185 return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
186 }
187
CheckNeedClose()188 void CProgressDialog::CheckNeedClose()
189 {
190 if (_needClose)
191 {
192 PostMsg(kCloseMessage);
193 _needClose = false;
194 }
195 }
196
OnExternalCloseMessage()197 bool CProgressDialog::OnExternalCloseMessage()
198 {
199 End(0);
200 return true;
201 }
202