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 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 _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
OnInit()48 bool CProgressDialog::OnInit()
49 {
50 _range = (UInt64)(Int64)-1;
51 _prevPercentValue = -1;
52
53 _wasCreated = true;
54 _dialogCreatedEvent.Set();
55
56 #ifdef LANG
57 LangSetDlgItems(*this, NULL, 0);
58 #endif
59
60 m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
61
62 if (IconID >= 0)
63 {
64 HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IconID));
65 SetIcon(ICON_BIG, icon);
66 }
67
68 _timer = SetTimer(kTimerID, kTimerElapse);
69 SetText(_title);
70 CheckNeedClose();
71 return CModalDialog::OnInit();
72 }
73
OnCancel()74 void CProgressDialog::OnCancel() { Sync.SetStopped(true); }
OnOK()75 void CProgressDialog::OnOK() { }
76
SetRange(UInt64 range)77 void CProgressDialog::SetRange(UInt64 range)
78 {
79 _range = range;
80 _peviousPos = (UInt64)(Int64)-1;
81 _converter.Init(range);
82 m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100%
83 }
84
SetPos(UInt64 pos)85 void CProgressDialog::SetPos(UInt64 pos)
86 {
87 bool redraw = true;
88 if (pos < _range && pos > _peviousPos)
89 {
90 UInt64 posDelta = pos - _peviousPos;
91 if (posDelta < (_range >> 10))
92 redraw = false;
93 }
94 if (redraw)
95 {
96 m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100%
97 _peviousPos = pos;
98 }
99 }
100
OnTimer(WPARAM,LPARAM)101 bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
102 {
103 if (Sync.GetPaused())
104 return true;
105
106 CheckNeedClose();
107
108 UInt64 total, completed;
109 Sync.GetProgress(total, completed);
110 if (total != _range)
111 SetRange(total);
112 SetPos(completed);
113
114 if (total == 0)
115 total = 1;
116
117 int percentValue = (int)(completed * 100 / total);
118 if (percentValue != _prevPercentValue)
119 {
120 wchar_t s[64];
121 ConvertUInt64ToString(percentValue, s);
122 UString title = s;
123 title += "% ";
124 SetText(title + _title);
125 #ifndef _SFX
126 AddToTitle(title + MainAddTitle);
127 #endif
128 _prevPercentValue = percentValue;
129 }
130 return true;
131 }
132
OnMessage(UINT message,WPARAM wParam,LPARAM lParam)133 bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
134 {
135 switch (message)
136 {
137 case kCloseMessage:
138 {
139 KillTimer(_timer);
140 _timer = 0;
141 if (_inCancelMessageBox)
142 {
143 _externalCloseMessageWasReceived = true;
144 break;
145 }
146 return OnExternalCloseMessage();
147 }
148 /*
149 case WM_SETTEXT:
150 {
151 if (_timer == 0)
152 return true;
153 }
154 */
155 }
156 return CModalDialog::OnMessage(message, wParam, lParam);
157 }
158
OnButtonClicked(int buttonID,HWND buttonHWND)159 bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
160 {
161 switch (buttonID)
162 {
163 case IDCANCEL:
164 {
165 bool paused = Sync.GetPaused();
166 Sync.SetPaused(true);
167 _inCancelMessageBox = true;
168 int res = ::MessageBoxW(*this, L"Are you sure you want to cancel?", _title, MB_YESNOCANCEL);
169 _inCancelMessageBox = false;
170 Sync.SetPaused(paused);
171 if (res == IDCANCEL || res == IDNO)
172 {
173 if (_externalCloseMessageWasReceived)
174 OnExternalCloseMessage();
175 return true;
176 }
177 break;
178 }
179 }
180 return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
181 }
182
CheckNeedClose()183 void CProgressDialog::CheckNeedClose()
184 {
185 if (_needClose)
186 {
187 PostMsg(kCloseMessage);
188 _needClose = false;
189 }
190 }
191
OnExternalCloseMessage()192 bool CProgressDialog::OnExternalCloseMessage()
193 {
194 End(0);
195 return true;
196 }
197