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 FString &fileName, bool isDir = false);
     84 
     85   HRESULT 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   HRESULT Set_Status2(const UString &s, const wchar_t *path, bool isDir = false);
     95   void Set_FilePath(const wchar_t *path, bool isDir = false);
     96 
     97   void AddError_Message(const wchar_t *message);
     98   void AddError_Message_Name(const wchar_t *message, const wchar_t *name);
     99   void AddError_Code_Name(DWORD systemError, const wchar_t *name);
    100 
    101   bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); }
    102 };
    103 
    104 class CProgressDialog: public NWindows::NControl::CModalDialog
    105 {
    106   UString _titleFileName;
    107   UString _filePath;
    108   UString _status;
    109   bool _isDir;
    110 
    111   UString _background_String;
    112   UString _backgrounded_String;
    113   UString _foreground_String;
    114   UString _pause_String;
    115   UString _continue_String;
    116   UString _paused_String;
    117 
    118   int _buttonSizeX;
    119   int _buttonSizeY;
    120 
    121   UINT_PTR _timer;
    122 
    123   UString _title;
    124 
    125   class CU64ToI32Converter
    126   {
    127     unsigned _numShiftBits;
    128     UInt64 _range;
    129   public:
    130     CU64ToI32Converter(): _numShiftBits(0), _range(1) {}
    131     void Init(UInt64 range)
    132     {
    133       _range = range;
    134       // Windows CE doesn't like big number for ProgressBar.
    135       for (_numShiftBits = 0; range >= ((UInt32)1 << 15); _numShiftBits++)
    136         range >>= 1;
    137     }
    138     int Count(UInt64 val)
    139     {
    140       int res = (int)(val >> _numShiftBits);
    141       if (val == _range)
    142         res++;
    143       return res;
    144     }
    145   };
    146 
    147   CU64ToI32Converter _progressConv;
    148   UInt64 _progressBar_Pos;
    149   UInt64 _progressBar_Range;
    150 
    151   NWindows::NControl::CProgressBar m_ProgressBar;
    152   NWindows::NControl::CListView _messageList;
    153 
    154   int _numMessages;
    155 
    156   #ifdef __ITaskbarList3_INTERFACE_DEFINED__
    157   CMyComPtr<ITaskbarList3> _taskbarList;
    158   #endif
    159   HWND _hwndForTaskbar;
    160 
    161   UInt32 _prevTime;
    162   UInt64 _elapsedTime;
    163 
    164   UInt64 _prevPercentValue;
    165   UInt64 _prevElapsedSec;
    166   UInt64 _prevRemainingSec;
    167 
    168   UInt64 _totalBytes_Prev;
    169   UInt64 _processed_Prev;
    170   UInt64 _packed_Prev;
    171   UInt64 _ratio_Prev;
    172   UString _filesStr_Prev;
    173 
    174   unsigned _prevSpeed_MoveBits;
    175   UInt64 _prevSpeed;
    176 
    177   bool _foreground;
    178 
    179   unsigned _numReduceSymbols;
    180 
    181   bool _wasCreated;
    182   bool _needClose;
    183 
    184   unsigned _numPostedMessages;
    185   UInt32 _numAutoSizeMessages;
    186 
    187   bool _errorsWereDisplayed;
    188 
    189   bool _waitCloseByCancelButton;
    190   bool _cancelWasPressed;
    191 
    192   bool _inCancelMessageBox;
    193   bool _externalCloseMessageWasReceived;
    194 
    195 
    196   #ifdef __ITaskbarList3_INTERFACE_DEFINED__
    197   void SetTaskbarProgressState(TBPFLAG tbpFlags)
    198   {
    199     if (_taskbarList && _hwndForTaskbar)
    200       _taskbarList->SetProgressState(_hwndForTaskbar, tbpFlags);
    201   }
    202   #endif
    203   void SetTaskbarProgressState();
    204 
    205   void UpdateStatInfo(bool showAll);
    206   bool OnTimer(WPARAM timerID, LPARAM callback);
    207   void SetProgressRange(UInt64 range);
    208   void SetProgressPos(UInt64 pos);
    209   virtual bool OnInit();
    210   virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
    211   virtual void OnCancel();
    212   virtual void OnOK();
    213   NWindows::NSynchronization::CManualResetEvent _createDialogEvent;
    214   NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent;
    215   #ifndef _SFX
    216   void AddToTitle(LPCWSTR string);
    217   #endif
    218 
    219   void SetPauseText();
    220   void SetPriorityText();
    221   void OnPauseButton();
    222   void OnPriorityButton();
    223   bool OnButtonClicked(int buttonID, HWND buttonHWND);
    224   bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
    225 
    226   void SetTitleText();
    227   void ShowSize(int id, UInt64 val, UInt64 &prev);
    228 
    229   void UpdateMessagesDialog();
    230 
    231   void AddMessageDirect(LPCWSTR message, bool needNumber);
    232   void AddMessage(LPCWSTR message);
    233 
    234   bool OnExternalCloseMessage();
    235   void EnableErrorsControls(bool enable);
    236 
    237   void ShowAfterMessages(HWND wndParent);
    238 
    239   void CheckNeedClose();
    240 public:
    241   CProgressSync Sync;
    242   bool CompressingMode;
    243   bool WaitMode;
    244   bool ShowCompressionInfo;
    245   bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages.
    246   int IconID;
    247 
    248   HWND MainWindow;
    249   #ifndef _SFX
    250   UString MainTitle;
    251   UString MainAddTitle;
    252   ~CProgressDialog();
    253   #endif
    254 
    255   CProgressDialog();
    256   void WaitCreating()
    257   {
    258     _createDialogEvent.Set();
    259     _dialogCreatedEvent.Lock();
    260   }
    261 
    262   INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0);
    263 
    264   void ProcessWasFinished();
    265 };
    266 
    267 
    268 class CProgressCloser
    269 {
    270   CProgressDialog *_p;
    271 public:
    272   CProgressCloser(CProgressDialog &p) : _p(&p) {}
    273   ~CProgressCloser() { _p->ProcessWasFinished(); }
    274 };
    275 
    276 class CProgressThreadVirt
    277 {
    278 protected:
    279   FStringVector ErrorPaths;
    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 AddErrorPath(const FString &path) { ErrorPaths.Add(path); }
    303 
    304   HRESULT Create(const UString &title, HWND parentWindow = 0);
    305   CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {}
    306 
    307   CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; }
    308 
    309 };
    310 
    311 UString HResultToMessage(HRESULT errorCode);
    312 
    313 #endif
    314