/* * CiderPress * Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved. * See the file LICENSE for distribution terms. */ /* * Miscellaneous utility classes. */ #ifndef UTIL_UTIL_H #define UTIL_UTIL_H #include /* * Gripper for a resizable window. */ class CGripper: public CScrollBar { protected: afx_msg LRESULT OnNcHitTest(CPoint point); DECLARE_MESSAGE_MAP() }; /* * Transfer a buffer of data into a rich edit control. */ class RichEditXfer { public: RichEditXfer(const void* buf, long len) : fBuf((char*)buf), fLen(len) {} static DWORD CALLBACK EditStreamCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb); const char* fBuf; long fLen; private: DECLARE_COPY_AND_OPEQ(RichEditXfer) }; /* * Buffer that expands as data is added to it with stdio-style calls. */ class ExpandBuffer { public: ExpandBuffer(long initialSize = 65536) { ASSERT(initialSize > 0); fInitialSize = initialSize; fWorkBuf = NULL; fWorkCount = fWorkMax = 0; } virtual ~ExpandBuffer(void) { if (fWorkBuf != NULL) { LOGI("ExpandBuffer: fWorkBuf not seized; freeing"); delete[] fWorkBuf; } } /* * Allocate the initial buffer. */ virtual int CreateWorkBuf(void); void Reset(void) { delete[] fWorkBuf; fWorkBuf = NULL; fWorkCount = fWorkMax = 0; } // Copy printf-formatted output into the output buffer. void Printf(_Printf_format_string_ const char* format, ...); // Write binary data to the buffer. void Write(const unsigned char* buf, long len); // Put a single character in. void Putc(char ch); // Seize control of the buffer. It will be the caller's duty to call // delete[] to free it. virtual void SeizeBuffer(char** ppBuf, long* pLen); protected: /* * Grow the buffer to the next incremental size. We keep doubling it until * we reach out maximum rate of expansion. * * Returns 0 on success, -1 on failure. */ virtual int GrowWorkBuf(void); enum { kWorkBufMaxIncrement = 4*1024*1024, // limit increase to 4MB jumps }; long fInitialSize; // initial size of the work buffer char* fWorkBuf; // work in progress long fWorkCount; // quantity of data in buffer long fWorkMax; // maximum size of buffer private: DECLARE_COPY_AND_OPEQ(ExpandBuffer) }; /* * ==================================== * Windows helpers * ==================================== */ /* * Enable or disable a control. */ void EnableControl(CDialog* pDlg, int id, bool enable=true); /* * Move a control so it maintains its same position relative to the bottom * and right edges. */ void MoveControl(CDialog* pDlg, int id, int deltaX, int deltaY, bool redraw = true); /* * Make a control larger by the same delta as the parent window. */ void StretchControl(CDialog* pDlg, int id, int deltaX, int deltaY, bool redraw = true); /* * Stretch and move a control. */ void MoveStretchControl(CDialog* pDlg, int id, int moveX, int moveY, int stretchX, int stretchY, bool redraw = true); /* * Move a control so it maintains its same position relative to the bottom * and right edges. */ HDWP MoveControl(HDWP hdwp, CDialog* pDlg, int id, int deltaX, int deltaY, bool redraw = true); /* * Make a control larger by the same delta as the parent window. */ HDWP StretchControl(HDWP hdwp, CDialog* pDlg, int id, int deltaX, int deltaY, bool redraw = true); /* * Stretch and move a control. */ HDWP MoveStretchControl(HDWP hdwp, CDialog* pDlg, int id, int moveX, int moveY, int stretchX, int stretchY, bool redraw = true); /* * Get the check state of a button in a dialog. */ int GetDlgButtonCheck(CWnd* pWnd, int id); /* * Set the check state of a button in a dialog. */ void SetDlgButtonCheck(CWnd* pWnd, int id, int checkVal); /* * Create a font, using defaults for most things. */ void CreateSimpleFont(CFont* pFont, CWnd* pWnd, const WCHAR* typeFace, int pointSize); /* * Get a Win32 error string for an error code returned by GetLastError. */ void GetWin32ErrorString(DWORD err, CString* pStr); /* * Post a failure message in a message box. */ void ShowFailureMsg(CWnd* pWnd, const CString& msg, int titleStrID); /* * Post a failure message in a message box. */ void ShowFailureMsg(CWnd* pWnd, int msgId, int titleStrID); /* * Returns "true" if we're running on Win9x (Win95, Win98, WinME), "false" * if not (could be WinNT/2K/XP or even Win31 with Win32s). */ bool IsWin9x(void); /* * Wrapper for CString::LoadString that checks the return value and logs a * complaint if the load fails. */ void CheckedLoadString(CString* pString, UINT nID); /* * Returns the desktop scaling factor (usually 1.0). Assumes vertical and * horizontal scaling is identical. */ float GetDesktopScaleFactor(); /* * ==================================== * Miscellaneous functions * ==================================== */ /* * Pull a pascal string out of a buffer and stuff it into "*pStr". * * Returns the length of the string found, or -1 on error. */ int GetPascalString(const uint8_t* buf, long maxLen, CString* pStr); /* * Dump a block of stuff to the log file. */ void LogHexDump(const void* buf, long len); /* * Compute a percentage. */ int ComputePercent(LONGLONG part, LONGLONG full); /* * Format a time_t into a string. * * (Should take format as an argument, so we can use global format set by * user preferences.) */ void FormatDate(time_t when, CString* pStr); /* * Case-insensitive version of strstr(), pulled from the MSDN stuff that * comes with VC++6.0. * * The isalpha() stuff is an optimization, so they can skip the tolower() * in the outer loop comparison. */ const WCHAR* Stristr(const WCHAR* string1, const WCHAR* string2); /* * Break a string down into its component parts. * * "mangle" will be mangled (various bits stomped by '\0'), "argv" will * receive pointers to the strings, and "*pArgc" will hold the number of * arguments in the vector. The initial value of "*pArgc" should hold the * maximum "argv" capacity (including program name in argv[0]). * * The argv pointers will point into "mangle"; no new storage will be * allocated. */ void VectorizeString(WCHAR* mangle, WCHAR** argv, int* pArgc); /* * Convert parts of the Mac OS Roman filename to lower case. * * If the name already has lowercase characters, do nothing. */ void InjectLowercase(CStringA* pStr); /* * Test to see if a sub-string matches a value in a set of strings. The set * comes from a semicolon-delimited string. */ bool MatchSemicolonList(const CString set, const CString match); /* * Like strcpy(), but allocate with new[] instead. * * If "str" is NULL, or "new" fails, this returns NULL. * * TODO: this should be "StrdupNew()". */ char* StrcpyNew(const char* str); /* time_t values for bad dates */ #define kDateNone ((time_t) -2) #define kDateInvalid ((time_t) -1) // should match return from mktime() #endif /*UTIL_UTIL_H*/