Make wxBasicString safer and easier to use as a BSTR RAII wrapper.

This commit is contained in:
PB
2017-07-01 12:50:24 +02:00
parent 564c0aafa5
commit ca3f919da9
3 changed files with 88 additions and 70 deletions

View File

@@ -66,46 +66,47 @@ inline void wxOleUninitialize()
class WXDLLIMPEXP_CORE wxBasicString class WXDLLIMPEXP_CORE wxBasicString
{ {
public: public:
// Takes over the ownership of bstr
explicit wxBasicString(BSTR bstr = NULL);
// Takes over the ownership of bstr // Constructs the BSTR from wxString
wxBasicString(BSTR bstr = NULL); wxBasicString(const wxString& str);
// Constructs the BSTR from wxString // Creates a copy of the BSTR owned by bstr
wxBasicString(const wxString& str); wxBasicString(const wxBasicString& bstr);
// Creates a copy of the BSTR owned by bstr // Frees the owned BSTR
wxBasicString(const wxBasicString& bstr); ~wxBasicString();
// Frees the owned BSTR // Returns the owned BSTR and gives up its ownership
~wxBasicString(); BSTR Detach();
// Frees the owned BSTR
void Free();
// Sets its BSTR to a copy of the BSTR owned by bstr // Returns a copy of the owned BSTR,
wxBasicString& operator=(const wxBasicString& bstr); // the caller is responsible for freeing it
BSTR Copy() const { return SysAllocString(m_bstrBuf); }
// Creates its BSTR from wxString // Returns the address of the owned BSTR, not to be called
wxBasicString& operator=(const wxString& str); // when wxBasicString already contains a non-NULL BSTR
BSTR* ByRef();
// Takes over the ownership of bstr // Sets its BSTR to a copy of the BSTR owned by bstr
wxBasicString& operator=(BSTR bstr); wxBasicString& operator=(const wxBasicString& bstr);
// Returns the owned BSTR and gives up its ownership // Creates its BSTR from wxString
BSTR Detach(); wxBasicString& operator=(const wxString& str);
// Takes over the ownership of bstr
wxBasicString& operator=(BSTR bstr);
/// Returns the owned BSTR while keeping its ownership /// Returns the owned BSTR while keeping its ownership
operator BSTR() const { return m_bstrBuf; } operator BSTR() const { return m_bstrBuf; }
// Returns the address of the owned BSTR // retrieve a copy of our string - caller must SysFreeString() it later!
operator BSTR*() { return &m_bstrBuf; } wxDEPRECATED_MSG("use Copy() instead")
BSTR Get() const { return Copy(); }
// Returns a copy of the owned BSTR
BSTR Copy() const { return SysAllocString(m_bstrBuf); }
// retrieve a copy of our string - caller must SysFreeString() it later!
wxDEPRECATED_MSG("use Copy() instead")
BSTR Get() const { return Copy(); }
private: private:
// actual string // actual string
BSTR m_bstrBuf; BSTR m_bstrBuf;

View File

@@ -73,7 +73,7 @@ WXDLLEXPORT wxString wxConvertStringFromOle(BSTR bStr)
wxBasicString::wxBasicString(BSTR bstr) wxBasicString::wxBasicString(BSTR bstr)
{ {
m_bstrBuf = bstr; m_bstrBuf = bstr;
} }
wxBasicString::wxBasicString(const wxString& str) wxBasicString::wxBasicString(const wxString& str)
@@ -91,42 +91,58 @@ wxBasicString::~wxBasicString()
SysFreeString(m_bstrBuf); SysFreeString(m_bstrBuf);
} }
BSTR wxBasicString::Detach()
{
BSTR bstr = m_bstrBuf;
m_bstrBuf = NULL;
return bstr;
}
void wxBasicString::Free()
{
SysFreeString(m_bstrBuf);
m_bstrBuf = NULL;
}
BSTR* wxBasicString::ByRef()
{
wxASSERT_MSG(!m_bstrBuf,
wxS("Can't get direct access to initialized BSTR"));
return &m_bstrBuf;
}
wxBasicString& wxBasicString::operator=(const wxBasicString& src) wxBasicString& wxBasicString::operator=(const wxBasicString& src)
{ {
if ( this != &src ) if ( this != &src )
{ {
SysFreeString(m_bstrBuf); wxCHECK_MSG(m_bstrBuf == NULL || m_bstrBuf != src.m_bstrBuf,
m_bstrBuf = src.Copy(); *this, wxS("Attempting to assign already owned BSTR"));
} SysFreeString(m_bstrBuf);
m_bstrBuf = src.Copy();
}
return *this; return *this;
} }
wxBasicString& wxBasicString::operator=(const wxString& str) wxBasicString& wxBasicString::operator=(const wxString& str)
{ {
SysFreeString(m_bstrBuf); SysFreeString(m_bstrBuf);
m_bstrBuf = ::SysAllocString(str.wc_str(*wxConvCurrent)); m_bstrBuf = SysAllocString(str.wc_str(*wxConvCurrent));
return *this; return *this;
} }
wxBasicString& wxBasicString::operator=(BSTR bstr) wxBasicString& wxBasicString::operator=(BSTR bstr)
{ {
wxCHECK_MSG(m_bstrBuf != bstr, *this, wxS("Attempting to attach already attached BSTR!")); wxCHECK_MSG(m_bstrBuf == NULL || m_bstrBuf != bstr,
*this, wxS("Attempting to assign already owned BSTR"));
SysFreeString(m_bstrBuf); SysFreeString(m_bstrBuf);
m_bstrBuf = bstr; m_bstrBuf = bstr;
return *this; return *this;
}
BSTR wxBasicString::Detach()
{
BSTR bstr = m_bstrBuf;
m_bstrBuf = NULL;
return bstr;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -232,7 +232,7 @@ wxString wxWebViewIE::GetPageSource() const
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {
wxBasicString bstr; wxBasicString bstr;
if ( htmlTag->get_outerHTML(bstr) == S_OK ) if ( htmlTag->get_outerHTML(bstr.ByRef()) == S_OK )
source = bstr; source = bstr;
} }
} }
@@ -577,7 +577,7 @@ wxString wxWebViewIE::GetCurrentTitle() const
if(document) if(document)
{ {
wxBasicString title; wxBasicString title;
if ( document->get_nameProp(title) == S_OK ) if ( document->get_nameProp(title.ByRef()) == S_OK )
s = title; s = title;
} }
@@ -706,7 +706,7 @@ bool wxWebViewIE::IsEditable() const
if(document) if(document)
{ {
wxBasicString mode; wxBasicString mode;
if ( document->get_designMode(mode) == S_OK ) if ( document->get_designMode(mode.ByRef()) == S_OK )
{ {
if ( wxString(mode) == "On" ) if ( wxString(mode) == "On" )
return true; return true;
@@ -732,7 +732,7 @@ bool wxWebViewIE::HasSelection() const
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {
wxBasicString type; wxBasicString type;
if ( selection->get_type(type) == S_OK ) if ( selection->get_type(type.ByRef()) == S_OK )
sel = type; sel = type;
} }
return sel != "None"; return sel != "None";
@@ -768,7 +768,7 @@ wxString wxWebViewIE::GetSelectedText() const
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {
wxBasicString text; wxBasicString text;
if ( range->get_text(text) == S_OK ) if ( range->get_text(text.ByRef()) == S_OK )
selected = text; selected = text;
} }
} }
@@ -801,7 +801,7 @@ wxString wxWebViewIE::GetSelectedSource() const
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {
wxBasicString text; wxBasicString text;
if ( range->get_htmlText(text) == S_OK ) if ( range->get_htmlText(text.ByRef()) == S_OK )
selected = text; selected = text;
} }
} }
@@ -842,7 +842,7 @@ wxString wxWebViewIE::GetPageText() const
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {
wxBasicString out; wxBasicString out;
if ( body->get_innerText(out) == S_OK ) if ( body->get_innerText(out.ByRef()) == S_OK )
text = out; text = out;
} }
return text; return text;
@@ -950,8 +950,6 @@ wxCOMPtr<IHTMLDocument2> wxWebViewIE::GetDocument() const
bool wxWebViewIE::IsElementVisible(wxCOMPtr<IHTMLElement> elm) bool wxWebViewIE::IsElementVisible(wxCOMPtr<IHTMLElement> elm)
{ {
wxCOMPtr<IHTMLElement> elm1 = elm; wxCOMPtr<IHTMLElement> elm1 = elm;
wxBasicString display_bstr;
wxBasicString visibility_bstr;
bool is_visible = true; bool is_visible = true;
//This method is not perfect but it does discover most of the hidden elements. //This method is not perfect but it does discover most of the hidden elements.
//so if a better solution is found, then please do improve. //so if a better solution is found, then please do improve.
@@ -963,15 +961,18 @@ bool wxWebViewIE::IsElementVisible(wxCOMPtr<IHTMLElement> elm)
wxCOMPtr<wxIHTMLCurrentStyle> style; wxCOMPtr<wxIHTMLCurrentStyle> style;
if(SUCCEEDED(elm2->get_currentStyle(&style))) if(SUCCEEDED(elm2->get_currentStyle(&style)))
{ {
wxBasicString display_bstr;
wxBasicString visibility_bstr;
//Check if the object has the style display:none. //Check if the object has the style display:none.
if((style->get_display(display_bstr) != S_OK) || if((style->get_display(display_bstr.ByRef()) != S_OK) ||
((BSTR)display_bstr != NULL && (wxCRT_StricmpW(display_bstr, L"none") == 0))) wxString(display_bstr).IsSameAs(wxS("none"), false))
{ {
is_visible = false; is_visible = false;
} }
//Check if the object has the style visibility:hidden. //Check if the object has the style visibility:hidden.
if((is_visible && (style->get_visibility(visibility_bstr) != S_OK)) || if((is_visible && (style->get_visibility(visibility_bstr.ByRef()) != S_OK)) ||
((BSTR)visibility_bstr != NULL && wxCRT_StricmpW(visibility_bstr, L"hidden") == 0)) wxString(visibility_bstr).IsSameAs(wxS("hidden"), false))
{ {
is_visible = false; is_visible = false;
} }