From 226fa6db3dc88370446602fd7490a8890305ffd3 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 23 Sep 2012 22:49:50 +0000 Subject: [PATCH 1/1] Improve SAFEARRAY support in wxMSW OLE Automation code. Add a new wxSafeArray<> class wrapping SAFEARRAY. Also add support for converting VARIANTs containing other, previously unsupported, standard types. Closes #14637. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72543 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 42 ++++ build/bakefiles/files.bkl | 2 + build/msw/makefile.bcc | 28 +++ build/msw/makefile.gcc | 28 +++ build/msw/makefile.vc | 28 +++ build/msw/makefile.wat | 28 +++ build/msw/wx_core.dsp | 8 + build/msw/wx_vc7_core.vcproj | 6 + build/msw/wx_vc8_core.vcproj | 8 + build/msw/wx_vc9_core.vcproj | 8 + docs/changes.txt | 1 + include/wx/msw/ole/oleutils.h | 29 +++ include/wx/msw/ole/safearray.h | 395 +++++++++++++++++++++++++++++++++ interface/wx/msw/ole/automtn.h | 129 ++++++++++- interface/wx/variant.h | 6 +- src/msw/ole/automtn.cpp | 6 + src/msw/ole/oleutils.cpp | 260 +++++++++------------- src/msw/ole/safearray.cpp | 134 +++++++++++ 18 files changed, 988 insertions(+), 158 deletions(-) create mode 100644 include/wx/msw/ole/safearray.h create mode 100644 src/msw/ole/safearray.cpp diff --git a/Makefile.in b/Makefile.in index dd2e500832..073ae2ebef 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3151,6 +3151,7 @@ COND_TOOLKIT_MSW_GUI_HDR = \ wx/msw/ole/dropsrc.h \ wx/msw/ole/droptgt.h \ wx/msw/ole/oleutils.h \ + wx/msw/ole/safearray.h \ wx/msw/ownerdrw.h \ wx/msw/palette.h \ wx/msw/panel.h \ @@ -3668,6 +3669,7 @@ COND_TOOLKIT_WINCE_GUI_HDR = \ wx/msw/ole/dropsrc.h \ wx/msw/ole/droptgt.h \ wx/msw/ole/oleutils.h \ + wx/msw/ole/safearray.h \ wx/msw/ownerdrw.h \ wx/msw/palette.h \ wx/msw/panel.h \ @@ -5268,6 +5270,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS = \ monodll_dropsrc.o \ monodll_droptgt.o \ monodll_oleutils.o \ + monodll_safearray.o \ monodll_msw_palette.o \ monodll_msw_pen.o \ monodll_msw_popupwin.o \ @@ -5329,6 +5332,7 @@ COND_TOOLKIT_WINCE___LOWLEVEL_SRC_OBJECTS = \ monodll_dropsrc.o \ monodll_droptgt.o \ monodll_oleutils.o \ + monodll_safearray.o \ monodll_msw_palette.o \ monodll_msw_pen.o \ monodll_msw_popupwin.o \ @@ -6204,6 +6208,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_1 = \ monodll_dropsrc.o \ monodll_droptgt.o \ monodll_oleutils.o \ + monodll_safearray.o \ monodll_msw_palette.o \ monodll_msw_pen.o \ monodll_msw_popupwin.o \ @@ -6265,6 +6270,7 @@ COND_TOOLKIT_WINCE___LOWLEVEL_SRC_OBJECTS_1 = \ monodll_dropsrc.o \ monodll_droptgt.o \ monodll_oleutils.o \ + monodll_safearray.o \ monodll_msw_palette.o \ monodll_msw_pen.o \ monodll_msw_popupwin.o \ @@ -7474,6 +7480,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_2 = \ monolib_dropsrc.o \ monolib_droptgt.o \ monolib_oleutils.o \ + monolib_safearray.o \ monolib_msw_palette.o \ monolib_msw_pen.o \ monolib_msw_popupwin.o \ @@ -7535,6 +7542,7 @@ COND_TOOLKIT_WINCE___LOWLEVEL_SRC_OBJECTS_2 = \ monolib_dropsrc.o \ monolib_droptgt.o \ monolib_oleutils.o \ + monolib_safearray.o \ monolib_msw_palette.o \ monolib_msw_pen.o \ monolib_msw_popupwin.o \ @@ -8410,6 +8418,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_3 = \ monolib_dropsrc.o \ monolib_droptgt.o \ monolib_oleutils.o \ + monolib_safearray.o \ monolib_msw_palette.o \ monolib_msw_pen.o \ monolib_msw_popupwin.o \ @@ -8471,6 +8480,7 @@ COND_TOOLKIT_WINCE___LOWLEVEL_SRC_OBJECTS_3 = \ monolib_dropsrc.o \ monolib_droptgt.o \ monolib_oleutils.o \ + monolib_safearray.o \ monolib_msw_palette.o \ monolib_msw_pen.o \ monolib_msw_popupwin.o \ @@ -9855,6 +9865,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_4 = \ coredll_dropsrc.o \ coredll_droptgt.o \ coredll_oleutils.o \ + coredll_safearray.o \ coredll_msw_palette.o \ coredll_msw_pen.o \ coredll_msw_popupwin.o \ @@ -9916,6 +9927,7 @@ COND_TOOLKIT_WINCE___LOWLEVEL_SRC_OBJECTS_4 = \ coredll_dropsrc.o \ coredll_droptgt.o \ coredll_oleutils.o \ + coredll_safearray.o \ coredll_msw_palette.o \ coredll_msw_pen.o \ coredll_msw_popupwin.o \ @@ -10791,6 +10803,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_5 = \ coredll_dropsrc.o \ coredll_droptgt.o \ coredll_oleutils.o \ + coredll_safearray.o \ coredll_msw_palette.o \ coredll_msw_pen.o \ coredll_msw_popupwin.o \ @@ -10852,6 +10865,7 @@ COND_TOOLKIT_WINCE___LOWLEVEL_SRC_OBJECTS_5 = \ coredll_dropsrc.o \ coredll_droptgt.o \ coredll_oleutils.o \ + coredll_safearray.o \ coredll_msw_palette.o \ coredll_msw_pen.o \ coredll_msw_popupwin.o \ @@ -11500,6 +11514,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_6 = \ corelib_dropsrc.o \ corelib_droptgt.o \ corelib_oleutils.o \ + corelib_safearray.o \ corelib_msw_palette.o \ corelib_msw_pen.o \ corelib_msw_popupwin.o \ @@ -11561,6 +11576,7 @@ COND_TOOLKIT_WINCE___LOWLEVEL_SRC_OBJECTS_6 = \ corelib_dropsrc.o \ corelib_droptgt.o \ corelib_oleutils.o \ + corelib_safearray.o \ corelib_msw_palette.o \ corelib_msw_pen.o \ corelib_msw_popupwin.o \ @@ -12436,6 +12452,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_7 = \ corelib_dropsrc.o \ corelib_droptgt.o \ corelib_oleutils.o \ + corelib_safearray.o \ corelib_msw_palette.o \ corelib_msw_pen.o \ corelib_msw_popupwin.o \ @@ -12497,6 +12514,7 @@ COND_TOOLKIT_WINCE___LOWLEVEL_SRC_OBJECTS_7 = \ corelib_dropsrc.o \ corelib_droptgt.o \ corelib_oleutils.o \ + corelib_safearray.o \ corelib_msw_palette.o \ corelib_msw_pen.o \ corelib_msw_popupwin.o \ @@ -19413,6 +19431,12 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1@monodll_oleutils.o: $(srcdir)/src/msw/ole/oleutils.cpp $(MONODLL_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/ole/oleutils.cpp +@COND_TOOLKIT_MSW_USE_GUI_1@monodll_safearray.o: $(srcdir)/src/msw/ole/safearray.cpp $(MONODLL_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/ole/safearray.cpp + +@COND_TOOLKIT_WINCE_USE_GUI_1@monodll_safearray.o: $(srcdir)/src/msw/ole/safearray.cpp $(MONODLL_ODEP) +@COND_TOOLKIT_WINCE_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/ole/safearray.cpp + @COND_TOOLKIT_MSW_USE_GUI_1@monodll_msw_palette.o: $(srcdir)/src/msw/palette.cpp $(MONODLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/palette.cpp @@ -25110,6 +25134,12 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1@monolib_oleutils.o: $(srcdir)/src/msw/ole/oleutils.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/ole/oleutils.cpp +@COND_TOOLKIT_MSW_USE_GUI_1@monolib_safearray.o: $(srcdir)/src/msw/ole/safearray.cpp $(MONOLIB_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/ole/safearray.cpp + +@COND_TOOLKIT_WINCE_USE_GUI_1@monolib_safearray.o: $(srcdir)/src/msw/ole/safearray.cpp $(MONOLIB_ODEP) +@COND_TOOLKIT_WINCE_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/ole/safearray.cpp + @COND_TOOLKIT_MSW_USE_GUI_1@monolib_msw_palette.o: $(srcdir)/src/msw/palette.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/palette.cpp @@ -30972,6 +31002,12 @@ coredll_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(COREDLL_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1@coredll_oleutils.o: $(srcdir)/src/msw/ole/oleutils.cpp $(COREDLL_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/ole/oleutils.cpp +@COND_TOOLKIT_MSW_USE_GUI_1@coredll_safearray.o: $(srcdir)/src/msw/ole/safearray.cpp $(COREDLL_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/ole/safearray.cpp + +@COND_TOOLKIT_WINCE_USE_GUI_1@coredll_safearray.o: $(srcdir)/src/msw/ole/safearray.cpp $(COREDLL_ODEP) +@COND_TOOLKIT_WINCE_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/ole/safearray.cpp + @COND_TOOLKIT_MSW_USE_GUI_1@coredll_msw_palette.o: $(srcdir)/src/msw/palette.cpp $(COREDLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/palette.cpp @@ -35217,6 +35253,12 @@ corelib_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(CORELIB_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1@corelib_oleutils.o: $(srcdir)/src/msw/ole/oleutils.cpp $(CORELIB_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/ole/oleutils.cpp +@COND_TOOLKIT_MSW_USE_GUI_1@corelib_safearray.o: $(srcdir)/src/msw/ole/safearray.cpp $(CORELIB_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/ole/safearray.cpp + +@COND_TOOLKIT_WINCE_USE_GUI_1@corelib_safearray.o: $(srcdir)/src/msw/ole/safearray.cpp $(CORELIB_ODEP) +@COND_TOOLKIT_WINCE_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/ole/safearray.cpp + @COND_TOOLKIT_MSW_USE_GUI_1@corelib_msw_palette.o: $(srcdir)/src/msw/palette.cpp $(CORELIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/palette.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index f9a867b51c..2084242cf8 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -1683,6 +1683,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/msw/ole/dropsrc.cpp src/msw/ole/droptgt.cpp src/msw/ole/oleutils.cpp + src/msw/ole/safearray.cpp src/msw/palette.cpp src/msw/pen.cpp src/msw/popupwin.cpp @@ -1842,6 +1843,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/msw/ole/dropsrc.h wx/msw/ole/droptgt.h wx/msw/ole/oleutils.h + wx/msw/ole/safearray.h wx/msw/ownerdrw.h wx/msw/palette.h wx/msw/panel.h diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc index 0a40aceed1..e6fb7888a3 100644 --- a/build/msw/makefile.bcc +++ b/build/msw/makefile.bcc @@ -1787,6 +1787,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_dropsrc.obj \ $(OBJS)\monodll_droptgt.obj \ $(OBJS)\monodll_oleutils.obj \ + $(OBJS)\monodll_safearray.obj \ $(OBJS)\monodll_palette.obj \ $(OBJS)\monodll_pen.obj \ $(OBJS)\monodll_popupwin.obj \ @@ -2061,6 +2062,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_dropsrc.obj \ $(OBJS)\monodll_droptgt.obj \ $(OBJS)\monodll_oleutils.obj \ + $(OBJS)\monodll_safearray.obj \ $(OBJS)\monodll_palette.obj \ $(OBJS)\monodll_pen.obj \ $(OBJS)\monodll_popupwin.obj \ @@ -2576,6 +2578,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_dropsrc.obj \ $(OBJS)\monolib_droptgt.obj \ $(OBJS)\monolib_oleutils.obj \ + $(OBJS)\monolib_safearray.obj \ $(OBJS)\monolib_palette.obj \ $(OBJS)\monolib_pen.obj \ $(OBJS)\monolib_popupwin.obj \ @@ -2850,6 +2853,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_dropsrc.obj \ $(OBJS)\monolib_droptgt.obj \ $(OBJS)\monolib_oleutils.obj \ + $(OBJS)\monolib_safearray.obj \ $(OBJS)\monolib_palette.obj \ $(OBJS)\monolib_pen.obj \ $(OBJS)\monolib_popupwin.obj \ @@ -3246,6 +3250,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_dropsrc.obj \ $(OBJS)\coredll_droptgt.obj \ $(OBJS)\coredll_oleutils.obj \ + $(OBJS)\coredll_safearray.obj \ $(OBJS)\coredll_palette.obj \ $(OBJS)\coredll_pen.obj \ $(OBJS)\coredll_popupwin.obj \ @@ -3520,6 +3525,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_dropsrc.obj \ $(OBJS)\coredll_droptgt.obj \ $(OBJS)\coredll_oleutils.obj \ + $(OBJS)\coredll_safearray.obj \ $(OBJS)\coredll_palette.obj \ $(OBJS)\coredll_pen.obj \ $(OBJS)\coredll_popupwin.obj \ @@ -3792,6 +3798,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_dropsrc.obj \ $(OBJS)\corelib_droptgt.obj \ $(OBJS)\corelib_oleutils.obj \ + $(OBJS)\corelib_safearray.obj \ $(OBJS)\corelib_palette.obj \ $(OBJS)\corelib_pen.obj \ $(OBJS)\corelib_popupwin.obj \ @@ -4066,6 +4073,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_dropsrc.obj \ $(OBJS)\corelib_droptgt.obj \ $(OBJS)\corelib_oleutils.obj \ + $(OBJS)\corelib_safearray.obj \ $(OBJS)\corelib_palette.obj \ $(OBJS)\corelib_pen.obj \ $(OBJS)\corelib_popupwin.obj \ @@ -7442,6 +7450,11 @@ $(OBJS)\monodll_oleutils.obj: ..\..\src\msw\ole\oleutils.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\ole\oleutils.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_safearray.obj: ..\..\src\msw\ole\safearray.cpp + $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\ole\safearray.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monodll_palette.obj: ..\..\src\msw\palette.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\palette.cpp @@ -9863,6 +9876,11 @@ $(OBJS)\monolib_oleutils.obj: ..\..\src\msw\ole\oleutils.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\ole\oleutils.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_safearray.obj: ..\..\src\msw\ole\safearray.cpp + $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\ole\safearray.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monolib_palette.obj: ..\..\src\msw\palette.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\palette.cpp @@ -12248,6 +12266,11 @@ $(OBJS)\coredll_oleutils.obj: ..\..\src\msw\ole\oleutils.cpp $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\ole\oleutils.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\coredll_safearray.obj: ..\..\src\msw\ole\safearray.cpp + $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\ole\safearray.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\coredll_palette.obj: ..\..\src\msw\palette.cpp $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\palette.cpp @@ -13663,6 +13686,11 @@ $(OBJS)\corelib_oleutils.obj: ..\..\src\msw\ole\oleutils.cpp $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\ole\oleutils.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\corelib_safearray.obj: ..\..\src\msw\ole\safearray.cpp + $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\ole\safearray.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\corelib_palette.obj: ..\..\src\msw\palette.cpp $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\palette.cpp diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index ae37b9d80b..7200c59fe4 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -1800,6 +1800,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_dropsrc.o \ $(OBJS)\monodll_droptgt.o \ $(OBJS)\monodll_oleutils.o \ + $(OBJS)\monodll_safearray.o \ $(OBJS)\monodll_palette.o \ $(OBJS)\monodll_pen.o \ $(OBJS)\monodll_popupwin.o \ @@ -2076,6 +2077,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_dropsrc.o \ $(OBJS)\monodll_droptgt.o \ $(OBJS)\monodll_oleutils.o \ + $(OBJS)\monodll_safearray.o \ $(OBJS)\monodll_palette.o \ $(OBJS)\monodll_pen.o \ $(OBJS)\monodll_popupwin.o \ @@ -2595,6 +2597,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_dropsrc.o \ $(OBJS)\monolib_droptgt.o \ $(OBJS)\monolib_oleutils.o \ + $(OBJS)\monolib_safearray.o \ $(OBJS)\monolib_palette.o \ $(OBJS)\monolib_pen.o \ $(OBJS)\monolib_popupwin.o \ @@ -2871,6 +2874,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_dropsrc.o \ $(OBJS)\monolib_droptgt.o \ $(OBJS)\monolib_oleutils.o \ + $(OBJS)\monolib_safearray.o \ $(OBJS)\monolib_palette.o \ $(OBJS)\monolib_pen.o \ $(OBJS)\monolib_popupwin.o \ @@ -3281,6 +3285,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_dropsrc.o \ $(OBJS)\coredll_droptgt.o \ $(OBJS)\coredll_oleutils.o \ + $(OBJS)\coredll_safearray.o \ $(OBJS)\coredll_palette.o \ $(OBJS)\coredll_pen.o \ $(OBJS)\coredll_popupwin.o \ @@ -3557,6 +3562,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_dropsrc.o \ $(OBJS)\coredll_droptgt.o \ $(OBJS)\coredll_oleutils.o \ + $(OBJS)\coredll_safearray.o \ $(OBJS)\coredll_palette.o \ $(OBJS)\coredll_pen.o \ $(OBJS)\coredll_popupwin.o \ @@ -3835,6 +3841,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_dropsrc.o \ $(OBJS)\corelib_droptgt.o \ $(OBJS)\corelib_oleutils.o \ + $(OBJS)\corelib_safearray.o \ $(OBJS)\corelib_palette.o \ $(OBJS)\corelib_pen.o \ $(OBJS)\corelib_popupwin.o \ @@ -4111,6 +4118,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_dropsrc.o \ $(OBJS)\corelib_droptgt.o \ $(OBJS)\corelib_oleutils.o \ + $(OBJS)\corelib_safearray.o \ $(OBJS)\corelib_palette.o \ $(OBJS)\corelib_pen.o \ $(OBJS)\corelib_popupwin.o \ @@ -7611,6 +7619,11 @@ $(OBJS)\monodll_oleutils.o: ../../src/msw/ole/oleutils.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monodll_safearray.o: ../../src/msw/ole/safearray.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\monodll_palette.o: ../../src/msw/palette.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -10032,6 +10045,11 @@ $(OBJS)\monolib_oleutils.o: ../../src/msw/ole/oleutils.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monolib_safearray.o: ../../src/msw/ole/safearray.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\monolib_palette.o: ../../src/msw/palette.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -12417,6 +12435,11 @@ $(OBJS)\coredll_oleutils.o: ../../src/msw/ole/oleutils.cpp $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\coredll_safearray.o: ../../src/msw/ole/safearray.cpp + $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\coredll_palette.o: ../../src/msw/palette.cpp $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< @@ -13832,6 +13855,11 @@ $(OBJS)\corelib_oleutils.o: ../../src/msw/ole/oleutils.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\corelib_safearray.o: ../../src/msw/ole/safearray.cpp + $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\corelib_palette.o: ../../src/msw/palette.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index 40f693e7a1..6a6aafad93 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -2079,6 +2079,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_dropsrc.obj \ $(OBJS)\monodll_droptgt.obj \ $(OBJS)\monodll_oleutils.obj \ + $(OBJS)\monodll_safearray.obj \ $(OBJS)\monodll_palette.obj \ $(OBJS)\monodll_pen.obj \ $(OBJS)\monodll_popupwin.obj \ @@ -2353,6 +2354,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_dropsrc.obj \ $(OBJS)\monodll_droptgt.obj \ $(OBJS)\monodll_oleutils.obj \ + $(OBJS)\monodll_safearray.obj \ $(OBJS)\monodll_palette.obj \ $(OBJS)\monodll_pen.obj \ $(OBJS)\monodll_popupwin.obj \ @@ -2874,6 +2876,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_dropsrc.obj \ $(OBJS)\monolib_droptgt.obj \ $(OBJS)\monolib_oleutils.obj \ + $(OBJS)\monolib_safearray.obj \ $(OBJS)\monolib_palette.obj \ $(OBJS)\monolib_pen.obj \ $(OBJS)\monolib_popupwin.obj \ @@ -3148,6 +3151,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_dropsrc.obj \ $(OBJS)\monolib_droptgt.obj \ $(OBJS)\monolib_oleutils.obj \ + $(OBJS)\monolib_safearray.obj \ $(OBJS)\monolib_palette.obj \ $(OBJS)\monolib_pen.obj \ $(OBJS)\monolib_popupwin.obj \ @@ -3610,6 +3614,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_dropsrc.obj \ $(OBJS)\coredll_droptgt.obj \ $(OBJS)\coredll_oleutils.obj \ + $(OBJS)\coredll_safearray.obj \ $(OBJS)\coredll_palette.obj \ $(OBJS)\coredll_pen.obj \ $(OBJS)\coredll_popupwin.obj \ @@ -3884,6 +3889,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_dropsrc.obj \ $(OBJS)\coredll_droptgt.obj \ $(OBJS)\coredll_oleutils.obj \ + $(OBJS)\coredll_safearray.obj \ $(OBJS)\coredll_palette.obj \ $(OBJS)\coredll_pen.obj \ $(OBJS)\coredll_popupwin.obj \ @@ -4162,6 +4168,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_dropsrc.obj \ $(OBJS)\corelib_droptgt.obj \ $(OBJS)\corelib_oleutils.obj \ + $(OBJS)\corelib_safearray.obj \ $(OBJS)\corelib_palette.obj \ $(OBJS)\corelib_pen.obj \ $(OBJS)\corelib_popupwin.obj \ @@ -4436,6 +4443,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_dropsrc.obj \ $(OBJS)\corelib_droptgt.obj \ $(OBJS)\corelib_oleutils.obj \ + $(OBJS)\corelib_safearray.obj \ $(OBJS)\corelib_palette.obj \ $(OBJS)\corelib_pen.obj \ $(OBJS)\corelib_popupwin.obj \ @@ -8126,6 +8134,11 @@ $(OBJS)\monodll_oleutils.obj: ..\..\src\msw\ole\oleutils.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\ole\oleutils.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_safearray.obj: ..\..\src\msw\ole\safearray.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\ole\safearray.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monodll_palette.obj: ..\..\src\msw\palette.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\palette.cpp @@ -10547,6 +10560,11 @@ $(OBJS)\monolib_oleutils.obj: ..\..\src\msw\ole\oleutils.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\ole\oleutils.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_safearray.obj: ..\..\src\msw\ole\safearray.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\ole\safearray.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monolib_palette.obj: ..\..\src\msw\palette.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\palette.cpp @@ -12932,6 +12950,11 @@ $(OBJS)\coredll_oleutils.obj: ..\..\src\msw\ole\oleutils.cpp $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\ole\oleutils.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\coredll_safearray.obj: ..\..\src\msw\ole\safearray.cpp + $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\ole\safearray.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\coredll_palette.obj: ..\..\src\msw\palette.cpp $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\palette.cpp @@ -14347,6 +14370,11 @@ $(OBJS)\corelib_oleutils.obj: ..\..\src\msw\ole\oleutils.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\ole\oleutils.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\corelib_safearray.obj: ..\..\src\msw\ole\safearray.cpp + $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\ole\safearray.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\corelib_palette.obj: ..\..\src\msw\palette.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\palette.cpp diff --git a/build/msw/makefile.wat b/build/msw/makefile.wat index 3f98157977..248328c26c 100644 --- a/build/msw/makefile.wat +++ b/build/msw/makefile.wat @@ -293,6 +293,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = & $(OBJS)\monodll_dropsrc.obj & $(OBJS)\monodll_droptgt.obj & $(OBJS)\monodll_oleutils.obj & + $(OBJS)\monodll_safearray.obj & $(OBJS)\monodll_palette.obj & $(OBJS)\monodll_pen.obj & $(OBJS)\monodll_popupwin.obj & @@ -569,6 +570,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = & $(OBJS)\monodll_dropsrc.obj & $(OBJS)\monodll_droptgt.obj & $(OBJS)\monodll_oleutils.obj & + $(OBJS)\monodll_safearray.obj & $(OBJS)\monodll_palette.obj & $(OBJS)\monodll_pen.obj & $(OBJS)\monodll_popupwin.obj & @@ -1093,6 +1095,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = & $(OBJS)\monolib_dropsrc.obj & $(OBJS)\monolib_droptgt.obj & $(OBJS)\monolib_oleutils.obj & + $(OBJS)\monolib_safearray.obj & $(OBJS)\monolib_palette.obj & $(OBJS)\monolib_pen.obj & $(OBJS)\monolib_popupwin.obj & @@ -1369,6 +1372,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = & $(OBJS)\monolib_dropsrc.obj & $(OBJS)\monolib_droptgt.obj & $(OBJS)\monolib_oleutils.obj & + $(OBJS)\monolib_safearray.obj & $(OBJS)\monolib_palette.obj & $(OBJS)\monolib_pen.obj & $(OBJS)\monolib_popupwin.obj & @@ -1790,6 +1794,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = & $(OBJS)\coredll_dropsrc.obj & $(OBJS)\coredll_droptgt.obj & $(OBJS)\coredll_oleutils.obj & + $(OBJS)\coredll_safearray.obj & $(OBJS)\coredll_palette.obj & $(OBJS)\coredll_pen.obj & $(OBJS)\coredll_popupwin.obj & @@ -2066,6 +2071,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = & $(OBJS)\coredll_dropsrc.obj & $(OBJS)\coredll_droptgt.obj & $(OBJS)\coredll_oleutils.obj & + $(OBJS)\coredll_safearray.obj & $(OBJS)\coredll_palette.obj & $(OBJS)\coredll_pen.obj & $(OBJS)\coredll_popupwin.obj & @@ -2346,6 +2352,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = & $(OBJS)\corelib_dropsrc.obj & $(OBJS)\corelib_droptgt.obj & $(OBJS)\corelib_oleutils.obj & + $(OBJS)\corelib_safearray.obj & $(OBJS)\corelib_palette.obj & $(OBJS)\corelib_pen.obj & $(OBJS)\corelib_popupwin.obj & @@ -2622,6 +2629,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = & $(OBJS)\corelib_dropsrc.obj & $(OBJS)\corelib_droptgt.obj & $(OBJS)\corelib_oleutils.obj & + $(OBJS)\corelib_safearray.obj & $(OBJS)\corelib_palette.obj & $(OBJS)\corelib_pen.obj & $(OBJS)\corelib_popupwin.obj & @@ -7884,6 +7892,11 @@ $(OBJS)\monodll_oleutils.obj : .AUTODEPEND ..\..\src\msw\ole\oleutils.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< !endif +!ifeq USE_GUI 1 +$(OBJS)\monodll_safearray.obj : .AUTODEPEND ..\..\src\msw\ole\safearray.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< +!endif + !ifeq USE_GUI 1 $(OBJS)\monodll_palette.obj : .AUTODEPEND ..\..\src\msw\palette.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< @@ -10305,6 +10318,11 @@ $(OBJS)\monolib_oleutils.obj : .AUTODEPEND ..\..\src\msw\ole\oleutils.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< !endif +!ifeq USE_GUI 1 +$(OBJS)\monolib_safearray.obj : .AUTODEPEND ..\..\src\msw\ole\safearray.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< +!endif + !ifeq USE_GUI 1 $(OBJS)\monolib_palette.obj : .AUTODEPEND ..\..\src\msw\palette.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< @@ -12690,6 +12708,11 @@ $(OBJS)\coredll_oleutils.obj : .AUTODEPEND ..\..\src\msw\ole\oleutils.cpp $(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $< !endif +!ifeq USE_GUI 1 +$(OBJS)\coredll_safearray.obj : .AUTODEPEND ..\..\src\msw\ole\safearray.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $< +!endif + !ifeq USE_GUI 1 $(OBJS)\coredll_palette.obj : .AUTODEPEND ..\..\src\msw\palette.cpp $(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $< @@ -14105,6 +14128,11 @@ $(OBJS)\corelib_oleutils.obj : .AUTODEPEND ..\..\src\msw\ole\oleutils.cpp $(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $< !endif +!ifeq USE_GUI 1 +$(OBJS)\corelib_safearray.obj : .AUTODEPEND ..\..\src\msw\ole\safearray.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $< +!endif + !ifeq USE_GUI 1 $(OBJS)\corelib_palette.obj : .AUTODEPEND ..\..\src\msw\palette.cpp $(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $< diff --git a/build/msw/wx_core.dsp b/build/msw/wx_core.dsp index 2970995eb5..dab6894f7e 100644 --- a/build/msw/wx_core.dsp +++ b/build/msw/wx_core.dsp @@ -2315,6 +2315,10 @@ SOURCE=..\..\src\msw\richmsgdlg.cpp # End Source File # Begin Source File +SOURCE=..\..\src\msw\ole\safearray.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\msw\scrolbar.cpp !IF "$(CFG)" == "core - Win32 DLL Universal Release" @@ -5360,6 +5364,10 @@ SOURCE=..\..\include\wx\msw\richmsgdlg.h # End Source File # Begin Source File +SOURCE=..\..\include\wx\msw\ole\safearray.h +# End Source File +# Begin Source File + SOURCE=..\..\include\wx\msw\scrolbar.h # End Source File # Begin Source File diff --git a/build/msw/wx_vc7_core.vcproj b/build/msw/wx_vc7_core.vcproj index e4b627a904..6c6888b9c3 100644 --- a/build/msw/wx_vc7_core.vcproj +++ b/build/msw/wx_vc7_core.vcproj @@ -2098,6 +2098,9 @@ Name="DLL Universal Release|Win32" ExcludedFromBuild="TRUE"/> + + + + diff --git a/build/msw/wx_vc8_core.vcproj b/build/msw/wx_vc8_core.vcproj index 13d622ea5f..178f1159b4 100644 --- a/build/msw/wx_vc8_core.vcproj +++ b/build/msw/wx_vc8_core.vcproj @@ -2831,6 +2831,10 @@ ExcludedFromBuild="true" /> + + @@ -6143,6 +6147,10 @@ RelativePath="..\..\include\wx\msw\richmsgdlg.h" > + + diff --git a/build/msw/wx_vc9_core.vcproj b/build/msw/wx_vc9_core.vcproj index 89758906c7..68d8e74f06 100644 --- a/build/msw/wx_vc9_core.vcproj +++ b/build/msw/wx_vc9_core.vcproj @@ -2827,6 +2827,10 @@ ExcludedFromBuild="true" /> + + @@ -6139,6 +6143,10 @@ RelativePath="..\..\include\wx\msw\richmsgdlg.h" > + + diff --git a/docs/changes.txt b/docs/changes.txt index f18a37c37e..1c45e52d1d 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -570,6 +570,7 @@ wxMSW: - Fix setting colours for the text part of wxComboBox (Igor Korot). - Add support for CURRENCY and SCODE types to OLE Automation helpers (PB). - Allow setting LCID used by wxAutomationObject (PB). +- Better support for SAFEARRAY in OLE Automation code (PB). - Fix calling Iconize(false) on hidden top level windows (Christian Walther). - Don't send any events from wxSpinCtrl::SetRange() even if the value changed. diff --git a/include/wx/msw/ole/oleutils.h b/include/wx/msw/ole/oleutils.h index 257025d7fb..37cbd5fb9e 100644 --- a/include/wx/msw/ole/oleutils.h +++ b/include/wx/msw/ole/oleutils.h @@ -289,6 +289,35 @@ private: SCODE m_value; }; +// wrapper for SAFEARRAY, used for passing multidimensional arrays in wxVariant +class WXDLLIMPEXP_CORE wxVariantDataSafeArray : public wxVariantData +{ +public: + wxEXPLICIT wxVariantDataSafeArray(SAFEARRAY* value = NULL) + { + m_value = value; + } + + SAFEARRAY* GetValue() const { return m_value; } + void SetValue(SAFEARRAY* value) { m_value = value; } + + virtual bool Eq(wxVariantData& data) const; + +#if wxUSE_STD_IOSTREAM + virtual bool Write(wxSTD ostream& str) const; +#endif + virtual bool Write(wxString& str) const; + + wxVariantData* Clone() const { return new wxVariantDataSafeArray(m_value); } + virtual wxString GetType() const { return wxS("safearray"); } + + DECLARE_WXANY_CONVERSION() + +private: + SAFEARRAY* m_value; +}; + + WXDLLIMPEXP_CORE bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant); WXDLLIMPEXP_CORE bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant); #endif // wxUSE_VARIANT diff --git a/include/wx/msw/ole/safearray.h b/include/wx/msw/ole/safearray.h new file mode 100644 index 0000000000..7ce6f35e84 --- /dev/null +++ b/include/wx/msw/ole/safearray.h @@ -0,0 +1,395 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: msw/ole/safearray.h +// Purpose: Helpers for working with OLE SAFEARRAYs. +// Author: PB +// Created: 2012-09-23 +// RCS-ID: $Id$ +// Copyright: (c) 2012 wxWidgets development team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSW_OLE_SAFEARRAY_H_ +#define _MSW_OLE_SAFEARRAY_H_ + +#include "wx/msw/ole/oleutils.h" + +#if wxUSE_OLE && wxUSE_VARIANT + +/* + wxSafeArray is wxWidgets wrapper for working with MS Windows SAFEARRAYs. + It also has convenience functions for converting between SAFEARRAY + and wxVariant with list type or wxArrayString. +*/ + +// The base class with type-independent methods. It exists solely in order to +// reduce the template bloat. +class WXDLLIMPEXP_CORE wxSafeArrayBase +{ +public: + // If owns a SAFEARRAY, it's unlocked and destroyed. + virtual ~wxSafeArrayBase() { Destroy(); } + + // Unlocks and destroys the owned SAFEARRAY. + void Destroy(); + + // Unlocks the owned SAFEARRAY, returns it and gives up its ownership. + SAFEARRAY* Detach(); + + // Returns true if has a valid SAFEARRAY. + bool HasArray() const { return m_array != NULL; } + + // Returns the number of dimensions. + size_t GetDim() const; + + // Returns lower bound for dimension dim in bound. Dimensions start at 1. + bool GetLBound(size_t dim, long& bound) const; + + // Returns upper bound for dimension dim in bound. Dimensions start at 1. + bool GetUBound(size_t dim, long& bound) const; + + // Returns element count for dimension dim. Dimensions start at 1. + size_t GetCount(size_t dim) const; + +protected: + // Default constructor, protected so the class can't be used on its own, + // it's only used as a base class of wxSafeArray<>. + wxSafeArrayBase() + { + m_array = NULL; + } + + bool Lock(); + bool Unlock(); + + SAFEARRAY* m_array; +}; + +// wxSafeArrayConvertor<> must be specialized for the type in order to allow +// using it with wxSafeArray<>. +// +// We specialize it below for the standard types. +template +struct wxSafeArrayConvertor {}; + +/** + Macro for specializing wxSafeArrayConvertor for simple types. + + The template parameters are: + - externType: basic C data type, e.g. wxFloat64 or wxInt32 + - varType: corresponding VARIANT type constant, e.g. VT_R8 or VT_I4. +*/ +#define wxSPECIALIZE_WXSAFEARRAY_CONVERTOR_SIMPLE(externType, varType) \ +template <> \ +struct wxSafeArrayConvertor \ +{ \ + typedef externType externT; \ + typedef externT internT; \ + static bool ToArray(const externT& from, internT& to) \ + { \ + to = from; \ + return true; \ + } \ + static bool FromArray(const internT& from, externT& to) \ + { \ + to = from; \ + return true; \ + } \ +} + +wxSPECIALIZE_WXSAFEARRAY_CONVERTOR_SIMPLE(wxInt16, VT_I2); +wxSPECIALIZE_WXSAFEARRAY_CONVERTOR_SIMPLE(wxInt32, VT_I4); +wxSPECIALIZE_WXSAFEARRAY_CONVERTOR_SIMPLE(wxFloat32, VT_R4); +wxSPECIALIZE_WXSAFEARRAY_CONVERTOR_SIMPLE(wxFloat64, VT_R8); + +// Specialization for VT_BSTR using wxString. +template <> +struct wxSafeArrayConvertor +{ + typedef wxString externT; + typedef BSTR internT; + + static bool ToArray(const wxString& from, BSTR& to) + { + BSTR bstr = wxConvertStringToOle(from); + + if ( !bstr && !from.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; + } + to = bstr; + return true; + } + + static bool FromArray(const BSTR from, wxString& to) + { + to = wxConvertStringFromOle(from); + return true; + } +}; + +// Specialization for VT_VARIANT using wxVariant. +template <> +struct wxSafeArrayConvertor +{ + typedef wxVariant externT; + typedef VARIANT internT; + + static bool ToArray(const wxVariant& from, VARIANT& to) + { + return wxConvertVariantToOle(from, to); + } + + static bool FromArray(const VARIANT& from, wxVariant& to) + { + return wxConvertOleToVariant(from, to); + } +}; + + +template +class wxSafeArray : public wxSafeArrayBase +{ +public: + typedef wxSafeArrayConvertor Convertor; + typedef typename Convertor::internT internT; + typedef typename Convertor::externT externT; + + // Default constructor. + wxSafeArray() + { + m_array = NULL; + } + + // Creates and locks a zero-based one-dimensional SAFEARRAY with the given + // number of elements. + bool Create(size_t count) + { + SAFEARRAYBOUND bound; + + bound.lLbound = 0; + bound.cElements = count; + return Create(&bound, 1); + } + + // Creates and locks a SAFEARRAY. See SafeArrayCreate() in MSDN + // documentation for more information. + bool Create(SAFEARRAYBOUND* bound, size_t dimensions) + { + wxCHECK_MSG( !m_array, false, wxS("Can't be created twice") ); + + m_array = SafeArrayCreate(varType, dimensions, bound); + if ( !m_array ) + return false; + + return Lock(); + } + + /** + Creates a 0-based one-dimensional SAFEARRAY from wxVariant with the + list type. + + Can be called only for wxSafeArray. + */ + bool CreateFromListVariant(const wxVariant& variant) + { + wxCHECK(varType == VT_VARIANT, false); + wxCHECK(variant.GetType() == wxS("list"), false); + + if ( !Create(variant.GetCount()) ) + return false; + + VARIANT* data = static_cast(m_array->pvData); + + for ( size_t i = 0; i < variant.GetCount(); i++) + { + if ( !Convertor::ToArray(variant[i], data[i]) ) + return false; + } + return true; + } + + /** + Creates a 0-based one-dimensional SAFEARRAY from wxArrayString. + + Can be called only for wxSafeArray. + */ + bool CreateFromArrayString(const wxArrayString& strings) + { + wxCHECK(varType == VT_BSTR, false); + + if ( !Create(strings.size()) ) + return false; + + BSTR* data = static_cast(m_array->pvData); + + for ( size_t i = 0; i < strings.size(); i++ ) + { + if ( !Convertor::ToArray(strings[i], data[i]) ) + return false; + } + return true; + } + + /** + Attaches and locks an existing SAFEARRAY. + The array must have the same VARTYPE as this wxSafeArray was + instantiated with. + */ + bool Attach(SAFEARRAY* array) + { + wxCHECK_MSG(!m_array && array, false, + wxS("Can only attach a valid array to an uninitialized one") ); + + VARTYPE vt; + HRESULT hr = SafeArrayGetVartype(array, &vt); + if ( FAILED(hr) ) + { + wxLogApiError(wxS("SafeArrayGetVarType()"), hr); + return false; + } + + wxCHECK_MSG(vt == varType, false, + wxS("Attaching array of invalid type")); + + m_array = array; + return Lock(); + } + + /** + Indices have the same row-column order as rgIndices in + SafeArrayPutElement(), i.e. they follow BASIC rules, NOT C ones. + */ + bool SetElement(long* indices, const externT& element) + { + wxCHECK_MSG( m_array, false, wxS("Uninitialized array") ); + wxCHECK_MSG( indices, false, wxS("Invalid index") ); + + internT* data; + + if ( FAILED( SafeArrayPtrOfIndex(m_array, indices, (void**)&data) ) ) + return false; + + return Convertor::ToArray(element, *data); + } + + /** + Indices have the same row-column order as rgIndices in + SafeArrayPutElement(), i.e. they follow BASIC rules, NOT C ones. + */ + bool GetElement(long* indices, externT& element) const + { + wxCHECK_MSG( m_array, false, wxS("Uninitialized array") ); + wxCHECK_MSG( indices, false, wxS("Invalid index") ); + + internT* data; + + if ( FAILED( SafeArrayPtrOfIndex(m_array, indices, (void**)&data) ) ) + return false; + + return Convertor::FromArray(*data, element); + } + + /** + Converts the array to a wxVariant with the list type, regardless of the + underlying SAFEARRAY type. + + If the array is multidimensional, it is flattened using the alghoritm + originally employed in wxConvertOleToVariant(). + */ + bool ConvertToVariant(wxVariant& variant) const + { + wxCHECK_MSG( m_array, false, wxS("Uninitialized array") ); + + size_t dims = m_array->cDims; + size_t count = 1; + + for ( size_t i = 0; i < dims; i++ ) + count *= m_array->rgsabound[i].cElements; + + const internT* data = static_cast(m_array->pvData); + externT element; + + variant.ClearList(); + for ( size_t i1 = 0; i1 < count; i1++ ) + { + if ( !Convertor::FromArray(data[i1], element) ) + { + variant.ClearList(); + return false; + } + variant.Append(element); + } + return true; + } + + /** + Converts an array to an ArrayString. + + Can be called only for wxSafeArray. If the array is + multidimensional, it is flattened using the alghoritm originally + employed in wxConvertOleToVariant(). + */ + bool ConvertToArrayString(wxArrayString& strings) const + { + wxCHECK_MSG( m_array, false, wxS("Uninitialized array") ); + wxCHECK(varType == VT_BSTR, false); + + size_t dims = m_array->cDims; + size_t count = 1; + + for ( size_t i = 0; i < dims; i++ ) + count *= m_array->rgsabound[i].cElements; + + const BSTR* data = static_cast(m_array->pvData); + wxString element; + + strings.clear(); + strings.reserve(count); + for ( size_t i1 = 0; i1 < count; i1++ ) + { + if ( !Convertor::FromArray(data[i1], element) ) + { + strings.clear(); + return false; + } + strings.push_back(element); + } + return true; + } + + static bool ConvertToVariant(SAFEARRAY* psa, wxVariant& variant) + { + wxSafeArray sa; + bool result = false; + + if ( sa.Attach(psa) ) + result = sa.ConvertToVariant(variant); + + if ( sa.HasArray() ) + sa.Detach(); + + return result; + } + + static bool ConvertToArrayString(SAFEARRAY* psa, wxArrayString& strings) + { + wxSafeArray sa; + bool result = false; + + if ( sa.Attach(psa) ) + result = sa.ConvertToArrayString(strings); + + if ( sa.HasArray() ) + sa.Detach(); + + return result; + } + + wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxSafeArray, varType); +}; + +#endif // wxUSE_OLE && wxUSE_VARIANT + +#endif // _MSW_OLE_SAFEARRAY_H_ diff --git a/interface/wx/msw/ole/automtn.h b/interface/wx/msw/ole/automtn.h index 9e7f3287a8..cfa2cb7144 100644 --- a/interface/wx/msw/ole/automtn.h +++ b/interface/wx/msw/ole/automtn.h @@ -215,6 +215,133 @@ public: virtual bool GetAsAny(wxAny* any) const; }; +/** + @class wxVariantDataSafeArray + + This class represents a thin wrapper for Microsoft Windows SAFEARRAY type. + + It is used for converting between wxVariant and OLE VARIANT + with type set to VT_ARRAY, which has more than one dimension. + When wxVariant stores wxVariantDataSafeArray, it returns "safearray" as its type. + + wxVariantDataSafeArray does NOT manage the SAFEARRAY it points to. + If you want to pass it to a wxAutomationObject as a parameter: + -# Assign a SAFEARRAY pointer to it and store it in a wxVariant. + -# Call the wxAutomationObject method (CallMethod(), SetProperty() or Invoke()) + -# wxAutomationObject will destroy the array after the approapriate automation call. + + An example of creating a 2-dimensional SAFEARRAY containing VARIANTs + and storing it in a wxVariant + @code + SAFEARRAYBOUND bounds[2]; // 2 dimensions + wxSafeArray safeArray; + unsigned rowCount = 1000; + unsigned colCount = 20; + + bounds[0].lLbound = 0; // elements start at 0 + bounds[0].cElements = rowCount; + bounds[1].lLbound = 0; // elements start at 0 + bounds[1].cElements = colCount; + + if ( !safeArray.Create(bounds, 2) ) + return false; + + long indices[2]; + + for ( unsigned row = 0; row < rowCount; row++ ) + { + indices[0] = row; + for ( unsigned col = 0; col < colCount; col++ ) + { + indices[1] = col; + if ( !safeArray.SetElement(indices, wxString::Format("R%ud C%ud", i+1, j+1)) )( + return false; + } + } + range.PutProperty("Value", wxVariant(new wxVariantDataSafeArray(sa.Detach()))); + @endcode + + If you you received wxVariantDataSafeArray as a result of wxAutomationObject method call: + (1) Get the data out of the array. + (2) Destroy the array. + @code + wxVariant result; + result = range.GetProperty("Value"); + if ( result.GetType() == "safearray" ) + { + wxSafeArray safeArray; + wxVariantDataSafeArray* const + sa = wxStaticCastVariantData(variant.GetData(), wxVariantDataSafeArray); + + if ( !safeArray.Attach(sa.GetValue() ) + { + if ( !safeArray.HasArray() ) + SafeArrayDestroy(sa.GetValue()); // we have to dispose the SAFEARRAY ourselves + return false; + } + + // get the data from the SAFEARRAY using wxSafeArray::GetElement() + // SAFEARRAY will be disposed by safeArray's dtor + } + @endcode + + @onlyfor{wxmsw} + @since 2.9.5 + + @library{wxcore} + @category{data} + + @see wxAutomationObject, wxVariant, wxVariantData, wxVariantDataErrorCode + + @header{wx/msw/ole/oleutils.h} +*/ +class wxVariantDataSafeArray : public wxVariantData +{ +public: + /** + Constructor initializes the object to @a value. + */ + explicit wxVariantDataSafeArray(SAFEARRAY* value = NULL); + + /** + Returns the stored array. + */ + SAFEARRAY* GetValue() const; + + /** + Set the stored array. + */ + void SetValue(SAFEARRAY* value); + + /** + Returns true if @a data is of wxVariantDataErrorCode type + and contains the same SCODE value. + */ + virtual bool Eq(wxVariantData& data) const; + + /** + Fills the provided string with the textual representation of this + object. + + The error code is just a number, so it's output as such. + */ + virtual bool Write(wxString& str) const; + + /** + Returns a copy of itself. + */ + wxVariantData* Clone() const; + + /** + Returns "safearray". + */ + virtual wxString GetType() const; + + /** + Converts the value of this object to wxAny. + */ + virtual bool GetAsAny(wxAny* any) const; +}; /** @class wxAutomationObject @@ -245,7 +372,7 @@ public: @library{wxcore} @category{data} - @see wxVariant, wxVariantDataCurrency, wxVariantDataErrorCode + @see wxVariant, wxVariantDataCurrency, wxVariantDataErrorCode, wxVariantDataSafeArray */ class wxAutomationObject : public wxObject { diff --git a/interface/wx/variant.h b/interface/wx/variant.h index ee3f8db494..9730565dd2 100644 --- a/interface/wx/variant.h +++ b/interface/wx/variant.h @@ -26,9 +26,9 @@ the wxVariantData object, unlike the case for basic data types where convenience functions such as GetLong() can be used. - Under Microsoft Windows, two additional wxVariantData-derived classes -- - wxVariantDataCurrency and wxVariantDataErrorCode -- are available for - interoperation with OLE VARIANT when using wxAutomationObject. + Under Microsoft Windows, three additional wxVariantData-derived classes -- + wxVariantDataCurrency, wxVariantDataErrorCode and wxVariantDataSafeArray -- + are available for interoperation with OLE VARIANT when using wxAutomationObject. Pointers to any wxObject derived class can also easily be stored in a wxVariant. wxVariant will then use wxWidgets' built-in RTTI system to set diff --git a/src/msw/ole/automtn.cpp b/src/msw/ole/automtn.cpp index 9c3600dd12..369dfec16f 100644 --- a/src/msw/ole/automtn.cpp +++ b/src/msw/ole/automtn.cpp @@ -222,6 +222,12 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, { vReturn.pdispVal = NULL; } + // Mustn't free the SAFEARRAY if it is contained in the retValue + if ((vReturn.vt & VT_ARRAY) && + retValue.GetType() == wxS("safearray")) + { + vReturn.parray = NULL; + } } } return true; diff --git a/src/msw/ole/oleutils.cpp b/src/msw/ole/oleutils.cpp index 30623186cf..293b4e68ba 100644 --- a/src/msw/ole/oleutils.cpp +++ b/src/msw/ole/oleutils.cpp @@ -48,6 +48,7 @@ #endif #include "wx/msw/ole/oleutils.h" +#include "wx/msw/ole/safearray.h" #if defined(__VISUALC__) && (__VISUALC__ > 1000) #include @@ -131,96 +132,6 @@ wxBasicString::~wxBasicString() #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 - - // ---------------------------------------------------------------------------- // wxVariantDataCurrency // ---------------------------------------------------------------------------- @@ -323,6 +234,52 @@ bool wxVariantDataErrorCode::Write(wxString& str) const } +// ---------------------------------------------------------------------------- +// wxVariantDataSafeArray +// ---------------------------------------------------------------------------- + +#if wxUSE_ANY + +bool wxVariantDataSafeArray::GetAsAny(wxAny* any) const +{ + *any = m_value; + return true; +} + +wxVariantData* wxVariantDataSafeArray::VariantDataFactory(const wxAny& any) +{ + return new wxVariantDataSafeArray(wxANY_AS(any, SAFEARRAY*)); +} + +REGISTER_WXANY_CONVERSION(SAFEARRAY*, wxVariantDataSafeArray) + +#endif // wxUSE_ANY + +bool wxVariantDataSafeArray::Eq(wxVariantData& data) const +{ + wxASSERT_MSG( (data.GetType() == wxS("safearray")), + "wxVariantDataSafeArray::Eq: argument mismatch" ); + + wxVariantDataSafeArray& otherData = (wxVariantDataSafeArray&) data; + + return otherData.m_value == m_value; +} + +#if wxUSE_STD_IOSTREAM +bool wxVariantDataSafeArray::Write(wxSTD ostream& str) const +{ + wxString s; + Write(s); + str << s; + return true; +} +#endif + +bool wxVariantDataSafeArray::Write(wxString& str) const +{ + str.Printf(wxS("SAFEARRAY: %p"), (void*)m_value); + return true; +} WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) { @@ -351,6 +308,25 @@ WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& ole oleVariant.vt = VT_CY; oleVariant.cyVal = c->GetValue(); } + else if (type == wxT("safearray")) + { + wxVariantDataSafeArray* const + vsa = wxStaticCastVariantData(variant.GetData(), + wxVariantDataSafeArray); + SAFEARRAY* psa = vsa->GetValue(); + VARTYPE vt; + + wxCHECK(psa, false); + HRESULT hr = SafeArrayGetVartype(psa, &vt); + if ( FAILED(hr) ) + { + wxLogApiError(wxS("SafeArrayGetVartype()"), hr); + SafeArrayDestroy(psa); + return false; + } + oleVariant.vt = vt | VT_ARRAY; + oleVariant.parray = psa; + } else if (type == wxT("long")) { oleVariant.vt = VT_I4; @@ -409,36 +385,22 @@ WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& ole } else if (type == wxT("list")) { - wxSafeArrayHelper sah; - - if (!sah.Create(VT_VARIANT, variant.GetCount())) + wxSafeArray safeArray; + if (!safeArray.CreateFromListVariant(variant)) return false; - for (size_t i = 0; i < variant.GetCount(); i++) - { - if (!sah.SetElement(i, variant[i])) - return false; - } - oleVariant.vt = VT_VARIANT | VT_ARRAY; - oleVariant.parray = sah.Detach(); + oleVariant.parray = safeArray.Detach(); } else if (type == wxT("arrstring")) { - wxArrayString strings(variant.GetArrayString()); - wxSafeArrayHelper sah; + wxSafeArray safeArray; - if (!sah.Create(VT_BSTR, strings.GetCount())) + if (!safeArray.CreateFromArrayString(variant.GetArrayString())) return false; - for (size_t i = 0; i < strings.GetCount(); i++) - { - if (!sah.SetElement(i, strings[i])) - return false; - } - oleVariant.vt = VT_BSTR | VT_ARRAY; - oleVariant.parray = sah.Detach(); + oleVariant.parray = safeArray.Detach(); } else { @@ -458,63 +420,53 @@ wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) bool ok = true; if ( oleVariant.vt & VT_ARRAY ) { - - // Compute the total number of elements in all array dimensions - int cElements = 1; - for ( int cDims = 0; cDims < oleVariant.parray->cDims; cDims++ ) - cElements *= oleVariant.parray->rgsabound[cDims].cElements; - - // Get a pointer to the data - void* pvdata; - HRESULT hr = SafeArrayAccessData(oleVariant.parray, &pvdata); - if ( FAILED(hr) ) - return false; - + // 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) { + 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: - { - variant.ClearList(); - VARIANTARG *variant_data=(VARIANTARG*)pvdata; - for ( int i = 0; i < cElements; i++ ) - { - VARIANTARG& oleElement = variant_data[i]; - wxVariant vElement; - if ( !wxConvertOleToVariant(oleElement, vElement) ) - { - ok = false; - variant.ClearList(); - break; - } - - variant.Append(vElement); - } - } + ok = wxSafeArray::ConvertToVariant(oleVariant.parray, variant); break; - case VT_BSTR: { wxArrayString strings; - BSTR *string_val=(BSTR*)pvdata; - for ( int i = 0; i < cElements; ++i ) - { - wxString str=wxConvertStringFromOle(*string_val); - strings.Add(str); - ++string_val; - } - variant=strings; + if ( wxSafeArray::ConvertToArrayString(oleVariant.parray, strings) ) + variant = strings; + else + ok = false; } break; - default: - wxLogDebug(wxT("unhandled VT_ARRAY type %x in wxConvertOleToVariant"), - oleVariant.vt & VT_TYPEMASK); - variant = wxVariant(); ok = false; break; } - - SafeArrayUnaccessData(oleVariant.parray); + 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/src/msw/ole/safearray.cpp b/src/msw/ole/safearray.cpp new file mode 100644 index 0000000000..c4061e75ab --- /dev/null +++ b/src/msw/ole/safearray.cpp @@ -0,0 +1,134 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: msw/ole/safearray.cpp +// Purpose: Implementation of wxSafeArrayBase class. +// Author: PB +// Created: 2012-09-23 +// RCS-ID: $Id$ +// Copyright: (c) 2012 wxWidgets development team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP + #include "wx/variant.h" +#endif // WX_PRECOMP + +#include "wx/msw/ole/safearray.h" + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxSafeArrayBase +// ---------------------------------------------------------------------------- + +void wxSafeArrayBase::Destroy() +{ + if ( m_array ) + { + Unlock(); + HRESULT hr = SafeArrayDestroy(m_array); + if ( FAILED(hr) ) + { + wxLogApiError(wxS("SafeArrayDestroy()"), hr); + } + m_array = NULL; + } +} + +SAFEARRAY* wxSafeArrayBase::Detach() +{ + wxCHECK_MSG( m_array, NULL, wxS("Uninitialized safe array") ); + + Unlock(); + SAFEARRAY* array = m_array; + m_array = NULL; + return array; +} + +size_t wxSafeArrayBase::GetDim() const +{ + wxASSERT( m_array ); + + return SafeArrayGetDim(m_array); +} + +bool wxSafeArrayBase::GetLBound(size_t dim, long& bound) const +{ + wxCHECK_MSG( m_array, false, wxS("Uninitialized safe array") ); + wxCHECK_MSG( dim > 0, false, wxS("Invalid dimension index") ); + + HRESULT hr = SafeArrayGetLBound(m_array, dim, &bound); + if ( FAILED(hr) ) + { + wxLogApiError(wxS("SafeArrayGetLBound()"), hr); + return false; + } + return true; +} + +bool wxSafeArrayBase::GetUBound(size_t dim, long& bound) const +{ + wxCHECK_MSG( m_array, false, wxS("Uninitialized safe array") ); + wxCHECK_MSG( dim > 0, false, wxS("Invalid dimension index") ); + + HRESULT hr = SafeArrayGetUBound(m_array, dim, &bound); + if ( FAILED(hr) ) + { + wxLogApiError(wxS("SafeArrayGetUBound()"), hr); + return false; + } + return true; +} + +size_t wxSafeArrayBase::GetCount(size_t dim) const +{ + long lBound, uBound; + + if ( GetLBound(dim, lBound) && GetUBound(dim, uBound) ) + return uBound - lBound + 1; + return 0; +} + +bool wxSafeArrayBase::Lock() +{ + wxCHECK_MSG( m_array, false, wxS("Uninitialized safe array") ); + + HRESULT hr = SafeArrayLock(m_array); + if ( FAILED(hr) ) + { + wxLogApiError(wxS("SafeArrayLock()"), hr); + return false; + } + return true; +} + +bool wxSafeArrayBase::Unlock() +{ + wxCHECK_MSG( m_array, false, wxS("Uninitialized safe array") ); + + HRESULT hr = SafeArrayUnlock(m_array); + if ( FAILED(hr) ) + { + wxLogApiError(wxS("SafeArrayUnlock()"), hr); + return false; + } + return true; +} + + -- 2.45.2