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 11using namespace NWindows; 12 13extern HINSTANCE g_hInstance; 14 15static const UINT_PTR kTimerID = 3; 16static const UINT kTimerElapse = 100; 17 18#ifdef LANG 19#include "LangUtils.h" 20#endif 21 22HRESULT 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 36CProgressDialog::~CProgressDialog() 37{ 38 AddToTitle(L""); 39} 40void CProgressDialog::AddToTitle(LPCWSTR s) 41{ 42 if (MainWindow != 0) 43 MySetWindowText(MainWindow, UString(s) + MainTitle); 44} 45#endif 46 47 48bool 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 74void CProgressDialog::OnCancel() { Sync.SetStopped(true); } 75void CProgressDialog::OnOK() { } 76 77void 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 85void 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 101bool 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 133bool 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 159bool 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 183void CProgressDialog::CheckNeedClose() 184{ 185 if (_needClose) 186 { 187 PostMessage(kCloseMessage); 188 _needClose = false; 189 } 190} 191 192bool CProgressDialog::OnExternalCloseMessage() 193{ 194 End(0); 195 return true; 196} 197