+ SysReAllocString(&m_bstrBuf, src);
+ return *this;
+}
+
+wxBasicString::~wxBasicString()
+{
+ SysFreeString(m_bstrBuf);
+}
+
+
+// ----------------------------------------------------------------------------
+// Convert variants
+// ----------------------------------------------------------------------------
+
+#if wxUSE_VARIANT
+
+namespace
+{
+
+// Helper class for creating and filling SAFEARRAY. To use it, call Create()
+// first, then SetElement() for each element and finally Detach() the SAFEARRAY
+// from it if you don't want it to be deleted when this class is.
+class wxSafeArrayHelper
+{
+public:
+ wxSafeArrayHelper();
+ ~wxSafeArrayHelper();
+
+ bool Create(VARTYPE vt, long count); // creates and locks the array
+
+ bool SetElement(size_t index, const wxVariant& variant);
+ bool SetElement(size_t index, const wxString& str);
+
+ SAFEARRAY* Detach(); // unlocks the array and gives up its ownership
+
+private:
+ void Unlock();
+
+ SAFEARRAY* m_array;
+};
+
+wxSafeArrayHelper::wxSafeArrayHelper()
+{
+ m_array = NULL;
+}
+
+wxSafeArrayHelper::~wxSafeArrayHelper()
+{
+ if ( m_array )
+ {
+ Unlock();
+ SafeArrayDestroy(m_array);
+ }
+}
+
+bool wxSafeArrayHelper::Create(VARTYPE vt, long count)
+{
+ SAFEARRAYBOUND saBound;
+
+ saBound.lLbound = 0;
+ saBound.cElements = count;
+ m_array = SafeArrayCreate(vt, 1, &saBound);
+ if ( !m_array )
+ return false;
+ return SUCCEEDED( SafeArrayLock(m_array) );
+}
+
+bool wxSafeArrayHelper::SetElement(size_t index, const wxVariant& variant)
+{
+ VARIANT* data = (VARIANT*)m_array->pvData;
+ return wxConvertVariantToOle(variant, data[index]);
+}
+
+bool wxSafeArrayHelper::SetElement(size_t index, const wxString& str)
+{
+ BSTR bstr = wxConvertStringToOle(str);
+
+ if ( !bstr && !str.empty() )
+ {
+ // BSTR can be NULL for empty strings but if the string was
+ // not empty, it means we failed to allocate memory for it.
+ return false;
+ }
+
+ BSTR* data = (BSTR*)m_array->pvData;
+ data[index] = bstr;
+ return true;
+}
+
+SAFEARRAY* wxSafeArrayHelper::Detach()
+{
+ Unlock();
+ SAFEARRAY* result = m_array;
+ m_array = NULL;
+ return result;
+}
+
+void wxSafeArrayHelper::Unlock()
+{
+ if ( m_array )
+ SafeArrayUnlock(m_array);
+}
+
+} // unnamed namespace
+
+
+WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant)
+{
+ VariantInit(&oleVariant);
+ if (variant.IsNull())
+ {
+ oleVariant.vt = VT_NULL;
+ return true;
+ }
+
+ wxString type(variant.GetType());
+
+
+ if (type == wxT("long"))
+ {
+ oleVariant.vt = VT_I4;
+ oleVariant.lVal = variant.GetLong() ;
+ }
+ // Original VC6 came with SDK too old to contain VARIANT::llVal declaration
+ // and there doesn't seem to be any way to test for it as Microsoft simply
+ // added it to the later version of oaidl.h without changing anything else.
+ // So assume it's not present for VC6, even though it might be if an
+ // updated SDK is used. In this case the user would need to disable this
+ // check himself.
+#if wxUSE_LONGLONG && !defined(__VISUALC6__)
+ else if (type == wxT("longlong"))
+ {
+ oleVariant.vt = VT_I8;
+ oleVariant.llVal = variant.GetLongLong().GetValue();
+ }
+#endif
+ else if (type == wxT("char"))
+ {
+ oleVariant.vt=VT_I1; // Signed Char
+ oleVariant.cVal=variant.GetChar();
+ }
+ else if (type == wxT("double"))
+ {
+ oleVariant.vt = VT_R8;
+ oleVariant.dblVal = variant.GetDouble();
+ }
+ else if (type == wxT("bool"))
+ {
+ oleVariant.vt = VT_BOOL;
+ oleVariant.boolVal = variant.GetBool() ? VARIANT_TRUE : VARIANT_FALSE;
+ }
+ else if (type == wxT("string"))
+ {
+ wxString str( variant.GetString() );
+ oleVariant.vt = VT_BSTR;
+ oleVariant.bstrVal = wxConvertStringToOle(str);
+ }
+#if wxUSE_DATETIME
+ else if (type == wxT("datetime"))
+ {
+ wxDateTime date( variant.GetDateTime() );
+ oleVariant.vt = VT_DATE;
+
+ SYSTEMTIME st;
+ date.GetAsMSWSysTime(&st);
+
+ SystemTimeToVariantTime(&st, &oleVariant.date);
+ }