CComBSTR Class
The new home for Visual Studio documentation is Visual Studio 2017 Documentation on docs.microsoft.com.
The latest version of this topic can be found at CComBSTR Class.
This class is a wrapper for BSTR
s.
Syntax
class CComBSTR
Members
Public Constructors
Name | Description |
---|---|
CComBSTR::CComBSTR | The constructor. |
CComBSTR::~CComBSTR | The destructor. |
Public Methods
Name | Description |
---|---|
CComBSTR::Append | Appends a string to m_str . |
CComBSTR::AppendBSTR | Appends a BSTR to m_str . |
CComBSTR::AppendBytes | Appends a specified number of bytes to m_str . |
CComBSTR::ArrayToBSTR | Creates a BSTR from the first character of each element in the safearray and attaches it to the CComBSTR object. |
CComBSTR::AssignBSTR | Assigns a BSTR to m_str . |
CComBSTR::Attach | Attaches a BSTR to the CComBSTR object. |
CComBSTR::BSTRToArray | Creates a zero-based one-dimensional safearray, where each element of the array is a character from the CComBSTR object. |
CComBSTR::ByteLength | Returns the length of m_str in bytes. |
CComBSTR::Copy | Returns a copy of m_str . |
CComBSTR::CopyTo | Returns a copy of m_str via an [out] parameter |
CComBSTR::Detach | Detaches m_str from the CComBSTR object. |
CComBSTR::Empty | Frees m_str . |
CComBSTR::Length | Returns the length of m_str . |
CComBSTR::LoadString | Loads a string resource. |
CComBSTR::ReadFromStream | Loads a BSTR object from a stream. |
CComBSTR::ToLower | Converts the string to lowercase. |
CComBSTR::ToUpper | Converts the string to uppercase. |
CComBSTR::WriteToStream | Saves m_str to a stream. |
Public Operators
Name | Description |
---|---|
CComBSTR::operator BSTR | Casts a CComBSTR object to a BSTR . |
CComBSTR::operator ! | Returns true or false , depending on whether m_str is NULL . |
CComBSTR::operator != | Compares a CComBSTR with a string. |
CComBSTR::operator & | Returns the address of m_str . |
CComBSTR::operator += | Appends a CComBSTR to the object. |
CComBSTR::operator < | Compares a CComBSTR with a string. |
CComBSTR::operator = | Assigns a value to m_str . |
CComBSTR::operator == | Compares a CComBSTR with a string. |
CComBSTR::operator > | Compares a CComBSTR with a string. |
Public Data Members
Name | Description |
---|---|
CComBSTR::m_str | Contains the BSTR associated with the CComBSTR object. |
Remarks
The CComBSTR
class is a wrapper for BSTR
s, which are length-prefixed strings. The length is stored as an integer at the memory location preceding the data in the string.
A BSTR is null-terminated after the last counted character but may also contain null characters embedded within the string. The string length is determined by the character count, not the first null character.
Note
The CComBSTR
class provides a number of members (constructors, assignment operators, and comparison operators) that take either ANSI or Unicode strings as arguments. The ANSI versions of these functions are less efficient than their Unicode counterparts because temporary Unicode strings are often created internally. For efficiency, use the Unicode versions where possible.
Note
Because of the improved lookup behavior implemented in Visual Studio .NET, code such as bstr = L"String2" + bstr;
, which may have compiled in previous releases, should instead be implemented as bstr = CStringW(L"String2") + bstr
.
For a list of cautions when using CComBSTR
, see Programming with CComBSTR.
Requirements
Header: atlbase.h
CComBSTR::Append
Appends either lpsz
or the BSTR
member of bstrSrc
to m_str.
HRESULT Append(const CComBSTR& bstrSrc) throw();
HRESULT Append(wchar_t ch) throw();
HRESULT Append(char ch) throw();
HRESULT Append(LPCOLESTR lpsz) throw();
HRESULT Append(LPCSTR lpsz) throw();
HRESULT Append(LPCOLESTR lpsz, int nLen) throw();
Parameters
bstrSrc
[in] A CComBSTR
object to append.
ch
[in] A character to append.
lpsz
[in] A zero-terminated character string to append. You can pass a Unicode string via the LPCOLESTR overload or an ANSI string via the LPCSTR
version.
nLen
[in] The number of characters from lpsz
to append.
Return Value
S_OK
on success, or any standard HRESULT
error value.
Remarks
An ANSI string will be converted to Unicode before being appended.
Example
enum { urlASP, urlHTM, urlISAPI } urlType;
urlType = urlASP;
CComBSTR bstrURL = OLESTR("https://SomeSite/");
CComBSTR bstrDEF = OLESTR("/OtherSite");
CComBSTR bstrASP = OLESTR("default.asp");
CComBSTR bstrTemp;
HRESULT hr;
switch (urlType)
{
case urlASP:
// bstrURL is 'https://SomeSite/default.asp'
hr = bstrURL.Append(bstrASP);
break;
case urlHTM:
// bstrURL is 'https://SomeSite/default.htm'
hr = bstrURL.Append(OLESTR("default.htm"));
break;
case urlISAPI:
// bstrURL is 'https://SomeSite/default.dll?func'
hr = bstrURL.Append(OLESTR("default.dll?func"));
break;
default:
// bstrTemp is 'https://'
hr = bstrTemp.Append(bstrURL, 7);
// bstrURL is 'https://OtherSite'
if (hr == S_OK)
hr = bstrTemp.Append(bstrDEF);
bstrURL = bstrTemp;
break;
}
CComBSTR::AppendBSTR
Appends the specified BSTR
to m_str.
HRESULT AppendBSTR(BSTR p) throw();
Parameters
p
[in] A BSTR
to append.
Return Value
S_OK
on success, or any standard HRESULT
error value.
Remarks
Do not pass an ordinary wide-character string to this method. The compiler cannot catch the error and run time errors will occur.
Example
CComBSTR bstrPre(OLESTR("Hello "));
CComBSTR bstrSuf(OLESTR("World!"));
HRESULT hr;
// Appends "World!" to "Hello "
hr = bstrPre.AppendBSTR(bstrSuf);
// Displays a message box with text "Hello World!"
::MessageBox(NULL, CW2CT(bstrPre), NULL, MB_OK);
CComBSTR::AppendBytes
Appends the specified number of bytes to m_str without conversion.
HRESULT AppendBytes(const char* lpsz, int nLen) throw();
Parameters
lpsz
[in] A pointer to an array of bytes to append.
p
[in] The number of bytes to append.
Return Value
S_OK
on success, or any standard HRESULT
error value.
Example
CComBSTR bstrPre(OLESTR("Hello "));
HRESULT hr;
// Appends "Wo" to "Hello " (4 bytes == 2 characters)
hr = bstrPre.AppendBytes(reinterpret_cast<char*>(OLESTR("World!")), 4);
// Displays a message box with text "Hello Wo"
::MessageBox(NULL, CW2CT(bstrPre), NULL, MB_OK);
CComBSTR::ArrayToBSTR
Frees any existing string held in the CComBSTR
object, then creates a BSTR
from the first character of each element in the safearray and attaches it to the CComBSTR
object.
HRESULT ArrayToBSTR(const SAFEARRAY* pSrc) throw();
Parameters
pSrc
[in] The safearray containing the elements used to create the string.
Return Value
S_OK
on success, or any standard HRESULT
error value.
CComBSTR::AssignBSTR
Assigns a BSTR
to m_str.
HRESULT AssignBSTR(const BSTR bstrSrc) throw();
Parameters
bstrSrc
[in] A BSTR
to assign to the current CComBSTR
object.
Return Value
S_OK
on success, or any standard HRESULT
error value.
CComBSTR::Attach
Attaches a BSTR
to the CComBSTR
object by setting the m_str member to src.
void Attach(BSTR src) throw();
Parameters
src
[in] The BSTR
to attach to the object.
Remarks
Do not pass an ordinary wide-character string to this method. The compiler cannot catch the error and run time errors will occur.
Note
This method will assert if m_str
is non- NULL.
Example
// STDMETHOD(BSTRToUpper)(/*[in, out]*/ BSTR bstrConv);
STDMETHODIMP InplaceBSTRToUpper(BSTR bstrConv)
{
// Assign bstrConv to m_str member of CComBSTR
CComBSTR bstrTemp;
bstrTemp.Attach(bstrConv);
// Make sure BSTR is not NULL string
if (!bstrTemp)
return E_POINTER;
// Make string uppercase
HRESULT hr;
hr = bstrTemp.ToUpper();
if (hr != S_OK)
return hr;
// Set m_str to NULL, so the BSTR is not freed
bstrTemp.Detach();
return S_OK;
}
CComBSTR::BSTRToArray
Creates a zero-based one-dimensional safearray, where each element of the array is a character from the CComBSTR
object.
HRESULT BSTRToArray(LPSAFEARRAY* ppArray) throw();
Parameters
ppArray
[out] The pointer to the safearray used to hold the results of the function.
Return Value
S_OK
on success, or any standard HRESULT
error value.
CComBSTR::ByteLength
Returns the number of bytes in m_str
, excluding the terminating null character.
unsigned int ByteLength() const throw();
Return Value
The length of the m_str member in bytes.
Remarks
Returns 0 if m_str
is NULL.
Example
// string with 11 chars (22 bytes)
CComBSTR bstrTemp(OLESTR("Hello World"));
unsigned int len = bstrTemp.ByteLength();
ATLASSERT(len == 22);
CComBSTR::CComBSTR
The constructor. The default constructor sets the m_str member to NULL.
CComBSTR() throw();
CComBSTR(const CComBSTR& src);
CComBSTR(REFGUID guid);
CComBSTR(int nSize);
CComBSTR(int nSize, LPCOLESTR sz);
CComBSTR(int nSize, LPCSTR sz);
CComBSTR(LPCOLESTR pSrc);
CComBSTR(LPCSTR pSrc);
CComBSTR(CComBSTR&& src);
Parameters
nSize
[in] The number of characters to copy from sz
or the initial size in characters for the CComBSTR
.
sz
[in] A string to copy. The Unicode version specifies an LPCOLESTR; the ANSI version specifies an LPCSTR
.
pSrc
[in] A string to copy. The Unicode version specifies an LPCOLESTR; the ANSI version specifies an LPCSTR
.
src
[in] A CComBSTR
object.
guid
[in] A reference to a GUID structure.
Remarks
The copy constructor sets m_str
to a copy of the BSTR
member of src. The REFGUID constructor converts the GUID to a string using StringFromGUID2 and stores the result.
The other constructors set m_str
to a copy of the specified string. If you pass a value for nSize
, then only nSize
characters will be copied, followed by a terminating null character.
CComBSTR
supports move semantics. You can use the move constructor (the constructor that takes an rvalue reference ( &&
) to create a new object that uses the same underlying data as the old object you pass in as an argument, without the overhead of copying the object.
The destructor frees the string pointed to by m_str
.
Example
CComBSTR bstr1; // BSTR points to NULL
bstr1 = "Bye"; // initialize with assignment operator
// ANSI string is converted to wide char
OLECHAR* str = OLESTR("Bye bye!"); // wide char string of length 5
int len = (int)wcslen(str);
CComBSTR bstr2(len + 1);// unintialized BSTR of length 6
wcsncpy_s(bstr2.m_str, bstr2.Length(), str, len); // copy wide char string to BSTR
CComBSTR bstr3(5, OLESTR("Hello World")); // BSTR containing 'Hello',
// input string is wide char
CComBSTR bstr4(5, "Hello World"); // same as above, input string
// is ANSI
CComBSTR bstr5(OLESTR("Hey there")); // BSTR containing 'Hey there',
// input string is wide char
CComBSTR bstr6("Hey there"); // same as above, input string
// is ANSI
CComBSTR bstr7(bstr6); // copy constructor, bstr7 contains 'Hey there'
CComBSTR::~CComBSTR
The destructor.
~CComBSTR();
Remarks
The destructor frees the string pointed to by m_str
.
CComBSTR::Copy
Allocates and returns a copy of m_str
.
BSTR Copy() const throw();
Return Value
A copy of the m_str member. If m_str
is NULL, returns NULL.
Example
CComBSTR m_bstrURL; // BSTR representing a URL
// put_URL is the put method for the URL property.
STDMETHOD(put_URL)(BSTR strURL)
{
ATLTRACE(_T("put_URL\n"));
// free existing string in m_bstrURL & make a copy
// of strURL pointed to by m_bstrURL
m_bstrURL = strURL;
return S_OK;
}
// get_URL is the get method for the URL property.
STDMETHOD(get_URL)(BSTR* pstrURL)
{
ATLTRACE(_T("get_URL\n"));
// make a copy of m_bstrURL pointed to by pstrURL
*pstrURL = m_bstrURL.Copy(); // See CComBSTR::CopyTo
return S_OK;
}
CComBSTR::CopyTo
Allocates and returns a copy of m_str via the parameter.
HRESULT CopyTo(BSTR* pbstr) throw();
HRESULT CopyTo(VARIANT* pvarDest) throw();
Parameters
pbstr
[out] The address of a BSTR
in which to return the string allocated by this method.
pvarDest
[out] The address of a VARIANT in which to return the string allocated by this method.
Return Value
A standard HRESULT
value indicating the success or failure of the copy.
Remarks
After calling this method, the VARIANT pointed to by pvarDest
will be of type VT_BSTR
.
Example
CComBSTR m_bstrURL; // BSTR representing a URL
// get_URL is the get method for the URL property.
STDMETHOD(get_URL)(BSTR* pstrURL)
{
// Make a copy of m_bstrURL and return it via pstrURL
return m_bstrURL.CopyTo(pstrURL);
}
CComBSTR::Detach
Detaches m_str from the CComBSTR
object and sets m_str
to NULL.
BSTR Detach() throw();
Return Value
The BSTR
associated with the CComBSTR
object.
Example
// Method which converts bstrIn to uppercase
STDMETHODIMP BSTRToUpper(BSTR bstrIn, BSTR* pbstrOut)
{
if (bstrIn == NULL || pbstrOut == NULL)
return E_POINTER;
// Create a temporary copy of bstrIn
CComBSTR bstrTemp(bstrIn);
if (!bstrTemp)
return E_OUTOFMEMORY;
// Make string uppercase
HRESULT hr;
hr = bstrTemp.ToUpper();
if (hr != S_OK)
return hr;
// Return m_str member of bstrTemp
*pbstrOut = bstrTemp.Detach();
return S_OK;
}
CComBSTR::Empty
Frees the m_str member.
void Empty() throw();
Example
CComBSTR bstr(OLESTR("abc"));
// Calls SysFreeString to free the BSTR
bstr.Empty();
ATLASSERT(bstr.Length() == 0);
CComBSTR::Length
Returns the number of characters in m_str
, excluding the terminating null character.
unsigned int Length() const throw();
Return Value
The length of the m_str member.
Example
// string with 11 chars
CComBSTR bstrTemp(OLESTR("Hello World"));
unsigned int len = bstrTemp.Length();
ATLASSERT(len == 11);
CComBSTR::LoadString
Loads a string resource specified by nID
and stores it in this object.
bool LoadString(HINSTANCE hInst, UINT nID) throw();
bool LoadString(UINT nID) throw();
Parameters
See LoadString in the Windows SDK.
Return Value
Returns true if the string is successfully loaded; otherwise, returns false.
Remarks
The first function loads the resource from the module identified by you via the hInst
parameter. The second function loads the resource from the resource module associated with the CComModule-derived object used in this project.
Example
CComBSTR bstrTemp;
// IDS_PROJNAME proj name stored as resource in string table
bstrTemp.LoadString(IDS_PROJNAME);
// the above is equivalent to:
// bstrTemp.LoadString(_Module.m_hInstResource, IDS_PROJNAME);
// display message box w/ proj name as title & text
::MessageBox(NULL, CW2CT(bstrTemp), CW2CT(bstrTemp), MB_OK);
CComBSTR::m_str
Contains the BSTR
associated with the CComBSTR
object.
BSTR m_str;
Example
CComBSTR GuidToBSTR(REFGUID guid)
{
// 39 - length of string representation of GUID + 1
CComBSTR b(39);
// Convert GUID to BSTR
// m_str member of CComBSTR is of type BSTR. When BSTR param
// is required, pass the m_str member explicitly or use implicit
// BSTR cast operator.
int nRet = StringFromGUID2(guid, b.m_str, 39);
// Above equivalent to:
// int nRet = StringFromGUID2(guid, b, 39);
// implicit BSTR cast operator used for 2nd param
// Both lines are equivalent to:
// CComBSTR b(guid);
// CComBSTR constructor can convert GUIDs
ATLASSERT(nRet);
return b;
}
CComBSTR::operator BSTR
Casts a CComBSTR
object to a BSTR
.
operator BSTR() const throw();
Remarks
Allows you to pass CComBSTR
objects to functions that have [in] BSTR parameters.
Example
See the example for CComBSTR::m_str.
CComBSTR::operator !
Checks whether BSTR
string is NULL.
bool operator!() const throw();
Return Value
Returns true if the m_str member is NULL; otherwise, false.
Remarks
This operator only checks for a NULL value, not for an empty string.
Example
// STDMETHOD(BSTRToUpper)(/*[in, out]*/ BSTR bstrConv);
STDMETHODIMP InplaceBSTRToUpper(BSTR bstrConv)
{
// Assign bstrConv to m_str member of CComBSTR
CComBSTR bstrTemp;
bstrTemp.Attach(bstrConv);
// Make sure BSTR is not NULL string
if (!bstrTemp)
return E_POINTER;
// Make string uppercase
HRESULT hr;
hr = bstrTemp.ToUpper();
if (hr != S_OK)
return hr;
// Set m_str to NULL, so the BSTR is not freed
bstrTemp.Detach();
return S_OK;
}
CComBSTR::operator !=
Returns the logical opposite of operator ==.
bool operator!= (const CComBSTR& bstrSrc) const throw();
bool operator!= (LPCOLESTR pszSrc) const;
bool operator!= (LPCSTR pszSrc) const;
bool operator!= (int nNull) const throw();
Parameters
bstrSrc
[in] A CComBSTR
object.
pszSrc
[in] A zero-terminated string.
nNull
[in] Must be NULL.
Return Value
Returns true if the item being compared is not equal to the CComBSTR
object; otherwise, returns false.
Remarks
CComBSTR
s are compared textually in the context of the user's default locale. The final comparison operator just compares the contained string against NULL.
CComBSTR::operator &
Returns the address of the BSTR
stored in the m_str member.
BSTR* operator&() throw();
Remarks
CComBstr operator &
has a special assertion associated with it to help identify memory leaks. The program will assert when the m_str
member is initialized. This assertion was created to identify situations where a programmer uses the & operator
to assign a new value to m_str
member without freeing the first allocation of m_str
. If m_str
equals NULL, the program assumes that m_str wasn't allocated yet. In this case, the program will not assert.
This assertion is not enabled by default. Define ATL_CCOMBSTR_ADDRESS_OF_ASSERT
to enable this assertion.
Example
#define ATL_NO_CCOMBSTR_ADDRESS_OF_ASSERT
void MyInitFunction(BSTR* pbstr)
{
::SysReAllocString(pbstr, OLESTR("Hello World"));
return;
}
CComBSTR bstrStr ;
// bstrStr is not initialized so this call will not assert.
MyInitFunction(&bstrStr);
CComBSTR bstrStr2(OLESTR("Hello World"));
// bstrStr2 is initialized so this call will assert.
::SysReAllocString(&bstrStr2, OLESTR("Bye"));
CComBSTR::operator +=
Appends a string to the CComBSTR
object.
CComBSTR& operator+= (const CComBSTR& bstrSrc);
CComBSTR& operator+= (const LPCOLESTR pszSrc);
Parameters
bstrSrc
[in] A CComBSTR
object to append.
pszSrc
[in] A zero-terminated string to append.
Remarks
CComBSTR
s are compared textually in the context of the user's default locale. The LPCOLESTR comparison is done using memcmp
on the raw data in each string. The LPCSTR
comparison is carried out in the same way once a temporary Unicode copy of pszSrc
has been created. The final comparison operator just compares the contained string against NULL.
Example
CComBSTR bstrPre(OLESTR("Hello "));
CComBSTR bstrSuf(OLESTR("World!"));
// Appends "World!" to "Hello "
bstrPre += bstrSuf;
// Displays a message box with text "Hello World!"
::MessageBox(NULL, CW2CT(bstrPre), NULL, MB_OK);
CComBSTR::operator <
Compares a CComBSTR
with a string.
bool operator<(const CComBSTR& bstrSrc) const throw();
bool operator<(LPCOLESTR pszSrc) const throw();
bool operator<(LPCSTR pszSrc) const throw();
Return Value
Returns true if the item being compared is less than the CComBSTR
object; otherwise, returns false.
Remarks
The comparison is performed using the user's default locale.
CComBSTR::operator =
Sets the m_str member to a copy of pSrc
or to a copy of the BSTR
member of src.
CComBSTR& operator= (const CComBSTR& src);
CComBSTR& operator= (LPCOLESTR pSrc);
CComBSTR& operator= (LPCSTR pSrc);
Remarks
The pSrc
parameter specifies either an LPCOLESTR for Unicode versions or LPCSTR
for ANSI versions.
Example
See the example for CComBSTR::Copy.
CComBSTR::operator ==
Compares a CComBSTR
with a string. CComBSTR
s are compared textually in the context of the user's default locale.
bool operator== (const CComBSTR& bstrSrc) const throw();
bool operator== (LPCOLESTR pszSrc) const;
bool operator== (LPCSTR pszSrc) const;
bool operator== (int nNull) const throw();
Parameters
bstrSrc
[in] A CComBSTR
object.
pszSrc
[in] A zero-terminated string.
nNull
[in] Must be NULL.
Return Value
Returns true if the item being compared is equal to the CComBSTR
object; otherwise, returns false.
Remarks
The final comparison operator just compares the contained string against NULL.
CComBSTR::operator >
Compares a CComBSTR
with a string.
bool operator>(const CComBSTR& bstrSrc) const throw();
Return Value
Returns true if the item being compared is greater than the CComBSTR
object; otherwise, returns false.
Remarks
The comparison is performed using the user's default locale.
CComBSTR::ReadFromStream
Sets the m_str member to the BSTR
contained in the specified stream.
HRESULT ReadFromStream(IStream* pStream) throw();
Parameters
pStream
[in] A pointer to the IStream interface on the stream containing the data.
Return Value
A standard HRESULT
value.
Remarks
ReadToStream requires the contents of the stream at the current position to be compatible with the data format written out by a call to WriteToStream.
Example
IDataObject* pDataObj;
// Fill in the FORMATETC struct to retrieve desired format
// from clipboard
FORMATETC formatetcIn = {CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_ISTREAM};
STGMEDIUM medium;
ZeroMemory(&medium, sizeof(STGMEDIUM));
// Get IDataObject from clipboard
HRESULT hr = ::OleGetClipboard(&pDataObj);
// Retrieve data from clipboard
hr = pDataObj->GetData(&formatetcIn, &medium);
if (SUCCEEDED(hr) && medium.tymed == TYMED_ISTREAM)
{
CComBSTR bstrStr;
// Get BSTR out of the stream
hr = bstrStr.ReadFromStream(medium.pstm);
//release the stream
::ReleaseStgMedium(&medium);
}
CComBSTR::ToLower
Converts the contained string to lowercase.
HRESULT ToLower() throw();
Return Value
A standard HRESULT
value.
Remarks
See CharLowerBuff for more information on how the conversion is performed.
CComBSTR::ToUpper
Converts the contained string to uppercase.
HRESULT ToUpper() throw();
Return Value
A standard HRESULT
value.
Remarks
See CharUpperBuff for more information on how the conversion is performed.
CComBSTR::WriteToStream
Saves the m_str member to a stream.
HRESULT WriteToStream(IStream* pStream) throw();
Parameters
pStream
[in] A pointer to the IStream interface on a stream.
Return Value
A standard HRESULT
value.
Remarks
You can recreate a BSTR from the contents of the stream using the ReadFromStream function.
Example
//implementation of IDataObject::GetData()
STDMETHODIMP CMyDataObj::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
{
HRESULT hr = S_OK;
if (pformatetcIn->cfFormat == CF_TEXT && pformatetcIn->tymed == TYMED_ISTREAM)
{
IStream *pStm;
// Create an IStream from global memory
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStm);
if (FAILED(hr))
return hr;
// Initialize CComBSTR
CComBSTR bstrStr = OLESTR("Hello World");
// Serialize string into stream
// the length followed by actual string is serialized into stream
hr = bstrStr.WriteToStream(pStm);
// Pass the IStream pointer back through STGMEDIUM struct
pmedium->tymed = TYMED_ISTREAM;
pmedium->pstm = pStm;
pmedium->pUnkForRelease = NULL;
}
return hr;
}