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 Z7_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 Z7_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
48#define UNDEFINED_VAL ((UInt64)(Int64)-1)
49
50bool CProgressDialog::OnInit()
51{
52  _range = UNDEFINED_VAL;
53  _prevPercentValue = UNDEFINED_VAL;
54
55  _wasCreated = true;
56  _dialogCreatedEvent.Set();
57
58  #ifdef Z7_LANG
59  LangSetDlgItems(*this, NULL, 0);
60  #endif
61
62  m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
63
64  if (IconID >= 0)
65  {
66    HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IconID));
67    SetIcon(ICON_BIG, icon);
68  }
69
70  _timer = SetTimer(kTimerID, kTimerElapse);
71  SetText(_title);
72  CheckNeedClose();
73  return CModalDialog::OnInit();
74}
75
76void CProgressDialog::OnCancel() { Sync.SetStopped(true); }
77void CProgressDialog::OnOK() { }
78
79void CProgressDialog::SetRange(UInt64 range)
80{
81  _range = range;
82  _peviousPos = (UInt64)(Int64)-1;
83  _converter.Init(range);
84  m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100%
85}
86
87void CProgressDialog::SetPos(UInt64 pos)
88{
89  bool redraw = true;
90  if (pos < _range && pos > _peviousPos)
91  {
92    UInt64 posDelta = pos - _peviousPos;
93    if (posDelta < (_range >> 10))
94      redraw = false;
95  }
96  if (redraw)
97  {
98    m_ProgressBar.SetPos(_converter.Count(pos));  // Test it for 100%
99    _peviousPos = pos;
100  }
101}
102
103bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
104{
105  if (Sync.GetPaused())
106    return true;
107
108  CheckNeedClose();
109
110  UInt64 total, completed;
111  Sync.GetProgress(total, completed);
112  if (total != _range)
113    SetRange(total);
114  SetPos(completed);
115
116  if (total == 0)
117    total = 1;
118
119  const UInt64 percentValue = completed * 100 / total;
120  if (percentValue != _prevPercentValue)
121  {
122    wchar_t s[64];
123    ConvertUInt64ToString(percentValue, s);
124    UString title = s;
125    title += "% ";
126    SetText(title + _title);
127    #ifndef Z7_SFX
128    AddToTitle(title + MainAddTitle);
129    #endif
130    _prevPercentValue = percentValue;
131  }
132  return true;
133}
134
135bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
136{
137  switch (message)
138  {
139    case kCloseMessage:
140    {
141      if (_timer)
142      {
143        KillTimer(kTimerID);
144        _timer = 0;
145      }
146      if (_inCancelMessageBox)
147      {
148        _externalCloseMessageWasReceived = true;
149        break;
150      }
151      return OnExternalCloseMessage();
152    }
153    /*
154    case WM_SETTEXT:
155    {
156      if (_timer == 0)
157        return true;
158    }
159    */
160  }
161  return CModalDialog::OnMessage(message, wParam, lParam);
162}
163
164bool CProgressDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND)
165{
166  switch (buttonID)
167  {
168    case IDCANCEL:
169    {
170      bool paused = Sync.GetPaused();
171      Sync.SetPaused(true);
172      _inCancelMessageBox = true;
173      int res = ::MessageBoxW(*this, L"Are you sure you want to cancel?", _title, MB_YESNOCANCEL);
174      _inCancelMessageBox = false;
175      Sync.SetPaused(paused);
176      if (res == IDCANCEL || res == IDNO)
177      {
178        if (_externalCloseMessageWasReceived)
179          OnExternalCloseMessage();
180        return true;
181      }
182      break;
183    }
184  }
185  return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
186}
187
188void CProgressDialog::CheckNeedClose()
189{
190  if (_needClose)
191  {
192    PostMsg(kCloseMessage);
193    _needClose = false;
194  }
195}
196
197bool CProgressDialog::OnExternalCloseMessage()
198{
199  End(0);
200  return true;
201}
202