/* * AUTHOR * N. Nielsen * * LICENSE * This software is in the public domain. * * The software is provided "as is", without warranty of any kind, * express or implied, including but not limited to the warranties * of merchantability, fitness for a particular purpose, and * noninfringement. In no event shall the author(s) be liable for any * claim, damages, or other liability, whether in an action of * contract, tort, or otherwise, arising from, out of, or in connection * with the software or the use or other dealings in the software. * * SUPPORT * Send bug reports to: */ // ProgressDlg.cpp : Implementation of CProgressDlg #include "stdafx.h" #include "ProgressDlg.h" // (Con|De)struction: ----------------------------------------------- ProgressDlg::ProgressDlg() { m_numFiles = 0; m_numReplaces = 0; m_flip = false; m_hThread = NULL; m_hEvent = NULL; m_isCancelled = false; InitializeCriticalSection(&m_sec); } ProgressDlg::~ProgressDlg() { DeleteCriticalSection(&m_sec); if(m_hEvent) CloseHandle(m_hEvent); } // threadProc: --------------------------------------------------------- // Runs the dialog in another thread static DWORD WINAPI threadProc(void* pv) { ProgressDlg* dlg = (ProgressDlg*)pv; return dlg->DoModal(NULL, NULL); } // startDialog: -------------------------------------------------------- // Starts the dialog thread HRESULT ProgressDlg::startDialog() { ASSERT(m_hThread == NULL); HRESULT ret = S_OK; if(m_hEvent) CloseHandle(m_hEvent); m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); DWORD threadID; m_hThread = CreateThread(NULL, 0, threadProc, this, CREATE_SUSPENDED, &threadID); if(!m_hThread) ret = HRESULT_FROM_WIN32(::GetLastError()); else ResumeThread(m_hThread); // Wait for dialog to start up. ::WaitForSingleObject(m_hEvent, 10000); CloseHandle(m_hEvent); m_hEvent = NULL; return S_OK; } // stopDialog: ---------------------------------------------------------- // Stops the dialog thread and closes the dialog int ProgressDlg::stopDialog() { int ret = 0; if(m_hThread && m_hWnd) { ::PostMessage(m_hWnd, WM_CLOSE, 0, 0); WaitForSingleObject(m_hThread, INFINITE); } else if(m_hThread) { EnterCriticalSection(&m_sec); TerminateThread(m_hThread, -1); } if(m_hThread) { DWORD code = 0; GetExitCodeThread(m_hThread, &code); CloseHandle(m_hThread); m_hThread = NULL; ret = (int)code; } return 0; } // isCancelled: ----------------------------------------------------------- // Checks if user pressed cancel button bool ProgressDlg::isCancelled() { bool ret = false; EnterCriticalSection(&m_sec); ret = m_isCancelled; LeaveCriticalSection(&m_sec); return ret; } // updateControls: -------------------------------------------------------- // Update dialog status void ProgressDlg::updateControls() { if(IsWindow()) { string status; status.format(_T("%d replaces in %d files"), m_numReplaces, m_numFiles); SetDlgItemText(IDC_STATUS, status); } } // onReplaced: ------------------------------------------------------------- // Called when a new replacement was made void ProgressDlg::onReplaced() { m_flip = !m_flip; m_numReplaces++; // Do flicker thing if(IsWindow()) ::ShowWindow(GetDlgItem(IDC_FLIP), m_flip ? SW_SHOW : SW_HIDE); updateControls(); } // onNewFile: -------------------------------------------------------------- // Called when a new file starts processing void ProgressDlg::onNewFile(LPCTSTR fileName) { if(IsWindow()) SetDlgItemText(IDC_FILENAME, fileName); m_numFiles++; updateControls(); } // setTitle: --------------------------------------------------------------- // Set the title. If no window then just store it void ProgressDlg::setTitle(const string& title) { m_title = title; if(IsWindow()) SetWindowText(title); } // onInitDialog: ------------------------------------------------------------ // Dialog initialization. We clear the event that says we've // started up. LRESULT ProgressDlg::onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { EnterCriticalSection(&m_sec); if(!m_title.empty()) SetWindowText(m_title.c_str()); if(m_hEvent) SetEvent(m_hEvent); CenterWindow(NULL); LeaveCriticalSection(&m_sec); return 1; } // onClose: ------------------------------------------------------------------ // Dialog was closed LRESULT ProgressDlg::onClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { EnterCriticalSection(&m_sec); m_isCancelled = true; LeaveCriticalSection(&m_sec); // TODO: will this get called by NC area? EndDialog(IDOK); return 1; } // onCancel: ------------------------------------------------------------------ // User clicked cancel, set flag LRESULT ProgressDlg::onCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { EnterCriticalSection(&m_sec); m_isCancelled = true; LeaveCriticalSection(&m_sec); EndDialog(IDCANCEL); return 0; }