CComBSTR Class

This class is a wrapper for BSTRs.

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 BSTRs, 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("http://SomeSite/");
CComBSTR bstrDEF = OLESTR("/OtherSite");
CComBSTR bstrASP = OLESTR("default.asp");

CComBSTR bstrTemp;
HRESULT hr;

switch (urlType)
{
case urlASP:
   // bstrURL is 'http://SomeSite/default.asp'
   hr = bstrURL.Append(bstrASP);
   break;

case urlHTM:
   // bstrURL is 'http://SomeSite/default.htm'
   hr = bstrURL.Append(OLESTR("default.htm"));
   break;

case urlISAPI:
   // bstrURL is 'http://SomeSite/default.dll?func'
   hr = bstrURL.Append(OLESTR("default.dll?func"));
   break;

default:
   // bstrTemp is 'http://'
   hr = bstrTemp.Append(bstrURL, 7);
   // bstrURL is 'http://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) throw(); // (Visual Studio 2017)

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

CComBSTRs 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

CComBSTRs 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. The move assignment operator moves src without copying it.

CComBSTR& operator= (const CComBSTR& src);
CComBSTR& operator= (LPCOLESTR pSrc);
CComBSTR& operator= (LPCSTR pSrc);
CComBSTR& operator= (CComBSTR&& src) throw(); // (Visual Studio 2017)

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. CComBSTRs 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;
}

See also

Class Overview
ATL and MFC String Conversion Macros