michael@0: // ProgressDialog.cpp michael@0: michael@0: #include "StdAfx.h" michael@0: #include "resource.h" michael@0: #include "ProgressDialog.h" michael@0: #include "Common/IntToString.h" michael@0: #include "Common/IntToString.h" michael@0: michael@0: using namespace NWindows; michael@0: michael@0: static const UINT_PTR kTimerID = 3; michael@0: static const UINT kTimerElapse = 50; michael@0: michael@0: #ifdef LANG michael@0: #include "../../LangUtils.h" michael@0: #endif michael@0: michael@0: #ifdef LANG michael@0: static CIDLangPair kIDLangPairs[] = michael@0: { michael@0: { IDCANCEL, 0x02000711 } michael@0: }; michael@0: #endif michael@0: michael@0: #ifndef _SFX michael@0: CProgressDialog::~CProgressDialog() michael@0: { michael@0: AddToTitle(TEXT("")); michael@0: } michael@0: void CProgressDialog::AddToTitle(LPCWSTR s) michael@0: { michael@0: if (MainWindow != 0) michael@0: ::MySetWindowText(MainWindow, UString(s) + MainTitle); michael@0: } michael@0: #endif michael@0: michael@0: michael@0: michael@0: bool CProgressDialog::OnInit() michael@0: { michael@0: _range = UINT64(-1); michael@0: _prevPercentValue = -1; michael@0: michael@0: #ifdef LANG michael@0: // LangSetWindowText(HWND(*this), 0x02000C00); michael@0: LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); michael@0: #endif michael@0: michael@0: m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); michael@0: _timer = SetTimer(kTimerID, kTimerElapse); michael@0: _dialogCreatedEvent.Set(); michael@0: SetText(_title); michael@0: return CModalDialog::OnInit(); michael@0: } michael@0: michael@0: void CProgressDialog::OnCancel() michael@0: { michael@0: ProgressSynch.SetStopped(true); michael@0: } michael@0: michael@0: void CProgressDialog::SetRange(UINT64 range) michael@0: { michael@0: _range = range; michael@0: _peviousPos = (UInt64)(Int64)-1; michael@0: _converter.Init(range); michael@0: m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100% michael@0: } michael@0: michael@0: void CProgressDialog::SetPos(UINT64 pos) michael@0: { michael@0: bool redraw = true; michael@0: if (pos < _range && pos > _peviousPos) michael@0: { michael@0: UINT64 posDelta = pos - _peviousPos; michael@0: if (posDelta < (_range >> 10)) michael@0: redraw = false; michael@0: } michael@0: if(redraw) michael@0: { michael@0: m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100% michael@0: _peviousPos = pos; michael@0: } michael@0: } michael@0: michael@0: bool CProgressDialog::OnTimer(WPARAM timerID, LPARAM callback) michael@0: { michael@0: if (ProgressSynch.GetPaused()) michael@0: return true; michael@0: UINT64 total, completed; michael@0: ProgressSynch.GetProgress(total, completed); michael@0: if (total != _range) michael@0: SetRange(total); michael@0: SetPos(completed); michael@0: michael@0: if (total == 0) michael@0: total = 1; michael@0: michael@0: int percentValue = (int)(completed * 100 / total); michael@0: if (percentValue != _prevPercentValue) michael@0: { michael@0: wchar_t s[64]; michael@0: ConvertUInt64ToString(percentValue, s); michael@0: UString title = s; michael@0: title += L"% "; michael@0: SetText(title + _title); michael@0: #ifndef _SFX michael@0: AddToTitle(title + MainAddTitle); michael@0: #endif michael@0: _prevPercentValue = percentValue; michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: michael@0: //////////////////// michael@0: // CU64ToI32Converter michael@0: michael@0: static const UINT64 kMaxIntValue = 0x7FFFFFFF; michael@0: michael@0: void CU64ToI32Converter::Init(UINT64 range) michael@0: { michael@0: _numShiftBits = 0; michael@0: while(range > kMaxIntValue) michael@0: { michael@0: range >>= 1; michael@0: _numShiftBits++; michael@0: } michael@0: } michael@0: michael@0: int CU64ToI32Converter::Count(UINT64 aValue) michael@0: { michael@0: return int(aValue >> _numShiftBits); michael@0: } michael@0: michael@0: const UINT CProgressDialog::kCloseMessage = WM_USER + 1; michael@0: michael@0: bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) michael@0: { michael@0: switch(message) michael@0: { michael@0: case kCloseMessage: michael@0: { michael@0: KillTimer(_timer); michael@0: _timer = 0; michael@0: End(0); michael@0: return true; michael@0: } michael@0: case WM_SETTEXT: michael@0: { michael@0: if (_timer == 0) michael@0: return true; michael@0: } michael@0: } michael@0: return CModalDialog::OnMessage(message, wParam, lParam); michael@0: } michael@0: michael@0: bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) michael@0: { michael@0: switch(buttonID) michael@0: { michael@0: case IDCANCEL: michael@0: { michael@0: bool paused = ProgressSynch.GetPaused();; michael@0: ProgressSynch.SetPaused(true); michael@0: int res = ::MessageBoxW(HWND(*this), michael@0: L"Are you sure you want to cancel?", michael@0: _title, MB_YESNO); michael@0: ProgressSynch.SetPaused(paused); michael@0: if (res == IDNO) michael@0: return true; michael@0: break; michael@0: } michael@0: } michael@0: return CModalDialog::OnButtonClicked(buttonID, buttonHWND); michael@0: }