1 // ProgressDialog.cpp
2
3 #include "StdAfx.h"
4 #include "resource.h"
5 #include "ProgressDialog.h"
6 #include "Common/IntToString.h"
7 #include "Common/IntToString.h"
8
9 using namespace NWindows;
10
11 static const UINT_PTR kTimerID = 3;
12 static const UINT kTimerElapse = 50;
13
14 #ifdef LANG
15 #include "../../LangUtils.h"
16 #endif
17
18 #ifdef LANG
19 static CIDLangPair kIDLangPairs[] =
20 {
21 { IDCANCEL, 0x02000711 }
22 };
23 #endif
24
25 #ifndef _SFX
~CProgressDialog()26 CProgressDialog::~CProgressDialog()
27 {
28 AddToTitle(TEXT(""));
29 }
AddToTitle(LPCWSTR s)30 void CProgressDialog::AddToTitle(LPCWSTR s)
31 {
32 if (MainWindow != 0)
33 ::MySetWindowText(MainWindow, UString(s) + MainTitle);
34 }
35 #endif
36
37
38
OnInit()39 bool CProgressDialog::OnInit()
40 {
41 _range = UINT64(-1);
42 _prevPercentValue = -1;
43
44 #ifdef LANG
45 // LangSetWindowText(HWND(*this), 0x02000C00);
46 LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
47 #endif
48
49 m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
50 _timer = SetTimer(kTimerID, kTimerElapse);
51 _dialogCreatedEvent.Set();
52 SetText(_title);
53 return CModalDialog::OnInit();
54 }
55
OnCancel()56 void CProgressDialog::OnCancel()
57 {
58 ProgressSynch.SetStopped(true);
59 }
60
SetRange(UINT64 range)61 void CProgressDialog::SetRange(UINT64 range)
62 {
63 _range = range;
64 _peviousPos = (UInt64)(Int64)-1;
65 _converter.Init(range);
66 m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100%
67 }
68
SetPos(UINT64 pos)69 void CProgressDialog::SetPos(UINT64 pos)
70 {
71 bool redraw = true;
72 if (pos < _range && pos > _peviousPos)
73 {
74 UINT64 posDelta = pos - _peviousPos;
75 if (posDelta < (_range >> 10))
76 redraw = false;
77 }
78 if(redraw)
79 {
80 m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100%
81 _peviousPos = pos;
82 }
83 }
84
OnTimer(WPARAM timerID,LPARAM callback)85 bool CProgressDialog::OnTimer(WPARAM timerID, LPARAM callback)
86 {
87 if (ProgressSynch.GetPaused())
88 return true;
89 UINT64 total, completed;
90 ProgressSynch.GetProgress(total, completed);
91 if (total != _range)
92 SetRange(total);
93 SetPos(completed);
94
95 if (total == 0)
96 total = 1;
97
98 int percentValue = (int)(completed * 100 / total);
99 if (percentValue != _prevPercentValue)
100 {
101 wchar_t s[64];
102 ConvertUInt64ToString(percentValue, s);
103 UString title = s;
104 title += L"% ";
105 SetText(title + _title);
106 #ifndef _SFX
107 AddToTitle(title + MainAddTitle);
108 #endif
109 _prevPercentValue = percentValue;
110 }
111 return true;
112 }
113
114
115 ////////////////////
116 // CU64ToI32Converter
117
118 static const UINT64 kMaxIntValue = 0x7FFFFFFF;
119
Init(UINT64 range)120 void CU64ToI32Converter::Init(UINT64 range)
121 {
122 _numShiftBits = 0;
123 while(range > kMaxIntValue)
124 {
125 range >>= 1;
126 _numShiftBits++;
127 }
128 }
129
Count(UINT64 aValue)130 int CU64ToI32Converter::Count(UINT64 aValue)
131 {
132 return int(aValue >> _numShiftBits);
133 }
134
135 const UINT CProgressDialog::kCloseMessage = WM_USER + 1;
136
OnMessage(UINT message,WPARAM wParam,LPARAM lParam)137 bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
138 {
139 switch(message)
140 {
141 case kCloseMessage:
142 {
143 KillTimer(_timer);
144 _timer = 0;
145 End(0);
146 return true;
147 }
148 case WM_SETTEXT:
149 {
150 if (_timer == 0)
151 return true;
152 }
153 }
154 return CModalDialog::OnMessage(message, wParam, lParam);
155 }
156
OnButtonClicked(int buttonID,HWND buttonHWND)157 bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
158 {
159 switch(buttonID)
160 {
161 case IDCANCEL:
162 {
163 bool paused = ProgressSynch.GetPaused();;
164 ProgressSynch.SetPaused(true);
165 int res = ::MessageBoxW(HWND(*this),
166 L"Are you sure you want to cancel?",
167 _title, MB_YESNO);
168 ProgressSynch.SetPaused(paused);
169 if (res == IDNO)
170 return true;
171 break;
172 }
173 }
174 return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
175 }
176