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 += L"% ";
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