2025-04-27 07:49:33 -04:00

543 lines
10 KiB
C++

// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//***************************************************************************
//
// (c) 1996 by Microsoft Corporation
//
// utils.cpp
//
// This file contains definitions for miscellaneous utility functions, classes,
// and so on.
//
// a-larryf 17-Sept-96 Created.
//
//***************************************************************************
#include "precomp.h"
#include "utils.h"
#include "resource.h"
//#include "gc.h"
#define MAXSTRING 1024
//***********************************************************************
// BStringToCString
//
// Convert a BSTR to a CString
//
// Parameters:
// CString& sResult
// The result is returned here.
//
// BSTR bstrSource
// The source BSTR
//
// Returns:
// Nothing.
//
//**********************************************************************
void BStringToCString(CString& sResult, BSTR bstrSource)
{
char sz[MAXSTRING];
wcstombs(sz, (OLECHAR*) bstrSource, sizeof(sz) - 1);
sResult = sz;
}
//***********************************************************************
// VariantToCString
//
// Convert a variant to a CString
//
// Parameters:
// CString& sResult
// The result is returned here.
//
// VARIANT& varSrc
// The source variant.
//
// Returns:
// Nothing.
//
//**********************************************************************
void VariantToCString(CString& sResult, const VARIANT& varSrc)
{
if (varSrc.vt == VT_BSTR) {
sResult = varSrc.bstrVal;
}
else {
COleVariant var(varSrc);
ToBSTR(var);
sResult = var.bstrVal;
}
}
//********************************************************************
// ToBSTR
//
// Convert a COleVariant to a BSTR
//
// Parameters:
// COleVariant& var
// The variant to convert.
//
// Returns:
// BSTR
// The place where the converted value is returned.
//
// Note that the BSTR returned is owned by the COleVariant.
//*******************************************************************
BSTR ToBSTR(COleVariant& var)
{
switch(var.vt) {
case VT_BSTR:
break;
case VT_NULL:
var = L"";
break;
default:
try
{
var.ChangeType(VT_BSTR);
}
catch(CException* )
{
var = L"";
}
break;
}
return var.bstrVal;
}
//***********************************************************************
// GenerateWindowID
//
// A series of unique window IDs are generated by sucessive calls to this
// method.
//
// Parameters:
// None.
//
// Returns:
// A unique window ID used when creating a new window.
//
//**********************************************************************
UINT GenerateWindowID()
{
static UINT nID = 2000;
return nID++;
}
//******************************************************************
// GetViewerFont
//
// Get the "global" font used by the HMOM object viewer. This method
// will probably be replaced when I can figure out a way to get the
// ambient font.
//
// Parameters:
// [in] CFont& font
// A reference to the font to return.
//
// [in] LONG lfHeight
// The desired font height.
//
// [in] LONG lfWeight
// The weight of the font (FW_BOLD, FW_NORMAL, etc.)
//
// Returns:
// Nothing.
//
//*******************************************************************
void GetViewerFont(CFont& font, LONG lfHeight, LONG lfWeight)
{
CFont fontTmp;
fontTmp.CreateStockObject(SYSTEM_FONT);
LOGFONT logFont;
fontTmp.GetObject(sizeof(LOGFONT), &logFont);
logFont.lfWidth = 0;
logFont.lfHeight = lfHeight;
logFont.lfWeight = lfWeight;
logFont.lfQuality = DEFAULT_QUALITY;
logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
lstrcpy(logFont.lfFaceName, _T("MS Shell Dlg"));
VERIFY(font.CreateFontIndirect(&logFont));
}
//***********************************************************
// LoadStringArray
//
// Load a string array with some number of strings from the
// string table.
//
// Parameters:
// CStringArray& sa
// The place where the strings are loaded into.
//
// UINT* puiResID
// Pointer to an array of resource ids for the strings.
//
// int nStrings
// The number of entries in the array.
//
// Returns:
// Nothing.
//
//************************************************************
void LoadStringArray(CStringArray& sa, UINT* puiResID, int nStrings)
{
for (int iString=0; iString < nStrings; ++iString) {
CString sText;
sText.LoadString(puiResID[iString]);
sa.Add(sText);
}
}
//*****************************************************************
// LoadStringMap
//
// This function should probably go away and CMapStringToLong should
// be used instead.
//
// This function loads a string array with the values in a TStrMap.
// This map is used to map string values to some integer value.
//
// Parameters:
// CStringArray& asGridStrings
// This is where the strings are returned.
//
// TStrMap* pStrMap
// A pointer to an array of entries containing {string, value} pairs
/// where the string is coded as a resource id.
//
// int nStrings
// The number of entries in the TStrMap array.
//
//*****************************************************************
void LoadStringMap(CStringArray& asGridStrings, TStrMap* pStrMap, int nStrings)
{
CString sValue;
for (int iStr =0; iStr<nStrings; ++iStr) {
sValue.LoadString(pStrMap[iStr].ids);
asGridStrings.SetAtGrow(pStrMap[iStr].iString, sValue);
}
}
//*****************************************************************
// CXStringArray::Load
//
// Given an array of resource ids, load the corresponding strings
// into this CStringArray.
//
// Parameters:
// UINT* puiResID
// Pointer to the array of string resource ids
//
// int nStrings
// The number of entries in the resource id array.
//
// Returns:
// Nothing.
//
//****************************************************************
void CXStringArray::Load(UINT* puiResID, int nStrings)
{
// If this string array was already loaded, do nothing.
if (GetSize() > 0) {
return;
}
CString sValue;
while (--nStrings >= 0) {
sValue.LoadString(*puiResID++);
Add(sValue);
}
}
BOOL IsEqualNoCase(BSTR bstr1, BSTR bstr2)
{
if (bstr1 == bstr2) {
return TRUE;
}
if (bstr1==NULL || bstr2==NULL) {
return FALSE;
}
while (TRUE) {
WCHAR wch1;
WCHAR wch2;
wch1 = towupper(*bstr1);
wch2 = towupper(*bstr2);
if (wch1 != wch2) {
break;
}
if (wch1 == 0) {
return TRUE;
}
++bstr1;
++bstr2;
}
return FALSE;
}
BOOL IsEqual(BSTR bstr1, BSTR bstr2)
{
if (bstr1 == bstr2) {
return TRUE;
}
if (bstr1==NULL || bstr2==NULL) {
return FALSE;
}
while (*bstr1 == *bstr2) {
if (*bstr1 == 0) {
return TRUE;
}
++bstr1;
++bstr2;
}
return FALSE;
}
BOOL IsEqual(COleVariant& varOperand1, BSTR bstrOperand2)
{
if (varOperand1.vt == VT_BSTR) {
return IsEqual(varOperand1.bstrVal, bstrOperand2);
}
else {
COleVariant varTemp;
varTemp = varOperand1;
ToBSTR(varTemp);
return IsEqual(varTemp.bstrVal, bstrOperand2);
}
}
//**********************************************
// IsEmptyString
//
// Check to see if a BSTR is all white space.
//
// Parameters:
// BSTR bstr
// The BSTR to examine.
//
// Returns:
// BOOL
// TRUE if the string is empty, FALSE otherwise.
//
//*********************************************
BOOL IsEmptyString(BSTR bstr)
{
ASSERT(bstr != NULL);
while (iswspace(*bstr)) {
++bstr;
}
return (*bstr == 0);
}
//**********************************************
// IsEmptyString
//
// Check to see if a CString is all white space.
//
// Parameters:
// CString& s
// The string to examine.
//
// Returns:
// BOOL
// TRUE if the string is empty, FALSE otherwise.
//
//*********************************************
BOOL IsEmptyString(CString& s)
{
LPCTSTR psz = s;
while(_istspace(*psz)) {
++psz;
}
return (*psz == 0);
}
//****************************************************
// RemoveLeadingWhiteSpace
//
// Remove any leading white space from the string
// contained in the variant.
//
// Parameters:
// [in] COleVariant& var
// The variant containing the string to trim.
//
// Returns:
// Nothing.
//
//****************************************************
void RemoveLeadingWhiteSpace(COleVariant& var)
{
ASSERT(var.vt == VT_BSTR);
if (var.vt != VT_BSTR) {
return;
}
BSTR bstr = var.bstrVal;
while (*bstr) {
if (!iswspace(*bstr)) {
break;
}
++bstr;
}
if (var.bstrVal != bstr) {
var = bstr;
}
}
//****************************************************
// RemoveTrailingWhiteSpace
//
// Remove any trailing white space from the string
// contained in the variant.
//
// Parameters:
// [in] COleVariant& var
// The variant containing the string to trim.
//
// Returns:
// Nothing.
//
//****************************************************
void RemoveTrailingWhiteSpace(COleVariant& var)
{
ASSERT(var.vt == VT_BSTR);
if (var.vt != VT_BSTR) {
return;
}
BSTR bstrStart = var.bstrVal;
BSTR bstr = bstrStart;
// Move the pointer to the end of the string
while(*bstr) {
++bstr;
}
if (bstr > bstrStart) {
--bstr;
while (TRUE) {
if (!iswspace(*bstr)) {
break;
}
if (bstr == bstrStart) {
break;
}
*bstr = 0;
--bstr;
}
}
}
CBSTR& CBSTR::operator=(LPCTSTR psz)
{
if (m_bstr) {
::SysFreeString(m_bstr);
}
CString s(psz);
m_bstr = s.AllocSysString();
return *this;
}
CBSTR& CBSTR::operator=(CString& s)
{
if (m_bstr) {
::SysFreeString(m_bstr);
}
m_bstr = s.AllocSysString();
return *this;
}
CBSTR& CBSTR::operator=(BSTR bstr)
{
if (m_bstr) {
::SysFreeString(m_bstr);
}
CString s;
s = bstr;
m_bstr = s.AllocSysString();
return *this;
}
//**********************************************************************
// IsPrefix
//
// Check to see if one string is the prefix of another.
//
// Parameters:
// [in] LPCTSTR pszPrefix
// The prefix to check for.
//
// [in] LPCTSTR pszValue
// The string to examine.
//
// Returns:
// TRUE if the pszPrefix is a prefix of sValue.
//
//**********************************************************************
BOOL IsPrefix(LPCTSTR pszPrefix, LPCTSTR pszValue)
{
while (*pszPrefix != 0) {
if (*pszPrefix != *pszValue) {
return FALSE;
}
++pszPrefix;
++pszValue;
}
return TRUE;
}