GME  13
ProgressWindow.cpp
Go to the documentation of this file.
00001 #include "StdAfx.h"
00002 #include "afxcmn.h"
00003 #include "afxmt.h"
00004 #include "resource.h"
00005 #include "ProgressWindow.h"
00006 
00007 #define WM_PROGRESSWINDOW_SENDLOGLINE (WM_APP+2001)
00008 #define WM_PROGRESSWINDOW_CLOSE (WM_PROGRESSWINDOW_SENDLOGLINE + 1)
00009 
00010 
00012 // CProgressDialog dialog
00013 class CProgressDialog : public CDialog
00014 {
00015         DECLARE_DYNAMIC(CProgressDialog)
00016 
00017 public:
00018         CProgressDialog(CWnd* pParent = NULL) :
00019                 CDialog(CProgressDialog::IDD, pParent)
00020         {
00021         }
00022 
00023         virtual ~CProgressDialog() {}
00024 
00025         enum { IDD = IDD_DIALOG_PROGRESS };
00026 
00027 protected:
00028         virtual void DoDataExchange(CDataExchange* pDX)
00029         {
00030                 CDialog::DoDataExchange(pDX);
00031                 DDX_Control(pDX, IDC_EDIT_PROGRESS, m_log);
00032                 DDX_Control(pDX, IDC_PROGRESS_BAR, m_bar);
00033         }
00034 
00035         DECLARE_MESSAGE_MAP()
00036 
00037 public:
00038         virtual BOOL OnInitDialog()
00039         {
00040                 CDialog::OnInitDialog();
00041                 //m_bar.SetMarquee(TRUE, 0);  // this needs UNICODE to be defined (why?)
00042                 m_bar.ModifyStyle(0, PBS_MARQUEE);
00043                 ::SendMessage(m_bar.GetSafeHwnd(), PBM_SETMARQUEE, TRUE, 0);
00044                 return TRUE;
00045         }
00046 
00047 protected:
00048         CEdit m_log;
00049         CProgressCtrl m_bar;
00050 public:
00051         afx_msg LRESULT OnSendLogLine(WPARAM wParam, LPARAM lParam)
00052         {
00053                 LPCTSTR line = (LPCTSTR)lParam;
00054 
00055                 CString logStr;
00056                 m_log.GetWindowText(logStr);
00057                 logStr += line;
00058                 m_log.SetWindowText(logStr);
00059 
00060                 m_log.LineScroll(m_log.GetLineCount());
00061 
00062                 delete [] line; // dynamically allocated by the main thread
00063 
00064                 return TRUE;
00065         }
00066 };
00067 
00068 IMPLEMENT_DYNAMIC(CProgressDialog, CDialog)
00069 
00070 BEGIN_MESSAGE_MAP(CProgressDialog, CDialog)
00071         ON_MESSAGE(WM_PROGRESSWINDOW_SENDLOGLINE, OnSendLogLine)
00072 END_MESSAGE_MAP()
00073 
00074 
00076 // CProgressThread
00077 class CProgressThread : public CWinThread
00078 {
00079         DECLARE_DYNCREATE(CProgressThread)
00080 
00081 public:
00082         CProgressThread() {}
00083         virtual ~CProgressThread() {
00084 
00085         }
00086 
00087 
00088         virtual BOOL InitInstance() 
00089         {
00090                 m_dlg.Create(CProgressDialog::IDD, CWnd::GetDesktopWindow());
00091                 m_dlg.ShowWindow(SW_SHOW);
00092                 initDone.SetEvent();
00093                 return TRUE;
00094         }
00095 
00096         virtual int ExitInstance()
00097         {
00098                 if (m_dlg.GetSafeHwnd()) {
00099                         m_dlg.DestroyWindow();
00100                 }
00101                 return CWinThread::ExitInstance();
00102         }
00103 
00104         CEvent initDone;
00105 
00106 protected:
00107         DECLARE_MESSAGE_MAP()
00108 
00109         CProgressDialog m_dlg;
00110 
00111 public:
00112         afx_msg void OnSendLogLine(WPARAM wParam, LPARAM lParam)
00113         {
00114                 if (m_dlg.GetSafeHwnd()) {
00115                         m_dlg.PostMessage(WM_PROGRESSWINDOW_SENDLOGLINE, wParam, lParam);
00116                 }
00117         }
00118 
00119         afx_msg void OnClose(WPARAM , LPARAM )
00120         {
00121                 PostQuitMessage(0);
00122         }
00123 };
00124 
00125 IMPLEMENT_DYNCREATE(CProgressThread, CWinThread)
00126 
00127 BEGIN_MESSAGE_MAP(CProgressThread, CWinThread)
00128         ON_THREAD_MESSAGE(WM_PROGRESSWINDOW_SENDLOGLINE, OnSendLogLine)
00129         ON_THREAD_MESSAGE(WM_PROGRESSWINDOW_CLOSE, OnClose)
00130 END_MESSAGE_MAP()
00131 
00132 
00134 // Public functions
00135 
00136 static CProgressThread* pThread = NULL;
00137 
00138 void CloseProgressWindow()
00139 {
00140         if (pThread == NULL) {
00141                 return;
00142         }
00143         pThread->PostThreadMessage(WM_PROGRESSWINDOW_CLOSE, NULL, NULL);
00144         ::WaitForSingleObject (pThread->m_hThread, INFINITE);
00145         delete pThread;
00146         pThread = NULL; // CProgressThread kills itself
00147 }
00148 
00149 void UpdateProgress(LPCTSTR msg)
00150 {
00151         if (!pThread) {
00152                 pThread = (CProgressThread*)AfxBeginThread (RUNTIME_CLASS (CProgressThread),
00153                                                                                                         THREAD_PRIORITY_NORMAL,
00154                                                                                                         0, CREATE_SUSPENDED);
00155                 pThread->m_bAutoDelete = FALSE;
00156                 pThread->ResumeThread();
00157                 pThread->initDone.Lock();
00158         }
00159         return;
00160         LPCTSTR str = (LPCTSTR)msg;
00161         size_t len = _tcsclen(str) + 1;
00162         LPTSTR strnew = new TCHAR[len]; // will be freed in the progress thread
00163         if (strnew) {
00164                 _tcscpy_s(strnew, len, str);
00165                 pThread->PostThreadMessage(WM_PROGRESSWINDOW_SENDLOGLINE, NULL, (LPARAM)strnew);
00166         }
00167 }