You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
760 lines
24 KiB
760 lines
24 KiB
//
|
|
// FauxMFC.h
|
|
//
|
|
|
|
#pragma once
|
|
|
|
#define _FAUXMFC // so we can distinguish between MFC and Faux MFC
|
|
|
|
|
|
#ifndef _FAUXMFC_NO_SYNCOBJ
|
|
#include "SyncObj.h"
|
|
#endif
|
|
|
|
#ifndef PRINTACTION_NETINSTALL
|
|
#define PRINTACTION_NETINSTALL 2
|
|
#endif
|
|
|
|
#ifndef _MAX_PATH
|
|
#define _MAX_PATH 260 /* max. length of full pathname */
|
|
#endif
|
|
|
|
#ifndef AFXAPI
|
|
#define AFXAPI __stdcall
|
|
#endif
|
|
|
|
// AFX_CDECL is used for rare functions taking variable arguments
|
|
#ifndef AFX_CDECL
|
|
#define AFX_CDECL __cdecl
|
|
#endif
|
|
|
|
// FASTCALL is used for static member functions with little or no params
|
|
#ifndef FASTCALL
|
|
#define FASTCALL __fastcall
|
|
#endif
|
|
|
|
#ifndef AFX_STATIC
|
|
#define AFX_STATIC extern
|
|
#define AFX_STATIC_DATA extern __declspec(selectany)
|
|
#endif
|
|
|
|
#ifndef _AFX
|
|
#define _AFX
|
|
#endif
|
|
|
|
#ifndef _AFX_INLINE
|
|
#define _AFX_INLINE inline
|
|
#endif
|
|
|
|
extern const LPCTSTR _afxPchNil;
|
|
#define afxEmptyString ((CString&)*(CString*)&_afxPchNil)
|
|
|
|
HINSTANCE AFXAPI AfxGetResourceHandle(void);
|
|
|
|
struct CStringData
|
|
{
|
|
long nRefs; // reference count
|
|
int nDataLength; // length of data (including terminator)
|
|
int nAllocLength; // length of allocation
|
|
// TCHAR data[nAllocLength]
|
|
|
|
TCHAR* data() // TCHAR* to managed data
|
|
{ return (TCHAR*)(this+1); }
|
|
};
|
|
|
|
class CString
|
|
{
|
|
public:
|
|
// Constructors
|
|
|
|
// constructs empty CString
|
|
CString();
|
|
// copy constructor
|
|
CString(const CString& stringSrc);
|
|
// from a single character
|
|
CString(TCHAR ch, int nRepeat = 1);
|
|
// from an ANSI string (converts to TCHAR)
|
|
CString(LPCSTR lpsz);
|
|
// from a UNICODE string (converts to TCHAR)
|
|
CString(LPCWSTR lpsz);
|
|
// subset of characters from an ANSI string (converts to TCHAR)
|
|
CString(LPCSTR lpch, int nLength);
|
|
// subset of characters from a UNICODE string (converts to TCHAR)
|
|
CString(LPCWSTR lpch, int nLength);
|
|
// from unsigned characters
|
|
CString(const unsigned char* psz);
|
|
|
|
// Attributes & Operations
|
|
|
|
// get data length
|
|
int GetLength() const;
|
|
// TRUE if zero length
|
|
BOOL IsEmpty() const;
|
|
// clear contents to empty
|
|
void Empty();
|
|
|
|
// return single character at zero-based index
|
|
TCHAR GetAt(int nIndex) const;
|
|
// return single character at zero-based index
|
|
TCHAR operator[](int nIndex) const;
|
|
// set a single character at zero-based index
|
|
void SetAt(int nIndex, TCHAR ch);
|
|
// return pointer to const string
|
|
operator LPCTSTR() const;
|
|
|
|
// overloaded assignment
|
|
|
|
// ref-counted copy from another CString
|
|
const CString& operator=(const CString& stringSrc);
|
|
// set string content to single character
|
|
// const CString& operator=(TCHAR ch);
|
|
#ifdef _UNICODE
|
|
const CString& operator=(char ch);
|
|
#endif
|
|
// copy string content from ANSI string (converts to TCHAR)
|
|
const CString& operator=(LPCSTR lpsz);
|
|
// copy string content from UNICODE string (converts to TCHAR)
|
|
const CString& operator=(LPCWSTR lpsz);
|
|
// copy string content from unsigned chars
|
|
const CString& operator=(const unsigned char* psz);
|
|
|
|
// string concatenation
|
|
|
|
// concatenate from another CString
|
|
const CString& operator+=(const CString& string);
|
|
|
|
// concatenate a single character
|
|
const CString& operator+=(TCHAR ch);
|
|
#ifdef _UNICODE
|
|
// concatenate an ANSI character after converting it to TCHAR
|
|
const CString& operator+=(char ch);
|
|
#endif
|
|
// concatenate a UNICODE character after converting it to TCHAR
|
|
const CString& operator+=(LPCTSTR lpsz);
|
|
|
|
friend CString AFXAPI operator+(const CString& string1,
|
|
const CString& string2);
|
|
friend CString AFXAPI operator+(const CString& string, TCHAR ch);
|
|
friend CString AFXAPI operator+(TCHAR ch, const CString& string);
|
|
#ifdef _UNICODE
|
|
friend CString AFXAPI operator+(const CString& string, char ch);
|
|
friend CString AFXAPI operator+(char ch, const CString& string);
|
|
#endif
|
|
friend CString AFXAPI operator+(const CString& string, LPCTSTR lpsz);
|
|
friend CString AFXAPI operator+(LPCTSTR lpsz, const CString& string);
|
|
|
|
// string comparison
|
|
|
|
// straight character comparison
|
|
int Compare(LPCTSTR lpsz) const;
|
|
// compare ignoring case
|
|
int CompareNoCase(LPCTSTR lpsz) const;
|
|
// NLS aware comparison, case sensitive
|
|
int Collate(LPCTSTR lpsz) const;
|
|
// NLS aware comparison, case insensitive
|
|
int CollateNoCase(LPCTSTR lpsz) const;
|
|
|
|
// simple sub-string extraction
|
|
|
|
// return nCount characters starting at zero-based nFirst
|
|
CString Mid(int nFirst, int nCount) const;
|
|
// return all characters starting at zero-based nFirst
|
|
CString Mid(int nFirst) const;
|
|
// return first nCount characters in string
|
|
CString Left(int nCount) const;
|
|
// return nCount characters from end of string
|
|
CString Right(int nCount) const;
|
|
|
|
// characters from beginning that are also in passed string
|
|
CString SpanIncluding(LPCTSTR lpszCharSet) const;
|
|
// characters from beginning that are not also in passed string
|
|
CString SpanExcluding(LPCTSTR lpszCharSet) const;
|
|
|
|
// upper/lower/reverse conversion
|
|
|
|
// NLS aware conversion to uppercase
|
|
void MakeUpper();
|
|
// NLS aware conversion to lowercase
|
|
void MakeLower();
|
|
// reverse string right-to-left
|
|
void MakeReverse();
|
|
|
|
// trimming whitespace (either side)
|
|
|
|
// remove whitespace starting from right edge
|
|
void TrimRight();
|
|
// remove whitespace starting from left side
|
|
void TrimLeft();
|
|
|
|
// trimming anything (either side)
|
|
|
|
// remove continuous occurrences of chTarget starting from right
|
|
void TrimRight(TCHAR chTarget);
|
|
// remove continuous occcurrences of characters in passed string,
|
|
// starting from right
|
|
void TrimRight(LPCTSTR lpszTargets);
|
|
// remove continuous occurrences of chTarget starting from left
|
|
void TrimLeft(TCHAR chTarget);
|
|
// remove continuous occcurrences of characters in
|
|
// passed string, starting from left
|
|
void TrimLeft(LPCTSTR lpszTargets);
|
|
|
|
// advanced manipulation
|
|
|
|
// replace occurrences of chOld with chNew
|
|
int Replace(TCHAR chOld, TCHAR chNew);
|
|
// replace occurrences of substring lpszOld with lpszNew;
|
|
// empty lpszNew removes instances of lpszOld
|
|
int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew);
|
|
// remove occurrences of chRemove
|
|
int Remove(TCHAR chRemove);
|
|
// insert character at zero-based index; concatenates
|
|
// if index is past end of string
|
|
int Insert(int nIndex, TCHAR ch);
|
|
// insert substring at zero-based index; concatenates
|
|
// if index is past end of string
|
|
int Insert(int nIndex, LPCTSTR pstr);
|
|
// delete nCount characters starting at zero-based index
|
|
int Delete(int nIndex, int nCount = 1);
|
|
|
|
// searching
|
|
|
|
// find character starting at left, -1 if not found
|
|
int Find(TCHAR ch) const;
|
|
// find character starting at right
|
|
int ReverseFind(TCHAR ch) const;
|
|
// find character starting at zero-based index and going right
|
|
int Find(TCHAR ch, int nStart) const;
|
|
// find first instance of any character in passed string
|
|
int FindOneOf(LPCTSTR lpszCharSet) const;
|
|
// find first instance of substring
|
|
int Find(LPCTSTR lpszSub) const;
|
|
// find first instance of substring starting at zero-based index
|
|
int Find(LPCTSTR lpszSub, int nStart) const;
|
|
|
|
// simple formatting
|
|
|
|
// printf-like formatting using passed string
|
|
void AFX_CDECL Format(LPCTSTR lpszFormat, ...);
|
|
// printf-like formatting using referenced string resource
|
|
void AFX_CDECL Format(UINT nFormatID, ...);
|
|
// printf-like formatting using variable arguments parameter
|
|
void FormatV(LPCTSTR lpszFormat, va_list argList);
|
|
|
|
// formatting for localization (uses FormatMessage API)
|
|
|
|
// format using FormatMessage API on passed string
|
|
void AFX_CDECL FormatMessage(LPCTSTR lpszFormat, ...);
|
|
// format using FormatMessage API on referenced string resource
|
|
void AFX_CDECL FormatMessage(UINT nFormatID, ...);
|
|
|
|
// input and output
|
|
//#ifdef _DEBUG
|
|
// friend CDumpContext& AFXAPI operator<<(CDumpContext& dc,
|
|
// const CString& string);
|
|
//#endif
|
|
// friend CArchive& AFXAPI operator<<(CArchive& ar, const CString& string);
|
|
// friend CArchive& AFXAPI operator>>(CArchive& ar, CString& string);
|
|
|
|
// load from string resource
|
|
BOOL LoadString(UINT nID);
|
|
|
|
#ifndef _UNICODE
|
|
// ANSI <-> OEM support (convert string in place)
|
|
|
|
// convert string from ANSI to OEM in-place
|
|
void AnsiToOem();
|
|
// convert string from OEM to ANSI in-place
|
|
void OemToAnsi();
|
|
#endif
|
|
|
|
//#ifndef _AFX_NO_BSTR_SUPPORT
|
|
// OLE BSTR support (use for OLE automation)
|
|
|
|
// return a BSTR initialized with this CString's data
|
|
// BSTR AllocSysString() const;
|
|
// reallocates the passed BSTR, copies content of this CString to it
|
|
// BSTR SetSysString(BSTR* pbstr) const;
|
|
//#endif
|
|
|
|
// Access to string implementation buffer as "C" character array
|
|
|
|
// get pointer to modifiable buffer at least as long as nMinBufLength
|
|
LPTSTR GetBuffer(int nMinBufLength);
|
|
// release buffer, setting length to nNewLength (or to first nul if -1)
|
|
void ReleaseBuffer(int nNewLength = -1);
|
|
// get pointer to modifiable buffer exactly as long as nNewLength
|
|
LPTSTR GetBufferSetLength(int nNewLength);
|
|
// release memory allocated to but unused by string
|
|
void FreeExtra();
|
|
|
|
// Use LockBuffer/UnlockBuffer to turn refcounting off
|
|
|
|
// turn refcounting back on
|
|
LPTSTR LockBuffer();
|
|
// turn refcounting off
|
|
void UnlockBuffer();
|
|
|
|
// Implementation
|
|
public:
|
|
~CString();
|
|
int GetAllocLength() const;
|
|
|
|
protected:
|
|
LPTSTR m_pchData; // pointer to ref counted string data
|
|
|
|
// implementation helpers
|
|
CStringData* GetData() const;
|
|
void Init();
|
|
void AllocCopy(CString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const;
|
|
void AllocBuffer(int nLen);
|
|
void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData);
|
|
void ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data, int nSrc2Len, LPCTSTR lpszSrc2Data);
|
|
void ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData);
|
|
void CopyBeforeWrite();
|
|
void AllocBeforeWrite(int nLen);
|
|
void Release();
|
|
static void PASCAL Release(CStringData* pData);
|
|
static int PASCAL SafeStrlen(LPCTSTR lpsz);
|
|
static void FASTCALL FreeData(CStringData* pData);
|
|
};
|
|
|
|
// Compare helpers
|
|
bool AFXAPI operator==(const CString& s1, const CString& s2);
|
|
bool AFXAPI operator==(const CString& s1, LPCTSTR s2);
|
|
bool AFXAPI operator==(LPCTSTR s1, const CString& s2);
|
|
bool AFXAPI operator!=(const CString& s1, const CString& s2);
|
|
bool AFXAPI operator!=(const CString& s1, LPCTSTR s2);
|
|
bool AFXAPI operator!=(LPCTSTR s1, const CString& s2);
|
|
bool AFXAPI operator<(const CString& s1, const CString& s2);
|
|
bool AFXAPI operator<(const CString& s1, LPCTSTR s2);
|
|
bool AFXAPI operator<(LPCTSTR s1, const CString& s2);
|
|
bool AFXAPI operator>(const CString& s1, const CString& s2);
|
|
bool AFXAPI operator>(const CString& s1, LPCTSTR s2);
|
|
bool AFXAPI operator>(LPCTSTR s1, const CString& s2);
|
|
bool AFXAPI operator<=(const CString& s1, const CString& s2);
|
|
bool AFXAPI operator<=(const CString& s1, LPCTSTR s2);
|
|
bool AFXAPI operator<=(LPCTSTR s1, const CString& s2);
|
|
bool AFXAPI operator>=(const CString& s1, const CString& s2);
|
|
bool AFXAPI operator>=(const CString& s1, LPCTSTR s2);
|
|
bool AFXAPI operator>=(LPCTSTR s1, const CString& s2);
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// CString inline functions
|
|
|
|
_AFX_INLINE CStringData* CString::GetData() const
|
|
{ ASSERT(m_pchData != NULL); return ((CStringData*)m_pchData)-1; }
|
|
_AFX_INLINE void CString::Init()
|
|
{ m_pchData = afxEmptyString.m_pchData; }
|
|
_AFX_INLINE CString::CString()
|
|
{ m_pchData = afxEmptyString.m_pchData; }
|
|
_AFX_INLINE CString::CString(const unsigned char* lpsz)
|
|
{ Init(); *this = (LPCSTR)lpsz; }
|
|
_AFX_INLINE const CString& CString::operator=(const unsigned char* lpsz)
|
|
{ *this = (LPCSTR)lpsz; return *this; }
|
|
_AFX_INLINE int CString::GetLength() const
|
|
{ return GetData()->nDataLength; }
|
|
_AFX_INLINE int CString::GetAllocLength() const
|
|
{ return GetData()->nAllocLength; }
|
|
_AFX_INLINE BOOL CString::IsEmpty() const
|
|
{ return GetData()->nDataLength == 0; }
|
|
_AFX_INLINE CString::operator LPCTSTR() const
|
|
{ return m_pchData; }
|
|
_AFX_INLINE int PASCAL CString::SafeStrlen(LPCTSTR lpsz)
|
|
{ return (lpsz == NULL) ? 0 : lstrlen(lpsz); }
|
|
_AFX_INLINE int CString::Compare(LPCTSTR lpsz) const
|
|
{ return lstrcmp(m_pchData, lpsz); } // MBCS/Unicode aware
|
|
_AFX_INLINE int CString::CompareNoCase(LPCTSTR lpsz) const
|
|
{ return lstrcmpi(m_pchData, lpsz); } // MBCS/Unicode aware
|
|
_AFX_INLINE TCHAR CString::GetAt(int nIndex) const
|
|
{
|
|
ASSERT(nIndex >= 0);
|
|
ASSERT(nIndex < GetData()->nDataLength);
|
|
return m_pchData[nIndex];
|
|
}
|
|
_AFX_INLINE TCHAR CString::operator[](int nIndex) const
|
|
{
|
|
// same as GetAt
|
|
ASSERT(nIndex >= 0);
|
|
ASSERT(nIndex < GetData()->nDataLength);
|
|
return m_pchData[nIndex];
|
|
}
|
|
_AFX_INLINE bool AFXAPI operator==(const CString& s1, const CString& s2)
|
|
{ return s1.Compare(s2) == 0; }
|
|
_AFX_INLINE bool AFXAPI operator==(const CString& s1, LPCTSTR s2)
|
|
{ return s1.Compare(s2) == 0; }
|
|
_AFX_INLINE bool AFXAPI operator==(LPCTSTR s1, const CString& s2)
|
|
{ return s2.Compare(s1) == 0; }
|
|
_AFX_INLINE bool AFXAPI operator!=(const CString& s1, const CString& s2)
|
|
{ return s1.Compare(s2) != 0; }
|
|
_AFX_INLINE bool AFXAPI operator!=(const CString& s1, LPCTSTR s2)
|
|
{ return s1.Compare(s2) != 0; }
|
|
_AFX_INLINE bool AFXAPI operator!=(LPCTSTR s1, const CString& s2)
|
|
{ return s2.Compare(s1) != 0; }
|
|
_AFX_INLINE bool AFXAPI operator<(const CString& s1, const CString& s2)
|
|
{ return s1.Compare(s2) < 0; }
|
|
_AFX_INLINE bool AFXAPI operator<(const CString& s1, LPCTSTR s2)
|
|
{ return s1.Compare(s2) < 0; }
|
|
_AFX_INLINE bool AFXAPI operator<(LPCTSTR s1, const CString& s2)
|
|
{ return s2.Compare(s1) > 0; }
|
|
_AFX_INLINE bool AFXAPI operator>(const CString& s1, const CString& s2)
|
|
{ return s1.Compare(s2) > 0; }
|
|
_AFX_INLINE bool AFXAPI operator>(const CString& s1, LPCTSTR s2)
|
|
{ return s1.Compare(s2) > 0; }
|
|
_AFX_INLINE bool AFXAPI operator>(LPCTSTR s1, const CString& s2)
|
|
{ return s2.Compare(s1) < 0; }
|
|
_AFX_INLINE bool AFXAPI operator<=(const CString& s1, const CString& s2)
|
|
{ return s1.Compare(s2) <= 0; }
|
|
_AFX_INLINE bool AFXAPI operator<=(const CString& s1, LPCTSTR s2)
|
|
{ return s1.Compare(s2) <= 0; }
|
|
_AFX_INLINE bool AFXAPI operator<=(LPCTSTR s1, const CString& s2)
|
|
{ return s2.Compare(s1) >= 0; }
|
|
_AFX_INLINE bool AFXAPI operator>=(const CString& s1, const CString& s2)
|
|
{ return s1.Compare(s2) >= 0; }
|
|
_AFX_INLINE bool AFXAPI operator>=(const CString& s1, LPCTSTR s2)
|
|
{ return s1.Compare(s2) >= 0; }
|
|
_AFX_INLINE bool AFXAPI operator>=(LPCTSTR s1, const CString& s2)
|
|
{ return s2.Compare(s1) <= 0; }
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// CWinThread
|
|
|
|
typedef DWORD (WINAPI *AFX_THREADPROC)(LPVOID);
|
|
|
|
class CWinThread
|
|
{
|
|
// DECLARE_DYNAMIC(CWinThread)
|
|
|
|
public:
|
|
// Constructors
|
|
CWinThread();
|
|
BOOL CreateThread(DWORD dwCreateFlags = 0, UINT nStackSize = 0,
|
|
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
|
|
|
|
// Attributes
|
|
// only valid while running
|
|
HANDLE m_hThread; // this thread's HANDLE
|
|
operator HANDLE() const;
|
|
DWORD m_nThreadID; // this thread's ID
|
|
|
|
int GetThreadPriority();
|
|
BOOL SetThreadPriority(int nPriority);
|
|
|
|
// Operations
|
|
DWORD SuspendThread();
|
|
DWORD ResumeThread();
|
|
BOOL PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam);
|
|
|
|
// Overridables
|
|
// thread initialization
|
|
virtual BOOL InitInstance();
|
|
|
|
// thread termination
|
|
virtual int ExitInstance(); // default will 'delete this'
|
|
|
|
|
|
// Implementation
|
|
public:
|
|
virtual ~CWinThread();
|
|
void CommonConstruct();
|
|
virtual void Delete();
|
|
|
|
public:
|
|
// constructor used by implementation of AfxBeginThread
|
|
CWinThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam);
|
|
|
|
// valid after construction
|
|
LPVOID m_pThreadParams; // generic parameters passed to starting function
|
|
AFX_THREADPROC m_pfnThreadProc;
|
|
};
|
|
|
|
// global helpers for threads
|
|
|
|
CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,
|
|
int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0,
|
|
DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
|
|
//CWinThread* AFXAPI AfxBeginThread(CRuntimeClass* pThreadClass,
|
|
// int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0,
|
|
// DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
|
|
|
|
CWinThread* AFXAPI AfxGetThread();
|
|
void AFXAPI AfxEndThread(UINT nExitCode, BOOL bDelete = TRUE);
|
|
|
|
void AFXAPI AfxInitThread();
|
|
void AFXAPI AfxTermThread(HINSTANCE hInstTerm = NULL);
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// CStringArray
|
|
|
|
class CStringArray // : public CObject
|
|
{
|
|
|
|
// DECLARE_SERIAL(CStringArray)
|
|
public:
|
|
|
|
// Construction
|
|
CStringArray();
|
|
|
|
// Attributes
|
|
int GetSize() const;
|
|
int GetUpperBound() const;
|
|
void SetSize(int nNewSize, int nGrowBy = -1);
|
|
|
|
// Operations
|
|
// Clean up
|
|
void FreeExtra();
|
|
void RemoveAll();
|
|
|
|
// Accessing elements
|
|
CString GetAt(int nIndex) const;
|
|
void SetAt(int nIndex, LPCTSTR newElement);
|
|
|
|
void SetAt(int nIndex, const CString& newElement);
|
|
|
|
CString& ElementAt(int nIndex);
|
|
|
|
// Direct Access to the element data (may return NULL)
|
|
const CString* GetData() const;
|
|
CString* GetData();
|
|
|
|
// Potentially growing the array
|
|
void SetAtGrow(int nIndex, LPCTSTR newElement);
|
|
|
|
void SetAtGrow(int nIndex, const CString& newElement);
|
|
|
|
int Add(LPCTSTR newElement);
|
|
|
|
int Add(const CString& newElement);
|
|
|
|
int Append(const CStringArray& src);
|
|
void Copy(const CStringArray& src);
|
|
|
|
// overloaded operator helpers
|
|
CString operator[](int nIndex) const;
|
|
CString& operator[](int nIndex);
|
|
|
|
// Operations that move elements around
|
|
void InsertAt(int nIndex, LPCTSTR newElement, int nCount = 1);
|
|
|
|
void InsertAt(int nIndex, const CString& newElement, int nCount = 1);
|
|
|
|
void RemoveAt(int nIndex, int nCount = 1);
|
|
void InsertAt(int nStartIndex, CStringArray* pNewArray);
|
|
|
|
// Implementation
|
|
protected:
|
|
CString* m_pData; // the actual array of data
|
|
int m_nSize; // # of elements (upperBound - 1)
|
|
int m_nMaxSize; // max allocated
|
|
int m_nGrowBy; // grow amount
|
|
|
|
void InsertEmpty(int nIndex, int nCount);
|
|
|
|
|
|
public:
|
|
~CStringArray();
|
|
|
|
// void Serialize(CArchive&);
|
|
#ifdef _DEBUG
|
|
// void Dump(CDumpContext&) const;
|
|
// void AssertValid() const;
|
|
#endif
|
|
|
|
protected:
|
|
// local typedefs for class templates
|
|
typedef CString BASE_TYPE;
|
|
typedef LPCTSTR BASE_ARG_TYPE;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef _AFXCOLL_INLINE
|
|
#define _AFXCOLL_INLINE inline
|
|
#endif
|
|
|
|
_AFXCOLL_INLINE int CStringArray::GetSize() const
|
|
{ return m_nSize; }
|
|
_AFXCOLL_INLINE int CStringArray::GetUpperBound() const
|
|
{ return m_nSize-1; }
|
|
_AFXCOLL_INLINE void CStringArray::RemoveAll()
|
|
{ SetSize(0); }
|
|
_AFXCOLL_INLINE CString CStringArray::GetAt(int nIndex) const
|
|
{ ASSERT(nIndex >= 0 && nIndex < m_nSize);
|
|
return m_pData[nIndex]; }
|
|
_AFXCOLL_INLINE void CStringArray::SetAt(int nIndex, LPCTSTR newElement)
|
|
{ ASSERT(nIndex >= 0 && nIndex < m_nSize);
|
|
m_pData[nIndex] = newElement; }
|
|
|
|
_AFXCOLL_INLINE void CStringArray::SetAt(int nIndex, const CString& newElement)
|
|
{ ASSERT(nIndex >= 0 && nIndex < m_nSize);
|
|
m_pData[nIndex] = newElement; }
|
|
|
|
_AFXCOLL_INLINE CString& CStringArray::ElementAt(int nIndex)
|
|
{ ASSERT(nIndex >= 0 && nIndex < m_nSize);
|
|
return m_pData[nIndex]; }
|
|
_AFXCOLL_INLINE const CString* CStringArray::GetData() const
|
|
{ return (const CString*)m_pData; }
|
|
_AFXCOLL_INLINE CString* CStringArray::GetData()
|
|
{ return (CString*)m_pData; }
|
|
_AFXCOLL_INLINE int CStringArray::Add(LPCTSTR newElement)
|
|
{ int nIndex = m_nSize;
|
|
SetAtGrow(nIndex, newElement);
|
|
return nIndex; }
|
|
|
|
_AFXCOLL_INLINE int CStringArray::Add(const CString& newElement)
|
|
{ int nIndex = m_nSize;
|
|
SetAtGrow(nIndex, newElement);
|
|
return nIndex; }
|
|
|
|
_AFXCOLL_INLINE CString CStringArray::operator[](int nIndex) const
|
|
{ return GetAt(nIndex); }
|
|
_AFXCOLL_INLINE CString& CStringArray::operator[](int nIndex)
|
|
{ return ElementAt(nIndex); }
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CPtrArray
|
|
|
|
class CPtrArray // : public CObject
|
|
{
|
|
// DECLARE_DYNAMIC(CPtrArray)
|
|
public:
|
|
|
|
// Construction
|
|
CPtrArray();
|
|
|
|
// Attributes
|
|
int GetSize() const;
|
|
int GetUpperBound() const;
|
|
void SetSize(int nNewSize, int nGrowBy = -1);
|
|
|
|
// Operations
|
|
// Clean up
|
|
void FreeExtra();
|
|
void RemoveAll();
|
|
|
|
// Accessing elements
|
|
void* GetAt(int nIndex) const;
|
|
void SetAt(int nIndex, void* newElement);
|
|
|
|
void*& ElementAt(int nIndex);
|
|
|
|
// Direct Access to the element data (may return NULL)
|
|
const void** GetData() const;
|
|
void** GetData();
|
|
|
|
// Potentially growing the array
|
|
void SetAtGrow(int nIndex, void* newElement);
|
|
|
|
int Add(void* newElement);
|
|
|
|
int Append(const CPtrArray& src);
|
|
void Copy(const CPtrArray& src);
|
|
|
|
// overloaded operator helpers
|
|
void* operator[](int nIndex) const;
|
|
void*& operator[](int nIndex);
|
|
|
|
// Operations that move elements around
|
|
void InsertAt(int nIndex, void* newElement, int nCount = 1);
|
|
|
|
void RemoveAt(int nIndex, int nCount = 1);
|
|
void InsertAt(int nStartIndex, CPtrArray* pNewArray);
|
|
|
|
// Implementation
|
|
protected:
|
|
void** m_pData; // the actual array of data
|
|
int m_nSize; // # of elements (upperBound - 1)
|
|
int m_nMaxSize; // max allocated
|
|
int m_nGrowBy; // grow amount
|
|
|
|
|
|
public:
|
|
~CPtrArray();
|
|
#ifdef _DEBUG
|
|
// void Dump(CDumpContext&) const;
|
|
// void AssertValid() const;
|
|
#endif
|
|
|
|
protected:
|
|
// local typedefs for class templates
|
|
typedef void* BASE_TYPE;
|
|
typedef void* BASE_ARG_TYPE;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
_AFXCOLL_INLINE int CPtrArray::GetSize() const
|
|
{ return m_nSize; }
|
|
_AFXCOLL_INLINE int CPtrArray::GetUpperBound() const
|
|
{ return m_nSize-1; }
|
|
_AFXCOLL_INLINE void CPtrArray::RemoveAll()
|
|
{ SetSize(0); }
|
|
_AFXCOLL_INLINE void* CPtrArray::GetAt(int nIndex) const
|
|
{ ASSERT(nIndex >= 0 && nIndex < m_nSize);
|
|
return m_pData[nIndex]; }
|
|
_AFXCOLL_INLINE void CPtrArray::SetAt(int nIndex, void* newElement)
|
|
{ ASSERT(nIndex >= 0 && nIndex < m_nSize);
|
|
m_pData[nIndex] = newElement; }
|
|
|
|
_AFXCOLL_INLINE void*& CPtrArray::ElementAt(int nIndex)
|
|
{ ASSERT(nIndex >= 0 && nIndex < m_nSize);
|
|
return m_pData[nIndex]; }
|
|
_AFXCOLL_INLINE const void** CPtrArray::GetData() const
|
|
{ return (const void**)m_pData; }
|
|
_AFXCOLL_INLINE void** CPtrArray::GetData()
|
|
{ return (void**)m_pData; }
|
|
_AFXCOLL_INLINE int CPtrArray::Add(void* newElement)
|
|
{ int nIndex = m_nSize;
|
|
SetAtGrow(nIndex, newElement);
|
|
return nIndex; }
|
|
|
|
_AFXCOLL_INLINE void* CPtrArray::operator[](int nIndex) const
|
|
{ return GetAt(nIndex); }
|
|
_AFXCOLL_INLINE void*& CPtrArray::operator[](int nIndex)
|
|
{ return ElementAt(nIndex); }
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTypedPtrArray<BASE_CLASS, TYPE>
|
|
|
|
template<class BASE_CLASS, class TYPE>
|
|
class CTypedPtrArray : public BASE_CLASS
|
|
{
|
|
public:
|
|
// Accessing elements
|
|
TYPE GetAt(int nIndex) const
|
|
{ return (TYPE)BASE_CLASS::GetAt(nIndex); }
|
|
TYPE& ElementAt(int nIndex)
|
|
{ return (TYPE&)BASE_CLASS::ElementAt(nIndex); }
|
|
void SetAt(int nIndex, TYPE ptr)
|
|
{ BASE_CLASS::SetAt(nIndex, ptr); }
|
|
|
|
// Potentially growing the array
|
|
void SetAtGrow(int nIndex, TYPE newElement)
|
|
{ BASE_CLASS::SetAtGrow(nIndex, newElement); }
|
|
int Add(TYPE newElement)
|
|
{ return BASE_CLASS::Add(newElement); }
|
|
int Append(const CTypedPtrArray<BASE_CLASS, TYPE>& src)
|
|
{ return BASE_CLASS::Append(src); }
|
|
void Copy(const CTypedPtrArray<BASE_CLASS, TYPE>& src)
|
|
{ BASE_CLASS::Copy(src); }
|
|
|
|
// Operations that move elements around
|
|
void InsertAt(int nIndex, TYPE newElement, int nCount = 1)
|
|
{ BASE_CLASS::InsertAt(nIndex, newElement, nCount); }
|
|
void InsertAt(int nStartIndex, CTypedPtrArray<BASE_CLASS, TYPE>* pNewArray)
|
|
{ BASE_CLASS::InsertAt(nStartIndex, pNewArray); }
|
|
|
|
// overloaded operator helpers
|
|
TYPE operator[](int nIndex) const
|
|
{ return (TYPE)BASE_CLASS::operator[](nIndex); }
|
|
TYPE& operator[](int nIndex)
|
|
{ return (TYPE&)BASE_CLASS::operator[](nIndex); }
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|