+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
+
+