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