📄 helpers.cpp
字号:
// HELPERS.CPP - Helper classes for easing BSTR, SAFEARRAY and VARIANT use.
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// <summary>
// This source file contains the implementation of helper classes to be used
// with the wrapper code in Visiwrap.h. You can choose to use no helpers, or
// non-MFC helpers or MFC-aware helpers.
// </summary>
//
//#ifdef MFC_HELPERS
#include "stdafx.h"
//#endif
#include <windows.h>
#include <ole2.h>
#include <winnls.h>
#include <tchar.h>
//#include <strsafe.h>
#include "helpers.h"
#define V_MAX_STR_CONVERT 2048
static OLECHAR szOleStr[V_MAX_STR_CONVERT];
// VBstr - Constructor
//
// <summary>
// Constructor for VBstr class
// </summary>
//
// Return Value:
// None
//
VBstr::VBstr()
{
m_bstr= NULL;
}
// VBstr - Constructor
//
// <summary>
// Copy constructor for VBstr class
// </summary>
//
// Return Value:
// None
//
VBstr::VBstr(const VBstr FAR &other)
{
m_bstr= SysAllocString(other.m_bstr);
}
// VBstr - Constructor
//
// <summary>
// Constructor for VBstr class, takes an LPCTSTR.
// </summary>
//
// Return Value:
// None
//
VBstr::VBstr(LPCTSTR lpStr)
{
m_bstr= NULL;
AllocFromLPCTSTR(lpStr);
}
// VBstr - Constructor
//
// <summary>
// Constructor for VBstr class. Can take responsibility for a BSTR.
// </summary>
//
// Return Value:
// None
//
VBstr::VBstr(BSTR bstr, BOOL bAssumeResponsibility /*= FALSE*/)
{
// *REQUIRED*
if (bAssumeResponsibility)
m_bstr= bstr;
else
m_bstr= SysAllocString(bstr);
}
// ~VBstr - Destructor
//
// <summary>
// Destructor for VBstr class. Frees any BSTR memory.
// </summary>
//
// Return Value:
// None
//
VBstr::~VBstr()
{
if (m_bstr)
SysFreeString(m_bstr);
}
// AllocFromLPCTSTR - allocate a BSTR given a LPCTSTR
//
// <summary>
// Allocate a BSTR member copy of the LPCTSTR passed in.
// </summary>
//
// Return Value:
// HRESULT - NOERROR or some HRESULT error code
//
HRESULT VBstr::AllocFromLPCTSTR(LPCTSTR lpStr)
{
if (lpStr)
{
#ifdef _UNICODE
m_bstr= SysAllocString(lpStr);
#else
#ifndef OLE2ANSI
int nBytes= _tcslen(lpStr) + 1;
OLECHAR* pOleStr= szOleStr;
if (nBytes > (ULONG)(V_MAX_STR_CONVERT))
{
pOleStr= new OLECHAR[nBytes];
if (NULL == pOleStr)
return E_OUTOFMEMORY;
}
MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, lpStr, -1, pOleStr, nBytes);
m_bstr= SysAllocString(pOleStr);
if (nBytes > (ULONG)(V_MAX_STR_CONVERT))
{
delete [] pOleStr;
}
#else
m_bstr= SysAllocString(lpStr);
#endif
#endif
}
return NOERROR;
}
// operator const BSTR - treat Vbstr like a BSTR
//
// <summary>
// Get const access to the BSTR member variable
// </summary>
//
// Return Value:
// const BSTR
//
VBstr::operator const BSTR() const
{
// *REQUIRED*
return m_bstr;
}
// operator= - Assignment operator for Vbstr
//
// <summary>
// Assign a Vbstr with a BSTR value
// </summary>
//
// Return Value:
// const VBstr FAR & - const reference to the BSTR member variable
//
const VBstr FAR &VBstr::operator=(const BSTR bstr)
{
// *REQUIRED*
if (m_bstr)
SysFreeString(m_bstr);
m_bstr= SysAllocString(bstr);
return (*this);
}
// operator= - Assignment operator for Vbstr
//
// <summary>
// Assign a Vbstr with a Vbstr value
// </summary>
//
// Return Value:
// const VBstr FAR & - const reference to the BSTR member variable
//
const VBstr FAR &VBstr::operator=(const VBstr &other)
{
if (&other!=this)
{
if (m_bstr)
SysFreeString(m_bstr);
m_bstr= SysAllocString(other.m_bstr);
}
return (*this);
}
// operator= - Assignment operator for Vbstr
//
// <summary>
// Assign a Vbstr with a LPCTSTR value
// </summary>
//
// Return Value:
// const VBstr FAR & - const reference to the BSTR member variable
//
const VBstr FAR &VBstr::operator=(LPCTSTR lpStr)
{
if (m_bstr)
SysFreeString(m_bstr);
m_bstr= NULL;
AllocFromLPCTSTR(lpStr);
return (*this);
}
// operator= - Assignment operator for Vbstr
//
// <summary>
// Assign a Vbstr with a LPCOLESTR value
// </summary>
//
// Return Value:
// const VBstr FAR & - const reference to the BSTR member variable
//
#ifndef _UNICODE
const VBstr FAR &VBstr:: operator=(LPCOLESTR lpOlestr)
{
if (m_bstr)
SysFreeString(m_bstr);
m_bstr= SysAllocString(lpOlestr);
return (*this);
}
#endif
#define VBSTR_COMPARE wcscmp
#define VBSTR_COMPARE_I _wcsicmp
// Since Borland 5.0 doesn't support wcscmp and Win95 only
// stubs lstrcmpW, write our own:
#ifdef __BORLANDC__
// Neither of these will work with embedded NULL OLECHARs:
// (but for simple string compares, it's better than nothing...)
int VBstr_cmp(unsigned short* s1, unsigned short* s2)
{
int ret;
ret= (int)((short)*s1 - (short)*s2);
while( (0==ret) && *s2)
++s1, ++s2, ret= (int)((short)*s1 - (short)*s2);
return ret;
}
// For characters outside the A to Z range, this function compares them
// exactly; watch out for strings with special accented characters - you may
// have to write your own version of this for certain applications with the
// Borland compiler...
// (but again, for simple string compares, it's better than nothing...)
int VBstr_cmpi(unsigned short* s1, unsigned short* s2)
{
wchar_t f,l;
do
{
f = ((*s1 <= L'Z') && (*s1 >= L'A'))
? *s1 + L'a' - L'A'
: *s1;
l = ((*s2 <= L'Z') && (*s2 >= L'A'))
? *s2 + L'a' - L'A'
: *s2;
s1++;
s2++;
} while ( (f) && (f == l) );
return (int)(f - l);
}
#undef VBSTR_COMPARE
#define VBSTR_COMPARE(s1, s2) \
VBstr_cmp((unsigned short*)(s1), (unsigned short*)(s2))
#undef VBSTR_COMPARE_I
#define VBSTR_COMPARE_I(s1, s2) \
VBstr_cmpi((unsigned short*)(s1), (unsigned short*)(s2))
#endif
// Compare - compare one Vbstr value to another
//
// <summary>
// Compare the value of a Vbstr with another Vbstr.
// </summary>
//
// Return Value:
// BOOL - TRUE if the strings are equal and FALSE otherwise
//
BOOL VBstr::Compare(const VBstr FAR &other,
BOOL bCaseSensitive /*= TRUE*/) const
{
// Use "vbstr.Compare(other, VBSTR_CASE_INSENSITIVE)"
// for case-insensitive compare...
// Use "vbstr.Compare(other)" for case-sensitive compare...
// Simple string comparison function.
// Only works on simple NULL terminated strings.
// If you embed NULL OLECHARs within you BSTRs,
// write another function to compare them.
// The strings must be identical or
// both NULL/"empty" to return TRUE.
if (NULL==m_bstr)
{
if (NULL==other.m_bstr || 0==other.m_bstr[0])
{
// They are both the "empty"/NULL string:
return TRUE;
}
else
{
// One's NULL, but the other is non-NULL with content:
return FALSE;
}
}
if (NULL==other.m_bstr)
{
if (0==m_bstr[0])
{
// They are both the "empty"/NULL string:
return TRUE;
}
else
{
// One's NULL, but the other is non-NULL with content:
return FALSE;
}
}
// They're both non-NULL, compare:
if (bCaseSensitive)
{
return (0==VBSTR_COMPARE(m_bstr, other.m_bstr));
}
else
{
return (0==VBSTR_COMPARE_I(m_bstr, other.m_bstr));
}
}
// operator== - compare one Vbstr value to another
//
// <summary>
// Compare the value of a Vbstr with another Vbstr.
// </summary>
//
// Return Value:
// BOOL - TRUE if the strings are equal and FALSE otherwise
//
BOOL VBstr::operator==(const VBstr FAR &other) const
{
// Case-sensitive!
// Use "vbstr.Compare(other, VBSTR_CASE_INSENSITIVE)"
// for case-insensitive compare...
return Compare(other);
}
// ConvertToCString - convert the Vbstr to a CString
//
// <summary>
// Convert the value of a Vbstr to an MFC CString
// </summary>
//
// Return Value:
// void
//
#ifdef MFC_HELPERS
void VBstr::ConvertToCString(CString FAR& cstr)
{
if (m_bstr)
{
#ifdef _UNICODE
cstr= m_bstr;
#else
#if !defined(OLE2ANSI)
int nbyte= WideCharToMultiByte(GetACP(), 0, m_bstr, -1, NULL, 0, 0, 0);
LPTSTR lpStr= cstr.GetBuffer(nbyte);
WideCharToMultiByte(GetACP(), 0, m_bstr, -1, lpStr, nbyte, 0, 0);
cstr.ReleaseBuffer();
#else
cstr= m_bstr;
#endif //!OLE2ANSI
#endif //_UNICODE
}
else
{
cstr = "";
}
}
#endif
// ConvertToLPTSTR - convert the Vbstr to an LPTSTR
//
// <summary>
// Convert the value of a Vbstr to an LPTSTR
// </summary>
//
// Return Value:
// HRESULT - NOERROR or some HRESULT error code
//
HRESULT VBstr::ConvertToLPTSTR(LPTSTR pStr, ULONG* pnBytes)
{
// *pnBytes should be size of pStr buffer on entry
// *pnBytes is size needed if E_FAIL is returned
// *pnBytes is size copied if NOERROR is returned
if (NULL==pStr || NULL==pnBytes)
return E_POINTER;
int nNeeded; // intentionally uninitialized - all code paths
// below initialize nNeeded properly
if (m_bstr)
{
#ifdef _UNICODE
size_t nLen = _tcslen(m_bstr);
nNeeded= (nLen + 1) * sizeof(TCHAR);
if ( (*pnBytes) >= ((ULONG)nNeeded) )
{
StringCchCopy(pStr, sizeof(pStr)/sizeof(WCHAR), m_bstr);
pStr[nLen]=0;
}
else
{
(*pnBytes) = (ULONG) nNeeded;
*pStr = 0;
return E_FAIL;
}
#else
#if !defined(OLE2ANSI)
nNeeded= WideCharToMultiByte(GetACP(), 0, m_bstr, -1, NULL, 0, 0, 0);
if ( (*pnBytes) >= ((ULONG)nNeeded) )
{
WideCharToMultiByte(GetACP(), 0, m_bstr, -1, pStr, nNeeded, 0, 0);
}
else
{
(*pnBytes) = (ULONG) nNeeded;
*pStr = 0;
return E_FAIL;
}
#else
size_t nLen = _tcslen(m_bstr);
nNeeded= _tcslen(m_bstr) + 1;
if ( (*pnBytes) >= ((ULONG)nNeeded) )
{
_tcsncpy(pStr, m_bstr, nLen);
pStr[nLen]=0;
}
else
{
(*pnBytes) = (ULONG) nNeeded;
*pStr = 0;
return E_FAIL;
}
#endif
#endif
}
else
{
nNeeded = sizeof(TCHAR);
if ( (*pnBytes) >= ((ULONG)nNeeded) )
{
(*pStr)= (TCHAR) 0;
}
else
{
(*pnBytes) = (ULONG) nNeeded;
*pStr = 0;
return E_FAIL;
}
}
(*pnBytes)= (ULONG) nNeeded;
return NOERROR;
}
// VVariant - Constructor
//
// <summary>
// Default constructor for VVariant class
// </summary>
//
// Return Value:
// None
//
VVariant::VVariant()
{
Init();
}
// VVariant - Constructor
//
// <summary>
// Copy constructor for VVariant class
// </summary>
//
// Return Value:
// None
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -