From 910f1a96d2ab48acdc5ae36dbedca490217f8c85 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 14 Oct 2013 15:08:35 +0000 Subject: [PATCH] Add wxOleConvertVariant_ReturnSafeArrays flag for better SAFEARRAY handling. While we can't change the type of wxVariant to which SAFEARRAYs are converted by default, it's much more convenient to work with the variant objects of the correct type, i.e. using wxVariantDataSafeArray, when dealing with SAFEARRAYs, so add a flag which can be set to tell a wxAutomationObject to behave in this way. Closes #14700. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75004 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 4 + include/wx/msw/ole/automtn.h | 11 ++ include/wx/msw/ole/oleutils.h | 20 ++- interface/wx/msw/ole/automtn.h | 51 +++++++ src/msw/ole/automtn.cpp | 16 ++- src/msw/ole/oleutils.cpp | 84 ++++++------ tests/Makefile.in | 4 + tests/makefile.bcc | 4 + tests/makefile.gcc | 4 + tests/makefile.vc | 4 + tests/makefile.wat | 4 + tests/misc/safearrayconverttest.cpp | 204 ++++++++++++++++++++++++++++ tests/test.bkl | 1 + tests/test_test_gui.dsp | 4 + tests/test_vc7_test_gui.vcproj | 3 + tests/test_vc8_test_gui.vcproj | 4 + tests/test_vc9_test_gui.vcproj | 4 + 17 files changed, 379 insertions(+), 47 deletions(-) create mode 100644 tests/misc/safearrayconverttest.cpp diff --git a/docs/changes.txt b/docs/changes.txt index e348292862..d73c20e3a5 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -568,6 +568,10 @@ All: - Add possibility to validate the input files against a schema to wxrc. - Fix recently broken compilation with Intel compiler. +wxMSW: + +- Optional better handling of SAFEARRAYs in wxAutomationObject (PB). + 3.0-RC1: (released 2013-10-07) ------------------------------ diff --git a/include/wx/msw/ole/automtn.h b/include/wx/msw/ole/automtn.h index a7c5f62a6b..8f85141f1e 100644 --- a/include/wx/msw/ole/automtn.h +++ b/include/wx/msw/ole/automtn.h @@ -115,11 +115,22 @@ public: // this object. The default is LOCALE_SYSTEM_DEFAULT. void SetLCID(WXLCID lcid); + // Returns the flags used for conversions between wxVariant and OLE + // VARIANT, see wxConvertVariantToOleFlags. The default value is + // wxOleConvertVariant_Default but all the objects obtained by GetObject() + // inherit the flags from the one that created them. + long GetConvertVariantFlags() const; + + // Sets the flags used for conversions between wxVariant and OLE VARIANT, + // see wxConvertVariantToOleFlags (default is wxOleConvertVariant_Default. + void SetConvertVariantFlags(long flags); + public: // public for compatibility only, don't use m_dispatchPtr directly. WXIDISPATCH* m_dispatchPtr; private: WXLCID m_lcid; + long m_convertVariantFlags; wxDECLARE_NO_COPY_CLASS(wxAutomationObject); }; diff --git a/include/wx/msw/ole/oleutils.h b/include/wx/msw/ole/oleutils.h index 1c25d36926..c9f7eb88c8 100644 --- a/include/wx/msw/ole/oleutils.h +++ b/include/wx/msw/ole/oleutils.h @@ -316,9 +316,25 @@ private: SAFEARRAY* m_value; }; +// Used by wxAutomationObject for its wxConvertOleToVariant() calls. +enum wxOleConvertVariantFlags +{ + wxOleConvertVariant_Default = 0, + + // If wxOleConvertVariant_ReturnSafeArrays flag is set, SAFEARRAYs + // contained in OLE VARIANTs will be returned as wxVariants + // with wxVariantDataSafeArray type instead of wxVariants + // with the list type containing the (flattened) SAFEARRAY's elements. + wxOleConvertVariant_ReturnSafeArrays = 1 +}; + +WXDLLIMPEXP_CORE +bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant); + +WXDLLIMPEXP_CORE +bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant, + long flags = wxOleConvertVariant_Default); -WXDLLIMPEXP_CORE bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant); -WXDLLIMPEXP_CORE bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant); #endif // wxUSE_VARIANT // Convert string to Unicode diff --git a/interface/wx/msw/ole/automtn.h b/interface/wx/msw/ole/automtn.h index ec0ec35efc..5f2dd6775d 100644 --- a/interface/wx/msw/ole/automtn.h +++ b/interface/wx/msw/ole/automtn.h @@ -41,6 +41,34 @@ enum wxAutomationInstanceFlags wxAutomationInstance_SilentIfNone = 2 }; +/** + Flags used for conversions between wxVariant and OLE VARIANT. + + These flags are used by wxAutomationObject for its wxConvertOleToVariant() + calls. They can be obtained by wxAutomationObject::GetConvertVariantFlags() + and set by wxAutomationObject::SetConvertVariantFlags(). + + @since 3.0 + + @header{wx/msw/ole/oleutils.h} +*/ +enum wxOleConvertVariantFlags +{ + /** + Default value. + */ + wxOleConvertVariant_Default = 0, + + /** + If this flag is used, SAFEARRAYs contained in OLE VARIANTs will be + returned as wxVariants with wxVariantDataSafeArray type instead of + wxVariants with the list type containing the (flattened) SAFEARRAY's + elements. + */ + wxOleConvertVariant_ReturnSafeArrays = 1 +}; + + /** @class wxVariantDataCurrency @@ -580,5 +608,28 @@ public: */ void SetLCID(LCID lcid); + /** + Returns the flags used for conversions between wxVariant and OLE + VARIANT, see wxConvertVariantToOleFlags. + + The default value is wxOleConvertVariant_Default for compatibility but + it can be changed using SetConvertVariantFlags(). + + Notice that objects obtained by GetObject() inherit the flags from the + one that created them. + + @since 3.0 + */ + long GetConvertVariantFlags() const; + + /** + Sets the flags used for conversions between wxVariant and OLE VARIANT, + see wxConvertVariantToOleFlags. + + The default value is wxOleConvertVariant_Default. + + @since 3.0 + */ + void SetConvertVariantFlags(long flags); }; diff --git a/src/msw/ole/automtn.cpp b/src/msw/ole/automtn.cpp index b3f5f72e4a..1c3bd0a2b9 100644 --- a/src/msw/ole/automtn.cpp +++ b/src/msw/ole/automtn.cpp @@ -70,6 +70,7 @@ wxAutomationObject::wxAutomationObject(WXIDISPATCH* dispatchPtr) { m_dispatchPtr = dispatchPtr; m_lcid = LOCALE_SYSTEM_DEFAULT; + m_convertVariantFlags = wxOleConvertVariant_Default; } wxAutomationObject::~wxAutomationObject() @@ -214,7 +215,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, if (vReturnPtr) { // Convert result to wxVariant form - if (!wxConvertOleToVariant(vReturn, retValue)) + if (!wxConvertOleToVariant(vReturn, retValue, m_convertVariantFlags)) return false; // Mustn't release the dispatch pointer if (vReturn.vt == VT_DISPATCH) @@ -474,6 +475,7 @@ bool wxAutomationObject::GetObject(wxAutomationObject& obj, const wxString& prop { obj.SetDispatchPtr(dispatch); obj.SetLCID(GetLCID()); + obj.SetConvertVariantFlags(GetConvertVariantFlags()); return true; } else @@ -488,6 +490,7 @@ bool wxAutomationObject::GetObject(wxAutomationObject& obj, const wxString& prop { obj.SetDispatchPtr(dispatch); obj.SetLCID(GetLCID()); + obj.SetConvertVariantFlags(GetConvertVariantFlags()); return true; } else @@ -607,6 +610,17 @@ void wxAutomationObject::SetLCID(LCID lcid) m_lcid = lcid; } +long wxAutomationObject::GetConvertVariantFlags() const +{ + return m_convertVariantFlags; +} + +void wxAutomationObject::SetConvertVariantFlags(long flags) +{ + m_convertVariantFlags = flags; +} + + static void ShowException(const wxString& member, HRESULT hr, diff --git a/src/msw/ole/oleutils.cpp b/src/msw/ole/oleutils.cpp index 57a7a6c2d7..ab4122e0aa 100644 --- a/src/msw/ole/oleutils.cpp +++ b/src/msw/ole/oleutils.cpp @@ -414,57 +414,53 @@ WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& ole #endif WXDLLEXPORT bool -wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) +wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant, long flags) { bool ok = true; if ( oleVariant.vt & VT_ARRAY ) { - // TODO: We currently return arrays as wxVariant of the list type - // containing the flattened form of array but we should allow - // getting it as wxVariantDataSafeArray instead. Doing this is - // simple, we'd just need to do something like this: - // - // if ( oleVariant.parray && SafeArrayGetDim(oleVariant.parray) > 1 ) - // { - // variant.SetData(new wxVariantDataSafeArray(oleVariant.parray)); - // } - // - // but currently we don't do it for compatibility reasons. - switch (oleVariant.vt & VT_TYPEMASK) + if ( flags & wxOleConvertVariant_ReturnSafeArrays ) { - case VT_I2: - ok = wxSafeArray::ConvertToVariant(oleVariant.parray, variant); - break; - case VT_I4: - ok = wxSafeArray::ConvertToVariant(oleVariant.parray, variant); - break; - case VT_R4: - ok = wxSafeArray::ConvertToVariant(oleVariant.parray, variant); - break; - case VT_R8: - ok = wxSafeArray::ConvertToVariant(oleVariant.parray, variant); - break; - case VT_VARIANT: - ok = wxSafeArray::ConvertToVariant(oleVariant.parray, variant); - break; - case VT_BSTR: - { - wxArrayString strings; - if ( wxSafeArray::ConvertToArrayString(oleVariant.parray, strings) ) - variant = strings; - else - ok = false; - } - break; - default: - ok = false; - break; + variant.SetData(new wxVariantDataSafeArray(oleVariant.parray)); } - if ( !ok ) + else { - wxLogDebug(wxT("unhandled VT_ARRAY type %x in wxConvertOleToVariant"), - oleVariant.vt & VT_TYPEMASK); - variant = wxVariant(); + switch (oleVariant.vt & VT_TYPEMASK) + { + case VT_I2: + ok = wxSafeArray::ConvertToVariant(oleVariant.parray, variant); + break; + case VT_I4: + ok = wxSafeArray::ConvertToVariant(oleVariant.parray, variant); + break; + case VT_R4: + ok = wxSafeArray::ConvertToVariant(oleVariant.parray, variant); + break; + case VT_R8: + ok = wxSafeArray::ConvertToVariant(oleVariant.parray, variant); + break; + case VT_VARIANT: + ok = wxSafeArray::ConvertToVariant(oleVariant.parray, variant); + break; + case VT_BSTR: + { + wxArrayString strings; + if ( wxSafeArray::ConvertToArrayString(oleVariant.parray, strings) ) + variant = strings; + else + ok = false; + } + break; + default: + ok = false; + break; + } + if ( !ok ) + { + wxLogDebug(wxT("unhandled VT_ARRAY type %x in wxConvertOleToVariant"), + oleVariant.vt & VT_TYPEMASK); + variant = wxVariant(); + } } } else if ( oleVariant.vt & VT_BYREF ) diff --git a/tests/Makefile.in b/tests/Makefile.in index 92e23c55bd..26dcca7203 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -223,6 +223,7 @@ TEST_GUI_OBJECTS = \ test_gui_guifuncs.o \ test_gui_selstoretest.o \ test_gui_garbage.o \ + test_gui_safearrayconverttest.o \ test_gui_settings.o \ test_gui_socket.o \ test_gui_boxsizer.o \ @@ -932,6 +933,9 @@ test_gui_selstoretest.o: $(srcdir)/misc/selstoretest.cpp $(TEST_GUI_ODEP) test_gui_garbage.o: $(srcdir)/misc/garbage.cpp $(TEST_GUI_ODEP) $(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/misc/garbage.cpp +test_gui_safearrayconverttest.o: $(srcdir)/misc/safearrayconverttest.cpp $(TEST_GUI_ODEP) + $(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/misc/safearrayconverttest.cpp + test_gui_settings.o: $(srcdir)/misc/settings.cpp $(TEST_GUI_ODEP) $(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/misc/settings.cpp diff --git a/tests/makefile.bcc b/tests/makefile.bcc index 604a0f377f..4a38261e7b 100644 --- a/tests/makefile.bcc +++ b/tests/makefile.bcc @@ -209,6 +209,7 @@ TEST_GUI_OBJECTS = \ $(OBJS)\test_gui_guifuncs.obj \ $(OBJS)\test_gui_selstoretest.obj \ $(OBJS)\test_gui_garbage.obj \ + $(OBJS)\test_gui_safearrayconverttest.obj \ $(OBJS)\test_gui_settings.obj \ $(OBJS)\test_gui_socket.obj \ $(OBJS)\test_gui_boxsizer.obj \ @@ -976,6 +977,9 @@ $(OBJS)\test_gui_selstoretest.obj: .\misc\selstoretest.cpp $(OBJS)\test_gui_garbage.obj: .\misc\garbage.cpp $(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\misc\garbage.cpp +$(OBJS)\test_gui_safearrayconverttest.obj: .\misc\safearrayconverttest.cpp + $(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\misc\safearrayconverttest.cpp + $(OBJS)\test_gui_settings.obj: .\misc\settings.cpp $(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\misc\settings.cpp diff --git a/tests/makefile.gcc b/tests/makefile.gcc index e583b236c5..3333273806 100644 --- a/tests/makefile.gcc +++ b/tests/makefile.gcc @@ -202,6 +202,7 @@ TEST_GUI_OBJECTS = \ $(OBJS)\test_gui_guifuncs.o \ $(OBJS)\test_gui_selstoretest.o \ $(OBJS)\test_gui_garbage.o \ + $(OBJS)\test_gui_safearrayconverttest.o \ $(OBJS)\test_gui_settings.o \ $(OBJS)\test_gui_socket.o \ $(OBJS)\test_gui_boxsizer.o \ @@ -961,6 +962,9 @@ $(OBJS)\test_gui_selstoretest.o: ./misc/selstoretest.cpp $(OBJS)\test_gui_garbage.o: ./misc/garbage.cpp $(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\test_gui_safearrayconverttest.o: ./misc/safearrayconverttest.cpp + $(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\test_gui_settings.o: ./misc/settings.cpp $(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $< diff --git a/tests/makefile.vc b/tests/makefile.vc index e923fbed47..06465ab3fe 100644 --- a/tests/makefile.vc +++ b/tests/makefile.vc @@ -206,6 +206,7 @@ TEST_GUI_OBJECTS = \ $(OBJS)\test_gui_guifuncs.obj \ $(OBJS)\test_gui_selstoretest.obj \ $(OBJS)\test_gui_garbage.obj \ + $(OBJS)\test_gui_safearrayconverttest.obj \ $(OBJS)\test_gui_settings.obj \ $(OBJS)\test_gui_socket.obj \ $(OBJS)\test_gui_boxsizer.obj \ @@ -1116,6 +1117,9 @@ $(OBJS)\test_gui_selstoretest.obj: .\misc\selstoretest.cpp $(OBJS)\test_gui_garbage.obj: .\misc\garbage.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\misc\garbage.cpp +$(OBJS)\test_gui_safearrayconverttest.obj: .\misc\safearrayconverttest.cpp + $(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\misc\safearrayconverttest.cpp + $(OBJS)\test_gui_settings.obj: .\misc\settings.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\misc\settings.cpp diff --git a/tests/makefile.wat b/tests/makefile.wat index ff8e120442..e8d4972c44 100644 --- a/tests/makefile.wat +++ b/tests/makefile.wat @@ -465,6 +465,7 @@ TEST_GUI_OBJECTS = & $(OBJS)\test_gui_guifuncs.obj & $(OBJS)\test_gui_selstoretest.obj & $(OBJS)\test_gui_garbage.obj & + $(OBJS)\test_gui_safearrayconverttest.obj & $(OBJS)\test_gui_settings.obj & $(OBJS)\test_gui_socket.obj & $(OBJS)\test_gui_boxsizer.obj & @@ -1023,6 +1024,9 @@ $(OBJS)\test_gui_selstoretest.obj : .AUTODEPEND .\misc\selstoretest.cpp $(OBJS)\test_gui_garbage.obj : .AUTODEPEND .\misc\garbage.cpp $(CXX) -bt=nt -zq -fo=$^@ $(TEST_GUI_CXXFLAGS) $< +$(OBJS)\test_gui_safearrayconverttest.obj : .AUTODEPEND .\misc\safearrayconverttest.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(TEST_GUI_CXXFLAGS) $< + $(OBJS)\test_gui_settings.obj : .AUTODEPEND .\misc\settings.cpp $(CXX) -bt=nt -zq -fo=$^@ $(TEST_GUI_CXXFLAGS) $< diff --git a/tests/misc/safearrayconverttest.cpp b/tests/misc/safearrayconverttest.cpp new file mode 100644 index 0000000000..20ad9a75c4 --- /dev/null +++ b/tests/misc/safearrayconverttest.cpp @@ -0,0 +1,204 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/misc/safearrayconverttest.cpp +// Purpose: Test conversions between wxVariant and OLE VARIANT using SAFEARRAYs +// Author: PB +// RCS-ID: $Id: typeinfotest.cpp 67656 2011-04-30 10:57:04Z DS $ +// Copyright: (c) the wxWidgets team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#include "testprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifdef __WINDOWS__ + +#if wxUSE_OLE && wxUSE_VARIANT + +#include "wx/msw/ole/oleutils.h" +#include "wx/msw/ole/safearray.h" + +// need this to be able to use CPPUNIT_ASSERT_EQUAL with wxVariant objects +inline std::ostream& operator<<(std::ostream& ostr, const wxVariant& v) +{ + ostr << v.GetString(); + return ostr; +} + +// ---------------------------------------------------------------------------- +// test class +// ---------------------------------------------------------------------------- + +class SafeArrayConvertTestCase : public CppUnit::TestCase +{ +public: + SafeArrayConvertTestCase () { } + +private: + CPPUNIT_TEST_SUITE( SafeArrayConvertTestCase ); + CPPUNIT_TEST( VariantListDefault ); + CPPUNIT_TEST( VariantStringsDefault ); + CPPUNIT_TEST( VariantListReturnSafeArray ); + CPPUNIT_TEST( StringsReturnSafeArray ); + CPPUNIT_TEST_SUITE_END(); + + void VariantListDefault(); + void VariantStringsDefault(); + + void VariantListReturnSafeArray(); + void StringsReturnSafeArray(); + + DECLARE_NO_COPY_CLASS(SafeArrayConvertTestCase ) +}; + +// register in the unnamed registry so that these tests are run by default +CPPUNIT_TEST_SUITE_REGISTRATION( SafeArrayConvertTestCase ); + +// also include in its own registry so that these tests can be run alone +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SafeArrayConvertTestCase, "SafeArrayConvertTestCase" ); + + + +// test converting a wxVariant with the list type to an OLE VARIANT +// and back to wxVariant the list type +void SafeArrayConvertTestCase::VariantListDefault() +{ + wxVariant variant; + VARIANT oleVariant; + + variant.NullList(); + variant.Append(true); + variant.Append(12.34); + variant.Append(42L); + variant.Append("ABC"); + CPPUNIT_ASSERT( wxConvertVariantToOle(variant, oleVariant) ); + + wxVariant variantCopy; + + CPPUNIT_ASSERT( wxConvertOleToVariant(oleVariant, variantCopy) ); + CPPUNIT_ASSERT( variant == variantCopy ); +} + +// test converting a wxVariant with the arrstring type to an OLE VARIANT +// and back to a wxVariant with the arrstring type +void SafeArrayConvertTestCase::VariantStringsDefault() +{ + wxVariant variant; + wxArrayString as; + VARIANT oleVariant; + + as.push_back("abc"); + as.push_back("def"); + as.push_back("ghi"); + variant = as; + CPPUNIT_ASSERT( wxConvertVariantToOle(variant, oleVariant) ); + + wxVariant variantCopy; + + CPPUNIT_ASSERT( wxConvertOleToVariant(oleVariant, variantCopy) ); + CPPUNIT_ASSERT( variant == variantCopy ); +} + +// test converting a wxVariant with the list type to an OLE VARIANT +// and then to a wxVariant with the safearray type +void SafeArrayConvertTestCase::VariantListReturnSafeArray() +{ + wxVariant variant; + VARIANT oleVariant; + + variant.NullList(); + variant.Append(true); + variant.Append(12.34); + variant.Append(42L); + variant.Append("test"); + CPPUNIT_ASSERT( wxConvertVariantToOle(variant, oleVariant) ); + + wxVariant variantCopy; + + CPPUNIT_ASSERT( + wxConvertOleToVariant(oleVariant, variantCopy, + wxOleConvertVariant_ReturnSafeArrays) + ); + CPPUNIT_ASSERT( variantCopy.GetType() == wxT("safearray") ); + + wxSafeArray safeArray; + wxVariantDataSafeArray* + vsa = wxStaticCastVariantData(variantCopy.GetData(), + wxVariantDataSafeArray); + long bound; + + CPPUNIT_ASSERT( vsa ); + CPPUNIT_ASSERT( safeArray.Attach(vsa->GetValue()) ); + CPPUNIT_ASSERT_EQUAL( 1, safeArray.GetDim() ); + CPPUNIT_ASSERT( safeArray.GetLBound(1, bound) ); + CPPUNIT_ASSERT_EQUAL( 0, bound ); + CPPUNIT_ASSERT( safeArray.GetUBound(1, bound) ); + + const long count = variant.GetCount(); + + // bound + 1 because safearray elements are accessed by index ranging from + // LBound to UBound inclusive + CPPUNIT_ASSERT_EQUAL( bound + 1, count ); + + wxVariant variantItem; + + for ( long i = 0; i < count; i++ ) + { + CPPUNIT_ASSERT( safeArray.GetElement(&i, variantItem) ); + CPPUNIT_ASSERT_EQUAL( variantItem, variant[i] ); + } +} + +// test converting a wxArrayString to an OLE VARIANT +// and then to a wxVariant with the safearray type +void SafeArrayConvertTestCase::StringsReturnSafeArray() +{ + wxArrayString as; + wxSafeArray safeArray; + + as.push_back("abc"); + as.push_back("def"); + as.push_back("ghi"); + CPPUNIT_ASSERT( safeArray.CreateFromArrayString(as) ); + + VARIANT oleVariant; + wxVariant variant; + + oleVariant.vt = VT_BSTR | VT_ARRAY; + oleVariant.parray = safeArray.Detach(); + CPPUNIT_ASSERT( oleVariant.parray ); + CPPUNIT_ASSERT( + wxConvertOleToVariant(oleVariant, variant, + wxOleConvertVariant_ReturnSafeArrays) + ); + CPPUNIT_ASSERT( variant.GetType() == wxT("safearray") ); + + wxVariantDataSafeArray* + vsa = wxStaticCastVariantData(variant.GetData(), + wxVariantDataSafeArray); + long bound; + + CPPUNIT_ASSERT( vsa ); + CPPUNIT_ASSERT( safeArray.Attach(vsa->GetValue()) ); + CPPUNIT_ASSERT_EQUAL( 1, safeArray.GetDim() ); + CPPUNIT_ASSERT( safeArray.GetLBound(1, bound) ); + CPPUNIT_ASSERT_EQUAL( 0, bound ); + CPPUNIT_ASSERT( safeArray.GetUBound(1, bound) ); + + const long count = as.size(); + CPPUNIT_ASSERT_EQUAL( bound + 1, count ); + + wxString str; + + for ( long i = 0; i < count; i++ ) + { + CPPUNIT_ASSERT( safeArray.GetElement(&i, str) ); + CPPUNIT_ASSERT( str == as[i] ); + } +} + +#endif // __WINDOWS__ + +#endif // wxUSE_OLE && wxUSE_VARIANT diff --git a/tests/test.bkl b/tests/test.bkl index fafb129fd4..4830927954 100644 --- a/tests/test.bkl +++ b/tests/test.bkl @@ -210,6 +210,7 @@ misc/guifuncs.cpp misc/selstoretest.cpp misc/garbage.cpp + misc/safearrayconverttest.cpp misc/settings.cpp