diff options
Diffstat (limited to 'win32/makedrop/dropsheet.cpp')
-rw-r--r-- | win32/makedrop/dropsheet.cpp | 301 |
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; +} |