diff options
author | Stef Walter <stef@thewalter.net> | 2003-09-20 07:12:49 +0000 |
---|---|---|
committer | Stef Walter <stef@thewalter.net> | 2003-09-20 07:12:49 +0000 |
commit | b49d8ebefe9b10c53a6a09ad564e22111b7b25c6 (patch) | |
tree | 1d5dd4abc38170a7bc106dabbc59b915017222f0 /win32 | |
parent | 1cda9ebbd62916c7c2136722597a86c583e1ecf6 (diff) |
Initial Import
Diffstat (limited to 'win32')
54 files changed, 5841 insertions, 0 deletions
diff --git a/win32/Makefile.am b/win32/Makefile.am new file mode 100644 index 0000000..144140f --- /dev/null +++ b/win32/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = common droplet makedrop + diff --git a/win32/common/Makefile.am b/win32/common/Makefile.am new file mode 100644 index 0000000..e247bdb --- /dev/null +++ b/win32/common/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = atlprsht.h atlwinhk.h droplet.cpp droplet.h errutil.cpp errutil.h mystring.h rep.ico rliberr.mc + diff --git a/win32/common/atlprsht.h b/win32/common/atlprsht.h new file mode 100644 index 0000000..e5181ea --- /dev/null +++ b/win32/common/atlprsht.h @@ -0,0 +1,915 @@ +/* + * 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> + */ + +// PropertyPage.h: interface for the CPropertyPage class. +// Implements Property Pages and Sheets for ATL +// By Stef 06/10/99 +// +// This class uses an MFC type Interface (CPropertySheet, CPropertyPage) +// the only difference being that many of the virtual notify functions +// are left for you to define in your derived classes using your message map +// +// Notes for CPropertySheet: +// 1. If you define a WM_INITDIALOG handler in your derived class make +// sure to either call the base handler (OnInitDialog) or set +// bHandled to false. +// +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_PROPERTYPAGE_H__1508DAF4_7AD1_11D3_BF96_0020182B97FC__INCLUDED_) +#define AFX_PROPERTYPAGE_H__1508DAF4_7AD1_11D3_BF96_0020182B97FC__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +#include <atlwin.h> +#include <atlwinhk.h> +#include <commctrl.h> + + +// Property Sheet control id's (determined with Spy++) +#define ID_APPLY_NOW 0x3021 +#define ID_WIZBACK 0x3023 +#define ID_WIZNEXT 0x3024 +#define ID_WIZFINISH 0x3025 + +#define AFX_IDC_TAB_CONTROL 0x3020 + +// determine number of elements in an array (not bytes) +#define _countof(array) (sizeof(array)/sizeof(array[0])) + +template <class TBase> class CPropertySheetT; +template <class TBase> class CPropertyPageT; + +const int _PropSheetIDs[] = + { ID_WIZNEXT, ID_WIZFINISH, ID_WIZBACK, IDCANCEL }; +const int _PropSheetButtons[] = + { IDOK, IDCANCEL, ID_APPLY_NOW, IDHELP }; + +//////////////////////////////////////////////////////////////////////// +// Implements one page of a Property Sheet +template <class TBase = CWindow> +class CPropertyPageT : public CDialogImplBaseT< TBase > +{ +// Construction +public: + CPropertyPageT(UINT IDD) : m_szCaption(NULL) + { Construct(IDD, _T("")); } + + // Caption from Resource + CPropertyPageT(UINT IDD, UINT nIDCaption) : m_szCaption(NULL) + { Construct(IDD, nIDCaption); } + + CPropertyPageT(UINT IDD, LPCTSTR szCaption) : m_szCaption(NULL) + { Construct(IDD, szCaption); } + + void Construct(UINT IDD, LPCTSTR szCaption) + { CommonConstruct(IDD, szCaption); } + + void Construct(UINT IDD, UINT nIDCaption) + { + ATLASSERT(nIDCaption != 0); + USES_CONVERSION; + CComBSTR bsCaption; + bsCaption.LoadString(nIDCaption); + CommonConstruct(IDD, OLE2T(bsCaption)); + } + + // All Construction ends up here + void CommonConstruct(UINT IDD, LPCTSTR szCaption); + + ~CPropertyPageT() + { if(m_szCaption) delete[] m_szCaption; } + +// Operations + void CancelToClose(); + void SetModified(bool bChanged); + void SetHelp(bool bHelp); + LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam); + bool IsButtonEnabled(int iButton); + void EndDialog(int nID); + +// Status + CPropertySheetT<TBase>* GetParentSheet(); + +// Implementaition +protected: + CPropertySheetT<TBase>* m_pSheet; // Pointer to Sheet + static UINT CALLBACK PropPageCallback(HWND hwnd, UINT uMsg, + LPPROPSHEETPAGE ppsp); + +// Data +public: + PROPSHEETPAGE m_psp; // API Structure + LPTSTR m_szCaption; // Caption + + friend class CPropertySheetT<TBase>; +}; + +// Common Construction +template <class TBase> +void CPropertyPageT<TBase>::CommonConstruct(UINT IDD, LPCTSTR szCaption) +{ + // Clear + memset(&m_psp, 0, sizeof(m_psp)); + + m_psp.dwSize = sizeof(m_psp); + m_psp.hInstance = _Module.m_hInstResource; + m_psp.pszTemplate = MAKEINTRESOURCE(IDD); + // Set to DialogProc + m_psp.pfnDlgProc = (DLGPROC)StartDialogProc; + // Use to hook up to ATL WndProc + m_psp.pfnCallback = PropPageCallback; + m_psp.dwFlags = PSP_USETITLE | PSP_USECALLBACK; + // Passed to PropPageCallback + m_psp.lParam = (LPARAM)this; + + // Allocate String + if(m_szCaption && _tcslen(m_szCaption) < _tcslen(szCaption)) + { + delete[] m_szCaption; + m_szCaption = NULL; + } + + if(!m_szCaption) + m_szCaption = new TCHAR[_tcslen(szCaption) + 1]; + + _tcscpy(m_szCaption, szCaption); + m_psp.pszTitle = m_szCaption; + + // Set by CPropertySheetT::AddPage + m_pSheet = NULL; + +} + +// Callback used during actual creation of page +template <class TBase> +UINT CALLBACK CPropertyPageT<TBase>::PropPageCallback(HWND hwnd, UINT uMsg, + LPPROPSHEETPAGE ppsp) +{ + switch (uMsg) + { + case PSPCB_CREATE: + { + // Get ready for hooking up to an ATL WndProc + CPropertyPageT<TBase>* pPage = + (CPropertyPageT<TBase>*)ppsp->lParam; + _Module.AddCreateWndData(&(pPage->m_thunk.cd), pPage); + + return TRUE; + } + case PSPCB_RELEASE: + break; + } + + return 0; +} + +// Thin Wrapper +template <class TBase> +void CPropertyPageT<TBase>::CancelToClose() +{ + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + + ::SendMessage(GetParent(), PSM_CANCELTOCLOSE, NULL, NULL); +} + +// Thin Wrapper +template <class TBase> +void CPropertyPageT<TBase>::SetModified(bool bChanged) +{ + ATLASSERT(m_hWnd != NULL); + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + + if (bChanged) + ::SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, NULL); + else + ::SendMessage(GetParent(), PSM_UNCHANGED, (WPARAM)m_hWnd, NULL); +} + +// Thin Wrapper +template <class TBase> +LRESULT CPropertyPageT<TBase>::QuerySiblings(WPARAM wParam, LPARAM lParam) +{ + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + + return ::SendMessage(GetParent(), PSM_QUERYSIBLINGS, wParam, lParam); +} + +template <class TBase> +void CPropertyPageT<TBase>::SetHelp(bool bHelp) +{ + if(bHelp) + m_psp.dwFlags |= PSP_HASHELP; + else + m_psp.dwFlags &= ~(PSP_HASHELP); +} + +// Thin wrapper +template <class TBase> +bool CPropertyPageT<TBase>::IsButtonEnabled(int iButton) +{ + HWND hWnd = ::GetDlgItem(::GetParent(m_hWnd), iButton); + if (hWnd == NULL) + return false; + return ::IsWindowEnabled(hWnd) ? true : false; +} + +// Routes EndDialog calls to the Sheet +template <class TBase> +void CPropertyPageT<TBase>::EndDialog(int nID) +{ + // Normally you shouldn't call EndDialog from a page. But in case it does + // happen during error situations, call CPropertySheetT::EndDialog instead. + CPropertySheetT<TBase>* pParent = GetParentSheet(); + if (pParent != NULL) + pParent->EndDialog(nID); +} + +// Return Sheet Pointer (which is initialized in CPropertySheetT::AddPage) +template <class TBase> +CPropertySheetT<TBase>* CPropertyPageT<TBase>::GetParentSheet() + { ATLASSERT(m_pSheet != NULL); return m_pSheet; } + + + + + +//////////////////////////////////////////////////////////////////////// +// Implements and hooks into Actual Property Sheet Window +template <class TBase = CWindow> +class CPropertySheetT : public CWindowImplBaseT< TBase > +{ +// Construction +public: + CPropertySheetT() : m_szCaption(NULL) + { CommonConstruct(_T(""), 0); } + + // Caption from Resource + CPropertySheetT(UINT nIDCaption, HWND hwndParent = NULL, UINT iSelectPage = 0) + : m_szCaption(NULL) + { Construct(nIDCaption, hwndParent, iSelectPage); } + + CPropertySheetT(LPCTSTR pszCaption, HWND hwndParent = NULL, UINT iSelectPage = 0) + : m_szCaption(NULL) + { Construct(pszCaption, hwndParent, iSelectPage); } + + // Caption from Resource + void Construct(UINT nIDCaption, HWND hwndParent = NULL, UINT iSelectPage = 0) + { + ATLASSERT(nIDCaption != 0); + USES_CONVERSION; + CComBSTR bsCaption; + bsCaption.LoadString(nIDCaption); + CommonConstruct(OLE2T(bsCaption), hwndParent, iSelectPage); + } + + void Construct(LPCTSTR pszCaption, HWND hwndParent = NULL, UINT iSelectPage = 0) + { CommonConstruct(pszCaption, hwndParent, iSelectPage); } + + // All actual initialization takes place here + void CommonConstruct(LPCTSTR sCaption, HWND hwndParent = NULL, UINT iSelectPage = 0); + + virtual ~CPropertySheetT() + { if(m_szCaption) delete[] m_szCaption; } + +// Creation +public: + // for modeless creation + // the default style, expressed by passing -1 as dwStyle, is actually: + // WS_SYSMENU | WS_POPUP | WS_CAPTION | DS_MODALFRAME | WS_VISIBLE + bool Create(HWND hwndParent = NULL, DWORD dwStyle = (DWORD)-1, DWORD dwExStyle = 0); + int DoModal(HWND hwndParent = NULL, DWORD dwStyle = (DWORD)-1, DWORD dwExStyle = 0); + +// Operations +public: + void AddPage(CPropertyPageT<TBase>* pPage); + void RemovePage(CPropertyPageT<TBase>* pPage); + void RemovePage(int nPage); + void EndDialog(int nEndID); // used to terminate a modal dialog + bool PressButton(int nButton); + +// Status and Settings +public: + int GetPageCount() const; + int GetActiveIndex() const; + CPropertyPageT<TBase>* GetActivePage() const; + CPropertyPageT<TBase>* GetPage(int nPage) const; + int GetPageIndex(CPropertyPageT<TBase>* pPage); + HWND GetTabControl() const; + void SetWizardMode(); + void SetHelp(bool bHelp); + void SetFinishText(LPCTSTR lpszText); + void SetWizardButtons(DWORD dwFlags); + void EnableStackedTabs(BOOL bStacked); + bool IsWizard() const; + bool SetActivePage(int nPage); + bool SetActivePage(CPropertyPageT<TBase>* pPage); + void SetTitle(LPCTSTR lpszText, UINT nStyle = 0); + +// Message Map +protected: +typedef CPropertySheetT<TBase> sheetClass; +BEGIN_MSG_MAP(sheetClass) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand) + MESSAGE_HANDLER(WM_CLOSE, OnClose) + COMMAND_HANDLER(IDCANCEL, BN_CLICKED, OnEndCode) + COMMAND_HANDLER(IDOK, BN_CLICKED, OnEndCode) + COMMAND_HANDLER(ID_WIZFINISH, BN_CLICKED, OnEndCode) +END_MSG_MAP() + +// Message Handlers + LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnEndCode(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + + +// Implementation +protected: + void BuildPropPageArray(); // Finalizes the Array of Pages + + // Used during creation to set styles + static int CALLBACK PropSheetCallback(HWND, UINT nMsg, LPARAM lParam); + + // For hooking into creation and subclassing the window + DECLARE_HOOK_AND_SUBCLASS(sheetClass); + + // Style cache (used in PropSheetCallback) + DWORD m_dwCurStyle; + DWORD m_dwCurExStyle; + +// Data +protected: + CSimpleArray< CPropertyPageT<TBase>* > m_pages; // array of CPropertyPageT pointers + LPTSTR m_szCaption; // caption of the pseudo-dialog + bool m_bStacked; // EnableStackedTabs sets this + bool m_bModeless; // TRUE when Create called instead of DoModal + int m_nDlgRet; // Result from EndDialog + +public: + PROPSHEETHEADER m_psh; +}; + +// All Initialization here +template <class TBase> +void CPropertySheetT<TBase>::CommonConstruct(LPCTSTR szCaption, + HWND hwndParent /*= NULL*/, + UINT iSelectPage /*= 0*/) +{ + // Clear + memset(&m_psh, 0, sizeof(m_psh)); + + m_psh.dwSize = sizeof(m_psh); + m_psh.dwFlags = PSH_PROPSHEETPAGE; + m_psh.nStartPage = iSelectPage; + + // Allocate String + if(m_szCaption && _tcslen(m_szCaption) < _tcslen(szCaption)) + { + delete[] m_szCaption; + m_szCaption = NULL; + } + + if(!m_szCaption) + m_szCaption = new TCHAR[_tcslen(szCaption) + 1]; + + _tcscpy(m_szCaption, szCaption); + m_psh.pszCaption = m_szCaption; + + m_bStacked = true; // Tab Control + m_bModeless = false; + m_dwCurStyle = 0; + m_dwCurExStyle = 0; + m_nDlgRet = 0; + + // m_psh.hwndParent set in DoModal/create +} + +// Callback used to set styles of Property Sheet +template <class TBase> +int CALLBACK CPropertySheetT<TBase>::PropSheetCallback(HWND hwnd, UINT nMsg, + LPARAM lParam) +{ + switch (nMsg) + { + case PSCB_PRECREATE: + { + // Extract Thunk Create (whatever) data + CPropertySheetT<TBase>* pThis = (CPropertySheetT<TBase>*)_Module.ExtractCreateWndData(); + // We need it later in the proces so add it back again + _Module.AddCreateWndData(&(pThis->m_thunk.cd), pThis); + + LPDLGTEMPLATE lpTemplate = (LPDLGTEMPLATE)lParam; + if (lpTemplate->style != pThis->m_dwCurStyle || + lpTemplate->dwExtendedStyle != pThis->m_dwCurExStyle) + { + + // Mark the dialog template as read-write. + DWORD dwOldProtect; + VirtualProtect(lpTemplate, sizeof(DLGTEMPLATE), PAGE_READWRITE, + &dwOldProtect); + + // Ensure DS_SETFONT is set correctly. + lpTemplate->style = lpTemplate->style & DS_SETFONT ? + pThis->m_dwCurStyle | DS_SETFONT : + pThis->m_dwCurStyle & ~DS_SETFONT; + + lpTemplate->dwExtendedStyle = pThis->m_dwCurExStyle; + } + return TRUE; + } + case PSCB_INITIALIZED: + return TRUE; + + } + + return 0; +} + +// Creates a Modeless Property Sheet +template <class TBase> +bool CPropertySheetT<TBase>::Create(HWND hwndParent /*= NULL*/, DWORD dwStyle /*= (DWORD)-1*/, + DWORD dwExStyle /*= 0*/) +{ + // Calculate the default window style. + if (dwStyle == (DWORD)-1) + { + dwStyle = DS_MODALFRAME | DS_3DLOOK | DS_SETFONT | WS_POPUP | + WS_VISIBLE | WS_CAPTION; + + // Wizards don't have WS_SYSMENU by default + if (!IsWizard()) + dwStyle |= WS_SYSMENU; + } + + // Cache the styles (for use in PropSheetCallback) + m_dwCurStyle = dwStyle; + m_dwCurExStyle = dwExStyle; + + ATLASSERT(m_hWnd == NULL); + + // finish building PROPSHEETHEADER structure + BuildPropPageArray(); + + // Some more settings + m_bModeless = true; + m_psh.dwFlags |= (PSH_MODELESS | PSH_USECALLBACK); + m_psh.pfnCallback = PropSheetCallback; + m_psh.hwndParent = hwndParent; + + // Add Create Thunk whatever Data + _Module.AddCreateWndData(&m_thunk.cd, this); + // Hook into creation so we can subclass before any messages come in + HOOK_AND_SUBCLASS_NEXT(); + + // Do it! + HWND hWnd = (HWND)::PropertySheet((PROPSHEETHEADER*)&m_psh); + + // Modeless so we return right away +#ifdef _DEBUG + DWORD dwError = ::GetLastError(); +#endif + + if (hWnd == NULL || hWnd == (HWND)-1) + { +#ifdef _DEBUG + ATLTRACE("PropertySheet() failed: GetLastError returned %d\n", dwError); +#endif + return false; + } + + m_hWnd = hWnd; + + return true; +} + +// Create a Modal Dialog +template <class TBase> +int CPropertySheetT<TBase>::DoModal(HWND hwndParent /*= NULL*/, DWORD dwStyle /*= (DWORD)-1*/, + DWORD dwExStyle /*= 0*/) +{ + ATLASSERT(m_hWnd == NULL); + + // Calculate the default window style. + if (dwStyle == (DWORD)-1) + { + dwStyle = DS_MODALFRAME | DS_3DLOOK | DS_SETFONT | WS_POPUP | + WS_VISIBLE | WS_CAPTION; + + // Wizards don't have WS_SYSMENU by default + if (!IsWizard()) + dwStyle |= WS_SYSMENU; + } + + // Cache the styles (for use in PropSheetCallback) + m_dwCurStyle = dwStyle; + m_dwCurExStyle = dwExStyle; + + // finish building PROPSHEETHEADER structure + BuildPropPageArray(); + + // Set options + m_bModeless = false; + m_nDlgRet = -1; + m_psh.dwFlags |= (PSH_USECALLBACK); + m_psh.pfnCallback = PropSheetCallback; + m_psh.hwndParent = hwndParent; + + // Add Create Thunk whatever Data + _Module.AddCreateWndData(&m_thunk.cd, this); + // Hook into creation so we can subclass before any messages come in + HOOK_AND_SUBCLASS_NEXT(); + + // Do it. Doesn't come back until after the fact + int nRet = ::PropertySheet((PROPSHEETHEADER*)&m_psh); + + if(nRet == -1) + return nRet; + + return m_nDlgRet; +} + +// Finalize the Array +template <class TBase> +void CPropertySheetT<TBase>::BuildPropPageArray() +{ + // delete existing prop page array + delete[] (PROPSHEETPAGE*)m_psh.ppsp; + m_psh.ppsp = NULL; + + // build new prop page array + PROPSHEETPAGE* ppsp = new PROPSHEETPAGE[m_pages.GetSize()]; + m_psh.ppsp = (PROPSHEETPAGE*)ppsp; + BOOL bWizard = (m_psh.dwFlags & (PSH_WIZARD)); + for (int i = 0; i < m_pages.GetSize(); i++) + { + CPropertyPageT<TBase>* pPage = GetPage(i); + memcpy(&ppsp[i], &pPage->m_psp, sizeof(pPage->m_psp)); +// pPage->PreProcessPageTemplate((PROPSHEETPAGE&)ppsp[i], bWizard); + } + m_psh.nPages = m_pages.GetSize(); +} + +// Adds a Page (either before or after we're on the screen) +template <class TBase> +void CPropertySheetT<TBase>::AddPage(CPropertyPageT<TBase>* pPage) +{ + ATLASSERT(pPage != NULL); + + // Add page to internal list + m_pages.Add(pPage); + pPage->m_pSheet = this; + + // Add page externally + if (m_hWnd != NULL) + { + // build new prop page array + PROPSHEETPAGE* ppsp = new PROPSHEETPAGE[m_pages.GetSize()]; + memcpy(ppsp, m_psh.ppsp, sizeof(PROPSHEETPAGE) * (m_pages.GetSize() - 1)); + delete[] (PROPSHEETPAGE*)m_psh.ppsp; + m_psh.ppsp = ppsp; + ppsp += m_pages.GetSize() - 1; + + // copy processed PROPSHEETPAGE struct to end + memcpy(ppsp, &(pPage->m_psp), sizeof(pPage->m_psp)); +// pPage->PreProcessPageTemplate((PROPSHEETPAGE&)*ppsp, IsWizard()); + HPROPSHEETPAGE hPSP = CreatePropertySheetPage((PROPSHEETPAGE*)ppsp); + ATLASSERT(hPSP != NULL); + + // Tray and add it + if (!SendMessage(PSM_ADDPAGE, 0, (LPARAM)hPSP)) + { + DestroyPropertySheetPage(hPSP); + ATLASSERT(false); + } + } +} + +// Removes a Page (either before or after we're on the screen) +template <class TBase> +void CPropertySheetT<TBase>::RemovePage(CPropertyPageT<TBase>* pPage) +{ + ATLASSERT(pPage != NULL); + + // Get Index + int nPage = GetPageIndex(pPage); + pPage->m_pSheet = NULL; + ATLASSERT(nPage >= 0); + + RemovePage(nPage); +} + +// Removes a Page (either before or after we're on the screen) +template <class TBase> +void CPropertySheetT<TBase>::RemovePage(int nPage) +{ + // remove the page externally + if (m_hWnd != NULL) + SendMessage(PSM_REMOVEPAGE, nPage); + + // remove the page from internal list + m_pages.RemoveAt(nPage); +} + +// Closes the Property Sheet +template <class TBase> +void CPropertySheetT<TBase>::EndDialog(int nEndID) +{ + m_nDlgRet = nEndID; + + if (m_bModeless) + DestroyWindow(); + else + PostMessage(PSM_PRESSBUTTON, PSBTN_CANCEL); +} + +// Need to handle WM_CLOSE for Modeless Property Sheets +template <class TBase> +LRESULT CPropertySheetT<TBase>::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + if (m_bModeless) + DestroyWindow(); + else + bHandled = false; + + return 0; +} + +// Need to handle SC_CLOSE for Modeless Property Sheets +template <class TBase> +LRESULT CPropertySheetT<TBase>::OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + switch (wParam & 0xFFF0) + { + case SC_CLOSE: + if (m_bModeless) + { + SendMessage(WM_CLOSE); + return 0; + } + } + bHandled = false; + return 0; +} + +// Returns number of Pages +template <class TBase> +int CPropertySheetT<TBase>::GetPageCount() const +{ + if (m_hWnd == NULL) + return m_pages.GetSize(); + + return TabCtrl_GetItemCount(GetTabControl()); +} + +// Returns Current Page +template <class TBase> +int CPropertySheetT<TBase>::GetActiveIndex() const +{ + if (m_hWnd == NULL) + return m_psh.nStartPage; + + return TabCtrl_GetCurSel(GetTabControl()); +} + +// Moves to Page +template <class TBase> +bool CPropertySheetT<TBase>::SetActivePage(int nPage) +{ + if (m_hWnd == NULL) + { + m_psh.nStartPage = nPage; + return true; + } + return (bool)SendMessage(PSM_SETCURSEL, nPage); +} + +// Moves to Page +template <class TBase> +bool CPropertySheetT<TBase>::SetActivePage(CPropertyPageT<TBase>* pPage) +{ + ATLASSERT(pPage != NULL); + + int nPage = GetPageIndex(pPage); + ATLASSERT(pPage >= 0); + + return SetActivePage(nPage); +} + +// Gets number of Page +template <class TBase> +int CPropertySheetT<TBase>::GetPageIndex(CPropertyPageT<TBase>* pPage) +{ + ATLASSERT(pPage != NULL); + for (int i = 0; i < GetPageCount(); i++) + { + if (GetPage(i) == pPage) + return i; + } + return -1; // pPage not found +} + +// Get a Page from Array +template <class TBase> +CPropertyPageT<TBase>* CPropertySheetT<TBase>::GetPage(int nPage) const + { return m_pages[nPage]; } + +// Initdialog: Complete creation and setup for modeless etc... +template <class TBase> +LRESULT CPropertySheetT<TBase>::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + // Change tab style if scrolling tabs desired (stacked tabs are default) + if (!m_bStacked) + ((CWindow)GetTabControl()).ModifyStyle(TCS_MULTILINE, TCS_SINGLELINE, 0); + + // For Property Sheets + if (!IsWizard()) + { + // Resize the tab control so the layout is less restrictive + HWND hWndTab = ::GetDlgItem(m_hWnd, AFX_IDC_TAB_CONTROL); + ATLASSERT(hWndTab != NULL); + RECT rcOld; + ::GetWindowRect(hWndTab, &rcOld); + ScreenToClient(&rcOld); + RECT rcNew = {0, 0, 0, 32}; + ::MapDialogRect(m_hWnd, &rcNew); + if (rcNew.bottom < rcNew.bottom) + { + // Move tab control + int cyDiff = (rcOld.bottom - rcOld.top) - rcNew.bottom; + ::SetWindowPos(hWndTab, NULL, 0, 0, rcOld.right - rcOld.left, rcNew.bottom, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + + // Move buttons by similar amount + for (int i = 0; i < _countof(_PropSheetButtons); i++) + { + HWND hWndBtn = ::GetDlgItem(m_hWnd, _PropSheetButtons[i]); + if (hWndBtn != NULL) + { + ::GetWindowRect(hWndBtn, &rcOld); + ScreenToClient(&rcOld); + ::SetWindowPos(hWndBtn, NULL, + rcOld.left, rcOld.top - cyDiff, + 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } + + // Resize property sheet itself similarly + GetWindowRect(&rcOld); + SetWindowPos(NULL, 0, 0, rcOld.right - rcOld.left, (rcOld.bottom - rcOld.top) - cyDiff, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } + + // For Modeless Sheets + if (m_bModeless && !IsWizard()) + { + // Layout property sheet so button area is not accounted for + RECT rcWnd; + GetWindowRect(&rcWnd); + RECT rcBtn; + HWND hWndBtn = ::GetDlgItem(m_hWnd, IDOK); + ATLASSERT(hWndBtn != NULL); + ::GetWindowRect(hWndBtn, &rcBtn); + SetWindowPos(NULL, 0, 0, + rcWnd.right - rcWnd.left, + (rcBtn.top - rcWnd.top) + ::GetSystemMetrics(SM_CYBORDER), + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + + // Remove standard buttons for modeless dialogs + for (int i = 0; i < _countof(_PropSheetButtons); i++) + { + hWndBtn = ::GetDlgItem(m_hWnd, _PropSheetButtons[i]); + if (hWndBtn != NULL) + { + ::ShowWindow(hWndBtn, SW_HIDE); + ::EnableWindow(hWndBtn, FALSE); + } + } + } + + // Center the property sheet relative to the parent window + if (!(GetStyle() & WS_CHILD)) + CenterWindow(); + + // API implementation probably needs this message + bHandled = FALSE; + return 1; +} + +// Gets the return code for DoModal +template <class TBase> +LRESULT CPropertySheetT<TBase>::OnEndCode(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) +{ + // API implementation probably needs this message + bHandled = FALSE; + m_nDlgRet = wID; + return 0; +} + + +// Are we a wizard? +template <class TBase> +bool CPropertySheetT<TBase>::IsWizard() const + { return ((m_psh.dwFlags & PSH_WIZARD) != 0); } + +// Return HWND of Tab Control +template <class TBase> +HWND CPropertySheetT<TBase>::GetTabControl() const + { ATLASSERT(::IsWindow(m_hWnd)); return (HWND)::SendMessage(m_hWnd, PSM_GETTABCONTROL, 0, 0); } + +// Press Button on Property Sheet +template <class TBase> +bool CPropertySheetT<TBase>::PressButton(int nButton) + { ATLASSERT(::IsWindow(m_hWnd)); return ::SendMessage(m_hWnd, PSM_PRESSBUTTON, nButton, 0) ? true : false; } + +// Get the Active Page +template <class TBase> +CPropertyPageT<TBase>* CPropertySheetT<TBase>::GetActivePage() const + { return GetPage(GetActiveIndex()); } + +// Change the Title +template <class TBase> +void CPropertySheetT<TBase>::SetTitle(LPCTSTR lpszText, UINT nStyle) +{ + ATLASSERT((nStyle & ~PSH_PROPTITLE) == 0); // only PSH_PROPTITLE is valid + + // Set Internal State + if(m_szCaption && _tcslen(m_szCaption) < _tcslen(lpszText)) + { + delete[] m_szCaption; + m_szCaption = NULL; + } + + if(!m_szCaption) + m_szCaption = new TCHAR[_tcslen(lpszText) + 1]; + + _tcscpy(m_szCaption, lpszText); + m_psh.pszCaption = m_szCaption; + + // Set the options + m_psh.dwFlags &= ~PSH_PROPTITLE; + m_psh.dwFlags |= nStyle; + + if (m_hWnd != NULL) + { + // set external state + SendMessage(PSM_SETTITLE, nStyle, (LPARAM)lpszText); + } +} + +// Make us a Wizard +template <class TBase> +void CPropertySheetT<TBase>::SetWizardMode() + { m_psh.dwFlags |= PSH_WIZARD; } + +template <class TBase> +void CPropertySheetT<TBase>::SetHelp(bool bHelp) +{ + if(bHelp) + m_psh.dwFlags |= PSH_HASHELP; + else + m_psh.dwFlags &= ~(PSH_HASHELP); +} + +// Set Text of Finish Button +template <class TBase> +void CPropertySheetT<TBase>::SetFinishText(LPCTSTR lpszText) + { ATLASSERT(::IsWindow(m_hWnd)); ::SendMessage(m_hWnd, PSM_SETFINISHTEXT, 0, (LPARAM)lpszText); } + +// Choose which buttons to have in Wizard +template <class TBase> +void CPropertySheetT<TBase>::SetWizardButtons(DWORD dwFlags) + { ATLASSERT(::IsWindow(m_hWnd)); ::PostMessage(m_hWnd, PSM_SETWIZBUTTONS, 0, dwFlags); } + +// Stacked Tabs +template <class TBase> +void CPropertySheetT<TBase>::EnableStackedTabs(BOOL bStacked) + { m_bStacked = bStacked; } + +typedef CPropertySheetT<CWindow> CPropertySheet; +typedef CPropertyPageT<CWindow> CPropertyPage; + +#endif // !defined(AFX_PROPERTYPAGE_H__1508DAF4_7AD1_11D3_BF96_0020182B97FC__INCLUDED_) diff --git a/win32/common/atlwinhk.h b/win32/common/atlwinhk.h new file mode 100644 index 0000000..4dddf82 --- /dev/null +++ b/win32/common/atlwinhk.h @@ -0,0 +1,151 @@ +/* + * AUTHOR + * N. Nielsen + * + * VERSION + * 2.2.0b + * + * 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> + */ + +#ifndef __ATLWINHK_H__ +#define __ATLWINHK_H__ + +///////////////////////////////////////////////////////////////////////// +// Hooks an CWindowImpl to windows that the API or other code creates +// By Stef: 06/10/99 + + +// Use this macro in the class definition and pass class name +// as first param +#define DECLARE_HOOK_AND_SUBCLASS(Class) \ + HHOOK m_hHookCur; \ + static LRESULT CALLBACK HookCreateProc(int nCode, \ + WPARAM wParam, \ + LPARAM lParam) \ + { \ + Class* pThis = (Class*) _Module.ExtractCreateWndData(); \ + \ + if (nCode != HCBT_CREATEWND) \ + { \ + /*Add it back again*/ \ + _Module.AddCreateWndData(&(pThis->m_thunk.cd), pThis); \ + /*wait for HCBT_CREATEWND just pass others on...*/ \ + return CallNextHookEx(pThis->m_hHookCur, nCode, wParam, lParam); \ + } \ + \ + pThis->SubclassWindow((HWND)wParam); \ + \ + UnhookWindowsHookEx(pThis->m_hHookCur); \ + HHOOK hHookCur = pThis->m_hHookCur; \ + pThis->m_hHookCur = NULL; \ + \ + return CallNextHookEx(hHookCur, nCode, wParam, lParam); \ + } + +// Use this *immediately* before the code that creates the window +// It will subclass the first window that's created by that thread +// so add immediately before. +#define HOOK_AND_SUBCLASS_NEXT() \ + ((m_hHookCur = SetWindowsHookEx(WH_CBT, HookCreateProc, NULL, ::GetCurrentThreadId())) == NULL) + +const LPCTSTR kDialogClass = (LPCTSTR)0x00008002; + +template<class _Class> +class CHookWindow +{ +public: + CHookWindow() + { + m_hHookCur = NULL; + m_szHookClass = NULL; + m_szHookName = NULL; + } + + bool SubclassNext(LPCTSTR szClass = NULL, LPCTSTR szName = NULL) + { + _Class* pThis = (_Class*)this; + _Module.AddCreateWndData(&(pThis->m_thunk.cd), pThis); + + m_hHookCur = SetWindowsHookEx(WH_CBT, HookCreateProc, NULL, ::GetCurrentThreadId()); + + if(m_hHookCur) + { + m_szHookClass = szClass; + m_szHookName = szName; + } + + return m_hHookCur == NULL; + } + + static LRESULT CALLBACK HookCreateProc(int nCode, WPARAM wParam, LPARAM lParam) + { + _Class* pThis = (_Class*) _Module.ExtractCreateWndData(); + HHOOK hHookCur = pThis->m_hHookCur; + + bool bSkip = false; + + if(nCode != HCBT_CREATEWND) + { + bSkip = true; + } + else + { + CBT_CREATEWND* pCreate = (CBT_CREATEWND*)lParam; + + if(pThis->m_szHookClass) + { + // If it's not a pointer (for at least two bytes) + if(IsBadReadPtr(pCreate->lpcs->lpszClass, 2) || IsBadReadPtr(pThis->m_szHookClass, 2)) + // Then just compare values + bSkip = pCreate->lpcs->lpszClass != pThis->m_szHookClass; + + else + // Otherwise compare strings + bSkip = _tcsicmp(pCreate->lpcs->lpszClass, pThis->m_szHookClass) != 0; + } + + if(pThis->m_szHookName) + { + if(IsBadReadPtr(pCreate->lpcs->lpszName, _tcslen(pThis->m_szHookName)) || + _tcsicmp(pCreate->lpcs->lpszName, pThis->m_szHookName)) + bSkip = true; + } + } + + if(bSkip) + { + /*Add it back again*/ + _Module.AddCreateWndData(&(pThis->m_thunk.cd), pThis); + } + else + { + pThis->SubclassWindow((HWND)wParam); + + UnhookWindowsHookEx(pThis->m_hHookCur); + pThis->m_hHookCur = NULL; + } + + return CallNextHookEx(hHookCur, nCode, wParam, lParam); + } + +protected: + HHOOK m_hHookCur; + LPCTSTR m_szHookName; + LPCTSTR m_szHookClass; +}; + + +#endif //__ATLWINHK_H__ diff --git a/win32/common/droplet.cpp b/win32/common/droplet.cpp new file mode 100644 index 0000000..e796f49 --- /dev/null +++ b/win32/common/droplet.cpp @@ -0,0 +1,226 @@ +/* + * 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 "lib/rep.h" +#include "common/binfile.h" +#include "common/repfile.h" +#include "Droplet.h" + +// (Con|De)struction: -------------------------------------------- + +Droplet::Droplet() +{ + m_keepBackups = false; + memset(&m_ctx, 0, sizeof(m_ctx)); +} + +Droplet::~Droplet() +{ + repFree(&m_ctx); +} + + +// All error handling jumps to 'cleanup' where wrapping up loose +// ends is done +#define RETURN(v) { ret = v; goto cleanup; } + + +// save: --------------------------------------------------- +// Saves a droplet to a file. The file must already exist +// and must be an executable + +bool Droplet::save(LPCTSTR fileName) +{ + HANDLE update = NULL; + void* data = NULL; + BFILE h = NULL; + bool ret = true; + + { + if(!m_ctx.script.ops) + RETURN(false); + + // Make the rep binfile + bfval val; + BFILE h = bfStartMem(NULL, 0, BF_REALLOC); + if(!h) RETURN(false); + + // Write out the headers + repfWriteHeader(h); + + // Write to it now + if(m_ctx.block != 0) + bfWriteInt(h, REPVAL_BUFSIZE, m_ctx.block); + + bfWriteInt(h, DROPVAL_BACKUPS, m_keepBackups ? 1 : 0); + + // Write the script out + val.id = REPVAL_SCRIPT; + val.len = m_ctx.script.len; + val.type = BINTYPE_DATA; + bfWriteValue(h, &val, m_ctx.script.ops); + + if(!m_title.empty()) + bfWriteString(h, DROPVAL_TITLE, m_title.c_str()); + + // Done + bfWriteEnd(h); + if(bfError(h)) RETURN(false); + + size_t len = bfCount(h); + data = bfInternal(h); + bfClose(h); + h = NULL; + + // Now actually modify the EXE + update = BeginUpdateResource(fileName, FALSE); + if(!update) RETURN(false); + + if(!UpdateResource(update, DROP_RESOURCE_TYPE, DROP_RESOURCE_ID, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), data, len) + || !EndUpdateResource(update, FALSE)) + RETURN(false); + + update = NULL; + } + +cleanup: + while(data) + { + free(data); + + if(h == NULL) + break; + + data = bfInternal(h); + bfClose(h); + h = NULL; + } + + if(update) + EndUpdateResource(update, TRUE); + + return true; +} + + +// load: --------------------------------------------------------------- +// Load a droplet from a file + +bool Droplet::load(LPCTSTR fileName) +{ + HMODULE module = LoadLibrary(fileName); + if(!module) + return false; + + bool ret = load(GetModuleHandle(fileName)); + + FreeLibrary(module); + + return ret; +} + + +// load: --------------------------------------------------------------- +// Load a droplet from a loaded module + +bool Droplet::load(HMODULE module) +{ + bool ret = true; + BFILE h = NULL; + + { + // In case we're called twice + repFree(&m_ctx); + + // Load the resource + HRSRC hRsrc = FindResourceEx(module, DROP_RESOURCE_TYPE, DROP_RESOURCE_ID, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)); + if(!hRsrc) RETURN(false); + + HGLOBAL hGlobal = LoadResource(module, hRsrc); + if(!hGlobal) RETURN(false); + + void* data = LockResource(hGlobal); + if(!data) RETURN(false); + + ::SetLastError(0); + + // And now read it + h = bfStartMem(data, SizeofResource(module, hRsrc), 0); + if(!h) RETURN(false); + + // Check the format + if(!repfReadHeader(h)) + RETURN(false); + + bfval val; + + while(bfReadValueInfo(h, &val)) + { + switch(val.id) + { + case REPVAL_BUFSIZE: + bfReadValueData(h, &val, &(m_ctx.block)); + continue; + + case DROPVAL_BACKUPS: + { + long value; + bfReadValueData(h, &val, &value); + m_keepBackups = value == 0 ? false : true; + } + continue; + + case REPVAL_SCRIPT: + { + // Script must have some length + if(val.len == 0) + RETURN(false); + + m_ctx.script.ops = (byte*)malloc(val.len); + if(!m_ctx.script.ops) + RETURN(false); + + bfReadValueData(h, &val, m_ctx.script.ops); + m_ctx.script.len = val.len; + } + continue; + + case DROPVAL_TITLE: + { + bfReadValueData(h, &val, m_title.get_buffer(val.len)); + m_title.release_buffer(); + } + continue; + + } + + bfSkipValueData(h, &val); + } + } + +cleanup: + if(h) + bfClose(h); + + return ret; +} + diff --git a/win32/common/droplet.h b/win32/common/droplet.h new file mode 100644 index 0000000..e98725e --- /dev/null +++ b/win32/common/droplet.h @@ -0,0 +1,98 @@ +/* + * 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> + */ + + +#ifndef __DROPLET_H__ +#define __DROPLET_H__ + + +// The resources in the droplet +#define DROP_RESOURCE_TYPE _T("REP") +#define DROP_RESOURCE_ID _T("SCRIPT") +#define DROP_RESOURCE_FILE _T("DROPLET") + +// Some extra binfile tags +#define DROPVAL_TITLE 0x0101 +#define DROPVAL_BACKUPS 0x0102 + +#include "lib/rlib.h" +#include "lib/rep.h" + + +// Droplet: --------------------------------------------------------------- +// A droplet provides the saving/loading/loaded functionality of the +// droplet. Replaces are not done here + +class Droplet +{ +public: + Droplet(); + ~Droplet(); + + // Load a droplet from a file + bool load(LPCTSTR fileName); + + // Load a droplet from a loaded executable + bool load(HMODULE module); + + // Save a droplet out to an existing executable + bool save(LPCTSTR fileName); + + + // Get the internal rlib stream + r_context& getContext() + { return m_ctx; } + + // Is there a valid script loaded + bool hasScript() + { return m_ctx.script.ops != NULL; } + + // Get dialog title stored in droplet + string getTitle() + { return m_title; } + + // Set dialog title stored in droplet + void setTitle(astring& title) + { m_title = title; } + + // Get the buffer size stored in droplet + // 0 = process entire file + size_t getBuffSize() + { return m_ctx.block; } + + // Set the buffer size to be stored in droplet + void setBuffSize(size_t buffSize) + { m_ctx.block = buffSize; } + + // Should backups be kept? + bool keepBackups() + { return m_keepBackups; } + + // Set backup options for droplet + void setBackups(bool backups) + { m_keepBackups = backups; } + +protected: + r_context m_ctx; + + astring m_title; // The dialog title + bool m_keepBackups; // Should backups be kept? +}; + +#endif //__DROPLET_H__
\ No newline at end of file diff --git a/win32/common/errutil.cpp b/win32/common/errutil.cpp new file mode 100644 index 0000000..302b4fa --- /dev/null +++ b/win32/common/errutil.cpp @@ -0,0 +1,106 @@ +/* + * 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 "rliberr.h" +#include "errutil.h" + +// rlibError: ------------------------------------------------------------- +// Displays errors from rlib. Assumes we have the appropriate +// error codes compiled in as resources + +HRESULT rlibError(HWND parent, int code, r_script* script) +{ + ASSERT(code < 0); + USES_CONVERSION; + + LPVOID lpMsgBuf; + HRESULT hr = HRESULT_FROM_RLIB(code); + string message; + + DWORD dwRet = ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | + FORMAT_MESSAGE_MAX_WIDTH_MASK, GetModuleHandle(NULL), hr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR)&lpMsgBuf, 0, NULL); + if(dwRet && lpMsgBuf) + { + message.append((LPTSTR)lpMsgBuf); + + // Free the buffer. + ::LocalFree(lpMsgBuf); + + // If there was a specific error message then tack that on + if(script->error) + { + message.append(_T("\n\n")); + message.append(A2T(script->error)); + } + + // If there's an error line then tack that on + if(script->errline != 0) + { + string line; + line.format(_T(" (near line %d)"), script->errline); + message.append(line); + } + + MessageBox(parent, message.c_str(), _T("Rep Droplet"), MB_OK | MB_ICONSTOP); + } + + return hr; +} + + +// errorMessage: ----------------------------------------------------------- +// Displays standard windows errors. + +HRESULT errorMessage(HWND parent, HRESULT hr, LPCTSTR format, ...) +{ + string message; + + va_list ap; + va_start(ap, format); + + message.format_v(format, ap); + + va_end(ap); + + if(FAILED(hr)) + { + LPVOID lpMsgBuf; + + DWORD dwRet = ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, hr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, 0, NULL); + if(dwRet && lpMsgBuf) + { + message.append(_T("\n\n")); + message.append((LPTSTR)lpMsgBuf); + message.resize(message.size() - 2); // Take off new line + + // Free the buffer. + ::LocalFree(lpMsgBuf); + } + } + + MessageBox(parent, message.c_str(), _T("Rep Droplet"), MB_OK | MB_ICONSTOP); + + return hr == S_OK ? E_FAIL : hr; +} diff --git a/win32/common/errutil.h b/win32/common/errutil.h new file mode 100644 index 0000000..0804149 --- /dev/null +++ b/win32/common/errutil.h @@ -0,0 +1,32 @@ +/* + * 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> + */ + +#ifndef __ERRUTIL_H__ +#define __ERRUTIL_H__ + +#include "lib/rlib.h" + +// Display a standard windows error message +HRESULT errorMessage(HWND parent, HRESULT hr, LPCTSTR format, ...); + +// Display an rlib error message +HRESULT rlibError(HWND parent, int code, r_script* script); + + +#endif //__ERRUTIL_H__
\ No newline at end of file diff --git a/win32/common/mystring.h b/win32/common/mystring.h new file mode 100644 index 0000000..470ac3c --- /dev/null +++ b/win32/common/mystring.h @@ -0,0 +1,536 @@ +/* + * 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> + */ + +#if !defined(_MYSTRING_H_) +#define _MYSTRING_H_ + +////////////////////////////////////////////////////////////////////////////// + +#include <tchar.h> + +#include <stdarg.h> + +#include <string> +#include <locale> + +#pragma warning(push) +#pragma warning(disable:4786) // Disable warning for names > 256 + +////////////////////////////////////////////////////////////////////////////// + +template<typename T> +class stringT : public std::basic_string<T> // T should be either char or wchar_t +{ +public: + // Constructors + stringT() + : std::basic_string<T>() + { } + + stringT(const stringT<T>& strInput) + : std::basic_string<T>(strInput) + { } + + + stringT(const std::basic_string<T>& strInput) + : std::basic_string<T>(strInput) + { } + + stringT(const std::basic_string<T>& strInput, size_type pos, size_type n) + : std::basic_string<T>(strInput, pos, n) + { } + + stringT(const std::basic_string<T>::const_iterator first, + const std::basic_string<T>::const_iterator last) + : std::basic_string<T>(first, last) + { } + + + stringT(const T* strInput) + : std::basic_string<T>(strInput) + { } + + + stringT(const T* strInput, size_type n) + : std::basic_string<T>(strInput, n) + { } + + +#ifdef _INC_COMDEF + stringT(_bstr_t bstr) + { + (*this) = (const T*)bstr; + } +#endif + + stringT(T ch, int nRepeat = 1) + : std::basic_string<T>(nRepeat, ch) + { } + + + // Other Conversions + stringT<T>& make_upper() + { + std::ctype<T> c; + T* p = get_buffer(); + c.toupper(p, p + size()); + release_buffer(); + return *this; + } + + stringT<T> upper() const + { + stringT<T> sTmp(*this); + sTmp.make_upper(); + return sTmp; + } + + stringT<T>& make_lower() + { + std::ctype<T> c; + T* p = get_buffer(); + c.tolower(p, p + size()); + release_buffer(); + return *this; + } + + stringT<T> lower() const + { + stringT<T> sTmp(*this); + sTmp.make_lower(); + return sTmp; + } + + void trim_left() + { + // TODO: Optimize + while(!empty() && _istspace(at(0))) + erase(0, 1); + } + + void trim_right() + { + // TODO: Optimize + while(!empty() && _istspace(at(length()-1))) + erase(length() - 1, 1); + } + + void trim() + { + trim_left(); + trim_right(); + } + + const stringT<T>& format(const T* pszFormat, ...) + { + va_list vl; + va_start(vl, pszFormat); + format_v(pszFormat, vl); + va_end(vl); + + return *this; + } + +#ifdef _WINDOWS_ + + const stringT<T>& format(HINSTANCE hInst, UINT nID, ... ) + { + stringT<T> sTemp; + sTemp.load_string(hInst, nID); + + va_list vl; + va_start(vl, nID); + format_v(sTemp, vl); + va_end(vl); + + return *this; + } + +#ifdef __ATLBASE_H__ + const stringT<T>& format(UINT nID, ... ) + { + stringT<T> sTemp; + sTemp.load_string(nID); + + va_list vl; + va_start(vl, nID); + format_v(sTemp, vl); + va_end(vl); + + return *this; + } +#endif // __ATLBASE_H__ + +#endif + + void format_v(const char* pszFormat, va_list vl) + { + // Copied Code.... + + // Doesn't have all the features of CString::Format() + T* pszTemp = NULL; + size_t nBufferSize = 32; + int nRetVal = -1; + + do + { + // Double the buffer size for next time around + nBufferSize += nBufferSize; + delete [] pszTemp; + pszTemp = new T [nBufferSize]; + nRetVal = _vsnprintf(pszTemp, nBufferSize, pszFormat, vl); + } while (nRetVal < 0); + + *this = pszTemp; + delete [] pszTemp; + + return; + } + + void format_v(const wchar_t* pszFormat, va_list vl) + { + // Copied Code.... + + // Doesn't have all the features of CString::Format() + T* pszTemp = NULL; + size_t nBufferSize = 32; + int nRetVal = -1; + + do + { + // Double the buffer size for next time around + nBufferSize += nBufferSize; + delete [] pszTemp; + pszTemp = new T [nBufferSize]; + nRetVal = _vsnwprintf(pszTemp, nBufferSize, pszFormat, vl); + } while (nRetVal < 0); + + *this = pszTemp; + delete [] pszTemp; + + return; + } + + int replace(const std::basic_string<T>& sFind, const std::basic_string<T>& sReplace, bool bMultiple = true, size_type nStart = 0) + { + stringT<T> sTemp = *this; + int nReplaced = 0; + + if((nStart = sTemp.find(sFind, nStart)) != npos) + { + sTemp.erase(nStart, sFind.length()); + sTemp.insert(nStart, sReplace); + nReplaced++; + } + + while(bMultiple && (nStart = sTemp.find(sFind, nStart + 1)) != npos) + { + sTemp.erase(nStart, sFind.length()); + sTemp.insert(nStart, sReplace); + nReplaced++; + } + + *this = sTemp; + return nReplaced; + } + + // Operators + + T operator[](int nIndex) const + { return at(nIndex); }; + +#ifdef _INC_COMDEF + operator _bstr_t() const + { return _bstr_t(c_str()); }; +#endif + + operator const T*() const + { return c_str(); }; + + + // Buffer Operations + // Derived code from MFC CString + T* get_buffer(size_t sz = npos) + { + if(sz == npos) + sz = size(); + + resize(sz + 1); + // Make sure we generate a write command + // so we have no extra references + // TODO: Does basic_string use reference counting? + // (much later) A: Yes it does! Reference is in the bytes before data + at(sz) = 0; + return const_cast<T*>(data()); + } + + void release_buffer() + { + if(!empty()) + { + // Make sure we generate a write command + // Find the null terminated end + for(string::size_type i = 0; i < capacity() && i < size(); i++) + if(at(i) == 0) + break; + + ASSERT(i != capacity()); + resize(i); + } + } + + void clear() + { resize(0); } + +#ifdef _WINDOWS_ + bool load_string(HINSTANCE hInst, unsigned int nID) + { + string::size_type nSize = 0x80; + do + { + release_buffer(); + nSize *= 2; + } + while(load_string(hInst, nID, get_buffer(nSize), nSize) == nSize); + + release_buffer(); + return nSize > 0; + } +#endif // WIN32 + +#ifdef __ATLBASE_H__ + bool load_string(unsigned int nID) + { + string::size_type nSize = 0x80; + do + { + release_buffer(); + nSize *= 2; + } + while(load_string(_Module.m_hInstResource, nID, get_buffer(nSize), nSize) == nSize); + + release_buffer(); + return nSize > 0; + } +#endif // __ATLBASE_H__ + + +protected: + +#ifdef _WINDOWS_ + + static int load_string(HINSTANCE hInst, UINT nID, char* pBuff, size_t nSize) + { + return ::LoadStringA(hInst, nID, pBuff, nSize); + } + + static int load_string(HINSTANCE hInst, UINT nID, wchar_t* pBuff, size_t nSize) + { +#ifdef _UNICODE + return ::LoadStringW(hInst, nID, pBuff, nSize); +#else + char* pABuff = new char[nSize]; + if(!pABuff) return 0; + + int nRet = load_string(hInst, nID, pABuff, nSize); + if(nRet) + { + pBuff[0] = L'\0'; + MultiByteToWideChar(GetACP(), 0, pABuff, -1, pBuff, nSize); + } + + return nRet; +#endif + } + + + +#endif + + +}; + + #ifndef _UNICODE + typedef stringT<char> string; + #else + typedef stringT<wchar_t> string; + #endif + + typedef stringT<char> astring; + typedef stringT<wchar_t> wstring; + + +template<typename T> +class cstringT +{ +public: + cstringT() + { clear(); }; + cstringT(const T* ptr, size_t len) + { set(ptr, len); }; + + operator stringT<T>() const + { + if(_Ptr) + return stringT<T>(_Ptr, _Len); + else + return stringT<T>(); + }; + + bool is_null() const + { return _Ptr ? false : true; } + // TODO: Maybe some validity checks + void set(const T* ptr, size_t len) + { _Ptr = ptr; _Len = len; } + void clear() + { _Ptr = 0; _Len = 0; } + +protected: + const T* _Ptr; + size_t _Len; +}; + + + #ifndef _UNICODE + typedef cstringT<char> cstring; + #else + typedef cstringT<wchar_t> cstring; + #endif + + typedef cstringT<char> castring; + typedef cstringT<wchar_t> cwstring; + + + +#include <vector> +#include <algorithm> + +template<typename S> +class string_arrayT : public std::vector<S> +{ +public: + string_arrayT(const std::vector<S> & x) + : std::vector<S>(x) {}; + string_arrayT(string_arrayT & x) + : std::vector<S>(x) {}; + string_arrayT(std::vector<S>::const_iterator first, std::vector<S>::const_iterator last, const std::vector<S>::allocator_type& al = std::vector<S>::allocator_type()) + : std::vector<S>(first, last, al) {}; + explicit string_arrayT(const const std::vector<S>::allocator_type& al = std::vector<S>::allocator_type()) + : std::vector<S>(al) {}; + explicit string_arrayT(std::vector<S>::size_type n, const std::vector<S>::value_type& v = std::vector<S>::value_type(), const std::vector<S>::allocator_type& al = std::vector<S>::allocator_type()) + : std::vector<S>(n, v, al) {}; + + std::vector<S>::size_type split(S sIn, S sDelim, bool bTrim = false) + { + S::size_type start = 0; + S::size_type ed = 0; + std::vector<S>::size_type cnt = 0; + S::size_type lenDelim = sDelim.size(); + S sTemp; + + if(lenDelim == 0) + { + if(bTrim) + sIn.trim(); + push_back(sIn); + return 1; + } + + while(ed != string::npos) + { + ed = sIn.find(sDelim, start); + if(ed == string::npos) + sTemp = sIn.substr(start); + else + sTemp = sIn.substr(start, ed - start); + + if(bTrim) + sTemp.trim(); + + push_back(sTemp); + + cnt++; + + start = ed + lenDelim; + } + + return cnt; + } + + S join(S sDelim) const + { + S sTemp; + const_iterator it = begin(); + const_iterator ed = end(); + + while(it != ed) + { + sTemp += *it; + it++; + } + + return sTemp; + } + + class no_case + { + public: + no_case(const S& s) : _str(s) + { _str.make_lower(); } + + bool operator()(const S& s) + { return s.lower() == _str; } + protected: + S _str; + }; + + bool has(S sVal, bool bCase = true) const + { return find(sVal, bCase) != end(); } + + const_iterator find(S sVal, bool bCase = true) const + { + if(bCase) + return std::find(begin(), end(), sVal); + else + { + no_case fndr(sVal); + return std::find_if(begin(), end(), fndr); + } + } + + iterator find(S sVal, bool bCase = true) + { + if(bCase) + return std::find(begin(), end(), sVal); + else + { + no_case fndr(sVal); + return std::find_if(begin(), end(), fndr); + } + } +}; + +typedef string_arrayT< string > string_array; +typedef string_arrayT< wstring > wstring_array; + +////////////////////////////////////////////////////////////////////////////// + +#pragma warning( pop ) + +#endif // !defined(_MYSTRING_H_) diff --git a/win32/common/rep.ico b/win32/common/rep.ico Binary files differnew file mode 100644 index 0000000..51cf5f8 --- /dev/null +++ b/win32/common/rep.ico diff --git a/win32/common/rliberr.h b/win32/common/rliberr.h new file mode 100644 index 0000000..8fe3a80 --- /dev/null +++ b/win32/common/rliberr.h @@ -0,0 +1,136 @@ +/* + * AUTHOR + * N. Nielsen + * + * VERSION + * 2.2.0b + * + * 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> + */ + +#ifndef _RLIBERR_H_ +#define _RLIBERR_H_ + +#ifndef _WINERROR_ + #error Include winerror.h first. +#endif + +#define HRESULT_FROM_RLIB(code) \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_RLIB, abs(code)) + +/* ------------------------------------------------------------------------ *\ + Rlib Errors +\* ------------------------------------------------------------------------ */ +// +// Values are 32 bit values layed out as follows: +// +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +// +---+-+-+-----------------------+-------------------------------+ +// |Sev|C|R| Facility | Code | +// +---+-+-+-----------------------+-------------------------------+ +// +// where +// +// Sev - is the severity code +// +// 00 - Success +// 01 - Informational +// 10 - Warning +// 11 - Error +// +// C - is the Customer code flag +// +// R - is a reserved bit +// +// Facility - is the facility code +// +// Code - is the facility's status code +// +// +// Define the facility codes +// +#define FACILITY_RLIB 0x196 + + +// +// Define the severity codes +// + + +// +// MessageId: RLIB_E_NOMEM +// +// MessageText: +// +// Out of Memory. +// +#define RLIB_E_NOMEM ((HRESULT)0x81960001L) + +// +// MessageId: RLIB_E_SYNTAX +// +// MessageText: +// +// Rep script syntax error. +// +#define RLIB_E_SYNTAX ((HRESULT)0x81960002L) + +// +// MessageId: RLIB_E_REGEXP +// +// MessageText: +// +// Regular expression syntax error. +// +#define RLIB_E_REGEXP ((HRESULT)0x81960003L) + +// +// MessageId: RLIB_E_LOOP +// +// MessageText: +// +// Rep encountered an endless loop. +// +#define RLIB_E_LOOP ((HRESULT)0x81960004L) + +// +// MessageId: RLIB_E_USER +// +// MessageText: +// +// User defined error. +// +#define RLIB_E_USER ((HRESULT)0x81960005L) + +// +// MessageId: RLIB_E_IOERR +// +// MessageText: +// +// There was an error reading or writing the data. +// +#define RLIB_E_IOERR ((HRESULT)0x81960006L) + +// +// MessageId: RLIB_E_INVARG +// +// MessageText: +// +// Programmer Error: Invalid argument. +// +#define RLIB_E_INVARG ((HRESULT)0x8196000AL) + +#endif // _RLIBERR_H_
\ No newline at end of file diff --git a/win32/common/rliberr.mc b/win32/common/rliberr.mc new file mode 100644 index 0000000..50ac61f --- /dev/null +++ b/win32/common/rliberr.mc @@ -0,0 +1,106 @@ +;/* +; * AUTHOR +; * N. Nielsen +; * +; * VERSION +; * 2.2.0b +; * +; * 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> +; */ +; +;#ifndef _RLIBERR_H_ +;#define _RLIBERR_H_ +; +;#ifndef _WINERROR_ +; #error Include winerror.h first. +;#endif +; +;#define HRESULT_FROM_RLIB(code) \ +; MAKE_HRESULT(SEVERITY_ERROR, FACILITY_RLIB, abs(code)) +; + +SeverityNames=( + Success=0x0 + Error=0x2 + ) + + +MessageIdTypedef=HRESULT +FacilityNames=( + System=0FF + Rlib=406:FACILITY_RLIB + ) + +;/* ------------------------------------------------------------------------ *\ +; Rlib Errors +;\* ------------------------------------------------------------------------ */ + +MessageId=1 +Severity=Error +Facility=Rlib +SymbolicName=RLIB_E_NOMEM +Language=English +Out of Memory. +. + +MessageId=2 +Severity=Error +Facility=Rlib +SymbolicName=RLIB_E_SYNTAX +Language=English +Rep script syntax error. +. + +MessageId=3 +Severity=Error +Facility=Rlib +SymbolicName=RLIB_E_REGEXP +Language=English +Regular expression syntax error. +. + +MessageId=4 +Severity=Error +Facility=Rlib +SymbolicName=RLIB_E_LOOP +Language=English +Rep encountered an endless loop. +. + +MessageId=5 +Severity=Error +Facility=Rlib +SymbolicName=RLIB_E_USER +Language=English +User defined error. +. + +MessageId=6 +Severity=Error +Facility=Rlib +SymbolicName=RLIB_E_IOERR +Language=English +There was an error reading or writing the data. +. + +MessageId=10 +Severity=Error +Facility=Rlib +SymbolicName=RLIB_E_INVARG +Language=English +Programmer Error: Invalid argument. +. + +;#endif // _RLIBERR_H_
\ No newline at end of file diff --git a/win32/droplet/Makefile.am b/win32/droplet/Makefile.am new file mode 100644 index 0000000..5a5ca0a --- /dev/null +++ b/win32/droplet/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = droplet.dsp droplet.rc dropletmain.cpp progressdlg.h progressdlg.cpp replace.cpp replace.h resource.h stdafx.h stdafx.cpp temp.rep + diff --git a/win32/droplet/droplet.dsp b/win32/droplet/droplet.dsp new file mode 100644 index 0000000..579b546 --- /dev/null +++ b/win32/droplet/droplet.dsp @@ -0,0 +1,223 @@ +# Microsoft Developer Studio Project File - Name="droplet" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=droplet - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "droplet.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "droplet.mak" CFG="droplet - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "droplet - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "droplet - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "droplet - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "debug" +# PROP Intermediate_Dir "debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../.." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 libpcre.a kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x500000" /subsystem:windows /debug /machine:I386 /out:"../debug/droplet.exe" /pdbtype:sept /libpath:"..\win32\pcre\lib\\" /libpath:"..\pcre\lib\\" + +!ELSEIF "$(CFG)" == "droplet - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "release" +# PROP Intermediate_Dir "release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /W3 /GX /O1 /I "../.." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 libpcre.a kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x500000" /subsystem:windows /machine:I386 /out:"../release/droplet.exe" /libpath:"..\pcre\lib\\" /opt:nowin98 +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "droplet - Win32 Debug" +# Name "droplet - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\common\droplet.cpp +# End Source File +# Begin Source File + +SOURCE=.\droplet.rc +# End Source File +# Begin Source File + +SOURCE=.\dropletmain.cpp +# End Source File +# Begin Source File + +SOURCE=..\common\errutil.cpp +# End Source File +# Begin Source File + +SOURCE=.\ProgressDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\Replace.cpp +# End Source File +# Begin Source File + +SOURCE=..\common\rliberr.mc + +!IF "$(CFG)" == "droplet - Win32 Debug" + +# Begin Custom Build +InputPath=..\common\rliberr.mc +InputName=rliberr + +"$(InputName).rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + mc $(InputPath) + copy $(InputName).h ..\Common + +# End Custom Build + +!ELSEIF "$(CFG)" == "droplet - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build +InputPath=..\common\rliberr.mc +InputName=rliberr + +"$(InputName).rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + mc $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=.\temp.rep + +!IF "$(CFG)" == "droplet - Win32 Debug" + +# Begin Custom Build +InputPath=.\temp.rep + +"temp.cmp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ..\debug\repc.exe temp.rep temp.cmp + +# End Custom Build + +!ELSEIF "$(CFG)" == "droplet - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build +InputPath=.\temp.rep + +"temp.cmp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ..\release\repc.exe temp.rep temp.cmp + +# End Custom Build + +!ENDIF + +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\common\droplet.h +# End Source File +# Begin Source File + +SOURCE=.\ProgressDlg.h +# End Source File +# Begin Source File + +SOURCE=.\Replace.h +# End Source File +# Begin Source File + +SOURCE=.\Resource.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\MSG00001.bin +# End Source File +# Begin Source File + +SOURCE=..\common\rep.ico +# End Source File +# Begin Source File + +SOURCE=.\temp.cmp +# End Source File +# End Group +# End Target +# End Project +# Section droplet : {00000000-0000-0000-0000-800000800000} +# 1:15:IDD_PROGRESSDLG:101 +# End Section diff --git a/win32/droplet/droplet.rc b/win32/droplet/droplet.rc new file mode 100644 index 0000000..f0254d7 --- /dev/null +++ b/win32/droplet/droplet.rc @@ -0,0 +1,197 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// REP +// + +SCRIPT REP DISCARDABLE "temp.cmp" +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""winres.h""\r\n" + "\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 2,3,0,1 + PRODUCTVERSION 2,3,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Nate Nielsen\0" + VALUE "FileDescription", "rep droplet\0" + VALUE "FileVersion", "2, 3, 0, 1\0" + VALUE "InternalName", "droplet\0" + VALUE "LegalCopyright", "Copyright 2002, Nate Nielsen \0" + VALUE "LegalTrademarks", "\0" + VALUE "OLESelfRegister", "\0" + VALUE "OriginalFilename", "droplet.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "rep\0" + VALUE "ProductVersion", "2, 3, 0, 1\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_PROGRESSDLG DIALOG DISCARDABLE 0, 0, 219, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Rep processing files..." +FONT 8, "Tahoma" +BEGIN + PUSHBUTTON "Cancel",2,162,74,50,14 + LTEXT "Preparing...",IDC_FILENAME,7,51,205,8 + LTEXT "",IDC_STATUS,7,62,205,8 + CONTROL "",IDC_FLIP,"Static",SS_GRAYRECT,7,75,148,10 + CONTROL "",IDC_STATIC,"Static",SS_GRAYFRAME,7,75,148,10 + ICON IDI_REP,IDC_STATIC,14,14,20,20 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_PROGRESSDLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 212 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// 11 +// + +1 11 DISCARDABLE "MSG00001.bin" + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_REP ICON DISCARDABLE "..\\common\\rep.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_PROJNAME "droplet" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/win32/droplet/dropletmain.cpp b/win32/droplet/dropletmain.cpp new file mode 100644 index 0000000..9610ce2 --- /dev/null +++ b/win32/droplet/dropletmain.cpp @@ -0,0 +1,76 @@ +/* + * 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 "resource.h" +#include <initguid.h> +#include "replace.h" + +// ATL Support +CComModule _Module; + +BEGIN_OBJECT_MAP(ObjectMap) +END_OBJECT_MAP() + + +// _tWinMain: ------------------------------------------------------------- +// Our starting point. Silly name + +extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, + HINSTANCE /*hPrevInstance*/, LPTSTR /* lpCmdLine */, int /*nShowCmd*/) +{ + // ATL support + HRESULT hRes = CoInitialize(NULL); + _ASSERTE(SUCCEEDED(hRes)); + _Module.Init(ObjectMap, hInstance, NULL); + HRESULT hr = S_OK; + + // Make sure we have something to process + if(__argc <= 1) + { + MessageBox(NULL, _T("Drag and drop files onto this droplet to process them."), _T("Rep Droplet"), MB_OK | MB_ICONINFORMATION); + hr = E_FAIL; + } + + else + { + Replace replace; + if(SUCCEEDED(replace.initialize())) + { + for(int i = 1; i < __argc; i++) + { + // Process arguments appropriately + DWORD attrs = GetFileAttributes(__argv[i]); + if(attrs != 0xFFFFFFFF && attrs & FILE_ATTRIBUTE_DIRECTORY) + hr = replace.replaceFolder(__argv[i]); + else + hr = replace.replaceSingleFile(__argv[i]); + + if(FAILED(hr)) + break; + } + + replace.terminate(); + } + } + + _Module.Term(); + CoUninitialize(); + return SUCCEEDED(hr) ? 0 : 1; +} 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; +} + diff --git a/win32/droplet/progressdlg.h b/win32/droplet/progressdlg.h new file mode 100644 index 0000000..1e416a1 --- /dev/null +++ b/win32/droplet/progressdlg.h @@ -0,0 +1,92 @@ +/* + * 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> + */ + +#ifndef __PROGRESSDLG_H_ +#define __PROGRESSDLG_H_ + +#include "resource.h" // main symbols +#include <atlhost.h> + +// ProgressDlg: -------------------------------------------------------- +// The status dialog which is run in another thread + +class ProgressDlg : + public CDialogImpl<ProgressDlg> +{ +public: + ProgressDlg(); + ~ProgressDlg(); + + enum { IDD = IDD_PROGRESSDLG }; + +BEGIN_MSG_MAP(ProgressDlg) + MESSAGE_HANDLER(WM_INITDIALOG, onInitDialog) + MESSAGE_HANDLER(WM_CLOSE, onClose) + COMMAND_ID_HANDLER(IDCANCEL, onCancel) +END_MSG_MAP() + +public: + // Start dialog in another thread + HRESULT startDialog(); + + // Stop the dialog thread + int stopDialog(); + + // Called when a replacement is noted + void onReplaced(); + + // Called (by Replace::replaceSingleFile) when starting + // to process new file + void onNewFile(LPCTSTR fileName); + + // Polled (by Replace::matchStatus) to check if user cancelled + bool isCancelled(); + + // Set the dialog title + void setTitle(const string& title); + +protected: + // Update status etc... + void updateControls(); + +// The message handlers +protected: + LRESULT onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT onClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT onCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + + // Handler prototypes: + // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled); + +protected: + HANDLE m_hThread; // The dialog thread + string m_title; // The dialog title + + HANDLE m_hEvent; // dialog initialization event + CRITICAL_SECTION m_sec; // Used for syncing access to date below + + bool m_isCancelled; // Set when user clicks cancel + uint m_numFiles; // Number of files processed + uint m_numReplaces; // Number of replaces seen + bool m_flip; // Used for flicker display +}; + +#endif //__PROGRESSDLG_H_ diff --git a/win32/droplet/replace.cpp b/win32/droplet/replace.cpp new file mode 100644 index 0000000..8a7b51b --- /dev/null +++ b/win32/droplet/replace.cpp @@ -0,0 +1,438 @@ +/* + * 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 "Replace.h" +#include "common/errutil.h" +#include "common/rliberr.h" +#include "common/mystring.h" + + +// Error Macros: ------------------------------------------------- +// Display error messages and all that +// Only valid in this context +// Each of these jumps to the 'cleanup' label for wrapping +// up any open objects. + +#define RETURN(v) \ + { ret = (v); goto cleanup; } +#define WINERR(f) \ + { HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); RETURN(errorMessage(m_dlg.m_hWnd, hr, f)); } +#define WINERR_1(f, a) \ + { HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); RETURN(errorMessage(m_dlg.m_hWnd, hr, f, a)); } +#define WINERR_E(e, f) \ + { RETURN(errorMessage(m_dlg.m_hWnd, e, f)); } +#define REPERR(c, s) \ + { RETURN(rlibError(m_dlg.m_hWnd, c, s)); } + + +// The extension appended to backup or temp files +LPCTSTR kBackupExt = _T(".x_r"); + +// (Con|De)struction: ------------------------------------------- + +Replace::Replace() +{ + m_outFile = NULL; +} + +Replace::~Replace() +{ + ASSERT(m_outFile == NULL); +} + + +// initialize: --------------------------------------------------- +// Loads the script from resources and sets up dialog +// in another thread + +HRESULT Replace::initialize() +{ + HRESULT ret = S_OK; + + { + if(!m_droplet.load(GetModuleHandle(NULL))) + { + errorMessage(NULL, 0, _T("Couldn't access droplet rep script. The droplet is probably corrupted.")); + RETURN(E_FAIL); + } + + m_dlg.setTitle(m_droplet.getTitle()); + + r_context& ctx = m_droplet.getContext(); + + int r = repInit(&ctx); + if(r < 0) + REPERR(r, &(ctx.script)); + + // This starts the dialog in another thread + // in order to keep it responsive + m_dlg.startDialog(); + } + +cleanup: + return ret; +} + + +// terminate: ---------------------------------------------------- +// Undoes above + +HRESULT Replace::terminate() +{ + m_dlg.stopDialog(); + r_context& ctx = m_droplet.getContext(); + repFree(&ctx); + return S_OK; +} + + +// writeFile: ---------------------------------------------------- +// The callback called from within rlib when data output +// is required. The argument passed through the r_stream +// is a pointer to the Replace object. + +int Replace::writeFile(r_stream* stream, byte* data, size_t len) +{ + Replace* replace = (Replace*)stream->arg; + + // The m_outFile member should be set (and only set) + // whenever we're inside rlibRun + ASSERT(replace->m_outFile != NULL); + DWORD written = 0; + + // Double check that everything was written + return WriteFile(replace->m_outFile, data, len, &written, NULL) && len == written; +} + +// matchStatus: -------------------------------------------------- +// Callback whenever something is replaced in rlib +// Updates the dialog. + +int Replace::matchStatus(r_stream* stream, r_replace* repl) +{ + Replace* replace = (Replace*)stream->arg; + ASSERT_PTR(replace); + + replace->m_dlg.onReplaced(); + return replace->m_dlg.isCancelled() ? 1 : 0; +} + + +// replaceFolder: ------------------------------------------------ +// Recursively processes a folder using replaceSingleFile + +HRESULT Replace::replaceFolder(LPCTSTR folder) +{ + HANDLE hFindFile = NULL; + WIN32_FIND_DATA findData; + TCHAR old[260]; // Save the current folder (as we'll change it) + HRESULT ret = S_FALSE; + + { + // Backup the current directory + if(!GetCurrentDirectory(260, old)) + WINERR("Couldn't get the current directory."); + + if(!SetCurrentDirectory(folder)) + WINERR_1("Couldn't change the current directory to %s", folder); + + if(hFindFile = FindFirstFile(_T("*.*"), &findData)) + { + // And for every file + do + { + HRESULT r = S_FALSE; + if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if(findData.cFileName[0] == '.' && + (findData.cFileName[1] == '.' || findData.cFileName[1] == '\0')) + continue; + + r = replaceFolder(findData.cFileName); + } + else + { + r = replaceSingleFile(findData.cFileName); + } + + if(FAILED(r)) + RETURN(r); + if(r == S_OK) + ret = r; + } + while(FindNextFile(hFindFile, &findData)); + } + + // Make sure we didn't miss anything + if(::GetLastError() != 0 && ::GetLastError() != ERROR_NO_MORE_FILES) + WINERR_1("Couldn't list the directory %s", folder); + + // Change directory back + SetCurrentDirectory(old); + } + +cleanup: + if(hFindFile) + FindClose(hFindFile); + + return ret; +} + + +// replaceSingleFile: ---------------------------------------------- +// Process a file into a temp file or backup etc... +// Calls replaceFilename for actual processing + +HRESULT Replace::replaceSingleFile(LPCTSTR fileName) +{ + HRESULT ret = S_FALSE; + string temp; + USES_CONVERSION; + + r_context& ctx = m_droplet.getContext(); + + { + // Update the dialog display + m_dlg.onNewFile(fileName); + + // This lets us use the filename from within the script + ret = rlibSetVar(&(ctx.stream), "FILENAME", T2CA(fileName)); + if(ret < 0) + REPERR(ret, &(ctx.script)); + + // Make a temp/backup name + temp.assign(fileName); + temp.append(kBackupExt); + + // Now we do this 2 ways, if we're keeping backups then... + if(m_droplet.keepBackups()) + { + DeleteFile(temp); + + // Rename the original file to the backup + if(!MoveFile(fileName, temp)) + WINERR_1("There was an error while creating the backup file: %s", temp.c_str()); + + // Do a replacement operation back to the original + // from the backup + ret = replaceFilename(temp, fileName); + + // If there were no replacements + if(ret != S_OK) + { + DeleteFile(fileName); + + // And rename the backup file back + if(!MoveFile(temp, fileName)) + WINERR_1("There was an error while renaming the file: %s", fileName); + } + } + + // No backups, much faster (when there's no replacements)! + else + { + // Do a replacement operation to a temp file + ret = replaceFilename(fileName, temp); + + // If there were replacements + if(ret == S_OK) + { + DeleteFile(fileName); + + // Rename temp to original + if(!MoveFile(temp, fileName)) + WINERR_1("There was an error while renaming the file: %s", fileName); + } + + // If no replacements + else + { + // Remove temp file + DeleteFile(temp); + } + } + } + +cleanup: + + return ret; +} + +// replaceFilename: ------------------------------------------------- +// Process one file into another +// Open the files and passes them to replaceFile + +HRESULT Replace::replaceFilename(LPCTSTR fileIn, LPCTSTR fileOut) +{ + HANDLE in = INVALID_HANDLE_VALUE; + HANDLE out = INVALID_HANDLE_VALUE; + HRESULT ret = S_FALSE; + + { + // Basic readonly open + in = CreateFile(fileIn, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, 0, NULL); + if(in == INVALID_HANDLE_VALUE) + WINERR_1("There was an error opening the file: %s", fileIn); + + // We need to know whether we're NT or not below + OSVERSIONINFO os; + os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&os); + + // This creates a new file for writing + // If we're running on NT, then use exactly the same + // attributes and permissions as original file + out = CreateFile(fileOut, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, + os.dwPlatformId & VER_PLATFORM_WIN32_NT ? in : NULL); + if(out == INVALID_HANDLE_VALUE) + WINERR_1("There was an error opening the file: %s", fileIn); + + + // Do replacements! + ret = replaceFile(in, out); + + } + +cleanup: + + if(in != INVALID_HANDLE_VALUE) + CloseHandle(in); + if(out != INVALID_HANDLE_VALUE) + CloseHandle(out); + + return ret; +} + + +// replaceFile: -------------------------------------------------------- +// Process one open file handle into another +// This memory maps the input file and passes it to replaceBuffer + +HRESULT Replace::replaceFile(HANDLE in, HANDLE out) +{ + HANDLE mapping = NULL; + void* data = NULL; + HRESULT ret = S_FALSE; + + { + // Memory map the input file + mapping = CreateFileMapping(in, NULL, PAGE_READONLY, 0, 0, NULL); + if(!mapping) + WINERR("There was an error reading the input file."); + + data = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); + if(!data) + WINERR("There was an error reading the input file."); + + size_t size = GetFileSize(in, NULL); + if(size == INVALID_FILE_SIZE) + WINERR("There was an error reading the input file."); + + // And pass it on + ret = replaceBuffer((byte*)data, size, out); + } + +cleanup: + + if(data) + UnmapViewOfFile(data); + if(mapping) + CloseHandle(mapping); + + return ret; +} + + +// replaceBuffer: ---------------------------------------------------- +// Process a memory buffer into a file for output +// Uses the rlib functions directly + +HRESULT Replace::replaceBuffer(byte* data, size_t size, HANDLE out) +{ + ASSERT(m_outFile == NULL); + + size_t blockSize = m_droplet.getBuffSize() * 2; // Block size + size_t batchSize; // Current batch size + int r = R_IN; + bool dirty = false; + HRESULT ret = S_OK; + + { + // If there's no blocksize then we process the + // entire file at once + if(blockSize == 0) + blockSize = size; + + batchSize = blockSize; + + // Setup the rlib stream + r_context& ctx = m_droplet.getContext(); + + ctx.stream.nextIn = data; + ctx.stream.availIn = blockSize; + ctx.stream.fWrite = writeFile; + ctx.stream.arg = this; + ctx.stream.fMatch = matchStatus; + + // This is used by writeFile + m_outFile = out; + + // While we have more data to put in ... + while(size > 0 || r == R_IN) + { + // If rlib wants data then give it + if(r == R_IN) + { + batchSize = (blockSize > size) ? size : blockSize; + + ctx.stream.nextIn = data; + ctx.stream.availIn = batchSize; + + } + + // call rlib + r = rlibRun(&(ctx.stream), &(ctx.script), (size - batchSize) <= 0); + + // Oops! + if(r < 0) + REPERR(r, &(ctx.script)); + + if(ctx.stream.total > 0) + dirty = true; + + // Increment last batch + data += (batchSize - ctx.stream.availIn); + size -= (batchSize - ctx.stream.availIn); + } + + // Clears and prepares for next file + rlibClear(&ctx.stream); + } + +cleanup: + + m_outFile = NULL; + + if(FAILED(ret)) + return ret; + + return dirty ? S_OK : S_FALSE; +} diff --git a/win32/droplet/replace.h b/win32/droplet/replace.h new file mode 100644 index 0000000..b3c72c3 --- /dev/null +++ b/win32/droplet/replace.h @@ -0,0 +1,73 @@ +/* + * 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> + */ + +#ifndef __REPLACE_H__ +#define __REPLACE_H__ + +#include "ProgressDlg.h" +#include "common/Droplet.h" +#include "lib/rlib.h" + +// Replace: -------------------------------------------------------- +// Main processing class. Calls rlib for replacements + +class Replace +{ +public: + Replace(); + virtual ~Replace(); + + // Initialize processing (dialog, droplet etc...) + HRESULT initialize(); + + // Undo initialization + HRESULT terminate(); + + // Recursively process files in a folder + HRESULT replaceFolder(LPCTSTR folder); + + // Process a single file into itself (maybe using backups) + HRESULT replaceSingleFile(LPCTSTR fileName); + + // Process one file into another + HRESULT replaceFilename(LPCTSTR fileIn, LPCTSTR fileOut); + + // Process one open file into another + HRESULT replaceFile(HANDLE in, HANDLE out); + + // Process a memory buffer into an open file + HRESULT replaceBuffer(byte* data, size_t size, HANDLE out); + + +private: + // Callback for rlib when data output is needed + static int writeFile(r_stream* stream, byte* data, size_t len); + + // Callback for rlib status updates + static int matchStatus(r_stream* stream, r_replace* repl); + +protected: + Droplet m_droplet; // The droplet + ProgressDlg m_dlg; // The progress dialog + +private: + HANDLE m_outFile; // Open output file handle used by writeFile +}; + +#endif // __REPLACE_H__ diff --git a/win32/droplet/resource.h b/win32/droplet/resource.h new file mode 100644 index 0000000..91516ec --- /dev/null +++ b/win32/droplet/resource.h @@ -0,0 +1,22 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by droplet.rc +// +#define IDS_PROJNAME 100 +#define IDR_Droplet 100 +#define IDD_PROGRESSDLG 101 +#define IDC_FLIP 202 +#define IDC_STATUS 203 +#define IDI_REP 203 +#define IDC_FILENAME 204 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 204 +#define _APS_NEXT_COMMAND_VALUE 32768 +#define _APS_NEXT_CONTROL_VALUE 205 +#define _APS_NEXT_SYMED_VALUE 102 +#endif +#endif diff --git a/win32/droplet/rliberr.h b/win32/droplet/rliberr.h new file mode 100644 index 0000000..8fe3a80 --- /dev/null +++ b/win32/droplet/rliberr.h @@ -0,0 +1,136 @@ +/* + * AUTHOR + * N. Nielsen + * + * VERSION + * 2.2.0b + * + * 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> + */ + +#ifndef _RLIBERR_H_ +#define _RLIBERR_H_ + +#ifndef _WINERROR_ + #error Include winerror.h first. +#endif + +#define HRESULT_FROM_RLIB(code) \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_RLIB, abs(code)) + +/* ------------------------------------------------------------------------ *\ + Rlib Errors +\* ------------------------------------------------------------------------ */ +// +// Values are 32 bit values layed out as follows: +// +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +// +---+-+-+-----------------------+-------------------------------+ +// |Sev|C|R| Facility | Code | +// +---+-+-+-----------------------+-------------------------------+ +// +// where +// +// Sev - is the severity code +// +// 00 - Success +// 01 - Informational +// 10 - Warning +// 11 - Error +// +// C - is the Customer code flag +// +// R - is a reserved bit +// +// Facility - is the facility code +// +// Code - is the facility's status code +// +// +// Define the facility codes +// +#define FACILITY_RLIB 0x196 + + +// +// Define the severity codes +// + + +// +// MessageId: RLIB_E_NOMEM +// +// MessageText: +// +// Out of Memory. +// +#define RLIB_E_NOMEM ((HRESULT)0x81960001L) + +// +// MessageId: RLIB_E_SYNTAX +// +// MessageText: +// +// Rep script syntax error. +// +#define RLIB_E_SYNTAX ((HRESULT)0x81960002L) + +// +// MessageId: RLIB_E_REGEXP +// +// MessageText: +// +// Regular expression syntax error. +// +#define RLIB_E_REGEXP ((HRESULT)0x81960003L) + +// +// MessageId: RLIB_E_LOOP +// +// MessageText: +// +// Rep encountered an endless loop. +// +#define RLIB_E_LOOP ((HRESULT)0x81960004L) + +// +// MessageId: RLIB_E_USER +// +// MessageText: +// +// User defined error. +// +#define RLIB_E_USER ((HRESULT)0x81960005L) + +// +// MessageId: RLIB_E_IOERR +// +// MessageText: +// +// There was an error reading or writing the data. +// +#define RLIB_E_IOERR ((HRESULT)0x81960006L) + +// +// MessageId: RLIB_E_INVARG +// +// MessageText: +// +// Programmer Error: Invalid argument. +// +#define RLIB_E_INVARG ((HRESULT)0x8196000AL) + +#endif // _RLIBERR_H_
\ No newline at end of file diff --git a/win32/droplet/rliberr.rc b/win32/droplet/rliberr.rc new file mode 100644 index 0000000..0885a89 --- /dev/null +++ b/win32/droplet/rliberr.rc @@ -0,0 +1,2 @@ +LANGUAGE 0x9,0x1 +1 11 MSG00001.bin diff --git a/win32/droplet/stdafx.cpp b/win32/droplet/stdafx.cpp new file mode 100644 index 0000000..7ab5779 --- /dev/null +++ b/win32/droplet/stdafx.cpp @@ -0,0 +1,31 @@ +/* + * 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> + */ + +// stdafx.cpp : source file that includes just the standard includes +// stdafx.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +#ifdef _ATL_STATIC_REGISTRY +#include <statreg.h> +#include <statreg.cpp> +#endif + +#include <atlimpl.cpp> diff --git a/win32/droplet/stdafx.h b/win32/droplet/stdafx.h new file mode 100644 index 0000000..16885d5 --- /dev/null +++ b/win32/droplet/stdafx.h @@ -0,0 +1,39 @@ +/* + * 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> + */ + +#if !defined(AFX_STDAFX_H__3607160A_967A_4E9D_A154_BC3CF029F2C2__INCLUDED_) +#define AFX_STDAFX_H__3607160A_967A_4E9D_A154_BC3CF029F2C2__INCLUDED_ + +#define STRICT +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif +#define _ATL_APARTMENT_THREADED + +#include <atlbase.h> +extern CComModule _Module; +#include <atlcom.h> +#include <atlwin.h> + +#include "config.win32.h" +#include "common/compat.h" +#include "common/usuals.h" +#include <mystring.h> + +#endif // !defined(AFX_STDAFX_H__3607160A_967A_4E9D_A154_BC3CF029F2C2__INCLUDED) diff --git a/win32/droplet/temp.cmp b/win32/droplet/temp.cmp Binary files differnew file mode 100644 index 0000000..137c82e --- /dev/null +++ b/win32/droplet/temp.cmp diff --git a/win32/droplet/temp.rep b/win32/droplet/temp.rep new file mode 100644 index 0000000..a2aaee4 --- /dev/null +++ b/win32/droplet/temp.rep @@ -0,0 +1,24 @@ +# +# 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> +# + +# This is a placeholder script for the one written +# into the droplet + +match "yada" + replace "blah"
\ No newline at end of file diff --git a/win32/makedrop/MSG00001.bin b/win32/makedrop/MSG00001.bin Binary files differnew file mode 100644 index 0000000..83bcd64 --- /dev/null +++ b/win32/makedrop/MSG00001.bin diff --git a/win32/makedrop/Makefile.am b/win32/makedrop/Makefile.am new file mode 100644 index 0000000..f79b2b5 --- /dev/null +++ b/win32/makedrop/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = dropsheet.cpp dropsheet.h makedrop.cpp makedrop.dsp makedrop.h makedrop.rc processpage.h processpage.cpp resource.h settingspage.cpp settingspage.h stdafx.h stdafx.cpp + 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; +} diff --git a/win32/makedrop/dropsheet.h b/win32/makedrop/dropsheet.h new file mode 100644 index 0000000..48ec758 --- /dev/null +++ b/win32/makedrop/dropsheet.h @@ -0,0 +1,72 @@ +/* + * 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> + */ + +#ifndef __DROPSHEET_H__ +#define __DROPSHEET_H__ + +#include "resource.h" +#include "common/droplet.h" + +// DropSheet: ------------------------------------------------------ +// The main window property sheet + +class DropSheet + : public CPropertySheet +{ +public: + DropSheet(); + virtual ~DropSheet(); + + BEGIN_MSG_MAP(DropSheet) + MESSAGE_HANDLER(WM_INITDIALOG, onInitDialog) + COMMAND_ID_HANDLER(ID_FILE_OPEN, onOpen) + COMMAND_ID_HANDLER(ID_FILE_SAVE, onSave) + COMMAND_ID_HANDLER(ID_FILE_EXIT, onExit) + MESSAGE_HANDLER(PSM_CHANGED, onChanged) + MESSAGE_HANDLER(WM_CLOSE, onClose) + CHAIN_MSG_MAP(CPropertySheet) + END_MSG_MAP() + + // Get the current internal droplet + Droplet& getDroplet() + { return m_droplet; } + +// Message Handlers +protected: + LRESULT onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT onClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT onChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT onOpen(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + LRESULT onSave(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + LRESULT onExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + +// Helper Functions +protected: + // Save the droplet, prompt user if not force + bool saveDroplet(bool force); + // Open the a droplet + void openDroplet(); + +protected: + Droplet m_droplet; // The internal loaded droplet + bool m_dirty; // Have changes been made? + string m_fileName; // The filename to save to +}; + +#endif // !defined(AFX_DROPSHEET_H__E3237E90_1FD0_4233_98EE_5991F4FB39F8__INCLUDED_) diff --git a/win32/makedrop/makedrop.cpp b/win32/makedrop/makedrop.cpp new file mode 100644 index 0000000..79a5b19 --- /dev/null +++ b/win32/makedrop/makedrop.cpp @@ -0,0 +1,74 @@ +/* + * 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 "resource.h" +#include <initguid.h> +#include "DropSheet.h" +#include "ProcessPage.h" +#include "SettingsPage.h" + +// ATL Support stuff +CComModule _Module; +BEGIN_OBJECT_MAP(ObjectMap) +END_OBJECT_MAP() + + +// _tWinMain: ------------------------------------------------------------ +// Our application entry point +extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, + HINSTANCE /*hPrevInstance*/, LPTSTR /* lpCmdLine */, int /*nShowCmd*/) +{ + // ATL Support Stuff + HRESULT hRes = CoInitialize(NULL); + _ASSERTE(SUCCEEDED(hRes)); + _Module.Init(ObjectMap, hInstance, NULL); + + int nRet = 0; + + // Create and start the property sheet + DropSheet sheet; + ProcessPage page1(sheet.getDroplet()); + SettingsPage page2(sheet.getDroplet()); + sheet.AddPage(&page1); + sheet.AddPage(&page2); + sheet.Create(); + + // Load the keyboard shortcuts + HACCEL accel = LoadAccelerators(_Module.GetResourceInstance(), + MAKEINTRESOURCE(IDR_ACCEL)); + + // Process messages + MSG msg; + while(GetMessage(&msg, NULL, 0, 0)) + { + if(!accel || !TranslateAccelerator(sheet.m_hWnd, accel, &msg)) + { + if(!sheet.IsWindow() || !sheet.IsDialogMessage(&msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + + _Module.Term(); + CoUninitialize(); + return nRet; +} diff --git a/win32/makedrop/makedrop.dsp b/win32/makedrop/makedrop.dsp new file mode 100644 index 0000000..af603d3 --- /dev/null +++ b/win32/makedrop/makedrop.dsp @@ -0,0 +1,203 @@ +# Microsoft Developer Studio Project File - Name="makedrop" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=makedrop - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "makedrop.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "makedrop.mak" CFG="makedrop - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "makedrop - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "makedrop - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "makedrop - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "debug" +# PROP Intermediate_Dir "debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\.." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 libpcre.a comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x400000" /subsystem:windows /debug /machine:I386 /out:"../debug/makedrop.exe" /pdbtype:sept /libpath:"..\pcre\lib\\" + +!ELSEIF "$(CFG)" == "makedrop - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "release" +# PROP Intermediate_Dir "release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /W3 /GX /O1 /I "..\.." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 libpcre.a comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x400000" /subsystem:windows /machine:I386 /out:"../release/makedrop.exe" /libpath:"..\pcre\lib\\" /opt:nowin98 +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "makedrop - Win32 Debug" +# Name "makedrop - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\common\droplet.cpp +# End Source File +# Begin Source File + +SOURCE=.\DropSheet.cpp +# End Source File +# Begin Source File + +SOURCE=..\common\errutil.cpp +# End Source File +# Begin Source File + +SOURCE=.\makedrop.cpp +# End Source File +# Begin Source File + +SOURCE=.\makedrop.rc +# End Source File +# Begin Source File + +SOURCE=.\ProcessPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\common\rliberr.mc + +!IF "$(CFG)" == "makedrop - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build +InputPath=..\common\rliberr.mc +InputName=rliberr + +"$(InputName).rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + mc $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "makedrop - Win32 Release" + +# PROP Ignore_Default_Tool 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\SettingsPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\common\droplet.h +# End Source File +# Begin Source File + +SOURCE=.\DropSheet.h +# End Source File +# Begin Source File + +SOURCE=.\ProcessPage.h +# End Source File +# Begin Source File + +SOURCE=.\Resource.h +# End Source File +# Begin Source File + +SOURCE=.\SettingsPage.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=..\debug\droplet.exe +# End Source File +# Begin Source File + +SOURCE=.\droplet.exe +# End Source File +# Begin Source File + +SOURCE=..\release\droplet.exe +# End Source File +# Begin Source File + +SOURCE=.\MSG00001.bin +# End Source File +# Begin Source File + +SOURCE=..\common\rep.ico +# End Source File +# End Group +# End Target +# End Project +# Section makedrop : {00000000-0000-0000-0000-800000800000} +# 1:14:IDD_DROPLETDLG:101 +# End Section diff --git a/win32/makedrop/makedrop.h b/win32/makedrop/makedrop.h new file mode 100644 index 0000000..1ef92a3 --- /dev/null +++ b/win32/makedrop/makedrop.h @@ -0,0 +1 @@ +/* MIDL: this ALWAYS GENERATED file contains the definitions for the interfaces */ diff --git a/win32/makedrop/makedrop.rc b/win32/makedrop/makedrop.rc new file mode 100644 index 0000000..0b61072 --- /dev/null +++ b/win32/makedrop/makedrop.rc @@ -0,0 +1,275 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// REP +// + +#if defined(APSTUDIO_INVOKED) || defined(NDEBUG) +#if defined(APSTUDIO_INVOKED) +DROPLET$(NDEBUG) REP DISCARDABLE "..\\release\\droplet.exe" +#else +DROPLET REP DISCARDABLE "..\\release\\droplet.exe" +#endif +#endif +#if defined(APSTUDIO_INVOKED) || defined(_DEBUG) +#if defined(APSTUDIO_INVOKED) +DROPLET$(_DEBUG) REP DISCARDABLE "..\\debug\\droplet.exe" +#else +DROPLET REP DISCARDABLE "..\\debug\\droplet.exe" +#endif +#endif +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 2,2,0,1 + PRODUCTVERSION 2,2,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Nate Nielsen\0" + VALUE "FileDescription", "Rep Droplet Maker\0" + VALUE "FileVersion", "2, 2, 0, 1\0" + VALUE "InternalName", "makedrop\0" + VALUE "LegalCopyright", "Copyright Nate Nielsen 2002\0" + VALUE "LegalTrademarks", "\0" + VALUE "OLESelfRegister", "\0" + VALUE "OriginalFilename", "makedrop.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "rep\0" + VALUE "ProductVersion", "2, 2, 0, 1\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 227, 210 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Settings" +FONT 8, "Tahoma" +BEGIN + LTEXT "This title is shown in the progress dialog for this droplet.", + IDC_STATIC,17,19,180,8 + EDITTEXT IDC_TITLE,17,32,192,14,ES_AUTOHSCROLL + CONTROL "Backup replaced files.",IDC_BACKUP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,17,75,167,10 + GROUPBOX "Backups",IDC_STATIC,7,61,213,75 + LTEXT "If this option is checked, then this droplet will backup any files it modifies. It adds a 'x_r' extension to those files.\n\nWhen a backup already exists it is overwritten.", + IDC_STATIC,17,91,192,32 + GROUPBOX "Title",IDC_STATIC,7,7,213,48 +END + +IDD_PROCESS DIALOG DISCARDABLE 0, 0, 227, 210 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Process" +FONT 8, "Tahoma" +BEGIN + CONTROL "Process entire file at once",IDC_USEFILE,"Button", + BS_AUTORADIOBUTTON,18,79,158,10 + CONTROL "Process file in chunks",IDC_USECHUNK,"Button", + BS_AUTORADIOBUTTON,18,126,140,10 + LTEXT "Largest match size:",IDC_STATIC,35,183,63,8 + EDITTEXT IDC_CHUNK,104,182,57,14,ES_AUTOHSCROLL | ES_NUMBER + GROUPBOX "Chunks",IDC_STATIC,7,65,213,138 + LTEXT "This runs replaces on all of the file at once. Although the most reliable method, it's slower, sometimes extremely so. ", + IDC_STATIC,18,94,191,22 + LTEXT "This option breaks up the file into smaller blocks for processing. Processing is much faster in this mode. The largest expected match should be entered below; anything larger won't be replaced.", + IDC_STATIC,18,140,191,34 + GROUPBOX "Script",IDC_STATIC,7,7,213,49 + EDITTEXT IDC_SCRIPT,18,33,170,14,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_BROWSE,190,33,19,14 + LTEXT "The rep script that will be compiled into the droplet. ", + IDC_STATIC,18,19,191,12 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_SETTINGS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 220 + VERTGUIDE, 17 + VERTGUIDE, 209 + TOPMARGIN, 7 + BOTTOMMARGIN, 203 + END + + IDD_PROCESS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 220 + VERTGUIDE, 18 + VERTGUIDE, 209 + TOPMARGIN, 7 + BOTTOMMARGIN, 203 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN + MENUITEM "&Save...\tCtrl+S", ID_FILE_SAVE + MENUITEM SEPARATOR + MENUITEM "E&xit\tCtrl+Q", ID_FILE_EXIT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ACCEL ACCELERATORS DISCARDABLE +BEGIN + "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT + "Q", ID_FILE_EXIT, VIRTKEY, CONTROL, NOINVERT + "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_REP ICON DISCARDABLE "..\\common\\rep.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// 11 +// + +1 11 DISCARDABLE "MSG00001.bin" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_PROJNAME "makedrop" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/win32/makedrop/processpage.cpp b/win32/makedrop/processpage.cpp new file mode 100644 index 0000000..be3951a --- /dev/null +++ b/win32/makedrop/processpage.cpp @@ -0,0 +1,239 @@ +/* + * 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 "ProcessPage.h" +#include "common/errutil.h" +#include "lib/rlib.h" +#include "lib/rep.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)); +#define CUSTERR(e, s) \ + { errorMessage(m_hWnd, 0, s); RETURN(e); } +#define CUSTERR_1(e, s, a) \ + { errorMessage(m_hWnd, 0, s, a); RETURN(e); } + + +// (Con|De)struction: --------------------------------------------------------- + +ProcessPage::ProcessPage(Droplet& droplet) : + CPropertyPage(IDD_PROCESS, _T("Script")), + m_droplet(droplet) +{ + m_inited = false; +} + +// compileScript: ---------------------------------------------------------- +// Load and possibly compile a script from a file + +HRESULT ProcessPage::compileScript(const string& script) +{ + FILE* file = NULL; + HRESULT ret = S_OK; + int r = R_OK; + + { + file = fopen(script, "rb"); + if(!file) + CUSTERR_1(E_FAIL, "Couldn't open script file: %s", script.c_str()); + + r_context& ctx = m_droplet.getContext(); + + r = repLoad(&ctx, file); + if(r < 0) + REPERR(r, &(ctx.script)); + } + +cleanup: + if(file) + fclose(file); + + return ret; +} + + +// loadData: ------------------------------------------------------------- +// Load data from the droplet onto page + +void ProcessPage::loadData() +{ + m_inited = false; + size_t buffSize = m_droplet.getBuffSize(); + CheckDlgButton(IDC_USEFILE, buffSize == 0); + CheckDlgButton(IDC_USECHUNK, buffSize != 0); + SetDlgItemInt(IDC_CHUNK, buffSize == 0 ? 2000 : buffSize, FALSE); + + if(m_droplet.hasScript()) + { + // By setting both to the same value we prevent rereading + // or compiling + m_script = _T("[compiled script]"); + SetDlgItemText(IDC_SCRIPT, m_script); + } + + m_inited = true; + updateControls(); +} + + +// onInitDialog: ----------------------------------------------------------- +// Dialog initialization + +LRESULT ProcessPage::onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + loadData(); + return 0; +} + + +// onInitDialog: ----------------------------------------------------------- +// Broadcast by sheet when required to reread droplet info + +LRESULT ProcessPage::onQuerySiblings(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + loadData(); + return 0; +} + + +// onInitDialog: ----------------------------------------------------------- +// Save droplet data from page + +LRESULT ProcessPage::onApply(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) +{ + string script; + GetDlgItemText(IDC_SCRIPT, script.get_buffer(MAX_PATH), MAX_PATH); + script.release_buffer(); + + // Make sure we have a script + if(script.empty()) + { + errorMessage(m_hWnd, 0, _T("You need to provide the filename of a rep script.")); + ::SetFocus(GetDlgItem(IDC_SCRIPT)); + SetModified(TRUE); + return PSNRET_INVALID; + } + + // If the the script changed + if(script != m_script) + { + // Then recompile it + if(SUCCEEDED(compileScript(script))) + { + m_script = script; + } + else + { + // By setting dirty we signal an error to sheet + SetModified(TRUE); + return PSNRET_INVALID; + } + } + + // Do buffer thing + if(IsDlgButtonChecked(IDC_USEFILE)) + { + // Process entire file at once + m_droplet.setBuffSize(0); + } + else + { + // Get the actual buffer size + BOOL translated; + UINT buffSize = GetDlgItemInt(IDC_CHUNK, &translated, FALSE); + if(buffSize < 16 || !translated) + { + errorMessage(m_hWnd, 0, _T("The chunk size must be a valid number greater than 16.")); + ::SetFocus(GetDlgItem(IDC_CHUNK)); + SetModified(TRUE); + return PSNRET_INVALID; + } + + m_droplet.setBuffSize(buffSize); + } + + return PSNRET_NOERROR; +} + + +// onChange: -------------------------------------------------------------- +// Signal dirty to parent sheet + +LRESULT ProcessPage::onChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) +{ + if(m_inited) + { + SetModified(TRUE); + updateControls(); + } + return 0; +} + + +// updateControls: -------------------------------------------------------- +// Make sure page remains valid when changes happen + +void ProcessPage::updateControls() +{ + ::EnableWindow(GetDlgItem(IDC_CHUNK), IsDlgButtonChecked(IDC_USECHUNK)); +} + + +// onBrowse: -------------------------------------------------------------- +// Browse for a script file + +LRESULT ProcessPage::onBrowse(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) +{ + string file; + OPENFILENAME ofn; + memset(&ofn, 0, sizeof(ofn)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFilter = _T("Rep Files (*.rep)\0*.rep\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(); + SetDlgItemText(IDC_SCRIPT, file); + SetModified(TRUE); + updateControls(); + } + + return 0; +} diff --git a/win32/makedrop/processpage.h b/win32/makedrop/processpage.h new file mode 100644 index 0000000..74ad6de --- /dev/null +++ b/win32/makedrop/processpage.h @@ -0,0 +1,75 @@ +/* + * 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> + */ + +#ifndef __PROCESSPAGE_H__ +#define __PROCESSPAGE_H__ + +#include "resource.h" // main symbols +#include <atlhost.h> +#include "common/droplet.h" + + +// ProcessPage: ------------------------------------------------------- +// Property page for script and buffer size + +class ProcessPage : + public CPropertyPage +{ +public: + ProcessPage(Droplet& droplet); + + BEGIN_MSG_MAP(ProcessPage) + MESSAGE_HANDLER(WM_INITDIALOG, onInitDialog) + MESSAGE_HANDLER(PSM_QUERYSIBLINGS, onQuerySiblings) + COMMAND_ID_HANDLER(IDC_BROWSE, onBrowse) + COMMAND_CODE_HANDLER(BN_CLICKED, onChange) + COMMAND_CODE_HANDLER(EN_CHANGE, onChange) + NOTIFY_CODE_HANDLER(PSN_APPLY, onApply) + END_MSG_MAP() + +// Message Handlers +protected: + LRESULT onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT onQuerySiblings(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT onApply(int idCtrl, LPNMHDR pnmh, BOOL& bHandled); + LRESULT onChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + LRESULT onBrowse(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + +// Helper Functions +protected: + // Updates all status etc... + void updateControls(); + + // Load data from droplet to page + void loadData(); + + // Load an already compiled rep script + HRESULT compileAlready(FILE* f); + + // Load and possibly compile a rep script + HRESULT compileScript(const string& script); + +protected: + Droplet& m_droplet; // Pointer to sheet's main droplet + string m_script; // The script file name last time it was saved + // Will not reload if the same + bool m_inited; // Have we finished being initialized (used by onChange) +}; + +#endif //__PROCESSPAGE_H__ diff --git a/win32/makedrop/resource.h b/win32/makedrop/resource.h new file mode 100644 index 0000000..4783aae --- /dev/null +++ b/win32/makedrop/resource.h @@ -0,0 +1,32 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by makedrop.rc +// +#define IDS_PROJNAME 100 +#define IDR_Makedrop 100 +#define IDC_TITLE 201 +#define IDR_MENU 201 +#define IDD_SETTINGS 202 +#define IDC_BACKUP 202 +#define IDR_ACCEL 202 +#define IDC_USEFILE 203 +#define IDD_PROCESS 203 +#define IDC_USECHUNK 204 +#define IDC_CHUNK 205 +#define IDC_SCRIPT 206 +#define IDC_BROWSE 207 +#define IDI_REP 208 +#define ID_FILE_OPEN 32768 +#define ID_FILE_SAVE 32769 +#define ID_FILE_EXIT 32770 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 210 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 208 +#define _APS_NEXT_SYMED_VALUE 102 +#endif +#endif diff --git a/win32/makedrop/rliberr.h b/win32/makedrop/rliberr.h new file mode 100644 index 0000000..8fe3a80 --- /dev/null +++ b/win32/makedrop/rliberr.h @@ -0,0 +1,136 @@ +/* + * AUTHOR + * N. Nielsen + * + * VERSION + * 2.2.0b + * + * 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> + */ + +#ifndef _RLIBERR_H_ +#define _RLIBERR_H_ + +#ifndef _WINERROR_ + #error Include winerror.h first. +#endif + +#define HRESULT_FROM_RLIB(code) \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_RLIB, abs(code)) + +/* ------------------------------------------------------------------------ *\ + Rlib Errors +\* ------------------------------------------------------------------------ */ +// +// Values are 32 bit values layed out as follows: +// +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +// +---+-+-+-----------------------+-------------------------------+ +// |Sev|C|R| Facility | Code | +// +---+-+-+-----------------------+-------------------------------+ +// +// where +// +// Sev - is the severity code +// +// 00 - Success +// 01 - Informational +// 10 - Warning +// 11 - Error +// +// C - is the Customer code flag +// +// R - is a reserved bit +// +// Facility - is the facility code +// +// Code - is the facility's status code +// +// +// Define the facility codes +// +#define FACILITY_RLIB 0x196 + + +// +// Define the severity codes +// + + +// +// MessageId: RLIB_E_NOMEM +// +// MessageText: +// +// Out of Memory. +// +#define RLIB_E_NOMEM ((HRESULT)0x81960001L) + +// +// MessageId: RLIB_E_SYNTAX +// +// MessageText: +// +// Rep script syntax error. +// +#define RLIB_E_SYNTAX ((HRESULT)0x81960002L) + +// +// MessageId: RLIB_E_REGEXP +// +// MessageText: +// +// Regular expression syntax error. +// +#define RLIB_E_REGEXP ((HRESULT)0x81960003L) + +// +// MessageId: RLIB_E_LOOP +// +// MessageText: +// +// Rep encountered an endless loop. +// +#define RLIB_E_LOOP ((HRESULT)0x81960004L) + +// +// MessageId: RLIB_E_USER +// +// MessageText: +// +// User defined error. +// +#define RLIB_E_USER ((HRESULT)0x81960005L) + +// +// MessageId: RLIB_E_IOERR +// +// MessageText: +// +// There was an error reading or writing the data. +// +#define RLIB_E_IOERR ((HRESULT)0x81960006L) + +// +// MessageId: RLIB_E_INVARG +// +// MessageText: +// +// Programmer Error: Invalid argument. +// +#define RLIB_E_INVARG ((HRESULT)0x8196000AL) + +#endif // _RLIBERR_H_
\ No newline at end of file diff --git a/win32/makedrop/rliberr.rc b/win32/makedrop/rliberr.rc new file mode 100644 index 0000000..0885a89 --- /dev/null +++ b/win32/makedrop/rliberr.rc @@ -0,0 +1,2 @@ +LANGUAGE 0x9,0x1 +1 11 MSG00001.bin diff --git a/win32/makedrop/settingspage.cpp b/win32/makedrop/settingspage.cpp new file mode 100644 index 0000000..953eebd --- /dev/null +++ b/win32/makedrop/settingspage.cpp @@ -0,0 +1,100 @@ +/* + * 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 "SettingsPage.h" + +// (Con|De)struction: ---------------------------------------------------- + +SettingsPage::SettingsPage(Droplet& droplet) : + CPropertyPage(IDD_SETTINGS, _T("Settings")), + m_droplet(droplet) +{ + m_inited = false; +} + + +// loadData: ------------------------------------------------------------- +// Load info from droplet onto page + +void SettingsPage::loadData() +{ + m_inited = false; + SetDlgItemText(IDC_TITLE, m_droplet.getTitle()); + CheckDlgButton(IDC_BACKUP, m_droplet.keepBackups()); + m_inited = true; + updateControls(); +} + + +// onQuerySiblings: ------------------------------------------------------ +// Broadcast from parent sheet when we have to reload droplet data + +LRESULT SettingsPage::onQuerySiblings(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + loadData(); + return 0; +} + + +// onInitDialog: --------------------------------------------------------- +// Page Initialization + +LRESULT SettingsPage::onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + loadData(); + return 0; +} + + +// onApply: -------------------------------------------------------------- +// Save data to droplet + +LRESULT SettingsPage::onApply(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) +{ + string title; + GetDlgItemText(IDC_TITLE, title.get_buffer(MAX_PATH), MAX_PATH); + title.release_buffer(); + m_droplet.setTitle(title); + + m_droplet.setBackups(IsDlgButtonChecked(IDC_BACKUP) ? true : false); + return PSNRET_NOERROR; +} + + +// onChange: ------------------------------------------------------------- +// Signal to parent when changes happen + +LRESULT SettingsPage::onChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) +{ + if(m_inited) + { + SetModified(TRUE); + updateControls(); + } + return 0; +} + +// updateControls: ------------------------------------------------------- +// Keep page status in sync + +void SettingsPage::updateControls() +{ + +}
\ No newline at end of file diff --git a/win32/makedrop/settingspage.h b/win32/makedrop/settingspage.h new file mode 100644 index 0000000..f122963 --- /dev/null +++ b/win32/makedrop/settingspage.h @@ -0,0 +1,65 @@ +/* + * 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> + */ + +#ifndef __SETTINGSPAGE_H_ +#define __SETTINGSPAGE_H_ + +#include "resource.h" // main symbols +#include <atlhost.h> +#include "common/droplet.h" + +// SettingsPage: ---------------------------------------------------------- +// Property page for misc drop settings + +class SettingsPage : + public CPropertyPage +{ +public: + SettingsPage(Droplet& droplet); + + BEGIN_MSG_MAP(SettingsPage) + MESSAGE_HANDLER(WM_INITDIALOG, onInitDialog) + MESSAGE_HANDLER(PSM_QUERYSIBLINGS, onQuerySiblings) + COMMAND_CODE_HANDLER(BN_CLICKED, onChange) + COMMAND_CODE_HANDLER(EN_CHANGE, onChange) + NOTIFY_CODE_HANDLER(PSN_APPLY, onApply) + END_MSG_MAP() + +// Message Handlers +protected: + LRESULT onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT onQuerySiblings(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT onApply(int idCtrl, LPNMHDR pnmh, BOOL& bHandled); + LRESULT onChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + +// Helper Functions +protected: + // Updates all status etc... + void updateControls(); + + // Load data from droplet to page + void loadData(); + +// Data +protected: + Droplet& m_droplet; // The Property sheet's internal droplet + bool m_inited; // Have we been initialized (used by onChange) +}; + +#endif //__SETTINGSPAGE_H_ diff --git a/win32/makedrop/stdafx.cpp b/win32/makedrop/stdafx.cpp new file mode 100644 index 0000000..ba86b3c --- /dev/null +++ b/win32/makedrop/stdafx.cpp @@ -0,0 +1,27 @@ +/* + * 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" + +#ifdef _ATL_STATIC_REGISTRY +#include <statreg.h> +#include <statreg.cpp> +#endif + +#include <atlimpl.cpp> diff --git a/win32/makedrop/stdafx.h b/win32/makedrop/stdafx.h new file mode 100644 index 0000000..2de0b77 --- /dev/null +++ b/win32/makedrop/stdafx.h @@ -0,0 +1,40 @@ +/* + * 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> + */ + +#if !defined(AFX_STDAFX_H__7FCAFA12_CBDF_41CC_98D1_56D72C99E1C5__INCLUDED_) +#define AFX_STDAFX_H__7FCAFA12_CBDF_41CC_98D1_56D72C99E1C5__INCLUDED_ + +#define STRICT +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif +#define _ATL_APARTMENT_THREADED + +#include <atlbase.h> +extern CComModule _Module; +#include <atlcom.h> +#include <atlwin.h> + +#include "config.win32.h" +#include "common/compat.h" +#include "common/usuals.h" +#include "common/atlprsht.h" +#include "common/mystring.h" + +#endif // !defined(AFX_STDAFX_H__7FCAFA12_CBDF_41CC_98D1_56D72C99E1C5__INCLUDED) diff --git a/win32/pcre/include/pcre.h b/win32/pcre/include/pcre.h new file mode 100644 index 0000000..d6c2393 --- /dev/null +++ b/win32/pcre/include/pcre.h @@ -0,0 +1,113 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* Copyright (c) 1997-2001 University of Cambridge */ + +#ifndef _PCRE_H +#define _PCRE_H + +/* The file pcre.h is build by "configure". Do not edit it; instead +make changes to pcre.in. */ + +#define PCRE_MAJOR 3 +#define PCRE_MINOR 9 +#define PCRE_DATE 02-Jan-2002 + +/* Win32 uses DLL by default */ + +#ifdef _WIN32 +# ifdef STATIC +# define PCRE_DL_IMPORT +# else +# define PCRE_DL_IMPORT __declspec(dllimport) +# endif +#else +# define PCRE_DL_IMPORT +#endif + +/* Have to include stdlib.h in order to ensure that size_t is defined; +it is needed here for malloc. */ + +#include <stdlib.h> + +/* Allow for C++ users */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Options */ + +#define PCRE_CASELESS 0x0001 +#define PCRE_MULTILINE 0x0002 +#define PCRE_DOTALL 0x0004 +#define PCRE_EXTENDED 0x0008 +#define PCRE_ANCHORED 0x0010 +#define PCRE_DOLLAR_ENDONLY 0x0020 +#define PCRE_EXTRA 0x0040 +#define PCRE_NOTBOL 0x0080 +#define PCRE_NOTEOL 0x0100 +#define PCRE_UNGREEDY 0x0200 +#define PCRE_NOTEMPTY 0x0400 +#define PCRE_UTF8 0x0800 + +/* Exec-time and get-time error codes */ + +#define PCRE_ERROR_NOMATCH (-1) +#define PCRE_ERROR_NULL (-2) +#define PCRE_ERROR_BADOPTION (-3) +#define PCRE_ERROR_BADMAGIC (-4) +#define PCRE_ERROR_UNKNOWN_NODE (-5) +#define PCRE_ERROR_NOMEMORY (-6) +#define PCRE_ERROR_NOSUBSTRING (-7) + +/* Request types for pcre_fullinfo() */ + +#define PCRE_INFO_OPTIONS 0 +#define PCRE_INFO_SIZE 1 +#define PCRE_INFO_CAPTURECOUNT 2 +#define PCRE_INFO_BACKREFMAX 3 +#define PCRE_INFO_FIRSTCHAR 4 +#define PCRE_INFO_FIRSTTABLE 5 +#define PCRE_INFO_LASTLITERAL 6 + +/* Types */ + +struct real_pcre; /* declaration; the definition is private */ +struct real_pcre_extra; /* declaration; the definition is private */ + +typedef struct real_pcre pcre; +typedef struct real_pcre_extra pcre_extra; + +/* Store get and free functions. These can be set to alternative malloc/free +functions if required. Some magic is required for Win32 DLL; it is null on +other OS. */ + +PCRE_DL_IMPORT extern void *(*pcre_malloc)(size_t); +PCRE_DL_IMPORT extern void (*pcre_free)(void *); + +#undef PCRE_DL_IMPORT + +/* Functions */ + +extern pcre *pcre_compile(const char *, int, const char **, int *, + const unsigned char *); +extern int pcre_copy_substring(const char *, int *, int, int, char *, int); +extern int pcre_exec(const pcre *, const pcre_extra *, const char *, + int, int, int, int *, int); +extern void pcre_free_substring(const char *); +extern void pcre_free_substring_list(const char **); +extern int pcre_get_substring(const char *, int *, int, int, const char **); +extern int pcre_get_substring_list(const char *, int *, int, const char ***); +extern int pcre_info(const pcre *, int *, int *); +extern int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); +extern const unsigned char *pcre_maketables(void); +extern pcre_extra *pcre_study(const pcre *, int, const char **); +extern const char *pcre_version(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* End of pcre.h */ diff --git a/win32/pcre/include/pcreposix.h b/win32/pcre/include/pcreposix.h new file mode 100644 index 0000000..e70af2d --- /dev/null +++ b/win32/pcre/include/pcreposix.h @@ -0,0 +1,88 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* Copyright (c) 1997-2001 University of Cambridge */ + +#ifndef _PCREPOSIX_H +#define _PCREPOSIX_H + +/* This is the header for the POSIX wrapper interface to the PCRE Perl- +Compatible Regular Expression library. It defines the things POSIX says should +be there. I hope. */ + +/* Have to include stdlib.h in order to ensure that size_t is defined. */ + +#include <stdlib.h> + +/* Allow for C++ users */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Options defined by POSIX. */ + +#define REG_ICASE 0x01 +#define REG_NEWLINE 0x02 +#define REG_NOTBOL 0x04 +#define REG_NOTEOL 0x08 + +/* These are not used by PCRE, but by defining them we make it easier +to slot PCRE into existing programs that make POSIX calls. */ + +#define REG_EXTENDED 0 +#define REG_NOSUB 0 + +/* Error values. Not all these are relevant or used by the wrapper. */ + +enum { + REG_ASSERT = 1, /* internal error ? */ + REG_BADBR, /* invalid repeat counts in {} */ + REG_BADPAT, /* pattern error */ + REG_BADRPT, /* ? * + invalid */ + REG_EBRACE, /* unbalanced {} */ + REG_EBRACK, /* unbalanced [] */ + REG_ECOLLATE, /* collation error - not relevant */ + REG_ECTYPE, /* bad class */ + REG_EESCAPE, /* bad escape sequence */ + REG_EMPTY, /* empty expression */ + REG_EPAREN, /* unbalanced () */ + REG_ERANGE, /* bad range inside [] */ + REG_ESIZE, /* expression too big */ + REG_ESPACE, /* failed to get memory */ + REG_ESUBREG, /* bad back reference */ + REG_INVARG, /* bad argument */ + REG_NOMATCH /* match failed */ +}; + + +/* The structure representing a compiled regular expression. */ + +typedef struct { + void *re_pcre; + size_t re_nsub; + size_t re_erroffset; +} regex_t; + +/* The structure in which a captured offset is returned. */ + +typedef int regoff_t; + +typedef struct { + regoff_t rm_so; + regoff_t rm_eo; +} regmatch_t; + +/* The functions */ + +extern int regcomp(regex_t *, const char *, int); +extern int regexec(regex_t *, const char *, size_t, regmatch_t *, int); +extern size_t regerror(int, const regex_t *, char *, size_t); +extern void regfree(regex_t *); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* End of pcreposix.h */ diff --git a/win32/pcre/lib/libpcre-bcc.def b/win32/pcre/lib/libpcre-bcc.def new file mode 100644 index 0000000..ecdd5c2 --- /dev/null +++ b/win32/pcre/lib/libpcre-bcc.def @@ -0,0 +1,21 @@ +LIBRARY PCRE.DLL + +EXPORTS + _pcre_compile = pcre_compile ; pcre_compile + _pcre_copy_substring = pcre_copy_substring ; pcre_copy_substring + _pcre_exec = pcre_exec ; pcre_exec + _pcre_free = pcre_free ; pcre_free + _pcre_free_substring = pcre_free_substring ; pcre_free_substring + _pcre_free_substring_list = pcre_free_substring_list ; pcre_free_substring_list + _pcre_fullinfo = pcre_fullinfo ; pcre_fullinfo + _pcre_get_substring = pcre_get_substring ; pcre_get_substring + _pcre_get_substring_list = pcre_get_substring_list ; pcre_get_substring_list + _pcre_info = pcre_info ; pcre_info + _pcre_maketables = pcre_maketables ; pcre_maketables + _pcre_malloc = pcre_malloc ; pcre_malloc + _pcre_study = pcre_study ; pcre_study + _pcre_version = pcre_version ; pcre_version + _regcomp = regcomp ; regcomp + _regerror = regerror ; regerror + _regexec = regexec ; regexec + _regfree = regfree ; regfree diff --git a/win32/pcre/lib/libpcre-bcc.lib b/win32/pcre/lib/libpcre-bcc.lib Binary files differnew file mode 100644 index 0000000..e807b0e --- /dev/null +++ b/win32/pcre/lib/libpcre-bcc.lib diff --git a/win32/pcre/lib/libpcre.def b/win32/pcre/lib/libpcre.def new file mode 100644 index 0000000..2db32cb --- /dev/null +++ b/win32/pcre/lib/libpcre.def @@ -0,0 +1,20 @@ +; i:\MINGW\BIN\dlltool.exe -Cn -a -z libpcre.def --export-all-symbols DLLTMPDIR.libpcre.a/get.o DLLTMPDIR.libpcre.a/maketables.o DLLTMPDIR.libpcre.a/pcre.o DLLTMPDIR.libpcre.a/study.o DLLTMPDIR.libpcreposix.a/pcreposix.o +EXPORTS + pcre_info @ 1 ; + pcre_copy_substring @ 2 ; + pcre_exec @ 3 ; + pcre_free @ 4 DATA ; + pcre_free_substring @ 5 ; + pcre_free_substring_list @ 6 ; + pcre_fullinfo @ 7 ; + pcre_get_substring @ 8 ; + pcre_get_substring_list @ 9 ; + pcre_compile @ 10 ; + pcre_maketables @ 11 ; + pcre_malloc @ 12 DATA ; + pcre_study @ 13 ; + pcre_version @ 14 ; + regcomp @ 15 ; + regerror @ 16 ; + regexec @ 17 ; + regfree @ 18 ; diff --git a/win32/pcre/lib/libpcre.la b/win32/pcre/lib/libpcre.la new file mode 100644 index 0000000..8072045 --- /dev/null +++ b/win32/pcre/lib/libpcre.la @@ -0,0 +1,32 @@ +# libpcre.la - a libtool library file +# Generated by ltmain.sh - GNU libtool 1.4 (1.920 2001/04/24 23:26:18) +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='' + +# Names of this library. +library_names='' + +# The name of the static archive. +old_library='libpcre.a' + +# Libraries that this one depends upon. +dependency_libs='' + +# Version information for libpcre. +current=0 +age=0 +revision=1 + +# Is this an already installed library? +installed=yes + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='c:/progra~1/pcre/lib' diff --git a/win32/pcre/lib/libpcre.lib b/win32/pcre/lib/libpcre.lib Binary files differnew file mode 100644 index 0000000..7b8be59 --- /dev/null +++ b/win32/pcre/lib/libpcre.lib diff --git a/win32/pcre/lib/libpcreposix.la b/win32/pcre/lib/libpcreposix.la new file mode 100644 index 0000000..39ab321 --- /dev/null +++ b/win32/pcre/lib/libpcreposix.la @@ -0,0 +1,32 @@ +# libpcreposix.la - a libtool library file +# Generated by ltmain.sh - GNU libtool 1.4 (1.920 2001/04/24 23:26:18) +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='' + +# Names of this library. +library_names='' + +# The name of the static archive. +old_library='libpcreposix.a' + +# Libraries that this one depends upon. +dependency_libs='' + +# Version information for libpcreposix. +current=0 +age=0 +revision=0 + +# Is this an already installed library? +installed=yes + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='c:/progra~1/pcre/lib' diff --git a/win32/pcre/manifest/pcre-3.9-lib.mft b/win32/pcre/manifest/pcre-3.9-lib.mft new file mode 100644 index 0000000..024ac72 --- /dev/null +++ b/win32/pcre/manifest/pcre-3.9-lib.mft @@ -0,0 +1,13 @@ +include/pcre.h +include/pcreposix.h +lib/libpcre-bcc.def +lib/libpcre-bcc.lib +lib/libpcre.a +lib/libpcre.def +lib/libpcre.dll.a +lib/libpcre.la +lib/libpcre.lib +lib/libpcreposix.a +lib/libpcreposix.la +manifest/pcre-3.9-lib.mft +manifest/pcre-3.9-lib.ver diff --git a/win32/pcre/manifest/pcre-3.9-lib.ver b/win32/pcre/manifest/pcre-3.9-lib.ver new file mode 100644 index 0000000..1bf9d6f --- /dev/null +++ b/win32/pcre/manifest/pcre-3.9-lib.ver @@ -0,0 +1,2 @@ +Pcre 3.9: developer files +Pcre: Perl-compatible regular-expression library |