Home | History | Annotate | Download | only in FileManager
      1 // ProgressDialog2.h
      2 
      3 #ifndef __PROGRESS_DIALOG_2_H
      4 #define __PROGRESS_DIALOG_2_H
      5 
      6 #include "../../../Common/MyCom.h"
      7 
      8 #include "../../../Windows/ErrorMsg.h"
      9 #include "../../../Windows/Synchronization.h"
     10 #include "../../../Windows/Thread.h"
     11 
     12 #include "../../../Windows/Control/Dialog.h"
     13 #include "../../../Windows/Control/ListView.h"
     14 #include "../../../Windows/Control/ProgressBar.h"
     15 
     16 #include "MyWindowsNew.h"
     17 
     18 struct CProgressMessageBoxPair
     19 {
     20   UString Title;
     21   UString Message;
     22 };
     23 
     24 struct CProgressFinalMessage
     25 {
     26   CProgressMessageBoxPair ErrorMessage;
     27   CProgressMessageBoxPair OkMessage;
     28 
     29   bool ThereIsMessage() const { return !ErrorMessage.Message.IsEmpty() || !OkMessage.Message.IsEmpty(); }
     30 };
     31 
     32 class CProgressSync
     33 {
     34   bool _stopped;
     35   bool _paused;
     36 
     37 public:
     38   bool _bytesProgressMode;
     39   UInt64 _totalBytes;
     40   UInt64 _completedBytes;
     41   UInt64 _totalFiles;
     42   UInt64 _curFiles;
     43   UInt64 _inSize;
     44   UInt64 _outSize;
     45 
     46   UString _titleFileName;
     47   UString _status;
     48   UString _filePath;
     49   bool _isDir;
     50 
     51   UStringVector Messages;
     52   CProgressFinalMessage FinalMessage;
     53 
     54   NWindows::NSynchronization::CCriticalSection _cs;
     55 
     56   CProgressSync();
     57 
     58   bool Get_Stopped()
     59   {
     60     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
     61     return _stopped;
     62   }
     63   void Set_Stopped(bool val)
     64   {
     65     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
     66     _stopped = val;
     67   }
     68 
     69   bool Get_Paused();
     70   void Set_Paused(bool val)
     71   {
     72     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
     73     _paused = val;
     74   }
     75 
     76   void Set_BytesProgressMode(bool bytesProgressMode)
     77   {
     78     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
     79     _bytesProgressMode = bytesProgressMode;
     80   }
     81 
     82   HRESULT CheckStop();
     83   HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const UString &fileName, bool isDir = false);
     84 
     85   void Set_NumFilesTotal(UInt64 val);
     86   void Set_NumBytesTotal(UInt64 val);
     87   void Set_NumFilesCur(UInt64 val);
     88   HRESULT Set_NumBytesCur(const UInt64 *val);
     89   HRESULT Set_NumBytesCur(UInt64 val);
     90   void Set_Ratio(const UInt64 *inSize, const UInt64 *outSize);
     91 
     92   void Set_TitleFileName(const UString &fileName);
     93   void Set_Status(const UString &s);
     94   void Set_FilePath(const UString &path, bool isDir = false);
     95 
     96   void AddError_Message(const wchar_t *message);
     97   void AddError_Message_Name(const wchar_t *message, const wchar_t *name);
     98   void AddError_Code_Name(DWORD systemError, const wchar_t *name);
     99 
    100   bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); }
    101 };
    102 
    103 class CProgressDialog: public NWindows::NControl::CModalDialog
    104 {
    105   UString _titleFileName;
    106   UString _filePath;
    107   UString _status;
    108   bool _isDir;
    109 
    110   UString _background_String;
    111   UString _backgrounded_String;
    112   UString _foreground_String;
    113   UString _pause_String;
    114   UString _continue_String;
    115   UString _paused_String;
    116 
    117   int _buttonSizeX;
    118   int _buttonSizeY;
    119 
    120   UINT_PTR _timer;
    121 
    122   UString _title;
    123 
    124   class CU64ToI32Converter
    125   {
    126     unsigned _numShiftBits;
    127     UInt64 _range;
    128   public:
    129     CU64ToI32Converter(): _numShiftBits(0), _range(1) {}
    130     void Init(UInt64 range)
    131     {
    132       _range = range;
    133       // Windows CE doesn't like big number for ProgressBar.
    134       for (_numShiftBits = 0; range >= ((UInt32)1 << 15); _numShiftBits++)
    135         range >>= 1;
    136     }
    137     int Count(UInt64 val)
    138     {
    139       int res = (int)(val >> _numShiftBits);
    140       if (val == _range)
    141         res++;
    142       return res;
    143     }
    144   };
    145 
    146   CU64ToI32Converter _progressConv;
    147   UInt64 _progressBar_Pos;
    148   UInt64 _progressBar_Range;
    149 
    150   NWindows::NControl::CProgressBar m_ProgressBar;
    151   NWindows::NControl::CListView _messageList;
    152 
    153   int _numMessages;
    154 
    155   #ifdef __ITaskbarList3_INTERFACE_DEFINED__
    156   CMyComPtr<ITaskbarList3> _taskbarList;
    157   #endif
    158   HWND _hwndForTaskbar;
    159 
    160   UInt32 _prevTime;
    161   UInt64 _elapsedTime;
    162 
    163   UInt64 _prevPercentValue;
    164   UInt64 _prevElapsedSec;
    165   UInt64 _prevRemainingSec;
    166 
    167   UInt64 _totalBytes_Prev;
    168   UInt64 _processed_Prev;
    169   UInt64 _packed_Prev;
    170   UInt64 _ratio_Prev;
    171   UString _filesStr_Prev;
    172 
    173   unsigned _prevSpeed_MoveBits;
    174   UInt64 _prevSpeed;
    175 
    176   bool _foreground;
    177 
    178   unsigned _numReduceSymbols;
    179 
    180   bool _wasCreated;
    181   bool _needClose;
    182 
    183   unsigned _numPostedMessages;
    184   UInt32 _numAutoSizeMessages;
    185 
    186   bool _errorsWereDisplayed;
    187 
    188   bool _waitCloseByCancelButton;
    189   bool _cancelWasPressed;
    190 
    191   bool _inCancelMessageBox;
    192   bool _externalCloseMessageWasReceived;
    193 
    194 
    195   #ifdef __ITaskbarList3_INTERFACE_DEFINED__
    196   void SetTaskbarProgressState(TBPFLAG tbpFlags)
    197   {
    198     if (_taskbarList && _hwndForTaskbar)
    199       _taskbarList->SetProgressState(_hwndForTaskbar, tbpFlags);
    200   }
    201   #endif
    202   void SetTaskbarProgressState();
    203 
    204   void UpdateStatInfo(bool showAll);
    205   bool OnTimer(WPARAM timerID, LPARAM callback);
    206   void SetProgressRange(UInt64 range);
    207   void SetProgressPos(UInt64 pos);
    208   virtual bool OnInit();
    209   virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
    210   virtual void OnCancel();
    211   virtual void OnOK();
    212   NWindows::NSynchronization::CManualResetEvent _createDialogEvent;
    213   NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent;
    214   #ifndef _SFX
    215   void AddToTitle(LPCWSTR string);
    216   #endif
    217 
    218   void SetPauseText();
    219   void SetPriorityText();
    220   void OnPauseButton();
    221   void OnPriorityButton();
    222   bool OnButtonClicked(int buttonID, HWND buttonHWND);
    223   bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
    224 
    225   void SetTitleText();
    226   void ShowSize(int id, UInt64 val, UInt64 &prev);
    227 
    228   void UpdateMessagesDialog();
    229 
    230   void AddMessageDirect(LPCWSTR message, bool needNumber);
    231   void AddMessage(LPCWSTR message);
    232 
    233   bool OnExternalCloseMessage();
    234   void EnableErrorsControls(bool enable);
    235 
    236   void ShowAfterMessages(HWND wndParent);
    237 
    238   void CheckNeedClose();
    239 public:
    240   CProgressSync Sync;
    241   bool CompressingMode;
    242   bool WaitMode;
    243   bool ShowCompressionInfo;
    244   bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages.
    245   int IconID;
    246 
    247   HWND MainWindow;
    248   #ifndef _SFX
    249   UString MainTitle;
    250   UString MainAddTitle;
    251   ~CProgressDialog();
    252   #endif
    253 
    254   CProgressDialog();
    255   void WaitCreating()
    256   {
    257     _createDialogEvent.Set();
    258     _dialogCreatedEvent.Lock();
    259   }
    260 
    261   INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0);
    262 
    263   void ProcessWasFinished();
    264 };
    265 
    266 
    267 class CProgressCloser
    268 {
    269   CProgressDialog *_p;
    270 public:
    271   CProgressCloser(CProgressDialog &p) : _p(&p) {}
    272   ~CProgressCloser() { _p->ProcessWasFinished(); }
    273 };
    274 
    275 class CProgressThreadVirt
    276 {
    277   FString ErrorPath1;
    278   FString ErrorPath2;
    279 protected:
    280   CProgressFinalMessage FinalMessage;
    281 
    282   // error if any of HRESULT, ErrorMessage, ErrorPath
    283   virtual HRESULT ProcessVirt() = 0;
    284   void Process();
    285 public:
    286   HRESULT Result;
    287   bool ThreadFinishedOK; // if there is no fatal exception
    288   CProgressDialog ProgressDialog;
    289 
    290   static THREAD_FUNC_DECL MyThreadFunction(void *param)
    291   {
    292     CProgressThreadVirt *p = (CProgressThreadVirt *)param;
    293     try
    294     {
    295       p->Process();
    296       p->ThreadFinishedOK = true;
    297     }
    298     catch (...) { p->Result = E_FAIL; }
    299     return 0;
    300   }
    301 
    302   void SetErrorPath1(const FString &path) { ErrorPath1 = path; }
    303   void SetErrorPath2(const FString &path) { ErrorPath2 = path; }
    304 
    305   HRESULT Create(const UString &title, HWND parentWindow = 0);
    306   CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {}
    307 
    308   CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; }
    309 
    310 };
    311 
    312 UString HResultToMessage(HRESULT errorCode);
    313 
    314 #endif
    315