josé
for CBSTR ,I have to add a constructor, operator let and cast for the BSTR
your method is not badly, but there is simpler with my method
to see widestring.bi and its test
#pragma once
#include once "windows.bi"
#include once "win/ole2.bi"
#Include once "win/shlwapi.bi"
#ifndef AFX_BSTR
#define AFX_BSTR WSTRING PTR
#endif
NAMESPACE Afx.CBStrClass
' ========================================================================================
' CBStr - OLE strings class
' ========================================================================================
TYPE CBStr
Private:
m_bstr AS AFX_BSTR
Public:
DECLARE CONSTRUCTOR (BYREF wszStr AS CONST WSTRING = "")
DECLARE CONSTRUCTOR (BYREF szStr AS STRING = "")
DECLARE CONSTRUCTOR (BYREF pCBStr AS CBStr)
DECLARE CONSTRUCTOR (BYREF bstrHandle AS AFX_BSTR = NULL)
DECLARE CONSTRUCTOR (BYVAL pCBStr AS BSTR)
DECLARE DESTRUCTOR
DECLARE OPERATOR Let (BYREF szStr AS STRING)
DECLARE OPERATOR Let (BYREF wszStr AS CONST WSTRING)
DECLARE OPERATOR Let (BYREF pCBStr AS CBStr)
DECLARE OPERATOR Let (BYREF bstrHandle AS AFX_BSTR)
DECLARE OPERATOR Let (BYVAL pBStr AS BSTR)
DECLARE OPERATOR += (BYREF wszStr AS CONST WSTRING)
DECLARE OPERATOR += (BYREF pCBStr AS CBStr)
DECLARE OPERATOR &= (BYREF wszStr AS CONST WSTRING)
DECLARE OPERATOR &= (BYREF pCBStr AS CBStr)
DECLARE PROPERTY Handle () AS AFX_BSTR
DECLARE SUB Append (BYREF wszStr AS CONST WSTRING)
DECLARE FUNCTION Concat (BYREF wszStr2 AS CONST WSTRING, BYREF wszStr2 AS CONST WSTRING) AS AFX_BSTR
DECLARE OPERATOR cast() AS String
DECLARE OPERATOR cast() AS BSTR
END TYPE
' ========================================================================================
' ========================================================================================
' CBStr class constructor
' ========================================================================================
CONSTRUCTOR CBStr (BYREF wszStr AS CONST WSTRING = "")
m_bstr = SysAllocString(wszStr)
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
CONSTRUCTOR CBStr (BYREF szStr AS STRING = "")
m_bstr = SysAllocString(WSTR(szStr))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
CONSTRUCTOR CBStr (BYREF pCBStr AS CBStr)
m_bstr = SysAllocString(*pCBStr.Handle)
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
CONSTRUCTOR CBStr (BYREF bstrHandle AS AFX_BSTR = NULL)
IF bstrHandle = NULL THEN
m_bstr = SysAllocString("")
ELSE
' Detect if the passed handle is an OLE string
' If it is an OLE string it must have a descriptor; otherwise, don't
' Get the length looking at the descriptor
DIM res AS INTEGER = PEEK(DWORD, CAST(ANY PTR, bstrHandle) - 4) \ 2
' If the retrieved length if the same that the returned by LEN, then it must be an OLE string
IF res = .LEN(*bstrHandle) THEN
' Free the current OLE string and attach the passed handle to the class
m_bstr = bstrHandle
ELSE
' Allocate an OLE string with the contents of the string pointer by bstrHandle
m_bstr = SysAllocString(*bstrHandle)
END IF
END IF
END CONSTRUCTOR
CONSTRUCTOR CBStr(BYVAL pCBStr AS BSTR)
m_bstr =Cast(WString Ptr,pCBStr)
End Constructor
' ========================================================================================
' CBStr class destructor
' ========================================================================================
DESTRUCTOR CBStr
IF m_bstr THEN SysFreeString m_bstr
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Assigns new text to the BSTR
' Note: We can also pass a FB ansi string (the conversion to Unicode is automatic)
' ========================================================================================
OPERATOR CBStr.Let (BYREF wszStr AS CONST WSTRING)
IF m_bstr THEN SysFreeString(m_bstr)
m_bstr = SysAllocString(wszStr)
END OPERATOR
' ========================================================================================
' ========================================================================================
OPERATOR CBStr.Let (BYREF szStr AS STRING)
IF m_bstr THEN SysFreeString(m_bstr)
m_bstr = SysAllocString(WSTR(szStr))
END OPERATOR
' ========================================================================================
' ========================================================================================
OPERATOR CBStr.Let (BYREF pCBStr AS CBStr)
IF m_bstr THEN SysFreeString(m_bstr)
m_bstr = SysAllocString(*pCBStr.Handle)
END OPERATOR
' ========================================================================================
' ========================================================================================
OPERATOR CBStr.Let (BYREF bstrHandle AS AFX_BSTR)
IF bstrHandle = NULL THEN EXIT OPERATOR
' Free the current OLE string
IF m_bstr THEN SysFreeString(m_bstr)
' Detect if the passed handle is an OLE string
' If it is an OLE string it must have a descriptor; otherwise, don't
' Get the length looking at the descriptor
DIM res AS INTEGER = PEEK(DWORD, CAST(ANY PTR, bstrHandle) - 4) \ 2
' If the retrieved length if the same that the returned by LEN, then it must be an OLE string
IF res = .LEN(*bstrHandle) THEN
' Attach the passed handle to the class
m_bstr = bstrHandle
ELSE
' Allocate an OLE string with the contents of the string pointer by bstrHandle
m_bstr = SysAllocString(*bstrHandle)
END IF
END OPERATOR
OPERATOR CBStr.Let (BYVAL szStr AS BSTR)
IF m_bstr THEN SysFreeString(m_bstr)
m_bstr = Cast(WString Ptr,szStr)
END Operator
OPERATOR CBStr.cast() AS String
Return *m_bstr
End Operator
OPERATOR CBStr.cast() AS BSTR
Return Cast(BSTR,m_bstr)
End Operator
' ========================================================================================
' Returns the handle of the BSTR
' ========================================================================================
PROPERTY CBStr.Handle () AS AFX_BSTR
PROPERTY = m_bstr
END PROPERTY
' ========================================================================================
' ========================================================================================
' Appends a string to the BSTR. The string can be a literal or a FB STRING or WSTRING variable.
' To append another BSTR:
' DIM bs1 AS CBStr = "1st string"
' DIM bs2 AS CBStr = "2nd string"
' bs1.Append *bs2.Handle
' -or-
' bs1.Append **bs2
' ========================================================================================
SUB CBStr.Append (BYREF wszStr AS CONST WSTRING)
DIM n1 AS UINT = SysStringLen(m_bstr)
DIM nLen AS UINT = .LEN(wszStr)
IF nLen = 0 THEN EXIT SUB
DIM b AS AFX_BSTR = SysAllocStringLen(NULL, n1+nLen)
IF b = NULL THEN EXIT SUB
memcpy(b, m_bstr, n1 * SIZEOF(WSTRING))
memcpy(b+n1, @wszStr, nLen * SIZEOF(WSTRING))
SysFreeString(m_bstr)
m_bstr = b
END SUB
' ========================================================================================
' ========================================================================================
' Appends a string to the BSTR. The string can be a literal or a FB STRING or WSTRING variable.
' ========================================================================================
OPERATOR CBStr.+= (BYREF wszStr AS CONST WSTRING)
this.Append(wszStr)
END OPERATOR
' ========================================================================================
' ========================================================================================
' Appends a BSTR to the BSTR.
' ========================================================================================
OPERATOR CBStr.+= (BYREF pCBStr AS CBStr)
this.Append(*pCBStr.Handle)
END OPERATOR
' ========================================================================================
' ========================================================================================
' Appends a string to the BSTR. The string can be a literal or a FB STRING or WSTRING variable.
' ========================================================================================
OPERATOR CBStr.&= (BYREF wszStr AS CONST WSTRING)
this.Append(wszStr)
END OPERATOR
' ========================================================================================
' ========================================================================================
' Appends a BSTR to the BSTR.
' ========================================================================================
OPERATOR CBStr.&= (BYREF pCBStr AS CBStr)
this.Append(*pCBStr.Handle)
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns vbTrue (-1) if the two BSTRings are equal; FALSE, otherwise.
' ========================================================================================
OPERATOR = (BYREF pCBStr1 AS CBStr, BYREF pCBStr2 AS CBStr) AS INTEGER
OPERATOR = StrCmpW(*pCBStr1.Handle, *pCBStr2.Handle) = 0
END OPERATOR
' ========================================================================================
' ========================================================================================
OPERATOR = (BYREF pCBStr AS CBStr, BYREF wszStr AS CONST WSTRING) AS INTEGER
OPERATOR = StrCmpW(*pCBStr.Handle, wszStr) = 0
END OPERATOR
' ========================================================================================
OPERATOR = (BYREF wszStr AS CONST WSTRING, BYREF pCBStr AS CBStr) AS INTEGER
OPERATOR = StrCmpW(wszStr, *pCBStr.Handle) = 0
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns vbTrue (-1) if the two BSTRings are not equal; FALSE, otherwise.
' ========================================================================================
OPERATOR <> (BYREF pCBStr1 AS CBStr, BYREF pCBStr2 AS CBStr) AS INTEGER
OPERATOR = StrCmpW(*pCBStr1.Handle, *pCBStr2.Handle) <> 0
END OPERATOR
' ========================================================================================
' ========================================================================================
OPERATOR <> (BYREF pCBStr AS CBStr, BYREF wszStr AS CONST WSTRING) AS INTEGER
OPERATOR = StrCmpW(*pCBStr.Handle, wszStr) <> 0
END OPERATOR
' ========================================================================================
OPERATOR <> (BYREF wszStr AS CONST WSTRING, BYREF pCBStr AS CBStr) AS INTEGER
OPERATOR = StrCmpW(wszStr, *pCBStr.Handle) <> 0
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns vbTrue (-1) if the the first BSTR is greater than the 2nd BSTR; FALSE, otherwise.
' ========================================================================================
OPERATOR > (BYREF pCBStr1 AS CBStr, BYREF pCBStr2 AS CBStr) AS INTEGER
OPERATOR = StrCmpW(*pCBStr1.Handle, *pCBStr2.Handle) > 0
END OPERATOR
' ========================================================================================
' ========================================================================================
OPERATOR > (BYREF pCBStr AS CBStr, BYREF wszStr AS CONST WSTRING) AS INTEGER
OPERATOR = StrCmpW(*pCBStr.Handle, wszStr) > 0
END OPERATOR
' ========================================================================================
OPERATOR > (BYREF wszStr AS CONST WSTRING, BYREF pCBStr AS CBStr) AS INTEGER
OPERATOR = StrCmpW(wszStr, *pCBStr.Handle) > 0
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns vbTrue (-1) if the the first BSTR is less than the 2nd BSTR; FALSE, otherwise.
' ========================================================================================
OPERATOR < (BYREF pCBStr1 AS CBStr, BYREF pCBStr2 AS CBStr) AS INTEGER
OPERATOR = StrCmpW(*pCBStr1.Handle, *pCBStr2.Handle) < 0
END OPERATOR
' ========================================================================================
' ========================================================================================
OPERATOR < (BYREF pCBStr AS CBStr, BYREF wszStr AS CONST WSTRING) AS INTEGER
OPERATOR = StrCmpW(*pCBStr.Handle, wszStr) < 0
END OPERATOR
' ========================================================================================
OPERATOR < (BYREF wszStr AS CONST WSTRING, BYREF pCBStr AS CBStr) AS INTEGER
OPERATOR = StrCmpW(wszStr, *pCBStr.Handle) < 0
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns vbTrue (-1) if the the first BSTR is greater or equal than the 2nd BSTR; FALSE, otherwise.
' ========================================================================================
OPERATOR >= (BYREF pCBStr1 AS CBStr, BYREF pCBStr2 AS CBStr) AS INTEGER
DIM nResult AS LONG
nResult = StrCmpW(*pCBStr1.Handle, *pCBStr2.Handle)
IF nResult > 0 OR nResult = 0 THEN OPERATOR = -1 ELSE OPERATOR = 0
END OPERATOR
' ========================================================================================
' ========================================================================================
OPERATOR >= (BYREF pCBStr AS CBStr, BYREF wszStr AS CONST WSTRING) AS INTEGER
DIM nResult AS LONG
nResult = StrCmpW(*pCBStr.Handle, wszStr)
IF nResult > 0 OR nResult = 0 THEN OPERATOR = -1 ELSE OPERATOR = 0
END OPERATOR
' ========================================================================================
OPERATOR >= (BYREF wszStr AS CONST WSTRING, BYREF pCBStr AS CBStr) AS INTEGER
DIM nResult AS LONG
nResult = StrCmpW(wszStr, *pCBStr.Handle)
IF nResult > 0 OR nResult = 0 THEN OPERATOR = -1 ELSE OPERATOR = 0