Introduces wxBSTR, an RAII wrapper for MSW BSTR type. wxBSTR also supersedes wxBasicString.

This commit is contained in:
pbfordev
2017-06-16 21:07:50 +02:00
parent 084009bff5
commit db22c91d44
7 changed files with 122 additions and 82 deletions

View File

@@ -21,7 +21,7 @@
// wx includes
//---------------------------------------------------------------------------
#include "wx/msw/ole/oleutils.h" // wxBasicString &c
#include "wx/msw/ole/oleutils.h"
#include "wx/msw/ole/uuid.h"
#include "wx/window.h"
#include "wx/variant.h"

View File

@@ -61,29 +61,6 @@ inline void wxOleUninitialize()
::OleUninitialize();
}
// wrapper around BSTR type (by Vadim Zeitlin)
class WXDLLIMPEXP_CORE wxBasicString
{
public:
// ctors & dtor
wxBasicString(const wxString& str);
wxBasicString(const wxBasicString& bstr);
~wxBasicString();
wxBasicString& operator=(const wxBasicString& bstr);
// accessors
// just get the string
operator BSTR() const { return m_bstrBuf; }
// retrieve a copy of our string - caller must SysFreeString() it later!
BSTR Get() const { return SysAllocString(m_bstrBuf); }
private:
// actual string
BSTR m_bstrBuf;
};
#if wxUSE_VARIANT
// Convert variants
class WXDLLIMPEXP_FWD_BASE wxVariant;
@@ -195,6 +172,55 @@ WXDLLIMPEXP_CORE BSTR wxConvertStringToOle(const wxString& str);
// Convert string from BSTR to wxString
WXDLLIMPEXP_CORE wxString wxConvertStringFromOle(BSTR bStr);
// A thin RAII wrapper for BSTR, which can create BSTR
// from wxString as well as return the owned BSTR as wxString.
// Unlike _b_str_t, wxBSTR is NOT reference counted.
class WXDLLIMPEXP_CORE wxBSTR
{
public:
wxBSTR() : m_bstr(NULL) {}
// If copy is true then a copy of bstr is created,
// if not then ownership of bstr is taken.
wxBSTR(BSTR bstr, bool copy);
// Creates BSTR from wxString
wxBSTR(const wxString& str) : m_bstr(::SysAllocString(str.wc_str(*wxConvCurrent))) {}
// Creates a copy of BSTR owned by wxbstr
wxBSTR(const wxBSTR& wxbstr) : m_bstr(wxbstr.GetCopy()) {}
// Frees the owned BSTR
~wxBSTR() { Free(); }
// Creates a copy of wxbstr
wxBSTR& operator=(const wxBSTR& wxbstr);
// Takes ownership of bstr
void Attach(BSTR bstr);
// Returns the owned BSTR and gives up its ownership
BSTR Detach();
// Frees the owned BSTR
void Free();
// Returnes the owned BSTR while keeping its ownership
BSTR GetBSTR() const { return m_bstr; }
operator BSTR() const { return GetBSTR(); }
// Returns the address of owned BSTR
BSTR* GetAddress() { return &m_bstr; }
// Return a copy of owned BSTR
BSTR GetCopy() const { return ::SysAllocString(m_bstr); }
// Returns the owned BSTR convert to wxString
wxString GetwxString() const { return wxConvertStringFromOle(m_bstr); }
private:
BSTR m_bstr;
};
#else // !wxUSE_OLE
// ----------------------------------------------------------------------------

View File

@@ -1127,7 +1127,7 @@ bool wxAMMediaBackend::Load(const wxURI& location, const wxURI& proxy)
if(pPlay)
{
pPlay->put_UseHTTPProxy(VARIANT_TRUE);
pPlay->put_HTTPProxyHost(wxBasicString(proxy.GetServer()).Get());
pPlay->put_HTTPProxyHost(wxBSTR(proxy.GetServer()).Detach());
pPlay->put_HTTPProxyPort(wxAtoi(proxy.GetPort()));
pPlay->Release();
}
@@ -1150,9 +1150,9 @@ bool wxAMMediaBackend::DoLoad(const wxString& location)
// the docs say its async and put_FileName is not -
// but in practice they both seem to be async anyway
if(GetMP())
hr = GetMP()->Open( wxBasicString(location).Get() );
hr = GetMP()->Open( wxBSTR(location).Detach() );
else
hr = GetAM()->put_FileName( wxBasicString(location).Get() );
hr = GetAM()->put_FileName( wxBSTR(location).Detach() );
if(FAILED(hr))
{

View File

@@ -905,21 +905,21 @@ bool wxWMP10MediaBackend::Load(const wxURI& location,
{
long lOldSetting;
if( pWMPNetwork->getProxySettings(
wxBasicString(location.GetScheme()).Get(), &lOldSetting
wxBSTR(location.GetScheme()).Detach(), &lOldSetting
) == 0 &&
pWMPNetwork->setProxySettings(
wxBasicString(location.GetScheme()).Get(), // protocol
wxBSTR(location.GetScheme()).Detach(), // protocol
2) == 0) // 2 == manually specify
{
BSTR bsOldName = NULL;
long lOldPort = 0;
pWMPNetwork->getProxyName(
wxBasicString(location.GetScheme()).Get(),
wxBSTR(location.GetScheme()).Detach(),
&bsOldName);
pWMPNetwork->getProxyPort(
wxBasicString(location.GetScheme()).Get(),
wxBSTR(location.GetScheme()).Detach(),
&lOldPort);
long lPort;
@@ -936,11 +936,11 @@ bool wxWMP10MediaBackend::Load(const wxURI& location,
}
if( pWMPNetwork->setProxyName(
wxBasicString(location.GetScheme()).Get(), // proto
wxBasicString(server).Get() ) == 0 &&
wxBSTR(location.GetScheme()).Detach(), // proto
wxBSTR(server).Detach() ) == 0 &&
pWMPNetwork->setProxyPort(
wxBasicString(location.GetScheme()).Get(), // proto
wxBSTR(location.GetScheme()).Detach(), // proto
lPort
) == 0
)
@@ -948,16 +948,16 @@ bool wxWMP10MediaBackend::Load(const wxURI& location,
bOK = DoLoad(location.BuildURI());
pWMPNetwork->setProxySettings(
wxBasicString(location.GetScheme()).Get(), // protocol
wxBSTR(location.GetScheme()).Detach(), // protocol
lOldSetting);
if(bsOldName)
pWMPNetwork->setProxyName(
wxBasicString(location.GetScheme()).Get(), // protocol
wxBSTR(location.GetScheme()).Detach(), // protocol
bsOldName);
if(lOldPort)
pWMPNetwork->setProxyPort(
wxBasicString(location.GetScheme()).Get(), // protocol
wxBSTR(location.GetScheme()).Detach(), // protocol
lOldPort);
pWMPNetwork->Release();
@@ -997,7 +997,7 @@ bool wxWMP10MediaBackend::DoLoad(const wxString& location)
{
IWMPMedia* pWMPMedia;
if( (hr = pWMPCore3->newMedia(wxBasicString(location).Get(),
if( (hr = pWMPCore3->newMedia(wxBSTR(location).Detach(),
&pWMPMedia)) == 0)
{
// this (get_duration) will actually FAIL, but it will work.
@@ -1012,7 +1012,7 @@ bool wxWMP10MediaBackend::DoLoad(const wxString& location)
#endif
{
// just load it the "normal" way
hr = m_pWMPPlayer->put_URL( wxBasicString(location).Get() );
hr = m_pWMPPlayer->put_URL( wxBSTR(location).Detach() );
}
if(FAILED(hr))
@@ -1061,12 +1061,12 @@ bool wxWMP10MediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags)
if(!flags)
{
m_pWMPPlayer->put_enabled(VARIANT_FALSE);
m_pWMPPlayer->put_uiMode(wxBasicString(wxT("none")).Get());
m_pWMPPlayer->put_uiMode(wxBSTR(wxT("none")).Detach());
}
else
{
// TODO: use "custom"? (note that CE only supports none/full)
m_pWMPPlayer->put_uiMode(wxBasicString(wxT("full")).Get());
m_pWMPPlayer->put_uiMode(wxBSTR(wxT("full")).Detach());
m_pWMPPlayer->put_enabled(VARIANT_TRUE);
}
@@ -1358,7 +1358,7 @@ wxLongLong wxWMP10MediaBackend::GetDownloadTotal()
if(m_pWMPPlayer->get_currentMedia(&pWMPMedia) == 0)
{
BSTR bsOut;
pWMPMedia->getItemInfo(wxBasicString(wxT("FileSize")).Get(),
pWMPMedia->getItemInfo(wxBSTR(wxT("FileSize")).Detach(),
&bsOut);
wxString sFileSize = wxConvertStringFromOle(bsOut);

View File

@@ -938,8 +938,7 @@ STDMETHODIMP wxIAccessible::get_accDefaultAction ( VARIANT varID, BSTR* pszDefau
}
else
{
wxBasicString basicString(defaultAction);
* pszDefaultAction = basicString.Get();
* pszDefaultAction = wxBSTR(defaultAction).Detach();
return S_OK;
}
}
@@ -999,8 +998,7 @@ STDMETHODIMP wxIAccessible::get_accDescription ( VARIANT varID, BSTR* pszDescrip
}
else
{
wxBasicString basicString(description);
* pszDescription = basicString.Get();
* pszDescription = wxBSTR(description).Detach();
return S_OK;
}
}
@@ -1060,8 +1058,7 @@ STDMETHODIMP wxIAccessible::get_accHelp ( VARIANT varID, BSTR* pszHelp)
}
else
{
wxBasicString basicString(helpString);
* pszHelp = basicString.Get();
* pszHelp = wxBSTR(helpString).Detach();
return S_OK;
}
}
@@ -1171,8 +1168,7 @@ STDMETHODIMP wxIAccessible::get_accKeyboardShortcut ( VARIANT varID, BSTR* pszKe
}
else
{
wxBasicString basicString(keyboardShortcut);
* pszKeyboardShortcut = basicString.Get();
* pszKeyboardShortcut = wxBSTR(keyboardShortcut).Detach();
return S_OK;
}
}
@@ -1235,8 +1231,7 @@ STDMETHODIMP wxIAccessible::get_accName ( VARIANT varID, BSTR* pszName)
}
else
{
wxBasicString basicString(name);
*pszName = basicString.Get();
*pszName = wxBSTR(name).Detach();
}
return S_OK;
}
@@ -1416,8 +1411,7 @@ STDMETHODIMP wxIAccessible::get_accValue ( VARIANT varID, BSTR* pszValue)
}
else
{
wxBasicString basicString(strValue);
* pszValue = basicString.Get();
* pszValue = wxBSTR(strValue).Detach();
return S_OK;
}
}

View File

@@ -130,7 +130,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action,
}
int namedArgStringCount = namedArgCount + 1;
wxVector<wxBasicString> argNames(namedArgStringCount, wxString());
wxVector<wxBSTR> argNames(namedArgStringCount, wxString());
argNames[0] = member;
// Note that arguments are specified in reverse order
@@ -156,7 +156,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action,
// Get the IDs for the member and its arguments. GetIDsOfNames expects the
// member name as the first name, followed by argument names (if any).
hr = ((IDispatch*)m_dispatchPtr)->GetIDsOfNames(IID_NULL,
// We rely on the fact that wxBasicString is
// We rely on the fact that wxBSTR is
// just BSTR with some methods here.
reinterpret_cast<BSTR *>(&argNames[0]),
1 + namedArgCount, m_lcid, &dispIds[0]);
@@ -499,7 +499,7 @@ namespace
HRESULT wxCLSIDFromProgID(const wxString& progId, CLSID& clsId)
{
HRESULT hr = CLSIDFromProgID(wxBasicString(progId), &clsId);
HRESULT hr = CLSIDFromProgID(wxBSTR(progId), &clsId);
if ( FAILED(hr) )
{
wxLogSysError(hr, _("Failed to find CLSID of \"%s\""), progId);

View File

@@ -38,7 +38,7 @@
WXDLLEXPORT BSTR wxConvertStringToOle(const wxString& str)
{
return wxBasicString(str).Get();
return wxBSTR(str).Detach();
}
WXDLLEXPORT wxString wxConvertStringFromOle(BSTR bStr)
@@ -68,28 +68,48 @@ WXDLLEXPORT wxString wxConvertStringFromOle(BSTR bStr)
}
// ----------------------------------------------------------------------------
// wxBasicString
// wxBSTR
// ----------------------------------------------------------------------------
wxBasicString::wxBasicString(const wxString& str)
wxBSTR::wxBSTR(BSTR bstr, bool copy)
{
m_bstrBuf = SysAllocString(str.wc_str(*wxConvCurrent));
if ( copy )
m_bstr = ::SysAllocString(bstr);
else
m_bstr = bstr;
}
wxBasicString::wxBasicString(const wxBasicString& src)
wxBSTR& wxBSTR::operator=(const wxBSTR& wxbstr)
{
m_bstrBuf = src.Get();
}
if ( wxbstr != *this )
{
Free();
m_bstr = wxbstr.GetCopy();
}
wxBasicString& wxBasicString::operator=(const wxBasicString& src)
{
SysReAllocString(&m_bstrBuf, src);
return *this;
}
wxBasicString::~wxBasicString()
void wxBSTR::Attach(BSTR bstr)
{
SysFreeString(m_bstrBuf);
wxCHECK_RET(m_bstr != bstr, wxS("Attaching already attached BSTR!"));
Free();
m_bstr = bstr;
}
BSTR wxBSTR::Detach()
{
BSTR bstr = m_bstr;
m_bstr = NULL;
return bstr;
}
void wxBSTR::Free()
{
::SysFreeString(m_bstr);
m_bstr = NULL;
}