You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
396 lines
9.2 KiB
C++
396 lines
9.2 KiB
C++
// XTVC50Helpers.cpp : Visual C++ 5.0 helpers
|
|
//
|
|
// This file is a part of the XTREME CONTROLS MFC class library.
|
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
|
|
|
#include "XTVC50Helpers.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#if (_MSC_VER <= 1100) // Using Visual C++ 5.0
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTStringHelper
|
|
|
|
CXTStringHelper::CXTStringHelper()
|
|
{
|
|
}
|
|
|
|
CXTStringHelper::CXTStringHelper(CString strIn) : CString(strIn)
|
|
{
|
|
}
|
|
|
|
int CXTStringHelper::Find(TCHAR ch) const
|
|
{
|
|
return CString::Find(ch);
|
|
}
|
|
|
|
int CXTStringHelper::Find(LPCTSTR lpszSub) const
|
|
{
|
|
return CString::Find(lpszSub);
|
|
}
|
|
|
|
const CString& CXTStringHelper::operator=(const CString& stringSrc)
|
|
{
|
|
return CString::operator=(stringSrc);
|
|
}
|
|
|
|
const CString& CXTStringHelper::operator=(TCHAR ch)
|
|
{
|
|
return CString::operator=(ch);
|
|
}
|
|
|
|
const CString& CXTStringHelper::operator=(const unsigned char* psz)
|
|
{
|
|
return CString::operator=(psz);
|
|
}
|
|
|
|
const CString& CXTStringHelper::operator=(LPCWSTR lpsz)
|
|
{
|
|
return CString::operator=(lpsz);
|
|
}
|
|
|
|
const CString& CXTStringHelper::operator=(LPCSTR lpsz)
|
|
{
|
|
return CString::operator=(lpsz);
|
|
}
|
|
|
|
int CXTStringHelper::Find(LPCTSTR lpszSub, int nStart) const
|
|
{
|
|
ASSERT(AfxIsValidString(lpszSub));
|
|
|
|
int nLength = GetData()->nDataLength;
|
|
if (nStart > nLength)
|
|
return -1;
|
|
|
|
// find first matching substring
|
|
LPTSTR lpsz = _tcsstr(m_pchData + nStart, lpszSub);
|
|
|
|
// return -1 for not found, distance from beginning otherwise
|
|
return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
|
|
}
|
|
|
|
int CXTStringHelper::Insert(int nIndex, TCHAR ch)
|
|
{
|
|
CopyBeforeWrite();
|
|
|
|
if (nIndex < 0)
|
|
nIndex = 0;
|
|
|
|
int nNewLength = GetData()->nDataLength;
|
|
if (nIndex > nNewLength)
|
|
nIndex = nNewLength;
|
|
nNewLength++;
|
|
|
|
if (GetData()->nAllocLength < nNewLength)
|
|
{
|
|
CStringData* pOldData = GetData();
|
|
LPTSTR pstr = m_pchData;
|
|
AllocBuffer(nNewLength);
|
|
memcpy(m_pchData, pstr, (pOldData->nDataLength + 1)*sizeof(TCHAR));
|
|
CString::Release(pOldData);
|
|
}
|
|
|
|
// move existing bytes down
|
|
memmove(m_pchData + nIndex + 1,
|
|
m_pchData + nIndex, (nNewLength-nIndex)*sizeof(TCHAR));
|
|
m_pchData[nIndex] = ch;
|
|
GetData()->nDataLength = nNewLength;
|
|
|
|
return nNewLength;
|
|
}
|
|
|
|
int CXTStringHelper::Insert(int nIndex, LPCTSTR pstr)
|
|
{
|
|
if (nIndex < 0)
|
|
nIndex = 0;
|
|
|
|
int nInsertLength = SafeStrlen(pstr);
|
|
int nNewLength = GetData()->nDataLength;
|
|
if (nInsertLength > 0)
|
|
{
|
|
CopyBeforeWrite();
|
|
if (nIndex > nNewLength)
|
|
nIndex = nNewLength;
|
|
nNewLength += nInsertLength;
|
|
|
|
if (GetData()->nAllocLength < nNewLength)
|
|
{
|
|
CStringData* pOldData = GetData();
|
|
LPTSTR pstr = m_pchData;
|
|
AllocBuffer(nNewLength);
|
|
memcpy(m_pchData, pstr, (pOldData->nDataLength + 1)*sizeof(TCHAR));
|
|
CString::Release(pOldData);
|
|
}
|
|
|
|
// move existing bytes down
|
|
memmove(m_pchData + nIndex + nInsertLength,
|
|
m_pchData + nIndex,
|
|
(nNewLength-nIndex-nInsertLength + 1)*sizeof(TCHAR));
|
|
memmove(m_pchData + nIndex,
|
|
pstr, nInsertLength*sizeof(TCHAR));
|
|
GetData()->nDataLength = nNewLength;
|
|
}
|
|
|
|
return nNewLength;
|
|
}
|
|
|
|
int CXTStringHelper::Remove(TCHAR chRemove)
|
|
{
|
|
CopyBeforeWrite();
|
|
|
|
LPTSTR pstrSource = m_pchData;
|
|
LPTSTR pstrDest = m_pchData;
|
|
LPTSTR pstrEnd = m_pchData + GetData()->nDataLength;
|
|
|
|
while (pstrSource < pstrEnd)
|
|
{
|
|
if (*pstrSource != chRemove)
|
|
{
|
|
*pstrDest = *pstrSource;
|
|
pstrDest = _tcsinc(pstrDest);
|
|
}
|
|
pstrSource = _tcsinc(pstrSource);
|
|
}
|
|
*pstrDest = '\0';
|
|
int nCount = pstrSource - pstrDest;
|
|
GetData()->nDataLength -= nCount;
|
|
|
|
return nCount;
|
|
}
|
|
|
|
int CXTStringHelper::Replace(TCHAR chOld, TCHAR chNew)
|
|
{
|
|
int nCount = 0;
|
|
|
|
// short-circuit the nop case
|
|
if (chOld != chNew)
|
|
{
|
|
// otherwise modify each character that matches in the string
|
|
CopyBeforeWrite();
|
|
LPTSTR psz = m_pchData;
|
|
LPTSTR pszEnd = psz + GetData()->nDataLength;
|
|
while (psz < pszEnd)
|
|
{
|
|
// replace instances of the specified character only
|
|
if (*psz == chOld)
|
|
{
|
|
*psz = chNew;
|
|
nCount++;
|
|
}
|
|
psz = _tcsinc(psz);
|
|
}
|
|
}
|
|
return nCount;
|
|
}
|
|
|
|
int CXTStringHelper::Replace(LPCTSTR lpszOld, LPCTSTR lpszNew)
|
|
{
|
|
// can't have empty or NULL lpszOld
|
|
|
|
int nSourceLen = SafeStrlen(lpszOld);
|
|
if (nSourceLen == 0)
|
|
return 0;
|
|
int nReplacementLen = SafeStrlen(lpszNew);
|
|
|
|
// loop once to figure out the size of the result string
|
|
int nCount = 0;
|
|
LPTSTR lpszStart = m_pchData;
|
|
LPTSTR lpszEnd = m_pchData + GetData()->nDataLength;
|
|
LPTSTR lpszTarget;
|
|
while (lpszStart < lpszEnd)
|
|
{
|
|
while ((lpszTarget = _tcsstr(lpszStart, lpszOld)) != NULL)
|
|
{
|
|
nCount++;
|
|
lpszStart = lpszTarget + nSourceLen;
|
|
}
|
|
lpszStart += lstrlen(lpszStart) + 1;
|
|
}
|
|
|
|
// if any changes were made, make them
|
|
if (nCount > 0)
|
|
{
|
|
CopyBeforeWrite();
|
|
|
|
// if the buffer is too small, just
|
|
// allocate a new buffer (slow but sure)
|
|
int nOldLength = GetData()->nDataLength;
|
|
int nNewLength = nOldLength + (nReplacementLen-nSourceLen)*nCount;
|
|
if (GetData()->nAllocLength < nNewLength || GetData()->nRefs > 1)
|
|
{
|
|
CStringData* pOldData = GetData();
|
|
LPTSTR pstr = m_pchData;
|
|
AllocBuffer(nNewLength);
|
|
memcpy(m_pchData, pstr, pOldData->nDataLength*sizeof(TCHAR));
|
|
CString::Release(pOldData);
|
|
}
|
|
// else, we just do it in-place
|
|
lpszStart = m_pchData;
|
|
lpszEnd = m_pchData + GetData()->nDataLength;
|
|
|
|
// loop again to actually do the work
|
|
while (lpszStart < lpszEnd)
|
|
{
|
|
while ((lpszTarget = _tcsstr(lpszStart, lpszOld)) != NULL)
|
|
{
|
|
int nBalance = nOldLength - (lpszTarget - m_pchData + nSourceLen);
|
|
memmove(lpszTarget + nReplacementLen, lpszTarget + nSourceLen,
|
|
nBalance * sizeof(TCHAR));
|
|
memcpy(lpszTarget, lpszNew, nReplacementLen*sizeof(TCHAR));
|
|
lpszStart = lpszTarget + nReplacementLen;
|
|
lpszStart[nBalance] = '\0';
|
|
nOldLength += (nReplacementLen - nSourceLen);
|
|
}
|
|
lpszStart += lstrlen(lpszStart) + 1;
|
|
}
|
|
ASSERT(m_pchData[nNewLength] == '\0');
|
|
GetData()->nDataLength = nNewLength;
|
|
}
|
|
|
|
return nCount;
|
|
}
|
|
|
|
int CXTStringHelper::Delete(int nIndex, int nCount)
|
|
{
|
|
if (nIndex < 0)
|
|
nIndex = 0;
|
|
int nNewLength = GetData()->nDataLength;
|
|
if (nCount > 0 && nIndex < nNewLength)
|
|
{
|
|
CopyBeforeWrite();
|
|
int nBytesToCopy = nNewLength - (nIndex + nCount) + 1;
|
|
|
|
memcpy(m_pchData + nIndex,
|
|
m_pchData + nIndex + nCount, nBytesToCopy * sizeof(TCHAR));
|
|
GetData()->nDataLength = nNewLength - nCount;
|
|
}
|
|
|
|
return nNewLength;
|
|
}
|
|
|
|
CXTStringHelper CXTStringHelper::Left(int nCount) const
|
|
{
|
|
if (nCount < 0)
|
|
nCount = 0;
|
|
if (nCount >= GetData()->nDataLength)
|
|
return *this;
|
|
|
|
CXTStringHelper dest;
|
|
AllocCopy(dest, nCount, 0, 0);
|
|
return dest;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTHeaderCtrlHelper
|
|
|
|
int CXTHeaderCtrlHelper::GetItemCount() const
|
|
{
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
return (int)::SendMessage(m_hWnd, HDM_GETITEMCOUNT, 0, 0L);
|
|
}
|
|
|
|
BOOL CXTHeaderCtrlHelper::GetItemRect(int nIndex, LPRECT lpRect) const
|
|
{
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
ASSERT(lpRect != NULL);
|
|
return (BOOL)::SendMessage(m_hWnd, HDM_GETITEMRECT, nIndex, (LPARAM)lpRect);
|
|
}
|
|
|
|
BOOL CXTHeaderCtrlHelper::GetOrderArray(LPINT piArray, int iCount /* = -1 */)
|
|
{
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
|
|
// if -1 was passed, find the count ourselves
|
|
|
|
int nCount = iCount;
|
|
if (nCount == -1)
|
|
{
|
|
nCount = GetItemCount();
|
|
|
|
if (nCount == -1)
|
|
return FALSE;
|
|
}
|
|
|
|
ASSERT(AfxIsValidAddress(piArray, iCount * sizeof(int)));
|
|
|
|
return (BOOL) ::SendMessage(m_hWnd, HDM_GETORDERARRAY,
|
|
(WPARAM) iCount, (LPARAM) piArray);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTListCtrlHelper
|
|
|
|
POSITION CXTListCtrlHelper::GetFirstSelectedItemPosition() const
|
|
{
|
|
ASSERT(::IsWindow(GetSafeHwnd()));
|
|
return (POSITION)(1 + GetNextItem(-1, LVIS_SELECTED));
|
|
}
|
|
|
|
int CXTListCtrlHelper::GetNextSelectedItem(POSITION& pos) const
|
|
{
|
|
ASSERT(::IsWindow(GetSafeHwnd()));
|
|
int nOldPos = (int)pos-1;
|
|
pos = (POSITION)(1 + GetNextItem(nOldPos, LVIS_SELECTED));
|
|
return nOldPos;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTListViewHelper
|
|
|
|
POSITION CXTListViewHelper::GetFirstSelectedItemPosition() const
|
|
{
|
|
ASSERT(::IsWindow(GetListCtrl().GetSafeHwnd()));
|
|
return (POSITION)(1 + GetListCtrl().GetNextItem(-1, LVIS_SELECTED));
|
|
}
|
|
|
|
int CXTListViewHelper::GetNextSelectedItem(POSITION& pos) const
|
|
{
|
|
ASSERT(::IsWindow(GetListCtrl().GetSafeHwnd()));
|
|
int nOldPos = (int)pos-1;
|
|
pos = (POSITION)(1 + GetListCtrl().GetNextItem(nOldPos, LVIS_SELECTED));
|
|
return nOldPos;
|
|
}
|
|
|
|
#else
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTListViewHelper
|
|
|
|
POSITION CXTListViewHelper::GetFirstSelectedItemPosition() const
|
|
{
|
|
return GetListCtrl().GetFirstSelectedItemPosition();
|
|
}
|
|
|
|
int CXTListViewHelper::GetNextSelectedItem(POSITION& pos) const
|
|
{
|
|
return GetListCtrl().GetNextSelectedItem(pos);
|
|
}
|
|
|
|
|
|
#endif//#if (_MSC_VER <= 1100)
|