diff options
Diffstat (limited to 'win32/droplet/progressdlg.cpp')
-rw-r--r-- | win32/droplet/progressdlg.cpp | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/win32/droplet/progressdlg.cpp b/win32/droplet/progressdlg.cpp new file mode 100644 index 0000000..53f5e14 --- /dev/null +++ b/win32/droplet/progressdlg.cpp @@ -0,0 +1,211 @@ +/* + * 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: <nielsen@memberwebs.com> + */ + +// 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; + 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) +{ + // TODO: will this get called by NC area? + EndDialog(IDOK); + return 0; +} + +// 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; +} + |