1370b324cSopenharmony_ci// ProgressDialog2.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#ifdef Z7_OLD_WIN_SDK
6370b324cSopenharmony_ci#include <ShlGuid.h>
7370b324cSopenharmony_ci#endif
8370b324cSopenharmony_ci
9370b324cSopenharmony_ci#include "../../../Common/IntToString.h"
10370b324cSopenharmony_ci#include "../../../Common/StringConvert.h"
11370b324cSopenharmony_ci
12370b324cSopenharmony_ci#include "../../../Windows/Clipboard.h"
13370b324cSopenharmony_ci#include "../../../Windows/ErrorMsg.h"
14370b324cSopenharmony_ci
15370b324cSopenharmony_ci#include "../GUI/ExtractRes.h"
16370b324cSopenharmony_ci
17370b324cSopenharmony_ci#include "LangUtils.h"
18370b324cSopenharmony_ci
19370b324cSopenharmony_ci#include "DialogSize.h"
20370b324cSopenharmony_ci#include "ProgressDialog2.h"
21370b324cSopenharmony_ci#include "ProgressDialog2Res.h"
22370b324cSopenharmony_ci
23370b324cSopenharmony_ciusing namespace NWindows;
24370b324cSopenharmony_ci
25370b324cSopenharmony_ciextern HINSTANCE g_hInstance;
26370b324cSopenharmony_ci
27370b324cSopenharmony_cistatic const UINT_PTR kTimerID = 3;
28370b324cSopenharmony_ci
29370b324cSopenharmony_cistatic const UINT kCloseMessage = WM_APP + 1;
30370b324cSopenharmony_ci// we can't use WM_USER, since WM_USER can be used by standard Windows procedure for Dialog
31370b324cSopenharmony_ci
32370b324cSopenharmony_cistatic const UINT kTimerElapse =
33370b324cSopenharmony_ci  #ifdef UNDER_CE
34370b324cSopenharmony_ci  500
35370b324cSopenharmony_ci  #else
36370b324cSopenharmony_ci  200
37370b324cSopenharmony_ci  #endif
38370b324cSopenharmony_ci  ;
39370b324cSopenharmony_ci
40370b324cSopenharmony_cistatic const UINT kCreateDelay =
41370b324cSopenharmony_ci  #ifdef UNDER_CE
42370b324cSopenharmony_ci  2500
43370b324cSopenharmony_ci  #else
44370b324cSopenharmony_ci  500
45370b324cSopenharmony_ci  #endif
46370b324cSopenharmony_ci  ;
47370b324cSopenharmony_ci
48370b324cSopenharmony_cistatic const DWORD kPauseSleepTime = 100;
49370b324cSopenharmony_ci
50370b324cSopenharmony_ci#ifdef Z7_LANG
51370b324cSopenharmony_ci
52370b324cSopenharmony_cistatic const UInt32 kLangIDs[] =
53370b324cSopenharmony_ci{
54370b324cSopenharmony_ci  IDT_PROGRESS_ELAPSED,
55370b324cSopenharmony_ci  IDT_PROGRESS_REMAINING,
56370b324cSopenharmony_ci  IDT_PROGRESS_TOTAL,
57370b324cSopenharmony_ci  IDT_PROGRESS_SPEED,
58370b324cSopenharmony_ci  IDT_PROGRESS_PROCESSED,
59370b324cSopenharmony_ci  IDT_PROGRESS_RATIO,
60370b324cSopenharmony_ci  IDT_PROGRESS_ERRORS,
61370b324cSopenharmony_ci  IDB_PROGRESS_BACKGROUND,
62370b324cSopenharmony_ci  IDB_PAUSE
63370b324cSopenharmony_ci};
64370b324cSopenharmony_ci
65370b324cSopenharmony_cistatic const UInt32 kLangIDs_Colon[] =
66370b324cSopenharmony_ci{
67370b324cSopenharmony_ci  IDT_PROGRESS_PACKED,
68370b324cSopenharmony_ci  IDT_PROGRESS_FILES
69370b324cSopenharmony_ci};
70370b324cSopenharmony_ci
71370b324cSopenharmony_ci#endif
72370b324cSopenharmony_ci
73370b324cSopenharmony_ci
74370b324cSopenharmony_ci#define UNDEFINED_VAL         ((UInt64)(Int64)-1)
75370b324cSopenharmony_ci#define INIT_AS_UNDEFINED(v)  v = UNDEFINED_VAL;
76370b324cSopenharmony_ci#define IS_UNDEFINED_VAL(v)   ((v) == UNDEFINED_VAL)
77370b324cSopenharmony_ci#define IS_DEFINED_VAL(v)     ((v) != UNDEFINED_VAL)
78370b324cSopenharmony_ci
79370b324cSopenharmony_ciCProgressSync::CProgressSync():
80370b324cSopenharmony_ci    _stopped(false), _paused(false),
81370b324cSopenharmony_ci    _bytesProgressMode(true),
82370b324cSopenharmony_ci    _isDir(false),
83370b324cSopenharmony_ci    _totalBytes(UNDEFINED_VAL), _completedBytes(0),
84370b324cSopenharmony_ci    _totalFiles(UNDEFINED_VAL), _curFiles(0),
85370b324cSopenharmony_ci    _inSize(UNDEFINED_VAL),
86370b324cSopenharmony_ci    _outSize(UNDEFINED_VAL)
87370b324cSopenharmony_ci    {}
88370b324cSopenharmony_ci
89370b324cSopenharmony_ci#define CHECK_STOP  if (_stopped) return E_ABORT; if (!_paused) return S_OK;
90370b324cSopenharmony_ci#define CRITICAL_LOCK NSynchronization::CCriticalSectionLock lock(_cs);
91370b324cSopenharmony_ci
92370b324cSopenharmony_cibool CProgressSync::Get_Paused()
93370b324cSopenharmony_ci{
94370b324cSopenharmony_ci  CRITICAL_LOCK
95370b324cSopenharmony_ci  return _paused;
96370b324cSopenharmony_ci}
97370b324cSopenharmony_ci
98370b324cSopenharmony_ciHRESULT CProgressSync::CheckStop()
99370b324cSopenharmony_ci{
100370b324cSopenharmony_ci  for (;;)
101370b324cSopenharmony_ci  {
102370b324cSopenharmony_ci    {
103370b324cSopenharmony_ci      CRITICAL_LOCK
104370b324cSopenharmony_ci      CHECK_STOP
105370b324cSopenharmony_ci    }
106370b324cSopenharmony_ci    ::Sleep(kPauseSleepTime);
107370b324cSopenharmony_ci  }
108370b324cSopenharmony_ci}
109370b324cSopenharmony_ci
110370b324cSopenharmony_ciHRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir)
111370b324cSopenharmony_ci{
112370b324cSopenharmony_ci  {
113370b324cSopenharmony_ci    CRITICAL_LOCK
114370b324cSopenharmony_ci    _totalFiles = numFiles;
115370b324cSopenharmony_ci    _totalBytes = totalSize;
116370b324cSopenharmony_ci    _filePath = fs2us(fileName);
117370b324cSopenharmony_ci    _isDir = isDir;
118370b324cSopenharmony_ci    // _completedBytes = 0;
119370b324cSopenharmony_ci    CHECK_STOP
120370b324cSopenharmony_ci  }
121370b324cSopenharmony_ci  return CheckStop();
122370b324cSopenharmony_ci}
123370b324cSopenharmony_ci
124370b324cSopenharmony_ciHRESULT CProgressSync::Set_NumFilesTotal(UInt64 val)
125370b324cSopenharmony_ci{
126370b324cSopenharmony_ci  {
127370b324cSopenharmony_ci    CRITICAL_LOCK
128370b324cSopenharmony_ci    _totalFiles = val;
129370b324cSopenharmony_ci    CHECK_STOP
130370b324cSopenharmony_ci  }
131370b324cSopenharmony_ci  return CheckStop();
132370b324cSopenharmony_ci}
133370b324cSopenharmony_ci
134370b324cSopenharmony_civoid CProgressSync::Set_NumBytesTotal(UInt64 val)
135370b324cSopenharmony_ci{
136370b324cSopenharmony_ci  CRITICAL_LOCK
137370b324cSopenharmony_ci  _totalBytes = val;
138370b324cSopenharmony_ci}
139370b324cSopenharmony_ci
140370b324cSopenharmony_civoid CProgressSync::Set_NumFilesCur(UInt64 val)
141370b324cSopenharmony_ci{
142370b324cSopenharmony_ci  CRITICAL_LOCK
143370b324cSopenharmony_ci  _curFiles = val;
144370b324cSopenharmony_ci}
145370b324cSopenharmony_ci
146370b324cSopenharmony_ciHRESULT CProgressSync::Set_NumBytesCur(const UInt64 *val)
147370b324cSopenharmony_ci{
148370b324cSopenharmony_ci  {
149370b324cSopenharmony_ci    CRITICAL_LOCK
150370b324cSopenharmony_ci    if (val)
151370b324cSopenharmony_ci      _completedBytes = *val;
152370b324cSopenharmony_ci    CHECK_STOP
153370b324cSopenharmony_ci  }
154370b324cSopenharmony_ci  return CheckStop();
155370b324cSopenharmony_ci}
156370b324cSopenharmony_ci
157370b324cSopenharmony_ciHRESULT CProgressSync::Set_NumBytesCur(UInt64 val)
158370b324cSopenharmony_ci{
159370b324cSopenharmony_ci  {
160370b324cSopenharmony_ci    CRITICAL_LOCK
161370b324cSopenharmony_ci    _completedBytes = val;
162370b324cSopenharmony_ci    CHECK_STOP
163370b324cSopenharmony_ci  }
164370b324cSopenharmony_ci  return CheckStop();
165370b324cSopenharmony_ci}
166370b324cSopenharmony_ci
167370b324cSopenharmony_civoid CProgressSync::Set_Ratio(const UInt64 *inSize, const UInt64 *outSize)
168370b324cSopenharmony_ci{
169370b324cSopenharmony_ci  CRITICAL_LOCK
170370b324cSopenharmony_ci  if (inSize)
171370b324cSopenharmony_ci    _inSize = *inSize;
172370b324cSopenharmony_ci  if (outSize)
173370b324cSopenharmony_ci    _outSize = *outSize;
174370b324cSopenharmony_ci}
175370b324cSopenharmony_ci
176370b324cSopenharmony_civoid CProgressSync::Set_TitleFileName(const UString &fileName)
177370b324cSopenharmony_ci{
178370b324cSopenharmony_ci  CRITICAL_LOCK
179370b324cSopenharmony_ci  _titleFileName = fileName;
180370b324cSopenharmony_ci}
181370b324cSopenharmony_ci
182370b324cSopenharmony_civoid CProgressSync::Set_Status(const UString &s)
183370b324cSopenharmony_ci{
184370b324cSopenharmony_ci  CRITICAL_LOCK
185370b324cSopenharmony_ci  _status = s;
186370b324cSopenharmony_ci}
187370b324cSopenharmony_ci
188370b324cSopenharmony_ciHRESULT CProgressSync::Set_Status2(const UString &s, const wchar_t *path, bool isDir)
189370b324cSopenharmony_ci{
190370b324cSopenharmony_ci  {
191370b324cSopenharmony_ci    CRITICAL_LOCK
192370b324cSopenharmony_ci    _status = s;
193370b324cSopenharmony_ci    if (path)
194370b324cSopenharmony_ci      _filePath = path;
195370b324cSopenharmony_ci    else
196370b324cSopenharmony_ci      _filePath.Empty();
197370b324cSopenharmony_ci    _isDir = isDir;
198370b324cSopenharmony_ci  }
199370b324cSopenharmony_ci  return CheckStop();
200370b324cSopenharmony_ci}
201370b324cSopenharmony_ci
202370b324cSopenharmony_civoid CProgressSync::Set_FilePath(const wchar_t *path, bool isDir)
203370b324cSopenharmony_ci{
204370b324cSopenharmony_ci  CRITICAL_LOCK
205370b324cSopenharmony_ci  if (path)
206370b324cSopenharmony_ci    _filePath = path;
207370b324cSopenharmony_ci  else
208370b324cSopenharmony_ci    _filePath.Empty();
209370b324cSopenharmony_ci  _isDir = isDir;
210370b324cSopenharmony_ci}
211370b324cSopenharmony_ci
212370b324cSopenharmony_ci
213370b324cSopenharmony_civoid CProgressSync::AddError_Message(const wchar_t *message)
214370b324cSopenharmony_ci{
215370b324cSopenharmony_ci  CRITICAL_LOCK
216370b324cSopenharmony_ci  Messages.Add(message);
217370b324cSopenharmony_ci}
218370b324cSopenharmony_ci
219370b324cSopenharmony_civoid CProgressSync::AddError_Message_Name(const wchar_t *message, const wchar_t *name)
220370b324cSopenharmony_ci{
221370b324cSopenharmony_ci  UString s;
222370b324cSopenharmony_ci  if (name && *name != 0)
223370b324cSopenharmony_ci    s += name;
224370b324cSopenharmony_ci  if (message && *message != 0)
225370b324cSopenharmony_ci  {
226370b324cSopenharmony_ci    if (!s.IsEmpty())
227370b324cSopenharmony_ci      s.Add_LF();
228370b324cSopenharmony_ci    s += message;
229370b324cSopenharmony_ci    if (!s.IsEmpty() && s.Back() == L'\n')
230370b324cSopenharmony_ci      s.DeleteBack();
231370b324cSopenharmony_ci  }
232370b324cSopenharmony_ci  AddError_Message(s);
233370b324cSopenharmony_ci}
234370b324cSopenharmony_ci
235370b324cSopenharmony_civoid CProgressSync::AddError_Code_Name(HRESULT systemError, const wchar_t *name)
236370b324cSopenharmony_ci{
237370b324cSopenharmony_ci  UString s = NError::MyFormatMessage(systemError);
238370b324cSopenharmony_ci  if (systemError == 0)
239370b324cSopenharmony_ci    s = "Error";
240370b324cSopenharmony_ci  AddError_Message_Name(s, name);
241370b324cSopenharmony_ci}
242370b324cSopenharmony_ci
243370b324cSopenharmony_ciCProgressDialog::CProgressDialog():
244370b324cSopenharmony_ci   _timer(0),
245370b324cSopenharmony_ci   CompressingMode(true),
246370b324cSopenharmony_ci   MainWindow(NULL)
247370b324cSopenharmony_ci{
248370b324cSopenharmony_ci  _isDir = false;
249370b324cSopenharmony_ci
250370b324cSopenharmony_ci  _numMessages = 0;
251370b324cSopenharmony_ci  IconID = -1;
252370b324cSopenharmony_ci  MessagesDisplayed = false;
253370b324cSopenharmony_ci  _wasCreated = false;
254370b324cSopenharmony_ci  _needClose = false;
255370b324cSopenharmony_ci  _inCancelMessageBox = false;
256370b324cSopenharmony_ci  _externalCloseMessageWasReceived = false;
257370b324cSopenharmony_ci
258370b324cSopenharmony_ci  _numPostedMessages = 0;
259370b324cSopenharmony_ci  _numAutoSizeMessages = 0;
260370b324cSopenharmony_ci  _errorsWereDisplayed = false;
261370b324cSopenharmony_ci  _waitCloseByCancelButton = false;
262370b324cSopenharmony_ci  _cancelWasPressed = false;
263370b324cSopenharmony_ci  ShowCompressionInfo = true;
264370b324cSopenharmony_ci  WaitMode = false;
265370b324cSopenharmony_ci  if (_dialogCreatedEvent.Create() != S_OK)
266370b324cSopenharmony_ci    throw 1334987;
267370b324cSopenharmony_ci  if (_createDialogEvent.Create() != S_OK)
268370b324cSopenharmony_ci    throw 1334987;
269370b324cSopenharmony_ci  // #ifdef __ITaskbarList3_INTERFACE_DEFINED__
270370b324cSopenharmony_ci  CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void**)&_taskbarList);
271370b324cSopenharmony_ci  if (_taskbarList)
272370b324cSopenharmony_ci    _taskbarList->HrInit();
273370b324cSopenharmony_ci  // #endif
274370b324cSopenharmony_ci}
275370b324cSopenharmony_ci
276370b324cSopenharmony_ci#ifndef Z7_SFX
277370b324cSopenharmony_ci
278370b324cSopenharmony_ciCProgressDialog::~CProgressDialog()
279370b324cSopenharmony_ci{
280370b324cSopenharmony_ci  // #ifdef __ITaskbarList3_INTERFACE_DEFINED__
281370b324cSopenharmony_ci  SetTaskbarProgressState(TBPF_NOPROGRESS);
282370b324cSopenharmony_ci  // #endif
283370b324cSopenharmony_ci  AddToTitle(L"");
284370b324cSopenharmony_ci}
285370b324cSopenharmony_civoid CProgressDialog::AddToTitle(LPCWSTR s)
286370b324cSopenharmony_ci{
287370b324cSopenharmony_ci  if (MainWindow)
288370b324cSopenharmony_ci  {
289370b324cSopenharmony_ci    CWindow window(MainWindow);
290370b324cSopenharmony_ci    window.SetText((UString)s + MainTitle);
291370b324cSopenharmony_ci  }
292370b324cSopenharmony_ci}
293370b324cSopenharmony_ci
294370b324cSopenharmony_ci#endif
295370b324cSopenharmony_ci
296370b324cSopenharmony_ci
297370b324cSopenharmony_civoid CProgressDialog::SetTaskbarProgressState()
298370b324cSopenharmony_ci{
299370b324cSopenharmony_ci  // #ifdef __ITaskbarList3_INTERFACE_DEFINED__
300370b324cSopenharmony_ci  if (_taskbarList && _hwndForTaskbar)
301370b324cSopenharmony_ci  {
302370b324cSopenharmony_ci    TBPFLAG tbpFlags;
303370b324cSopenharmony_ci    if (Sync.Get_Paused())
304370b324cSopenharmony_ci      tbpFlags = TBPF_PAUSED;
305370b324cSopenharmony_ci    else
306370b324cSopenharmony_ci      tbpFlags = _errorsWereDisplayed ? TBPF_ERROR: TBPF_NORMAL;
307370b324cSopenharmony_ci    SetTaskbarProgressState(tbpFlags);
308370b324cSopenharmony_ci  }
309370b324cSopenharmony_ci  // #endif
310370b324cSopenharmony_ci}
311370b324cSopenharmony_ci
312370b324cSopenharmony_cistatic const unsigned kTitleFileNameSizeLimit = 36;
313370b324cSopenharmony_cistatic const unsigned kCurrentFileNameSizeLimit = 82;
314370b324cSopenharmony_ci
315370b324cSopenharmony_cistatic void ReduceString(UString &s, unsigned size)
316370b324cSopenharmony_ci{
317370b324cSopenharmony_ci  if (s.Len() <= size)
318370b324cSopenharmony_ci    return;
319370b324cSopenharmony_ci  s.Delete(size / 2, s.Len() - size);
320370b324cSopenharmony_ci  s.Insert(size / 2, L" ... ");
321370b324cSopenharmony_ci}
322370b324cSopenharmony_ci
323370b324cSopenharmony_civoid CProgressDialog::EnableErrorsControls(bool enable)
324370b324cSopenharmony_ci{
325370b324cSopenharmony_ci  ShowItem_Bool(IDT_PROGRESS_ERRORS, enable);
326370b324cSopenharmony_ci  ShowItem_Bool(IDT_PROGRESS_ERRORS_VAL, enable);
327370b324cSopenharmony_ci  ShowItem_Bool(IDL_PROGRESS_MESSAGES, enable);
328370b324cSopenharmony_ci}
329370b324cSopenharmony_ci
330370b324cSopenharmony_cibool CProgressDialog::OnInit()
331370b324cSopenharmony_ci{
332370b324cSopenharmony_ci  _hwndForTaskbar = MainWindow;
333370b324cSopenharmony_ci  if (!_hwndForTaskbar)
334370b324cSopenharmony_ci    _hwndForTaskbar = GetParent();
335370b324cSopenharmony_ci  if (!_hwndForTaskbar)
336370b324cSopenharmony_ci    _hwndForTaskbar = *this;
337370b324cSopenharmony_ci
338370b324cSopenharmony_ci  INIT_AS_UNDEFINED(_progressBar_Range)
339370b324cSopenharmony_ci  INIT_AS_UNDEFINED(_progressBar_Pos)
340370b324cSopenharmony_ci
341370b324cSopenharmony_ci  INIT_AS_UNDEFINED(_prevPercentValue)
342370b324cSopenharmony_ci  INIT_AS_UNDEFINED(_prevElapsedSec)
343370b324cSopenharmony_ci  INIT_AS_UNDEFINED(_prevRemainingSec)
344370b324cSopenharmony_ci
345370b324cSopenharmony_ci  INIT_AS_UNDEFINED(_prevSpeed)
346370b324cSopenharmony_ci  _prevSpeed_MoveBits = 0;
347370b324cSopenharmony_ci
348370b324cSopenharmony_ci  _prevTime = ::GetTickCount();
349370b324cSopenharmony_ci  _elapsedTime = 0;
350370b324cSopenharmony_ci
351370b324cSopenharmony_ci  INIT_AS_UNDEFINED(_totalBytes_Prev)
352370b324cSopenharmony_ci  INIT_AS_UNDEFINED(_processed_Prev)
353370b324cSopenharmony_ci  INIT_AS_UNDEFINED(_packed_Prev)
354370b324cSopenharmony_ci  INIT_AS_UNDEFINED(_ratio_Prev)
355370b324cSopenharmony_ci
356370b324cSopenharmony_ci  _filesStr_Prev.Empty();
357370b324cSopenharmony_ci  _filesTotStr_Prev.Empty();
358370b324cSopenharmony_ci
359370b324cSopenharmony_ci  _foreground = true;
360370b324cSopenharmony_ci
361370b324cSopenharmony_ci  m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
362370b324cSopenharmony_ci  _messageList.Attach(GetItem(IDL_PROGRESS_MESSAGES));
363370b324cSopenharmony_ci  _messageList.SetUnicodeFormat();
364370b324cSopenharmony_ci  _messageList.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT);
365370b324cSopenharmony_ci
366370b324cSopenharmony_ci  _wasCreated = true;
367370b324cSopenharmony_ci  _dialogCreatedEvent.Set();
368370b324cSopenharmony_ci
369370b324cSopenharmony_ci  #ifdef Z7_LANG
370370b324cSopenharmony_ci  LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs));
371370b324cSopenharmony_ci  LangSetDlgItems_Colon(*this, kLangIDs_Colon, Z7_ARRAY_SIZE(kLangIDs_Colon));
372370b324cSopenharmony_ci  #endif
373370b324cSopenharmony_ci
374370b324cSopenharmony_ci  CWindow window(GetItem(IDB_PROGRESS_BACKGROUND));
375370b324cSopenharmony_ci  window.GetText(_background_String);
376370b324cSopenharmony_ci  _backgrounded_String = _background_String;
377370b324cSopenharmony_ci  _backgrounded_String.RemoveChar(L'&');
378370b324cSopenharmony_ci
379370b324cSopenharmony_ci  window = GetItem(IDB_PAUSE);
380370b324cSopenharmony_ci  window.GetText(_pause_String);
381370b324cSopenharmony_ci
382370b324cSopenharmony_ci  LangString(IDS_PROGRESS_FOREGROUND, _foreground_String);
383370b324cSopenharmony_ci  LangString(IDS_CONTINUE, _continue_String);
384370b324cSopenharmony_ci  LangString(IDS_PROGRESS_PAUSED, _paused_String);
385370b324cSopenharmony_ci
386370b324cSopenharmony_ci  SetText(_title);
387370b324cSopenharmony_ci  SetPauseText();
388370b324cSopenharmony_ci  SetPriorityText();
389370b324cSopenharmony_ci
390370b324cSopenharmony_ci  _messageList.InsertColumn(0, L"", 30);
391370b324cSopenharmony_ci  _messageList.InsertColumn(1, L"", 600);
392370b324cSopenharmony_ci
393370b324cSopenharmony_ci  _messageList.SetColumnWidthAuto(0);
394370b324cSopenharmony_ci  _messageList.SetColumnWidthAuto(1);
395370b324cSopenharmony_ci
396370b324cSopenharmony_ci  EnableErrorsControls(false);
397370b324cSopenharmony_ci
398370b324cSopenharmony_ci  GetItemSizes(IDCANCEL, _buttonSizeX, _buttonSizeY);
399370b324cSopenharmony_ci  _numReduceSymbols = kCurrentFileNameSizeLimit;
400370b324cSopenharmony_ci  NormalizeSize(true);
401370b324cSopenharmony_ci
402370b324cSopenharmony_ci  if (!ShowCompressionInfo)
403370b324cSopenharmony_ci  {
404370b324cSopenharmony_ci    HideItem(IDT_PROGRESS_PACKED);
405370b324cSopenharmony_ci    HideItem(IDT_PROGRESS_PACKED_VAL);
406370b324cSopenharmony_ci    HideItem(IDT_PROGRESS_RATIO);
407370b324cSopenharmony_ci    HideItem(IDT_PROGRESS_RATIO_VAL);
408370b324cSopenharmony_ci  }
409370b324cSopenharmony_ci
410370b324cSopenharmony_ci  if (IconID >= 0)
411370b324cSopenharmony_ci  {
412370b324cSopenharmony_ci    HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IconID));
413370b324cSopenharmony_ci    // SetIcon(ICON_SMALL, icon);
414370b324cSopenharmony_ci    SetIcon(ICON_BIG, icon);
415370b324cSopenharmony_ci  }
416370b324cSopenharmony_ci  _timer = SetTimer(kTimerID, kTimerElapse);
417370b324cSopenharmony_ci  #ifdef UNDER_CE
418370b324cSopenharmony_ci  Foreground();
419370b324cSopenharmony_ci  #endif
420370b324cSopenharmony_ci
421370b324cSopenharmony_ci  CheckNeedClose();
422370b324cSopenharmony_ci
423370b324cSopenharmony_ci  SetTaskbarProgressState();
424370b324cSopenharmony_ci
425370b324cSopenharmony_ci  return CModalDialog::OnInit();
426370b324cSopenharmony_ci}
427370b324cSopenharmony_ci
428370b324cSopenharmony_cistatic const UINT kIDs[] =
429370b324cSopenharmony_ci{
430370b324cSopenharmony_ci  IDT_PROGRESS_ELAPSED,   IDT_PROGRESS_ELAPSED_VAL,
431370b324cSopenharmony_ci  IDT_PROGRESS_REMAINING, IDT_PROGRESS_REMAINING_VAL,
432370b324cSopenharmony_ci  IDT_PROGRESS_FILES,     IDT_PROGRESS_FILES_VAL,
433370b324cSopenharmony_ci  0,                      IDT_PROGRESS_FILES_TOTAL,
434370b324cSopenharmony_ci  IDT_PROGRESS_ERRORS,    IDT_PROGRESS_ERRORS_VAL,
435370b324cSopenharmony_ci
436370b324cSopenharmony_ci  IDT_PROGRESS_TOTAL,     IDT_PROGRESS_TOTAL_VAL,
437370b324cSopenharmony_ci  IDT_PROGRESS_SPEED,     IDT_PROGRESS_SPEED_VAL,
438370b324cSopenharmony_ci  IDT_PROGRESS_PROCESSED, IDT_PROGRESS_PROCESSED_VAL,
439370b324cSopenharmony_ci  IDT_PROGRESS_PACKED,    IDT_PROGRESS_PACKED_VAL,
440370b324cSopenharmony_ci  IDT_PROGRESS_RATIO,     IDT_PROGRESS_RATIO_VAL
441370b324cSopenharmony_ci};
442370b324cSopenharmony_ci
443370b324cSopenharmony_cibool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
444370b324cSopenharmony_ci{
445370b324cSopenharmony_ci  int sY;
446370b324cSopenharmony_ci  int sStep;
447370b324cSopenharmony_ci  int mx, my;
448370b324cSopenharmony_ci  {
449370b324cSopenharmony_ci    RECT r;
450370b324cSopenharmony_ci    GetClientRectOfItem(IDT_PROGRESS_ELAPSED, r);
451370b324cSopenharmony_ci    mx = r.left;
452370b324cSopenharmony_ci    my = r.top;
453370b324cSopenharmony_ci    sY = RECT_SIZE_Y(r);
454370b324cSopenharmony_ci    GetClientRectOfItem(IDT_PROGRESS_REMAINING, r);
455370b324cSopenharmony_ci    sStep = r.top - my;
456370b324cSopenharmony_ci  }
457370b324cSopenharmony_ci
458370b324cSopenharmony_ci  InvalidateRect(NULL);
459370b324cSopenharmony_ci
460370b324cSopenharmony_ci  const int xSizeClient = xSize - mx * 2;
461370b324cSopenharmony_ci
462370b324cSopenharmony_ci  {
463370b324cSopenharmony_ci    unsigned i;
464370b324cSopenharmony_ci    for (i = 800; i > 40; i = i * 9 / 10)
465370b324cSopenharmony_ci      if (Units_To_Pixels_X((int)i) <= xSizeClient)
466370b324cSopenharmony_ci        break;
467370b324cSopenharmony_ci    _numReduceSymbols = i / 4;
468370b324cSopenharmony_ci  }
469370b324cSopenharmony_ci
470370b324cSopenharmony_ci  int yPos = ySize - my - _buttonSizeY;
471370b324cSopenharmony_ci
472370b324cSopenharmony_ci  ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_STATUS), xSize - mx * 2);
473370b324cSopenharmony_ci  ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_FILE_NAME), xSize - mx * 2);
474370b324cSopenharmony_ci  ChangeSubWindowSizeX(GetItem(IDC_PROGRESS1), xSize - mx * 2);
475370b324cSopenharmony_ci
476370b324cSopenharmony_ci  int bSizeX = _buttonSizeX;
477370b324cSopenharmony_ci  int mx2 = mx;
478370b324cSopenharmony_ci  for (;; mx2--)
479370b324cSopenharmony_ci  {
480370b324cSopenharmony_ci    const int bSize2 = bSizeX * 3 + mx2 * 2;
481370b324cSopenharmony_ci    if (bSize2 <= xSizeClient)
482370b324cSopenharmony_ci      break;
483370b324cSopenharmony_ci    if (mx2 < 5)
484370b324cSopenharmony_ci    {
485370b324cSopenharmony_ci      bSizeX = (xSizeClient - mx2 * 2) / 3;
486370b324cSopenharmony_ci      break;
487370b324cSopenharmony_ci    }
488370b324cSopenharmony_ci  }
489370b324cSopenharmony_ci  if (bSizeX < 2)
490370b324cSopenharmony_ci    bSizeX = 2;
491370b324cSopenharmony_ci
492370b324cSopenharmony_ci  {
493370b324cSopenharmony_ci    RECT r;
494370b324cSopenharmony_ci    GetClientRectOfItem(IDL_PROGRESS_MESSAGES, r);
495370b324cSopenharmony_ci    const int y = r.top;
496370b324cSopenharmony_ci    int ySize2 = yPos - my - y;
497370b324cSopenharmony_ci    const int kMinYSize = _buttonSizeY + _buttonSizeY * 3 / 4;
498370b324cSopenharmony_ci    int xx = xSize - mx * 2;
499370b324cSopenharmony_ci    if (ySize2 < kMinYSize)
500370b324cSopenharmony_ci    {
501370b324cSopenharmony_ci      ySize2 = kMinYSize;
502370b324cSopenharmony_ci      if (xx > bSizeX * 2)
503370b324cSopenharmony_ci        xx -= bSizeX;
504370b324cSopenharmony_ci    }
505370b324cSopenharmony_ci
506370b324cSopenharmony_ci    _messageList.Move(mx, y, xx, ySize2);
507370b324cSopenharmony_ci  }
508370b324cSopenharmony_ci
509370b324cSopenharmony_ci  {
510370b324cSopenharmony_ci    int xPos = xSize - mx;
511370b324cSopenharmony_ci    xPos -= bSizeX;
512370b324cSopenharmony_ci    MoveItem(IDCANCEL, xPos, yPos, bSizeX, _buttonSizeY);
513370b324cSopenharmony_ci    xPos -= (mx2 + bSizeX);
514370b324cSopenharmony_ci    MoveItem(IDB_PAUSE, xPos, yPos, bSizeX, _buttonSizeY);
515370b324cSopenharmony_ci    xPos -= (mx2 + bSizeX);
516370b324cSopenharmony_ci    MoveItem(IDB_PROGRESS_BACKGROUND, xPos, yPos, bSizeX, _buttonSizeY);
517370b324cSopenharmony_ci  }
518370b324cSopenharmony_ci
519370b324cSopenharmony_ci  int valueSize;
520370b324cSopenharmony_ci  int labelSize;
521370b324cSopenharmony_ci  int padSize;
522370b324cSopenharmony_ci
523370b324cSopenharmony_ci  labelSize = Units_To_Pixels_X(MY_PROGRESS_LABEL_UNITS_MIN);
524370b324cSopenharmony_ci  valueSize = Units_To_Pixels_X(MY_PROGRESS_VAL_UNITS);
525370b324cSopenharmony_ci  padSize = Units_To_Pixels_X(MY_PROGRESS_PAD_UNITS);
526370b324cSopenharmony_ci  const int requiredSize = (labelSize + valueSize) * 2 + padSize;
527370b324cSopenharmony_ci
528370b324cSopenharmony_ci  int gSize;
529370b324cSopenharmony_ci  {
530370b324cSopenharmony_ci    if (requiredSize < xSizeClient)
531370b324cSopenharmony_ci    {
532370b324cSopenharmony_ci      const int incr = (xSizeClient - requiredSize) / 3;
533370b324cSopenharmony_ci      labelSize += incr;
534370b324cSopenharmony_ci    }
535370b324cSopenharmony_ci    else
536370b324cSopenharmony_ci      labelSize = (xSizeClient - valueSize * 2 - padSize) / 2;
537370b324cSopenharmony_ci    if (labelSize < 0)
538370b324cSopenharmony_ci      labelSize = 0;
539370b324cSopenharmony_ci
540370b324cSopenharmony_ci    gSize = labelSize + valueSize;
541370b324cSopenharmony_ci    padSize = xSizeClient - gSize * 2;
542370b324cSopenharmony_ci  }
543370b324cSopenharmony_ci
544370b324cSopenharmony_ci  labelSize = gSize - valueSize;
545370b324cSopenharmony_ci
546370b324cSopenharmony_ci  yPos = my;
547370b324cSopenharmony_ci  for (unsigned i = 0; i < Z7_ARRAY_SIZE(kIDs); i += 2)
548370b324cSopenharmony_ci  {
549370b324cSopenharmony_ci    int x = mx;
550370b324cSopenharmony_ci    const unsigned kNumColumn1Items = 5 * 2;
551370b324cSopenharmony_ci    if (i >= kNumColumn1Items)
552370b324cSopenharmony_ci    {
553370b324cSopenharmony_ci      if (i == kNumColumn1Items)
554370b324cSopenharmony_ci        yPos = my;
555370b324cSopenharmony_ci      x = mx + gSize + padSize;
556370b324cSopenharmony_ci    }
557370b324cSopenharmony_ci    if (kIDs[i] != 0)
558370b324cSopenharmony_ci    MoveItem(kIDs[i], x, yPos, labelSize, sY);
559370b324cSopenharmony_ci    MoveItem(kIDs[i + 1], x + labelSize, yPos, valueSize, sY);
560370b324cSopenharmony_ci    yPos += sStep;
561370b324cSopenharmony_ci  }
562370b324cSopenharmony_ci  return false;
563370b324cSopenharmony_ci}
564370b324cSopenharmony_ci
565370b324cSopenharmony_civoid CProgressDialog::OnCancel() { Sync.Set_Stopped(true); }
566370b324cSopenharmony_civoid CProgressDialog::OnOK() { }
567370b324cSopenharmony_ci
568370b324cSopenharmony_civoid CProgressDialog::SetProgressRange(UInt64 range)
569370b324cSopenharmony_ci{
570370b324cSopenharmony_ci  if (range == _progressBar_Range)
571370b324cSopenharmony_ci    return;
572370b324cSopenharmony_ci  _progressBar_Range = range;
573370b324cSopenharmony_ci  INIT_AS_UNDEFINED(_progressBar_Pos)
574370b324cSopenharmony_ci  _progressConv.Init(range);
575370b324cSopenharmony_ci  m_ProgressBar.SetRange32(0, _progressConv.Count(range));
576370b324cSopenharmony_ci}
577370b324cSopenharmony_ci
578370b324cSopenharmony_civoid CProgressDialog::SetProgressPos(UInt64 pos)
579370b324cSopenharmony_ci{
580370b324cSopenharmony_ci  if (pos >= _progressBar_Range ||
581370b324cSopenharmony_ci      pos <= _progressBar_Pos ||
582370b324cSopenharmony_ci      pos - _progressBar_Pos >= (_progressBar_Range >> 10))
583370b324cSopenharmony_ci  {
584370b324cSopenharmony_ci    m_ProgressBar.SetPos(_progressConv.Count(pos));
585370b324cSopenharmony_ci    // #ifdef __ITaskbarList3_INTERFACE_DEFINED__
586370b324cSopenharmony_ci    if (_taskbarList && _hwndForTaskbar)
587370b324cSopenharmony_ci      _taskbarList->SetProgressValue(_hwndForTaskbar, pos, _progressBar_Range);
588370b324cSopenharmony_ci    // #endif
589370b324cSopenharmony_ci    _progressBar_Pos = pos;
590370b324cSopenharmony_ci  }
591370b324cSopenharmony_ci}
592370b324cSopenharmony_ci
593370b324cSopenharmony_ci#define UINT_TO_STR_2(val) { s[0] = (wchar_t)('0' + (val) / 10); s[1] = (wchar_t)('0' + (val) % 10); s += 2; }
594370b324cSopenharmony_ci
595370b324cSopenharmony_civoid GetTimeString(UInt64 timeValue, wchar_t *s);
596370b324cSopenharmony_civoid GetTimeString(UInt64 timeValue, wchar_t *s)
597370b324cSopenharmony_ci{
598370b324cSopenharmony_ci  UInt64 hours = timeValue / 3600;
599370b324cSopenharmony_ci  UInt32 seconds = (UInt32)(timeValue - hours * 3600);
600370b324cSopenharmony_ci  UInt32 minutes = seconds / 60;
601370b324cSopenharmony_ci  seconds %= 60;
602370b324cSopenharmony_ci  if (hours > 99)
603370b324cSopenharmony_ci  {
604370b324cSopenharmony_ci    ConvertUInt64ToString(hours, s);
605370b324cSopenharmony_ci    for (; *s != 0; s++);
606370b324cSopenharmony_ci  }
607370b324cSopenharmony_ci  else
608370b324cSopenharmony_ci  {
609370b324cSopenharmony_ci    UInt32 hours32 = (UInt32)hours;
610370b324cSopenharmony_ci    UINT_TO_STR_2(hours32)
611370b324cSopenharmony_ci  }
612370b324cSopenharmony_ci  *s++ = ':'; UINT_TO_STR_2(minutes)
613370b324cSopenharmony_ci  *s++ = ':'; UINT_TO_STR_2(seconds)
614370b324cSopenharmony_ci  *s = 0;
615370b324cSopenharmony_ci}
616370b324cSopenharmony_ci
617370b324cSopenharmony_cistatic void ConvertSizeToString(UInt64 v, wchar_t *s)
618370b324cSopenharmony_ci{
619370b324cSopenharmony_ci  Byte c = 0;
620370b324cSopenharmony_ci       if (v >= ((UInt64)100000 << 20)) { v >>= 30; c = 'G'; }
621370b324cSopenharmony_ci  else if (v >= ((UInt64)100000 << 10)) { v >>= 20; c = 'M'; }
622370b324cSopenharmony_ci  else if (v >= ((UInt64)100000 <<  0)) { v >>= 10; c = 'K'; }
623370b324cSopenharmony_ci  ConvertUInt64ToString(v, s);
624370b324cSopenharmony_ci  if (c != 0)
625370b324cSopenharmony_ci  {
626370b324cSopenharmony_ci    s += MyStringLen(s);
627370b324cSopenharmony_ci    *s++ = ' ';
628370b324cSopenharmony_ci    *s++ = c;
629370b324cSopenharmony_ci    *s++ = 'B';
630370b324cSopenharmony_ci    *s++ = 0;
631370b324cSopenharmony_ci  }
632370b324cSopenharmony_ci}
633370b324cSopenharmony_ci
634370b324cSopenharmony_civoid CProgressDialog::ShowSize(unsigned id, UInt64 val, UInt64 &prev)
635370b324cSopenharmony_ci{
636370b324cSopenharmony_ci  if (val == prev)
637370b324cSopenharmony_ci    return;
638370b324cSopenharmony_ci  prev = val;
639370b324cSopenharmony_ci  wchar_t s[40];
640370b324cSopenharmony_ci  s[0] = 0;
641370b324cSopenharmony_ci  if (IS_DEFINED_VAL(val))
642370b324cSopenharmony_ci    ConvertSizeToString(val, s);
643370b324cSopenharmony_ci  SetItemText(id, s);
644370b324cSopenharmony_ci}
645370b324cSopenharmony_ci
646370b324cSopenharmony_cistatic void GetChangedString(const UString &newStr, UString &prevStr, bool &hasChanged)
647370b324cSopenharmony_ci{
648370b324cSopenharmony_ci  hasChanged = !(prevStr == newStr);
649370b324cSopenharmony_ci  if (hasChanged)
650370b324cSopenharmony_ci    prevStr = newStr;
651370b324cSopenharmony_ci}
652370b324cSopenharmony_ci
653370b324cSopenharmony_cistatic unsigned GetPower32(UInt32 val)
654370b324cSopenharmony_ci{
655370b324cSopenharmony_ci  const unsigned kStart = 32;
656370b324cSopenharmony_ci  UInt32 mask = ((UInt32)1 << (kStart - 1));
657370b324cSopenharmony_ci  for (unsigned i = kStart;; i--)
658370b324cSopenharmony_ci  {
659370b324cSopenharmony_ci    if (i == 0 || (val & mask) != 0)
660370b324cSopenharmony_ci      return i;
661370b324cSopenharmony_ci    mask >>= 1;
662370b324cSopenharmony_ci  }
663370b324cSopenharmony_ci}
664370b324cSopenharmony_ci
665370b324cSopenharmony_cistatic unsigned GetPower64(UInt64 val)
666370b324cSopenharmony_ci{
667370b324cSopenharmony_ci  UInt32 high = (UInt32)(val >> 32);
668370b324cSopenharmony_ci  if (high == 0)
669370b324cSopenharmony_ci    return GetPower32((UInt32)val);
670370b324cSopenharmony_ci  return GetPower32(high) + 32;
671370b324cSopenharmony_ci}
672370b324cSopenharmony_ci
673370b324cSopenharmony_cistatic UInt64 MyMultAndDiv(UInt64 mult1, UInt64 mult2, UInt64 divider)
674370b324cSopenharmony_ci{
675370b324cSopenharmony_ci  unsigned pow1 = GetPower64(mult1);
676370b324cSopenharmony_ci  unsigned pow2 = GetPower64(mult2);
677370b324cSopenharmony_ci  while (pow1 + pow2 > 64)
678370b324cSopenharmony_ci  {
679370b324cSopenharmony_ci    if (pow1 > pow2) { pow1--; mult1 >>= 1; }
680370b324cSopenharmony_ci    else             { pow2--; mult2 >>= 1; }
681370b324cSopenharmony_ci    divider >>= 1;
682370b324cSopenharmony_ci  }
683370b324cSopenharmony_ci  UInt64 res = mult1 * mult2;
684370b324cSopenharmony_ci  if (divider != 0)
685370b324cSopenharmony_ci    res /= divider;
686370b324cSopenharmony_ci  return res;
687370b324cSopenharmony_ci}
688370b324cSopenharmony_ci
689370b324cSopenharmony_civoid CProgressDialog::UpdateStatInfo(bool showAll)
690370b324cSopenharmony_ci{
691370b324cSopenharmony_ci  UInt64 total, completed, totalFiles, completedFiles, inSize, outSize;
692370b324cSopenharmony_ci  bool bytesProgressMode;
693370b324cSopenharmony_ci
694370b324cSopenharmony_ci  bool titleFileName_Changed;
695370b324cSopenharmony_ci  bool curFilePath_Changed;
696370b324cSopenharmony_ci  bool status_Changed;
697370b324cSopenharmony_ci  unsigned numErrors;
698370b324cSopenharmony_ci  {
699370b324cSopenharmony_ci    NSynchronization::CCriticalSectionLock lock(Sync._cs);
700370b324cSopenharmony_ci    total = Sync._totalBytes;
701370b324cSopenharmony_ci    completed = Sync._completedBytes;
702370b324cSopenharmony_ci    totalFiles = Sync._totalFiles;
703370b324cSopenharmony_ci    completedFiles = Sync._curFiles;
704370b324cSopenharmony_ci    inSize = Sync._inSize;
705370b324cSopenharmony_ci    outSize = Sync._outSize;
706370b324cSopenharmony_ci    bytesProgressMode = Sync._bytesProgressMode;
707370b324cSopenharmony_ci
708370b324cSopenharmony_ci    GetChangedString(Sync._titleFileName, _titleFileName, titleFileName_Changed);
709370b324cSopenharmony_ci    GetChangedString(Sync._filePath, _filePath, curFilePath_Changed);
710370b324cSopenharmony_ci    GetChangedString(Sync._status, _status, status_Changed);
711370b324cSopenharmony_ci    if (_isDir != Sync._isDir)
712370b324cSopenharmony_ci    {
713370b324cSopenharmony_ci      curFilePath_Changed = true;
714370b324cSopenharmony_ci      _isDir = Sync._isDir;
715370b324cSopenharmony_ci    }
716370b324cSopenharmony_ci    numErrors = Sync.Messages.Size();
717370b324cSopenharmony_ci  }
718370b324cSopenharmony_ci
719370b324cSopenharmony_ci  UInt32 curTime = ::GetTickCount();
720370b324cSopenharmony_ci
721370b324cSopenharmony_ci  const UInt64 progressTotal = bytesProgressMode ? total : totalFiles;
722370b324cSopenharmony_ci  const UInt64 progressCompleted = bytesProgressMode ? completed : completedFiles;
723370b324cSopenharmony_ci  {
724370b324cSopenharmony_ci    if (IS_UNDEFINED_VAL(progressTotal))
725370b324cSopenharmony_ci    {
726370b324cSopenharmony_ci      // SetPos(0);
727370b324cSopenharmony_ci      // SetRange(progressCompleted);
728370b324cSopenharmony_ci    }
729370b324cSopenharmony_ci    else
730370b324cSopenharmony_ci    {
731370b324cSopenharmony_ci      if (_progressBar_Pos != 0 || progressCompleted != 0 ||
732370b324cSopenharmony_ci          (_progressBar_Range == 0 && progressTotal != 0))
733370b324cSopenharmony_ci      {
734370b324cSopenharmony_ci        SetProgressRange(progressTotal);
735370b324cSopenharmony_ci        SetProgressPos(progressCompleted);
736370b324cSopenharmony_ci      }
737370b324cSopenharmony_ci    }
738370b324cSopenharmony_ci  }
739370b324cSopenharmony_ci
740370b324cSopenharmony_ci  ShowSize(IDT_PROGRESS_TOTAL_VAL, total, _totalBytes_Prev);
741370b324cSopenharmony_ci
742370b324cSopenharmony_ci  _elapsedTime += (curTime - _prevTime);
743370b324cSopenharmony_ci  _prevTime = curTime;
744370b324cSopenharmony_ci  UInt64 elapsedSec = _elapsedTime / 1000;
745370b324cSopenharmony_ci  bool elapsedChanged = false;
746370b324cSopenharmony_ci  if (elapsedSec != _prevElapsedSec)
747370b324cSopenharmony_ci  {
748370b324cSopenharmony_ci    _prevElapsedSec = elapsedSec;
749370b324cSopenharmony_ci    elapsedChanged = true;
750370b324cSopenharmony_ci    wchar_t s[40];
751370b324cSopenharmony_ci    GetTimeString(elapsedSec, s);
752370b324cSopenharmony_ci    SetItemText(IDT_PROGRESS_ELAPSED_VAL, s);
753370b324cSopenharmony_ci  }
754370b324cSopenharmony_ci
755370b324cSopenharmony_ci  bool needSetTitle = false;
756370b324cSopenharmony_ci  if (elapsedChanged || showAll)
757370b324cSopenharmony_ci  {
758370b324cSopenharmony_ci    if (numErrors > _numPostedMessages)
759370b324cSopenharmony_ci    {
760370b324cSopenharmony_ci      UpdateMessagesDialog();
761370b324cSopenharmony_ci      wchar_t s[32];
762370b324cSopenharmony_ci      ConvertUInt64ToString(numErrors, s);
763370b324cSopenharmony_ci      SetItemText(IDT_PROGRESS_ERRORS_VAL, s);
764370b324cSopenharmony_ci      if (!_errorsWereDisplayed)
765370b324cSopenharmony_ci      {
766370b324cSopenharmony_ci        _errorsWereDisplayed = true;
767370b324cSopenharmony_ci        EnableErrorsControls(true);
768370b324cSopenharmony_ci        SetTaskbarProgressState();
769370b324cSopenharmony_ci      }
770370b324cSopenharmony_ci    }
771370b324cSopenharmony_ci
772370b324cSopenharmony_ci    if (progressCompleted != 0)
773370b324cSopenharmony_ci    {
774370b324cSopenharmony_ci      if (IS_UNDEFINED_VAL(progressTotal))
775370b324cSopenharmony_ci      {
776370b324cSopenharmony_ci        if (IS_DEFINED_VAL(_prevRemainingSec))
777370b324cSopenharmony_ci        {
778370b324cSopenharmony_ci          INIT_AS_UNDEFINED(_prevRemainingSec)
779370b324cSopenharmony_ci          SetItemText(IDT_PROGRESS_REMAINING_VAL, L"");
780370b324cSopenharmony_ci        }
781370b324cSopenharmony_ci      }
782370b324cSopenharmony_ci      else
783370b324cSopenharmony_ci      {
784370b324cSopenharmony_ci        UInt64 remainingTime = 0;
785370b324cSopenharmony_ci        if (progressCompleted < progressTotal)
786370b324cSopenharmony_ci          remainingTime = MyMultAndDiv(_elapsedTime, progressTotal - progressCompleted, progressCompleted);
787370b324cSopenharmony_ci        UInt64 remainingSec = remainingTime / 1000;
788370b324cSopenharmony_ci        if (remainingSec != _prevRemainingSec)
789370b324cSopenharmony_ci        {
790370b324cSopenharmony_ci          _prevRemainingSec = remainingSec;
791370b324cSopenharmony_ci          wchar_t s[40];
792370b324cSopenharmony_ci          GetTimeString(remainingSec, s);
793370b324cSopenharmony_ci          SetItemText(IDT_PROGRESS_REMAINING_VAL, s);
794370b324cSopenharmony_ci        }
795370b324cSopenharmony_ci      }
796370b324cSopenharmony_ci      {
797370b324cSopenharmony_ci        const UInt64 elapsedTime = (_elapsedTime == 0) ? 1 : _elapsedTime;
798370b324cSopenharmony_ci        // 22.02: progressCompleted can be for number of files
799370b324cSopenharmony_ci        UInt64 v = (completed * 1000) / elapsedTime;
800370b324cSopenharmony_ci        Byte c = 0;
801370b324cSopenharmony_ci        unsigned moveBits = 0;
802370b324cSopenharmony_ci             if (v >= ((UInt64)10000 << 10)) { moveBits = 20; c = 'M'; }
803370b324cSopenharmony_ci        else if (v >= ((UInt64)10000 <<  0)) { moveBits = 10; c = 'K'; }
804370b324cSopenharmony_ci        v >>= moveBits;
805370b324cSopenharmony_ci        if (moveBits != _prevSpeed_MoveBits || v != _prevSpeed)
806370b324cSopenharmony_ci        {
807370b324cSopenharmony_ci          _prevSpeed_MoveBits = moveBits;
808370b324cSopenharmony_ci          _prevSpeed = v;
809370b324cSopenharmony_ci          wchar_t s[40];
810370b324cSopenharmony_ci          ConvertUInt64ToString(v, s);
811370b324cSopenharmony_ci          unsigned pos = MyStringLen(s);
812370b324cSopenharmony_ci          s[pos++] = ' ';
813370b324cSopenharmony_ci          if (moveBits != 0)
814370b324cSopenharmony_ci            s[pos++] = c;
815370b324cSopenharmony_ci          s[pos++] = 'B';
816370b324cSopenharmony_ci          s[pos++] = '/';
817370b324cSopenharmony_ci          s[pos++] = 's';
818370b324cSopenharmony_ci          s[pos++] = 0;
819370b324cSopenharmony_ci          SetItemText(IDT_PROGRESS_SPEED_VAL, s);
820370b324cSopenharmony_ci        }
821370b324cSopenharmony_ci      }
822370b324cSopenharmony_ci    }
823370b324cSopenharmony_ci
824370b324cSopenharmony_ci    {
825370b324cSopenharmony_ci      UInt64 percent = 0;
826370b324cSopenharmony_ci      {
827370b324cSopenharmony_ci        if (IS_DEFINED_VAL(progressTotal))
828370b324cSopenharmony_ci        {
829370b324cSopenharmony_ci          percent = progressCompleted * 100;
830370b324cSopenharmony_ci          if (progressTotal != 0)
831370b324cSopenharmony_ci            percent /= progressTotal;
832370b324cSopenharmony_ci        }
833370b324cSopenharmony_ci      }
834370b324cSopenharmony_ci      if (percent != _prevPercentValue)
835370b324cSopenharmony_ci      {
836370b324cSopenharmony_ci        _prevPercentValue = percent;
837370b324cSopenharmony_ci        needSetTitle = true;
838370b324cSopenharmony_ci      }
839370b324cSopenharmony_ci    }
840370b324cSopenharmony_ci
841370b324cSopenharmony_ci    {
842370b324cSopenharmony_ci      wchar_t s[64];
843370b324cSopenharmony_ci
844370b324cSopenharmony_ci      ConvertUInt64ToString(completedFiles, s);
845370b324cSopenharmony_ci      if (_filesStr_Prev != s)
846370b324cSopenharmony_ci      {
847370b324cSopenharmony_ci        _filesStr_Prev = s;
848370b324cSopenharmony_ci        SetItemText(IDT_PROGRESS_FILES_VAL, s);
849370b324cSopenharmony_ci      }
850370b324cSopenharmony_ci
851370b324cSopenharmony_ci      s[0] = 0;
852370b324cSopenharmony_ci      if (IS_DEFINED_VAL(totalFiles))
853370b324cSopenharmony_ci      {
854370b324cSopenharmony_ci        MyStringCopy(s, L" / ");
855370b324cSopenharmony_ci        ConvertUInt64ToString(totalFiles, s + MyStringLen(s));
856370b324cSopenharmony_ci      }
857370b324cSopenharmony_ci      if (_filesTotStr_Prev != s)
858370b324cSopenharmony_ci      {
859370b324cSopenharmony_ci        _filesTotStr_Prev = s;
860370b324cSopenharmony_ci        SetItemText(IDT_PROGRESS_FILES_TOTAL, s);
861370b324cSopenharmony_ci      }
862370b324cSopenharmony_ci    }
863370b324cSopenharmony_ci
864370b324cSopenharmony_ci    const UInt64 packSize   = CompressingMode ? outSize : inSize;
865370b324cSopenharmony_ci    const UInt64 unpackSize = CompressingMode ? inSize : outSize;
866370b324cSopenharmony_ci
867370b324cSopenharmony_ci    if (IS_UNDEFINED_VAL(unpackSize) &&
868370b324cSopenharmony_ci        IS_UNDEFINED_VAL(packSize))
869370b324cSopenharmony_ci    {
870370b324cSopenharmony_ci      ShowSize(IDT_PROGRESS_PROCESSED_VAL, completed, _processed_Prev);
871370b324cSopenharmony_ci      ShowSize(IDT_PROGRESS_PACKED_VAL, UNDEFINED_VAL, _packed_Prev);
872370b324cSopenharmony_ci    }
873370b324cSopenharmony_ci    else
874370b324cSopenharmony_ci    {
875370b324cSopenharmony_ci      ShowSize(IDT_PROGRESS_PROCESSED_VAL, unpackSize, _processed_Prev);
876370b324cSopenharmony_ci      ShowSize(IDT_PROGRESS_PACKED_VAL, packSize, _packed_Prev);
877370b324cSopenharmony_ci
878370b324cSopenharmony_ci      if (IS_DEFINED_VAL(packSize) &&
879370b324cSopenharmony_ci          IS_DEFINED_VAL(unpackSize) &&
880370b324cSopenharmony_ci          unpackSize != 0)
881370b324cSopenharmony_ci      {
882370b324cSopenharmony_ci        wchar_t s[32];
883370b324cSopenharmony_ci        UInt64 ratio = packSize * 100 / unpackSize;
884370b324cSopenharmony_ci        if (_ratio_Prev != ratio)
885370b324cSopenharmony_ci        {
886370b324cSopenharmony_ci          _ratio_Prev = ratio;
887370b324cSopenharmony_ci          ConvertUInt64ToString(ratio, s);
888370b324cSopenharmony_ci          MyStringCat(s, L"%");
889370b324cSopenharmony_ci          SetItemText(IDT_PROGRESS_RATIO_VAL, s);
890370b324cSopenharmony_ci        }
891370b324cSopenharmony_ci      }
892370b324cSopenharmony_ci    }
893370b324cSopenharmony_ci  }
894370b324cSopenharmony_ci
895370b324cSopenharmony_ci  if (needSetTitle || titleFileName_Changed)
896370b324cSopenharmony_ci    SetTitleText();
897370b324cSopenharmony_ci
898370b324cSopenharmony_ci  if (status_Changed)
899370b324cSopenharmony_ci  {
900370b324cSopenharmony_ci    UString s = _status;
901370b324cSopenharmony_ci    ReduceString(s, _numReduceSymbols);
902370b324cSopenharmony_ci    SetItemText(IDT_PROGRESS_STATUS, _status);
903370b324cSopenharmony_ci  }
904370b324cSopenharmony_ci
905370b324cSopenharmony_ci  if (curFilePath_Changed)
906370b324cSopenharmony_ci  {
907370b324cSopenharmony_ci    UString s1, s2;
908370b324cSopenharmony_ci    if (_isDir)
909370b324cSopenharmony_ci      s1 = _filePath;
910370b324cSopenharmony_ci    else
911370b324cSopenharmony_ci    {
912370b324cSopenharmony_ci      int slashPos = _filePath.ReverseFind_PathSepar();
913370b324cSopenharmony_ci      if (slashPos >= 0)
914370b324cSopenharmony_ci      {
915370b324cSopenharmony_ci        s1.SetFrom(_filePath, (unsigned)(slashPos + 1));
916370b324cSopenharmony_ci        s2 = _filePath.Ptr((unsigned)(slashPos + 1));
917370b324cSopenharmony_ci      }
918370b324cSopenharmony_ci      else
919370b324cSopenharmony_ci        s2 = _filePath;
920370b324cSopenharmony_ci    }
921370b324cSopenharmony_ci    ReduceString(s1, _numReduceSymbols);
922370b324cSopenharmony_ci    ReduceString(s2, _numReduceSymbols);
923370b324cSopenharmony_ci    s1.Add_LF();
924370b324cSopenharmony_ci    s1 += s2;
925370b324cSopenharmony_ci    SetItemText(IDT_PROGRESS_FILE_NAME, s1);
926370b324cSopenharmony_ci  }
927370b324cSopenharmony_ci}
928370b324cSopenharmony_ci
929370b324cSopenharmony_cibool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
930370b324cSopenharmony_ci{
931370b324cSopenharmony_ci  if (Sync.Get_Paused())
932370b324cSopenharmony_ci    return true;
933370b324cSopenharmony_ci  CheckNeedClose();
934370b324cSopenharmony_ci  UpdateStatInfo(false);
935370b324cSopenharmony_ci  return true;
936370b324cSopenharmony_ci}
937370b324cSopenharmony_ci
938370b324cSopenharmony_cistruct CWaitCursor
939370b324cSopenharmony_ci{
940370b324cSopenharmony_ci  HCURSOR _waitCursor;
941370b324cSopenharmony_ci  HCURSOR _oldCursor;
942370b324cSopenharmony_ci  CWaitCursor()
943370b324cSopenharmony_ci  {
944370b324cSopenharmony_ci    _waitCursor = LoadCursor(NULL, IDC_WAIT);
945370b324cSopenharmony_ci    if (_waitCursor != NULL)
946370b324cSopenharmony_ci      _oldCursor = SetCursor(_waitCursor);
947370b324cSopenharmony_ci  }
948370b324cSopenharmony_ci  ~CWaitCursor()
949370b324cSopenharmony_ci  {
950370b324cSopenharmony_ci    if (_waitCursor != NULL)
951370b324cSopenharmony_ci      SetCursor(_oldCursor);
952370b324cSopenharmony_ci  }
953370b324cSopenharmony_ci};
954370b324cSopenharmony_ci
955370b324cSopenharmony_ciINT_PTR CProgressDialog::Create(const UString &title, NWindows::CThread &thread, HWND wndParent)
956370b324cSopenharmony_ci{
957370b324cSopenharmony_ci  INT_PTR res = 0;
958370b324cSopenharmony_ci  try
959370b324cSopenharmony_ci  {
960370b324cSopenharmony_ci    if (WaitMode)
961370b324cSopenharmony_ci    {
962370b324cSopenharmony_ci      CWaitCursor waitCursor;
963370b324cSopenharmony_ci      HANDLE h[] = { thread, _createDialogEvent };
964370b324cSopenharmony_ci
965370b324cSopenharmony_ci      const DWORD res2 = WaitForMultipleObjects(Z7_ARRAY_SIZE(h), h, FALSE, kCreateDelay);
966370b324cSopenharmony_ci      if (res2 == WAIT_OBJECT_0 && !Sync.ThereIsMessage())
967370b324cSopenharmony_ci        return 0;
968370b324cSopenharmony_ci    }
969370b324cSopenharmony_ci    _title = title;
970370b324cSopenharmony_ci    BIG_DIALOG_SIZE(360, 192);
971370b324cSopenharmony_ci    res = CModalDialog::Create(SIZED_DIALOG(IDD_PROGRESS), wndParent);
972370b324cSopenharmony_ci  }
973370b324cSopenharmony_ci  catch(...)
974370b324cSopenharmony_ci  {
975370b324cSopenharmony_ci    _wasCreated = true;
976370b324cSopenharmony_ci    _dialogCreatedEvent.Set();
977370b324cSopenharmony_ci  }
978370b324cSopenharmony_ci  thread.Wait_Close();
979370b324cSopenharmony_ci  if (!MessagesDisplayed)
980370b324cSopenharmony_ci    MessageBoxW(wndParent, L"Progress Error", L"7-Zip", MB_ICONERROR);
981370b324cSopenharmony_ci  return res;
982370b324cSopenharmony_ci}
983370b324cSopenharmony_ci
984370b324cSopenharmony_cibool CProgressDialog::OnExternalCloseMessage()
985370b324cSopenharmony_ci{
986370b324cSopenharmony_ci  // it doesn't work if there is MessageBox.
987370b324cSopenharmony_ci  // #ifdef __ITaskbarList3_INTERFACE_DEFINED__
988370b324cSopenharmony_ci  SetTaskbarProgressState(TBPF_NOPROGRESS);
989370b324cSopenharmony_ci  // #endif
990370b324cSopenharmony_ci  // AddToTitle(L"Finished ");
991370b324cSopenharmony_ci  // SetText(L"Finished2 ");
992370b324cSopenharmony_ci
993370b324cSopenharmony_ci  UpdateStatInfo(true);
994370b324cSopenharmony_ci
995370b324cSopenharmony_ci  SetItemText(IDCANCEL, LangString(IDS_CLOSE));
996370b324cSopenharmony_ci  ::SendMessage(GetItem(IDCANCEL), BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0));
997370b324cSopenharmony_ci  HideItem(IDB_PROGRESS_BACKGROUND);
998370b324cSopenharmony_ci  HideItem(IDB_PAUSE);
999370b324cSopenharmony_ci
1000370b324cSopenharmony_ci  ProcessWasFinished_GuiVirt();
1001370b324cSopenharmony_ci
1002370b324cSopenharmony_ci  bool thereAreMessages;
1003370b324cSopenharmony_ci  CProgressFinalMessage fm;
1004370b324cSopenharmony_ci  {
1005370b324cSopenharmony_ci    NSynchronization::CCriticalSectionLock lock(Sync._cs);
1006370b324cSopenharmony_ci    thereAreMessages = !Sync.Messages.IsEmpty();
1007370b324cSopenharmony_ci    fm = Sync.FinalMessage;
1008370b324cSopenharmony_ci  }
1009370b324cSopenharmony_ci
1010370b324cSopenharmony_ci  if (!fm.ErrorMessage.Message.IsEmpty())
1011370b324cSopenharmony_ci  {
1012370b324cSopenharmony_ci    MessagesDisplayed = true;
1013370b324cSopenharmony_ci    if (fm.ErrorMessage.Title.IsEmpty())
1014370b324cSopenharmony_ci      fm.ErrorMessage.Title = "7-Zip";
1015370b324cSopenharmony_ci    MessageBoxW(*this, fm.ErrorMessage.Message, fm.ErrorMessage.Title, MB_ICONERROR);
1016370b324cSopenharmony_ci  }
1017370b324cSopenharmony_ci  else if (!thereAreMessages)
1018370b324cSopenharmony_ci  {
1019370b324cSopenharmony_ci    MessagesDisplayed = true;
1020370b324cSopenharmony_ci
1021370b324cSopenharmony_ci    if (!fm.OkMessage.Message.IsEmpty())
1022370b324cSopenharmony_ci    {
1023370b324cSopenharmony_ci      if (fm.OkMessage.Title.IsEmpty())
1024370b324cSopenharmony_ci        fm.OkMessage.Title = "7-Zip";
1025370b324cSopenharmony_ci      MessageBoxW(*this, fm.OkMessage.Message, fm.OkMessage.Title, MB_OK);
1026370b324cSopenharmony_ci    }
1027370b324cSopenharmony_ci  }
1028370b324cSopenharmony_ci
1029370b324cSopenharmony_ci  if (thereAreMessages && !_cancelWasPressed)
1030370b324cSopenharmony_ci  {
1031370b324cSopenharmony_ci    _waitCloseByCancelButton = true;
1032370b324cSopenharmony_ci    UpdateMessagesDialog();
1033370b324cSopenharmony_ci    return true;
1034370b324cSopenharmony_ci  }
1035370b324cSopenharmony_ci
1036370b324cSopenharmony_ci  End(0);
1037370b324cSopenharmony_ci  return true;
1038370b324cSopenharmony_ci}
1039370b324cSopenharmony_ci
1040370b324cSopenharmony_cibool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
1041370b324cSopenharmony_ci{
1042370b324cSopenharmony_ci  switch (message)
1043370b324cSopenharmony_ci  {
1044370b324cSopenharmony_ci    case kCloseMessage:
1045370b324cSopenharmony_ci    {
1046370b324cSopenharmony_ci      if (_timer)
1047370b324cSopenharmony_ci      {
1048370b324cSopenharmony_ci        /* 21.03 : KillTimer(kTimerID) instead of KillTimer(_timer).
1049370b324cSopenharmony_ci           But (_timer == kTimerID) in Win10. So it worked too */
1050370b324cSopenharmony_ci        KillTimer(kTimerID);
1051370b324cSopenharmony_ci        _timer = 0;
1052370b324cSopenharmony_ci      }
1053370b324cSopenharmony_ci      if (_inCancelMessageBox)
1054370b324cSopenharmony_ci      {
1055370b324cSopenharmony_ci        /* if user is in MessageBox(), we will call OnExternalCloseMessage()
1056370b324cSopenharmony_ci           later, when MessageBox() will be closed */
1057370b324cSopenharmony_ci        _externalCloseMessageWasReceived = true;
1058370b324cSopenharmony_ci        break;
1059370b324cSopenharmony_ci      }
1060370b324cSopenharmony_ci      return OnExternalCloseMessage();
1061370b324cSopenharmony_ci    }
1062370b324cSopenharmony_ci    /*
1063370b324cSopenharmony_ci    case WM_SETTEXT:
1064370b324cSopenharmony_ci    {
1065370b324cSopenharmony_ci      if (_timer == 0)
1066370b324cSopenharmony_ci        return true;
1067370b324cSopenharmony_ci      break;
1068370b324cSopenharmony_ci    }
1069370b324cSopenharmony_ci    */
1070370b324cSopenharmony_ci  }
1071370b324cSopenharmony_ci  return CModalDialog::OnMessage(message, wParam, lParam);
1072370b324cSopenharmony_ci}
1073370b324cSopenharmony_ci
1074370b324cSopenharmony_civoid CProgressDialog::SetTitleText()
1075370b324cSopenharmony_ci{
1076370b324cSopenharmony_ci  UString s;
1077370b324cSopenharmony_ci  if (Sync.Get_Paused())
1078370b324cSopenharmony_ci  {
1079370b324cSopenharmony_ci    s += _paused_String;
1080370b324cSopenharmony_ci    s.Add_Space();
1081370b324cSopenharmony_ci  }
1082370b324cSopenharmony_ci  if (IS_DEFINED_VAL(_prevPercentValue))
1083370b324cSopenharmony_ci  {
1084370b324cSopenharmony_ci    char temp[32];
1085370b324cSopenharmony_ci    ConvertUInt64ToString(_prevPercentValue, temp);
1086370b324cSopenharmony_ci    s += temp;
1087370b324cSopenharmony_ci    s += '%';
1088370b324cSopenharmony_ci  }
1089370b324cSopenharmony_ci  if (!_foreground)
1090370b324cSopenharmony_ci  {
1091370b324cSopenharmony_ci    s.Add_Space();
1092370b324cSopenharmony_ci    s += _backgrounded_String;
1093370b324cSopenharmony_ci  }
1094370b324cSopenharmony_ci
1095370b324cSopenharmony_ci  s.Add_Space();
1096370b324cSopenharmony_ci  #ifndef Z7_SFX
1097370b324cSopenharmony_ci  {
1098370b324cSopenharmony_ci    unsigned len = s.Len();
1099370b324cSopenharmony_ci    s += MainAddTitle;
1100370b324cSopenharmony_ci    AddToTitle(s);
1101370b324cSopenharmony_ci    s.DeleteFrom(len);
1102370b324cSopenharmony_ci  }
1103370b324cSopenharmony_ci  #endif
1104370b324cSopenharmony_ci
1105370b324cSopenharmony_ci  s += _title;
1106370b324cSopenharmony_ci  if (!_titleFileName.IsEmpty())
1107370b324cSopenharmony_ci  {
1108370b324cSopenharmony_ci    UString fileName = _titleFileName;
1109370b324cSopenharmony_ci    ReduceString(fileName, kTitleFileNameSizeLimit);
1110370b324cSopenharmony_ci    s.Add_Space();
1111370b324cSopenharmony_ci    s += fileName;
1112370b324cSopenharmony_ci  }
1113370b324cSopenharmony_ci  SetText(s);
1114370b324cSopenharmony_ci}
1115370b324cSopenharmony_ci
1116370b324cSopenharmony_civoid CProgressDialog::SetPauseText()
1117370b324cSopenharmony_ci{
1118370b324cSopenharmony_ci  SetItemText(IDB_PAUSE, Sync.Get_Paused() ? _continue_String : _pause_String);
1119370b324cSopenharmony_ci  SetTitleText();
1120370b324cSopenharmony_ci}
1121370b324cSopenharmony_ci
1122370b324cSopenharmony_civoid CProgressDialog::OnPauseButton()
1123370b324cSopenharmony_ci{
1124370b324cSopenharmony_ci  bool paused = !Sync.Get_Paused();
1125370b324cSopenharmony_ci  Sync.Set_Paused(paused);
1126370b324cSopenharmony_ci  UInt32 curTime = ::GetTickCount();
1127370b324cSopenharmony_ci  if (paused)
1128370b324cSopenharmony_ci    _elapsedTime += (curTime - _prevTime);
1129370b324cSopenharmony_ci  SetTaskbarProgressState();
1130370b324cSopenharmony_ci  _prevTime = curTime;
1131370b324cSopenharmony_ci  SetPauseText();
1132370b324cSopenharmony_ci}
1133370b324cSopenharmony_ci
1134370b324cSopenharmony_civoid CProgressDialog::SetPriorityText()
1135370b324cSopenharmony_ci{
1136370b324cSopenharmony_ci  SetItemText(IDB_PROGRESS_BACKGROUND, _foreground ?
1137370b324cSopenharmony_ci      _background_String :
1138370b324cSopenharmony_ci      _foreground_String);
1139370b324cSopenharmony_ci  SetTitleText();
1140370b324cSopenharmony_ci}
1141370b324cSopenharmony_ci
1142370b324cSopenharmony_civoid CProgressDialog::OnPriorityButton()
1143370b324cSopenharmony_ci{
1144370b324cSopenharmony_ci  _foreground = !_foreground;
1145370b324cSopenharmony_ci  #ifndef UNDER_CE
1146370b324cSopenharmony_ci  SetPriorityClass(GetCurrentProcess(), _foreground ? NORMAL_PRIORITY_CLASS: IDLE_PRIORITY_CLASS);
1147370b324cSopenharmony_ci  #endif
1148370b324cSopenharmony_ci  SetPriorityText();
1149370b324cSopenharmony_ci}
1150370b324cSopenharmony_ci
1151370b324cSopenharmony_civoid CProgressDialog::AddMessageDirect(LPCWSTR message, bool needNumber)
1152370b324cSopenharmony_ci{
1153370b324cSopenharmony_ci  wchar_t sz[16];
1154370b324cSopenharmony_ci  sz[0] = 0;
1155370b324cSopenharmony_ci  if (needNumber)
1156370b324cSopenharmony_ci    ConvertUInt32ToString(_numMessages + 1, sz);
1157370b324cSopenharmony_ci  const unsigned itemIndex = _messageStrings.Size(); // _messageList.GetItemCount();
1158370b324cSopenharmony_ci  if (_messageList.InsertItem(itemIndex, sz) == (int)itemIndex)
1159370b324cSopenharmony_ci  {
1160370b324cSopenharmony_ci    _messageList.SetSubItem(itemIndex, 1, message);
1161370b324cSopenharmony_ci    _messageStrings.Add(message);
1162370b324cSopenharmony_ci  }
1163370b324cSopenharmony_ci}
1164370b324cSopenharmony_ci
1165370b324cSopenharmony_civoid CProgressDialog::AddMessage(LPCWSTR message)
1166370b324cSopenharmony_ci{
1167370b324cSopenharmony_ci  UString s = message;
1168370b324cSopenharmony_ci  bool needNumber = true;
1169370b324cSopenharmony_ci  while (!s.IsEmpty())
1170370b324cSopenharmony_ci  {
1171370b324cSopenharmony_ci    const int pos = s.Find(L'\n');
1172370b324cSopenharmony_ci    if (pos < 0)
1173370b324cSopenharmony_ci      break;
1174370b324cSopenharmony_ci    AddMessageDirect(s.Left((unsigned)pos), needNumber);
1175370b324cSopenharmony_ci    needNumber = false;
1176370b324cSopenharmony_ci    s.DeleteFrontal((unsigned)pos + 1);
1177370b324cSopenharmony_ci  }
1178370b324cSopenharmony_ci  AddMessageDirect(s, needNumber);
1179370b324cSopenharmony_ci  _numMessages++;
1180370b324cSopenharmony_ci}
1181370b324cSopenharmony_ci
1182370b324cSopenharmony_cistatic unsigned GetNumDigits(UInt32 val)
1183370b324cSopenharmony_ci{
1184370b324cSopenharmony_ci  unsigned i;
1185370b324cSopenharmony_ci  for (i = 0; val >= 10; i++)
1186370b324cSopenharmony_ci    val /= 10;
1187370b324cSopenharmony_ci  return i;
1188370b324cSopenharmony_ci}
1189370b324cSopenharmony_ci
1190370b324cSopenharmony_civoid CProgressDialog::UpdateMessagesDialog()
1191370b324cSopenharmony_ci{
1192370b324cSopenharmony_ci  UStringVector messages;
1193370b324cSopenharmony_ci  {
1194370b324cSopenharmony_ci    NSynchronization::CCriticalSectionLock lock(Sync._cs);
1195370b324cSopenharmony_ci    unsigned num = Sync.Messages.Size();
1196370b324cSopenharmony_ci    if (num > _numPostedMessages)
1197370b324cSopenharmony_ci    {
1198370b324cSopenharmony_ci      messages.ClearAndReserve(num - _numPostedMessages);
1199370b324cSopenharmony_ci      for (unsigned i = _numPostedMessages; i < num; i++)
1200370b324cSopenharmony_ci        messages.AddInReserved(Sync.Messages[i]);
1201370b324cSopenharmony_ci      _numPostedMessages = num;
1202370b324cSopenharmony_ci    }
1203370b324cSopenharmony_ci  }
1204370b324cSopenharmony_ci  if (!messages.IsEmpty())
1205370b324cSopenharmony_ci  {
1206370b324cSopenharmony_ci    FOR_VECTOR (i, messages)
1207370b324cSopenharmony_ci      AddMessage(messages[i]);
1208370b324cSopenharmony_ci    if (_numAutoSizeMessages < 256 || GetNumDigits(_numPostedMessages) > GetNumDigits(_numAutoSizeMessages))
1209370b324cSopenharmony_ci    {
1210370b324cSopenharmony_ci      _messageList.SetColumnWidthAuto(0);
1211370b324cSopenharmony_ci      _messageList.SetColumnWidthAuto(1);
1212370b324cSopenharmony_ci      _numAutoSizeMessages = _numPostedMessages;
1213370b324cSopenharmony_ci    }
1214370b324cSopenharmony_ci  }
1215370b324cSopenharmony_ci}
1216370b324cSopenharmony_ci
1217370b324cSopenharmony_ci
1218370b324cSopenharmony_cibool CProgressDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND)
1219370b324cSopenharmony_ci{
1220370b324cSopenharmony_ci  switch (buttonID)
1221370b324cSopenharmony_ci  {
1222370b324cSopenharmony_ci    // case IDOK: // if IDCANCEL is not DEFPUSHBUTTON
1223370b324cSopenharmony_ci    case IDCANCEL:
1224370b324cSopenharmony_ci    {
1225370b324cSopenharmony_ci      if (_waitCloseByCancelButton)
1226370b324cSopenharmony_ci      {
1227370b324cSopenharmony_ci        MessagesDisplayed = true;
1228370b324cSopenharmony_ci        End(IDCLOSE);
1229370b324cSopenharmony_ci        break;
1230370b324cSopenharmony_ci      }
1231370b324cSopenharmony_ci
1232370b324cSopenharmony_ci      if (_cancelWasPressed)
1233370b324cSopenharmony_ci        return true;
1234370b324cSopenharmony_ci
1235370b324cSopenharmony_ci      const bool paused = Sync.Get_Paused();
1236370b324cSopenharmony_ci
1237370b324cSopenharmony_ci      if (!paused)
1238370b324cSopenharmony_ci      {
1239370b324cSopenharmony_ci        OnPauseButton();
1240370b324cSopenharmony_ci      }
1241370b324cSopenharmony_ci
1242370b324cSopenharmony_ci      _inCancelMessageBox = true;
1243370b324cSopenharmony_ci      const int res = ::MessageBoxW(*this, LangString(IDS_PROGRESS_ASK_CANCEL), _title, MB_YESNOCANCEL);
1244370b324cSopenharmony_ci      _inCancelMessageBox = false;
1245370b324cSopenharmony_ci      if (res == IDYES)
1246370b324cSopenharmony_ci        _cancelWasPressed = true;
1247370b324cSopenharmony_ci
1248370b324cSopenharmony_ci      if (!paused)
1249370b324cSopenharmony_ci      {
1250370b324cSopenharmony_ci        OnPauseButton();
1251370b324cSopenharmony_ci      }
1252370b324cSopenharmony_ci
1253370b324cSopenharmony_ci      if (_externalCloseMessageWasReceived)
1254370b324cSopenharmony_ci      {
1255370b324cSopenharmony_ci        /* we have received kCloseMessage while we were in MessageBoxW().
1256370b324cSopenharmony_ci           so we call OnExternalCloseMessage() here.
1257370b324cSopenharmony_ci           it can show MessageBox and it can close dialog */
1258370b324cSopenharmony_ci        OnExternalCloseMessage();
1259370b324cSopenharmony_ci        return true;
1260370b324cSopenharmony_ci      }
1261370b324cSopenharmony_ci
1262370b324cSopenharmony_ci      if (!_cancelWasPressed)
1263370b324cSopenharmony_ci        return true;
1264370b324cSopenharmony_ci
1265370b324cSopenharmony_ci      MessagesDisplayed = true;
1266370b324cSopenharmony_ci      // we will call Sync.Set_Stopped(true) in OnButtonClicked() : OnCancel()
1267370b324cSopenharmony_ci      break;
1268370b324cSopenharmony_ci    }
1269370b324cSopenharmony_ci
1270370b324cSopenharmony_ci    case IDB_PAUSE:
1271370b324cSopenharmony_ci      OnPauseButton();
1272370b324cSopenharmony_ci      return true;
1273370b324cSopenharmony_ci    case IDB_PROGRESS_BACKGROUND:
1274370b324cSopenharmony_ci      OnPriorityButton();
1275370b324cSopenharmony_ci      return true;
1276370b324cSopenharmony_ci  }
1277370b324cSopenharmony_ci  return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
1278370b324cSopenharmony_ci}
1279370b324cSopenharmony_ci
1280370b324cSopenharmony_civoid CProgressDialog::CheckNeedClose()
1281370b324cSopenharmony_ci{
1282370b324cSopenharmony_ci  if (_needClose)
1283370b324cSopenharmony_ci  {
1284370b324cSopenharmony_ci    PostMsg(kCloseMessage);
1285370b324cSopenharmony_ci    _needClose = false;
1286370b324cSopenharmony_ci  }
1287370b324cSopenharmony_ci}
1288370b324cSopenharmony_ci
1289370b324cSopenharmony_civoid CProgressDialog::ProcessWasFinished()
1290370b324cSopenharmony_ci{
1291370b324cSopenharmony_ci  // Set Window title here.
1292370b324cSopenharmony_ci  if (!WaitMode)
1293370b324cSopenharmony_ci    WaitCreating();
1294370b324cSopenharmony_ci
1295370b324cSopenharmony_ci  if (_wasCreated)
1296370b324cSopenharmony_ci    PostMsg(kCloseMessage);
1297370b324cSopenharmony_ci  else
1298370b324cSopenharmony_ci    _needClose = true;
1299370b324cSopenharmony_ci}
1300370b324cSopenharmony_ci
1301370b324cSopenharmony_ci
1302370b324cSopenharmony_cibool CProgressDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
1303370b324cSopenharmony_ci{
1304370b324cSopenharmony_ci  if (header->hwndFrom != _messageList)
1305370b324cSopenharmony_ci    return false;
1306370b324cSopenharmony_ci  switch (header->code)
1307370b324cSopenharmony_ci  {
1308370b324cSopenharmony_ci    case LVN_KEYDOWN:
1309370b324cSopenharmony_ci    {
1310370b324cSopenharmony_ci      LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header);
1311370b324cSopenharmony_ci      switch (keyDownInfo->wVKey)
1312370b324cSopenharmony_ci      {
1313370b324cSopenharmony_ci        case 'A':
1314370b324cSopenharmony_ci        {
1315370b324cSopenharmony_ci          if (IsKeyDown(VK_CONTROL))
1316370b324cSopenharmony_ci          {
1317370b324cSopenharmony_ci            _messageList.SelectAll();
1318370b324cSopenharmony_ci            return true;
1319370b324cSopenharmony_ci          }
1320370b324cSopenharmony_ci          break;
1321370b324cSopenharmony_ci        }
1322370b324cSopenharmony_ci        case VK_INSERT:
1323370b324cSopenharmony_ci        case 'C':
1324370b324cSopenharmony_ci        {
1325370b324cSopenharmony_ci          if (IsKeyDown(VK_CONTROL))
1326370b324cSopenharmony_ci          {
1327370b324cSopenharmony_ci            CopyToClipboard();
1328370b324cSopenharmony_ci            return true;
1329370b324cSopenharmony_ci          }
1330370b324cSopenharmony_ci          break;
1331370b324cSopenharmony_ci        }
1332370b324cSopenharmony_ci      }
1333370b324cSopenharmony_ci    }
1334370b324cSopenharmony_ci  }
1335370b324cSopenharmony_ci  return false;
1336370b324cSopenharmony_ci}
1337370b324cSopenharmony_ci
1338370b324cSopenharmony_ci
1339370b324cSopenharmony_cistatic void ListView_GetSelected(NControl::CListView &listView, CUIntVector &vector)
1340370b324cSopenharmony_ci{
1341370b324cSopenharmony_ci  vector.Clear();
1342370b324cSopenharmony_ci  int index = -1;
1343370b324cSopenharmony_ci  for (;;)
1344370b324cSopenharmony_ci  {
1345370b324cSopenharmony_ci    index = listView.GetNextSelectedItem(index);
1346370b324cSopenharmony_ci    if (index < 0)
1347370b324cSopenharmony_ci      break;
1348370b324cSopenharmony_ci    vector.Add((unsigned)index);
1349370b324cSopenharmony_ci  }
1350370b324cSopenharmony_ci}
1351370b324cSopenharmony_ci
1352370b324cSopenharmony_ci
1353370b324cSopenharmony_civoid CProgressDialog::CopyToClipboard()
1354370b324cSopenharmony_ci{
1355370b324cSopenharmony_ci  CUIntVector indexes;
1356370b324cSopenharmony_ci  ListView_GetSelected(_messageList, indexes);
1357370b324cSopenharmony_ci  UString s;
1358370b324cSopenharmony_ci  unsigned numIndexes = indexes.Size();
1359370b324cSopenharmony_ci  if (numIndexes == 0)
1360370b324cSopenharmony_ci    numIndexes = (unsigned)_messageList.GetItemCount();
1361370b324cSopenharmony_ci
1362370b324cSopenharmony_ci  for (unsigned i = 0; i < numIndexes; i++)
1363370b324cSopenharmony_ci  {
1364370b324cSopenharmony_ci    const unsigned index = (i < indexes.Size() ? indexes[i] : i);
1365370b324cSopenharmony_ci    // s.Add_UInt32(index);
1366370b324cSopenharmony_ci    // s += ": ";
1367370b324cSopenharmony_ci    s += _messageStrings[index];
1368370b324cSopenharmony_ci    {
1369370b324cSopenharmony_ci      s +=
1370370b324cSopenharmony_ci        #ifdef _WIN32
1371370b324cSopenharmony_ci          "\r\n"
1372370b324cSopenharmony_ci        #else
1373370b324cSopenharmony_ci          "\n"
1374370b324cSopenharmony_ci        #endif
1375370b324cSopenharmony_ci        ;
1376370b324cSopenharmony_ci    }
1377370b324cSopenharmony_ci  }
1378370b324cSopenharmony_ci
1379370b324cSopenharmony_ci  ClipboardSetText(*this, s);
1380370b324cSopenharmony_ci}
1381370b324cSopenharmony_ci
1382370b324cSopenharmony_ci
1383370b324cSopenharmony_cistatic THREAD_FUNC_DECL MyThreadFunction(void *param)
1384370b324cSopenharmony_ci{
1385370b324cSopenharmony_ci  CProgressThreadVirt *p = (CProgressThreadVirt *)param;
1386370b324cSopenharmony_ci  try
1387370b324cSopenharmony_ci  {
1388370b324cSopenharmony_ci    p->Process();
1389370b324cSopenharmony_ci    p->ThreadFinishedOK = true;
1390370b324cSopenharmony_ci  }
1391370b324cSopenharmony_ci  catch (...) { p->Result = E_FAIL; }
1392370b324cSopenharmony_ci  return 0;
1393370b324cSopenharmony_ci}
1394370b324cSopenharmony_ci
1395370b324cSopenharmony_ci
1396370b324cSopenharmony_ciHRESULT CProgressThreadVirt::Create(const UString &title, HWND parentWindow)
1397370b324cSopenharmony_ci{
1398370b324cSopenharmony_ci  NWindows::CThread thread;
1399370b324cSopenharmony_ci  const WRes wres = thread.Create(MyThreadFunction, this);
1400370b324cSopenharmony_ci  if (wres != 0)
1401370b324cSopenharmony_ci    return HRESULT_FROM_WIN32(wres);
1402370b324cSopenharmony_ci  CProgressDialog::Create(title, thread, parentWindow);
1403370b324cSopenharmony_ci  return S_OK;
1404370b324cSopenharmony_ci}
1405370b324cSopenharmony_ci
1406370b324cSopenharmony_cistatic void AddMessageToString(UString &dest, const UString &src)
1407370b324cSopenharmony_ci{
1408370b324cSopenharmony_ci  if (!src.IsEmpty())
1409370b324cSopenharmony_ci  {
1410370b324cSopenharmony_ci    if (!dest.IsEmpty())
1411370b324cSopenharmony_ci      dest.Add_LF();
1412370b324cSopenharmony_ci    dest += src;
1413370b324cSopenharmony_ci  }
1414370b324cSopenharmony_ci}
1415370b324cSopenharmony_ci
1416370b324cSopenharmony_civoid CProgressThreadVirt::Process()
1417370b324cSopenharmony_ci{
1418370b324cSopenharmony_ci  CProgressCloser closer(*this);
1419370b324cSopenharmony_ci  UString m;
1420370b324cSopenharmony_ci  try { Result = ProcessVirt(); }
1421370b324cSopenharmony_ci  catch(const wchar_t *s) { m = s; }
1422370b324cSopenharmony_ci  catch(const UString &s) { m = s; }
1423370b324cSopenharmony_ci  catch(const char *s) { m = GetUnicodeString(s); }
1424370b324cSopenharmony_ci  catch(int v)
1425370b324cSopenharmony_ci  {
1426370b324cSopenharmony_ci    m = "Error #";
1427370b324cSopenharmony_ci    m.Add_UInt32((unsigned)v);
1428370b324cSopenharmony_ci  }
1429370b324cSopenharmony_ci  catch(...) { m = "Error"; }
1430370b324cSopenharmony_ci  if (Result != E_ABORT)
1431370b324cSopenharmony_ci  {
1432370b324cSopenharmony_ci    if (m.IsEmpty() && Result != S_OK)
1433370b324cSopenharmony_ci      m = HResultToMessage(Result);
1434370b324cSopenharmony_ci  }
1435370b324cSopenharmony_ci  AddMessageToString(m, FinalMessage.ErrorMessage.Message);
1436370b324cSopenharmony_ci
1437370b324cSopenharmony_ci  {
1438370b324cSopenharmony_ci    FOR_VECTOR(i, ErrorPaths)
1439370b324cSopenharmony_ci    {
1440370b324cSopenharmony_ci      if (i >= 32)
1441370b324cSopenharmony_ci        break;
1442370b324cSopenharmony_ci      AddMessageToString(m, fs2us(ErrorPaths[i]));
1443370b324cSopenharmony_ci    }
1444370b324cSopenharmony_ci  }
1445370b324cSopenharmony_ci
1446370b324cSopenharmony_ci  CProgressSync &sync = Sync;
1447370b324cSopenharmony_ci  NSynchronization::CCriticalSectionLock lock(sync._cs);
1448370b324cSopenharmony_ci  if (m.IsEmpty())
1449370b324cSopenharmony_ci  {
1450370b324cSopenharmony_ci    if (!FinalMessage.OkMessage.Message.IsEmpty())
1451370b324cSopenharmony_ci      sync.FinalMessage.OkMessage = FinalMessage.OkMessage;
1452370b324cSopenharmony_ci  }
1453370b324cSopenharmony_ci  else
1454370b324cSopenharmony_ci  {
1455370b324cSopenharmony_ci    sync.FinalMessage.ErrorMessage.Message = m;
1456370b324cSopenharmony_ci    if (Result == S_OK)
1457370b324cSopenharmony_ci      Result = E_FAIL;
1458370b324cSopenharmony_ci  }
1459370b324cSopenharmony_ci}
1460370b324cSopenharmony_ci
1461370b324cSopenharmony_ciUString HResultToMessage(HRESULT errorCode)
1462370b324cSopenharmony_ci{
1463370b324cSopenharmony_ci  if (errorCode == E_OUTOFMEMORY)
1464370b324cSopenharmony_ci    return LangString(IDS_MEM_ERROR);
1465370b324cSopenharmony_ci  else
1466370b324cSopenharmony_ci    return NError::MyFormatMessage(errorCode);
1467370b324cSopenharmony_ci}
1468