// ProgressDialog2.h | |
#ifndef __PROGRESS_DIALOG_2_H | |
#define __PROGRESS_DIALOG_2_H | |
#include "../../../Common/MyCom.h" | |
#include "../../../Windows/ErrorMsg.h" | |
#include "../../../Windows/Synchronization.h" | |
#include "../../../Windows/Thread.h" | |
#include "../../../Windows/Control/Dialog.h" | |
#include "../../../Windows/Control/ListView.h" | |
#include "../../../Windows/Control/ProgressBar.h" | |
#include "MyWindowsNew.h" | |
struct CProgressMessageBoxPair | |
{ | |
UString Title; | |
UString Message; | |
}; | |
struct CProgressFinalMessage | |
{ | |
CProgressMessageBoxPair ErrorMessage; | |
CProgressMessageBoxPair OkMessage; | |
bool ThereIsMessage() const { return !ErrorMessage.Message.IsEmpty() || !OkMessage.Message.IsEmpty(); } | |
}; | |
class CProgressSync | |
{ | |
bool _stopped; | |
bool _paused; | |
public: | |
bool _bytesProgressMode; | |
UInt64 _totalBytes; | |
UInt64 _completedBytes; | |
UInt64 _totalFiles; | |
UInt64 _curFiles; | |
UInt64 _inSize; | |
UInt64 _outSize; | |
UString _titleFileName; | |
UString _status; | |
UString _filePath; | |
bool _isDir; | |
UStringVector Messages; | |
CProgressFinalMessage FinalMessage; | |
NWindows::NSynchronization::CCriticalSection _cs; | |
CProgressSync(); | |
bool Get_Stopped() | |
{ | |
NWindows::NSynchronization::CCriticalSectionLock lock(_cs); | |
return _stopped; | |
} | |
void Set_Stopped(bool val) | |
{ | |
NWindows::NSynchronization::CCriticalSectionLock lock(_cs); | |
_stopped = val; | |
} | |
bool Get_Paused(); | |
void Set_Paused(bool val) | |
{ | |
NWindows::NSynchronization::CCriticalSectionLock lock(_cs); | |
_paused = val; | |
} | |
void Set_BytesProgressMode(bool bytesProgressMode) | |
{ | |
NWindows::NSynchronization::CCriticalSectionLock lock(_cs); | |
_bytesProgressMode = bytesProgressMode; | |
} | |
HRESULT CheckStop(); | |
HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const UString &fileName, bool isDir = false); | |
void Set_NumFilesTotal(UInt64 val); | |
void Set_NumBytesTotal(UInt64 val); | |
void Set_NumFilesCur(UInt64 val); | |
HRESULT Set_NumBytesCur(const UInt64 *val); | |
HRESULT Set_NumBytesCur(UInt64 val); | |
void Set_Ratio(const UInt64 *inSize, const UInt64 *outSize); | |
void Set_TitleFileName(const UString &fileName); | |
void Set_Status(const UString &s); | |
void Set_FilePath(const UString &path, bool isDir = false); | |
void AddError_Message(const wchar_t *message); | |
void AddError_Message_Name(const wchar_t *message, const wchar_t *name); | |
void AddError_Code_Name(DWORD systemError, const wchar_t *name); | |
bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); } | |
}; | |
class CProgressDialog: public NWindows::NControl::CModalDialog | |
{ | |
UString _titleFileName; | |
UString _filePath; | |
UString _status; | |
bool _isDir; | |
UString _background_String; | |
UString _backgrounded_String; | |
UString _foreground_String; | |
UString _pause_String; | |
UString _continue_String; | |
UString _paused_String; | |
int _buttonSizeX; | |
int _buttonSizeY; | |
UINT_PTR _timer; | |
UString _title; | |
class CU64ToI32Converter | |
{ | |
unsigned _numShiftBits; | |
UInt64 _range; | |
public: | |
CU64ToI32Converter(): _numShiftBits(0), _range(1) {} | |
void Init(UInt64 range) | |
{ | |
_range = range; | |
// Windows CE doesn't like big number for ProgressBar. | |
for (_numShiftBits = 0; range >= ((UInt32)1 << 15); _numShiftBits++) | |
range >>= 1; | |
} | |
int Count(UInt64 val) | |
{ | |
int res = (int)(val >> _numShiftBits); | |
if (val == _range) | |
res++; | |
return res; | |
} | |
}; | |
CU64ToI32Converter _progressConv; | |
UInt64 _progressBar_Pos; | |
UInt64 _progressBar_Range; | |
NWindows::NControl::CProgressBar m_ProgressBar; | |
NWindows::NControl::CListView _messageList; | |
int _numMessages; | |
#ifdef __ITaskbarList3_INTERFACE_DEFINED__ | |
CMyComPtr<ITaskbarList3> _taskbarList; | |
#endif | |
HWND _hwndForTaskbar; | |
UInt32 _prevTime; | |
UInt64 _elapsedTime; | |
UInt64 _prevPercentValue; | |
UInt64 _prevElapsedSec; | |
UInt64 _prevRemainingSec; | |
UInt64 _totalBytes_Prev; | |
UInt64 _processed_Prev; | |
UInt64 _packed_Prev; | |
UInt64 _ratio_Prev; | |
UString _filesStr_Prev; | |
unsigned _prevSpeed_MoveBits; | |
UInt64 _prevSpeed; | |
bool _foreground; | |
unsigned _numReduceSymbols; | |
bool _wasCreated; | |
bool _needClose; | |
unsigned _numPostedMessages; | |
UInt32 _numAutoSizeMessages; | |
bool _errorsWereDisplayed; | |
bool _waitCloseByCancelButton; | |
bool _cancelWasPressed; | |
bool _inCancelMessageBox; | |
bool _externalCloseMessageWasReceived; | |
#ifdef __ITaskbarList3_INTERFACE_DEFINED__ | |
void SetTaskbarProgressState(TBPFLAG tbpFlags) | |
{ | |
if (_taskbarList && _hwndForTaskbar) | |
_taskbarList->SetProgressState(_hwndForTaskbar, tbpFlags); | |
} | |
#endif | |
void SetTaskbarProgressState(); | |
void UpdateStatInfo(bool showAll); | |
bool OnTimer(WPARAM timerID, LPARAM callback); | |
void SetProgressRange(UInt64 range); | |
void SetProgressPos(UInt64 pos); | |
virtual bool OnInit(); | |
virtual bool OnSize(WPARAM wParam, int xSize, int ySize); | |
virtual void OnCancel(); | |
virtual void OnOK(); | |
NWindows::NSynchronization::CManualResetEvent _createDialogEvent; | |
NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; | |
#ifndef _SFX | |
void AddToTitle(LPCWSTR string); | |
#endif | |
void SetPauseText(); | |
void SetPriorityText(); | |
void OnPauseButton(); | |
void OnPriorityButton(); | |
bool OnButtonClicked(int buttonID, HWND buttonHWND); | |
bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); | |
void SetTitleText(); | |
void ShowSize(int id, UInt64 val, UInt64 &prev); | |
void UpdateMessagesDialog(); | |
void AddMessageDirect(LPCWSTR message, bool needNumber); | |
void AddMessage(LPCWSTR message); | |
bool OnExternalCloseMessage(); | |
void EnableErrorsControls(bool enable); | |
void ShowAfterMessages(HWND wndParent); | |
void CheckNeedClose(); | |
public: | |
CProgressSync Sync; | |
bool CompressingMode; | |
bool WaitMode; | |
bool ShowCompressionInfo; | |
bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages. | |
int IconID; | |
HWND MainWindow; | |
#ifndef _SFX | |
UString MainTitle; | |
UString MainAddTitle; | |
~CProgressDialog(); | |
#endif | |
CProgressDialog(); | |
void WaitCreating() | |
{ | |
_createDialogEvent.Set(); | |
_dialogCreatedEvent.Lock(); | |
} | |
INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0); | |
void ProcessWasFinished(); | |
}; | |
class CProgressCloser | |
{ | |
CProgressDialog *_p; | |
public: | |
CProgressCloser(CProgressDialog &p) : _p(&p) {} | |
~CProgressCloser() { _p->ProcessWasFinished(); } | |
}; | |
class CProgressThreadVirt | |
{ | |
FString ErrorPath1; | |
FString ErrorPath2; | |
protected: | |
CProgressFinalMessage FinalMessage; | |
// error if any of HRESULT, ErrorMessage, ErrorPath | |
virtual HRESULT ProcessVirt() = 0; | |
void Process(); | |
public: | |
HRESULT Result; | |
bool ThreadFinishedOK; // if there is no fatal exception | |
CProgressDialog ProgressDialog; | |
static THREAD_FUNC_DECL MyThreadFunction(void *param) | |
{ | |
CProgressThreadVirt *p = (CProgressThreadVirt *)param; | |
try | |
{ | |
p->Process(); | |
p->ThreadFinishedOK = true; | |
} | |
catch (...) { p->Result = E_FAIL; } | |
return 0; | |
} | |
void SetErrorPath1(const FString &path) { ErrorPath1 = path; } | |
void SetErrorPath2(const FString &path) { ErrorPath2 = path; } | |
HRESULT Create(const UString &title, HWND parentWindow = 0); | |
CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {} | |
CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; } | |
}; | |
UString HResultToMessage(HRESULT errorCode); | |
#endif |