summaryrefslogtreecommitdiff
path: root/win32/makedrop/dropsheet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'win32/makedrop/dropsheet.cpp')
-rw-r--r--win32/makedrop/dropsheet.cpp301
1 files changed, 301 insertions, 0 deletions
diff --git a/win32/makedrop/dropsheet.cpp b/win32/makedrop/dropsheet.cpp
new file mode 100644
index 0000000..04801b4
--- /dev/null
+++ b/win32/makedrop/dropsheet.cpp
@@ -0,0 +1,301 @@
+/*
+ * 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>
+ */
+
+#include "stdafx.h"
+#include "DropSheet.h"
+#include "common/errutil.h"
+
+
+// Error Macros: ----------------------------------------------------------
+// Context specific macros. Each one jumps to 'cleanup' so any wrapping
+// up can be performed
+
+#define RETURN(v) \
+ { ret = (v); goto cleanup; }
+#define WINERR(f) \
+ RETURN(errorMessage(m_hWnd, HRESULT_FROM_WIN32(::GetLastError()), f))
+#define WINERR_1(f, a) \
+ RETURN(errorMessage(m_hWnd, HRESULT_FROM_WIN32(::GetLastError()), f, a))
+#define WINERR_E(e, f) \
+ RETURN(errorMessage(m_hWnd, e, f));
+#define REPERR(c, s) \
+ RETURN(rlibError(m_hWnd, c, s));
+
+
+
+// (Con|De)struction: -------------------------------------------------------
+
+DropSheet::DropSheet() :
+ CPropertySheet(_T("Rep Droplet"))
+{
+ m_dirty = false;
+}
+
+DropSheet::~DropSheet()
+{
+
+}
+
+
+
+// CopyResourceToFile: -----------------------------------------------------
+// Dumps raw data from a resource to a file
+
+bool CopyResourceToFile(LPCTSTR type, LPCTSTR name, LPCTSTR fileName)
+{
+ // Open the Resource
+ HRSRC hRsrc = FindResource(_Module.GetResourceInstance(), name, type);
+ if(!hRsrc) return false;
+
+ HGLOBAL hGlobal = LoadResource(_Module.GetResourceInstance(), hRsrc);
+ if(!hRsrc) return false;
+
+ void* data = LockResource(hGlobal);
+ if(!data) return false;
+
+ // Open the file
+ HANDLE file = CreateFile(fileName, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, 0, NULL);
+ if(file == INVALID_HANDLE_VALUE) return false;
+
+ DWORD size = SizeofResource(_Module.GetResourceInstance(), hRsrc);
+
+ // Write it
+ DWORD written = 0;
+ bool ret = WriteFile(file, data, size, &written, NULL) ? true : false;
+
+ if(written != size)
+ ret = false;
+
+ CloseHandle(file);
+
+ return ret;
+}
+
+
+
+// saveDroplet: -------------------------------------------------------------
+// Gets property pages to save data, prompts user, saves etc...
+
+bool DropSheet::saveDroplet(bool force)
+{
+ HRESULT ret = S_OK;
+ bool noReturn = false;
+
+ {
+ // The return value is whether or not an exit can
+ // take place
+
+ if(!m_dirty && !force)
+ return true;
+
+ // Prompt the user and see if they want to save
+ if(m_dirty && !force)
+ {
+ switch(MessageBox(_T("You've made changes, would you like to save?"), _T("Rep Droplet"),
+ MB_YESNOCANCEL | MB_ICONQUESTION))
+ {
+ case IDYES:
+ break;
+ case IDNO:
+ return true;
+ case IDCANCEL:
+ return false;
+ }
+ }
+
+ // Clear the dirty flag here
+ m_dirty = false;
+
+ // Now get every page to apply theirs again
+ // if necessary
+ PressButton(PSBTN_APPLYNOW);
+
+ // If dirty is set now, then something failed
+ if(m_dirty)
+ return false;
+
+ // If the user hasn't saved/loaded yet then get a file name
+ if(m_fileName.empty())
+ {
+ OPENFILENAME ofn;
+ memset(&ofn, 0, sizeof(ofn));
+
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = m_hWnd;
+ ofn.lpstrFilter = _T("Droplet Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0\0");
+ ofn.lpstrFile = m_fileName.get_buffer(MAX_PATH);
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = _T("Save Droplet");
+ ofn.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
+ ofn.lpstrDefExt = _T("exe");
+
+ if(GetSaveFileName(&ofn))
+ m_fileName.release_buffer();
+ else
+ return false;
+ }
+
+ // Okay now we copy out the droplet from our resources
+ if(!CopyResourceToFile(DROP_RESOURCE_TYPE, DROP_RESOURCE_FILE,
+ m_fileName))
+ WINERR_1("Couldn't write out droplet: %s", m_fileName.c_str());
+
+ noReturn = true;
+
+ // Now save our droplet data into the stock droplet
+ if(!m_droplet.save(m_fileName))
+ WINERR_1("Couldn't write out droplet: %s", m_fileName.c_str());
+ }
+
+cleanup:
+ // If failed and we already wrote out the stock
+ // droplet, then delete it
+ if(FAILED(ret) && noReturn &&
+ !m_fileName.empty())
+ DeleteFile(m_fileName);
+
+ return SUCCEEDED(ret);
+}
+
+
+// openDroplet: --------------------------------------------------------
+// Prompt user for file, open it and refresh property pages
+
+void DropSheet::openDroplet()
+{
+ HRESULT ret = S_OK;
+
+ {
+ string file;
+ OPENFILENAME ofn;
+ memset(&ofn, 0, sizeof(ofn));
+
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = m_hWnd;
+ ofn.lpstrFilter = _T("Droplet Files\0*.exe\0All Files\0*.*\0\0");
+ ofn.lpstrFile = file.get_buffer(MAX_PATH);
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = _T("Choose Rep Script");
+ ofn.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST;
+ ofn.lpstrDefExt = _T("rep");;
+
+ if(GetOpenFileName(&ofn))
+ {
+ file.release_buffer();
+
+ if(!m_droplet.load(file))
+ WINERR_1("Couldn't read droplet: %s", file.c_str());
+
+ m_fileName = file;
+
+ // Send around a message to the property pages to reload
+ SendMessage(PSM_QUERYSIBLINGS);
+ }
+ }
+
+cleanup:
+ ;
+}
+
+
+// onInitDialog: ----------------------------------------------------------
+// Initialize basic Property sheet stuff and pass on message
+
+LRESULT DropSheet::onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ // Add the menu
+ HMENU hMenu = LoadMenu(_Module.GetResourceInstance(),
+ MAKEINTRESOURCE(IDR_MENU));
+ SetMenu(hMenu);
+
+ SetIcon(::LoadIcon(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDI_REP)), TRUE);
+ SetIcon((HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDI_REP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR), FALSE);
+
+
+ // Base implementations need this message
+ bHandled = FALSE;
+ return 0;
+}
+
+
+// onClose: -----------------------------------------------------------------
+// Check if save is required, close
+
+LRESULT DropSheet::onClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ // Make sure user saves first
+ if(!m_dirty || saveDroplet(false))
+ {
+ // Modeless dialog, so this is right
+ PostQuitMessage(0);
+ bHandled = FALSE;
+ }
+ else
+ bHandled = TRUE;
+
+ return 0;
+}
+
+
+// onChanged: ---------------------------------------------------------------
+// Catch message sent by property pages, so we can update our dirty flag
+
+LRESULT DropSheet::onChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ m_dirty = true;
+ bHandled = FALSE;
+ return 0;
+}
+
+
+// onOpen: ------------------------------------------------------------------
+// "Open" menu or keyboard accel
+
+LRESULT DropSheet::onOpen(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
+{
+ // Make sure user saves first
+ if(!m_dirty || saveDroplet(false))
+ {
+ openDroplet();
+ }
+
+ return 0;
+}
+
+
+// onSave: ------------------------------------------------------------------
+// "Save" menu or keyboard accel
+
+LRESULT DropSheet::onSave(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
+{
+ // Force a save
+ saveDroplet(true);
+ return 0;
+}
+
+
+// onExit: ------------------------------------------------------------------
+// "Exit" menu or keyboard accel
+
+LRESULT DropSheet::onExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
+{
+ onClose(WM_CLOSE, 0, 0, bHandled);
+ return 0;
+}