/* * 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: */ #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; }