/** * @file XTVC50Helpers.cpp * * @copyright * (c) 1998-2025 Codejock Software, All Rights Reserved. * * This source file is the property of Codejock Software and must not be * redistributed by any means without the explicit written permission of * Codejock Software. * * The use of this source code is governed by the terms and conditions specified * in the Toolkit Pro license agreement. Codejock Software grants you, as a * single software developer, the limited right to use this software on one * computer only. * * Contact Information: * support@codejock.com * http://www.codejock.com * */ #include "stdafx.h" #include "XTVC50Helpers.h" #include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.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 { _ASSERTE(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; } _ASSERTE(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 { _ASSERTE(::IsWindow(m_hWnd)); return (int)::SendMessage(m_hWnd, HDM_GETITEMCOUNT, 0, 0L); } BOOL CXTHeaderCtrlHelper::GetItemRect(int nIndex, LPRECT lpRect) const { _ASSERTE(::IsWindow(m_hWnd)); _ASSERTE(lpRect != NULL); return (BOOL)::SendMessage(m_hWnd, HDM_GETITEMRECT, nIndex, (LPARAM)lpRect); } BOOL CXTHeaderCtrlHelper::GetOrderArray(LPINT piArray, int iCount /* = -1 */) { _ASSERTE(::IsWindow(m_hWnd)); // if -1 was passed, find the count ourselves int nCount = iCount; if (nCount == -1) { nCount = GetItemCount(); if (nCount == -1) return FALSE; } _ASSERTE(AfxIsValidAddress(piArray, iCount * sizeof(int))); return (BOOL)::SendMessage(m_hWnd, HDM_GETORDERARRAY, (WPARAM)iCount, (LPARAM)piArray); } ///////////////////////////////////////////////////////////////////////////// // CXTListCtrlHelper POSITION CXTListCtrlHelper::GetFirstSelectedItemPosition() const { _ASSERTE(::IsWindow(GetSafeHwnd())); return (POSITION)(1 + GetNextItem(-1, LVIS_SELECTED)); } int CXTListCtrlHelper::GetNextSelectedItem(POSITION& pos) const { _ASSERTE(::IsWindow(GetSafeHwnd())); int nOldPos = (int)pos - 1; pos = (POSITION)(1 + GetNextItem(nOldPos, LVIS_SELECTED)); return nOldPos; } ///////////////////////////////////////////////////////////////////////////// // CXTListViewHelper POSITION CXTListViewHelper::GetFirstSelectedItemPosition() const { _ASSERTE(::IsWindow(GetListCtrl().GetSafeHwnd())); return (POSITION)(1 + GetListCtrl().GetNextItem(-1, LVIS_SELECTED)); } int CXTListViewHelper::GetNextSelectedItem(POSITION& pos) const { _ASSERTE(::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)