Home | History | Annotate | Download | only in FileManager
      1 // ProgressDialog.h
      2 
      3 #ifndef __PROGRESS_DIALOG_H
      4 #define __PROGRESS_DIALOG_H
      5 
      6 #include "../../../Windows/Synchronization.h"
      7 #include "../../../Windows/Thread.h"
      8 
      9 #include "../../../Windows/Control/Dialog.h"
     10 #include "../../../Windows/Control/ProgressBar.h"
     11 
     12 #include "ProgressDialogRes.h"
     13 
     14 class CProgressSync
     15 {
     16   NWindows::NSynchronization::CCriticalSection _cs;
     17   bool _stopped;
     18   bool _paused;
     19   UInt64 _total;
     20   UInt64 _completed;
     21 public:
     22   CProgressSync(): _stopped(false), _paused(false), _total(1), _completed(0) {}
     23 
     24   HRESULT ProcessStopAndPause();
     25   bool GetStopped()
     26   {
     27     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
     28     return _stopped;
     29   }
     30   void SetStopped(bool value)
     31   {
     32     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
     33     _stopped = value;
     34   }
     35   bool GetPaused()
     36   {
     37     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
     38     return _paused;
     39   }
     40   void SetPaused(bool value)
     41   {
     42     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
     43     _paused = value;
     44   }
     45   void SetProgress(UInt64 total, UInt64 completed)
     46   {
     47     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
     48     _total = total;
     49     _completed = completed;
     50   }
     51   void SetPos(UInt64 completed)
     52   {
     53     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
     54     _completed = completed;
     55   }
     56   void GetProgress(UInt64 &total, UInt64 &completed)
     57   {
     58     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
     59     total = _total;
     60     completed = _completed;
     61   }
     62 };
     63 
     64 class CU64ToI32Converter
     65 {
     66   UInt64 _numShiftBits;
     67 public:
     68   void Init(UInt64 range)
     69   {
     70     // Windows CE doesn't like big number here.
     71     for (_numShiftBits = 0; range > (1 << 15); _numShiftBits++)
     72       range >>= 1;
     73   }
     74   int Count(UInt64 value) { return int(value >> _numShiftBits); }
     75 };
     76 
     77 class CProgressDialog: public NWindows::NControl::CModalDialog
     78 {
     79 private:
     80   UINT_PTR _timer;
     81 
     82   UString _title;
     83   CU64ToI32Converter _converter;
     84   UInt64 _peviousPos;
     85   UInt64 _range;
     86   NWindows::NControl::CProgressBar m_ProgressBar;
     87 
     88   int _prevPercentValue;
     89 
     90   bool _wasCreated;
     91   bool _needClose;
     92   bool _inCancelMessageBox;
     93   bool _externalCloseMessageWasReceived;
     94 
     95   bool OnTimer(WPARAM timerID, LPARAM callback);
     96   void SetRange(UInt64 range);
     97   void SetPos(UInt64 pos);
     98   virtual bool OnInit();
     99   virtual void OnCancel();
    100   virtual void OnOK();
    101   NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent;
    102   #ifndef _SFX
    103   void AddToTitle(LPCWSTR string);
    104   #endif
    105   bool OnButtonClicked(int buttonID, HWND buttonHWND);
    106 
    107   void WaitCreating() { _dialogCreatedEvent.Lock(); }
    108   void CheckNeedClose();
    109   bool OnExternalCloseMessage();
    110 public:
    111   CProgressSync Sync;
    112   int IconID;
    113 
    114   #ifndef _SFX
    115   HWND MainWindow;
    116   UString MainTitle;
    117   UString MainAddTitle;
    118   ~CProgressDialog();
    119   #endif
    120 
    121   CProgressDialog(): _timer(0)
    122     #ifndef _SFX
    123     ,MainWindow(0)
    124     #endif
    125   {
    126     IconID = -1;
    127     _wasCreated = false;
    128     _needClose = false;
    129     _inCancelMessageBox = false;
    130     _externalCloseMessageWasReceived = false;
    131 
    132     if (_dialogCreatedEvent.Create() != S_OK)
    133       throw 1334987;
    134   }
    135 
    136   INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0)
    137   {
    138     _title = title;
    139     INT_PTR res = CModalDialog::Create(IDD_PROGRESS, wndParent);
    140     thread.Wait();
    141     return res;
    142   }
    143 
    144   enum
    145   {
    146     kCloseMessage = WM_APP + 1
    147   };
    148 
    149   virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
    150 
    151   void ProcessWasFinished()
    152   {
    153     WaitCreating();
    154     if (_wasCreated)
    155       PostMessage(kCloseMessage);
    156     else
    157       _needClose = true;
    158   };
    159 };
    160 
    161 
    162 class CProgressCloser
    163 {
    164   CProgressDialog *_p;
    165 public:
    166   CProgressCloser(CProgressDialog &p) : _p(&p) {}
    167   ~CProgressCloser() { _p->ProcessWasFinished(); }
    168 };
    169 
    170 #endif
    171