summaryrefslogtreecommitdiff
path: root/win32/droplet/progressdlg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'win32/droplet/progressdlg.cpp')
-rw-r--r--win32/droplet/progressdlg.cpp211
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;
+}
+