]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/ole/oleutils.cpp
8cf7899187bd82f42a82bb3a981610084a9896a6
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/ole/oleutils.cpp
3 // Purpose: implementation of OLE helper functions
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
23 #if defined(__BORLANDC__)
35 #include "wx/msw/private.h"
47 #include "wx/msw/ole/uuid.h"
50 #include "wx/msw/ole/oleutils.h"
52 #if defined(__VISUALC__) && (__VISUALC__ > 1000)
56 // ============================================================================
58 // ============================================================================
60 // return true if the iid is in the array
61 bool IsIidFromList(REFIID riid
, const IID
*aIids
[], size_t nCount
)
63 for ( size_t i
= 0; i
< nCount
; i
++ ) {
64 if ( riid
== *aIids
[i
] )
71 WXDLLEXPORT BSTR
wxConvertStringToOle(const wxString
& str
)
73 return wxBasicString(str
).Get();
76 WXDLLEXPORT wxString
wxConvertStringFromOle(BSTR bStr
)
78 // NULL BSTR is equivalent to an empty string (this is the convention used
79 // by VB and hence we must follow it)
83 const int len
= SysStringLen(bStr
);
86 wxString
str(bStr
, len
);
91 wxStringBufferLength
buf(str
, len
); // asserts if len == 0
92 buf
.SetLength(WideCharToMultiByte(CP_ACP
, 0 /* no flags */,
93 bStr
, len
/* not necessarily NUL-terminated */,
95 NULL
, NULL
/* no default char */));
102 // ----------------------------------------------------------------------------
104 // ----------------------------------------------------------------------------
106 wxBasicString::wxBasicString(const wxString
& str
)
108 m_bstrBuf
= SysAllocString(str
.wc_str(*wxConvCurrent
));
111 wxBasicString::wxBasicString(const wxBasicString
& src
)
113 m_bstrBuf
= src
.Get();
116 wxBasicString
& wxBasicString::operator=(const wxBasicString
& src
)
118 SysReAllocString(&m_bstrBuf
, src
);
122 wxBasicString::~wxBasicString()
124 SysFreeString(m_bstrBuf
);
128 // ----------------------------------------------------------------------------
130 // ----------------------------------------------------------------------------
137 * Zeros a variant structure without regard to current contents
139 void wxClearVariant(VARIANTARG
*pvarg
)
141 pvarg
->vt
= VT_EMPTY
;
142 pvarg
->wReserved1
= 0;
143 pvarg
->wReserved2
= 0;
144 pvarg
->wReserved3
= 0;
151 * Clears a particular variant structure and releases any external objects
152 * or memory contained in the variant. Supports the data types listed above.
154 void wxReleaseVariant(VARIANTARG
*pvarg
)
157 VARIANTARG _huge
*pvargArray
;
158 LONG lLBound
, lUBound
, l
;
160 vt
= (VARTYPE
)(pvarg
->vt
& 0xfff); // mask off flags
162 // check if an array. If so, free its contents, then the array itself.
163 if (V_ISARRAY(pvarg
))
165 // variant arrays are all this routine currently knows about. Since a
166 // variant can contain anything (even other arrays), call ourselves
168 if (vt
== VT_VARIANT
)
170 SafeArrayGetLBound(pvarg
->parray
, 1, &lLBound
);
171 SafeArrayGetUBound(pvarg
->parray
, 1, &lUBound
);
173 if (lUBound
> lLBound
)
177 SafeArrayAccessData(pvarg
->parray
, (void**)&pvargArray
);
179 for (l
= 0; l
< lUBound
; l
++)
181 wxReleaseVariant(pvargArray
);
185 SafeArrayUnaccessData(pvarg
->parray
);
190 wxLogWarning(wxT("wxReleaseVariant: Array contains non-variant type"));
193 // Free the array itself.
194 SafeArrayDestroy(pvarg
->parray
);
202 pvarg
->pdispVal
->Release();
206 SysFreeString(pvarg
->bstrVal
);
213 case VT_ERROR
: // to avoid erroring on an error return from Excel
216 // no work for these types
220 wxLogWarning(wxT("wxReleaseVariant: Unknown type"));
225 wxClearVariant(pvarg
);
228 WXDLLEXPORT
bool wxConvertVariantToOle(const wxVariant
& variant
, VARIANTARG
& oleVariant
)
230 wxClearVariant(&oleVariant
);
231 if (variant
.IsNull())
233 oleVariant
.vt
= VT_NULL
;
237 wxString
type(variant
.GetType());
240 if (type
== wxT("long"))
242 oleVariant
.vt
= VT_I4
;
243 oleVariant
.lVal
= variant
.GetLong() ;
245 // cVal not always present
247 else if (type
== wxT("char"))
249 oleVariant
.vt
=VT_I1
; // Signed Char
250 oleVariant
.cVal
=variant
.GetChar();
253 else if (type
== wxT("double"))
255 oleVariant
.vt
= VT_R8
;
256 oleVariant
.dblVal
= variant
.GetDouble();
258 else if (type
== wxT("bool"))
260 oleVariant
.vt
= VT_BOOL
;
261 // 'bool' required for VC++ 4 apparently
262 #if (defined(__VISUALC__) && (__VISUALC__ <= 1000))
263 oleVariant
.bool = variant
.GetBool();
265 oleVariant
.boolVal
= variant
.GetBool();
268 else if (type
== wxT("string"))
270 wxString
str( variant
.GetString() );
271 oleVariant
.vt
= VT_BSTR
;
272 oleVariant
.bstrVal
= wxConvertStringToOle(str
);
275 else if (type
== wxT("datetime"))
277 wxDateTime
date( variant
.GetDateTime() );
278 oleVariant
.vt
= VT_DATE
;
281 date
.GetAsMSWSysTime(&st
);
283 SystemTimeToVariantTime(&st
, &oleVariant
.date
);
286 else if (type
== wxT("void*"))
288 oleVariant
.vt
= VT_DISPATCH
;
289 oleVariant
.pdispVal
= (IDispatch
*) variant
.GetVoidPtr();
291 else if (type
== wxT("list") || type
== wxT("stringlist"))
293 oleVariant
.vt
= VT_VARIANT
| VT_ARRAY
;
296 SAFEARRAYBOUND saBound
;
297 VARIANTARG
*pvargBase
;
301 int iCount
= variant
.GetCount();
304 saBound
.cElements
= iCount
;
306 psa
= SafeArrayCreate(VT_VARIANT
, 1, &saBound
);
310 SafeArrayAccessData(psa
, (void**)&pvargBase
);
313 for (i
= 0; i
< iCount
; i
++)
315 // copy each string in the list of strings
316 wxVariant
eachVariant(variant
[i
]);
317 if (!wxConvertVariantToOle(eachVariant
, * pvarg
))
319 // memory failure: back out and free strings alloc'ed up to
320 // now, and then the array itself.
322 for (j
= 0; j
< i
; j
++)
324 SysFreeString(pvarg
->bstrVal
);
327 SafeArrayDestroy(psa
);
333 SafeArrayUnaccessData(psa
);
335 oleVariant
.parray
= psa
;
339 oleVariant
.vt
= VT_NULL
;
346 #define VT_TYPEMASK 0xfff
350 wxConvertOleToVariant(const VARIANTARG
& oleVariant
, wxVariant
& variant
)
353 if ( oleVariant
.vt
& VT_ARRAY
)
356 // Compute the total number of elements in all array dimensions
358 for ( int cDims
= 0; cDims
< oleVariant
.parray
->cDims
; cDims
++ )
359 cElements
*= oleVariant
.parray
->rgsabound
[cDims
].cElements
;
361 // Get a pointer to the data
363 HRESULT hr
= SafeArrayAccessData(oleVariant
.parray
, &pvdata
);
367 switch (oleVariant
.vt
& VT_TYPEMASK
)
372 VARIANTARG
*variant_data
=(VARIANTARG
*)pvdata
;
373 for ( int i
= 0; i
< cElements
; i
++ )
375 VARIANTARG
& oleElement
= variant_data
[i
];
377 if ( !wxConvertOleToVariant(oleElement
, vElement
) )
384 variant
.Append(vElement
);
391 wxArrayString strings
;
392 BSTR
*string_val
=(BSTR
*)pvdata
;
393 for ( int i
= 0; i
< cElements
; ++i
)
395 wxString str
=wxConvertStringFromOle(*string_val
);
404 wxLogDebug(wxT("unhandled VT_ARRAY type %x in wxConvertOleToVariant"),
405 oleVariant
.vt
& VT_TYPEMASK
);
406 variant
= wxVariant();
411 SafeArrayUnaccessData(oleVariant
.parray
);
413 else if ( oleVariant
.vt
& VT_BYREF
)
415 switch ( oleVariant
.vt
& VT_TYPEMASK
)
419 VARIANTARG
& oleReference
= *((LPVARIANT
)oleVariant
.byref
);
420 if (!wxConvertOleToVariant(oleReference
,variant
))
426 wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: [as yet] unhandled reference %X"),
431 else // simply type (not array or reference)
433 switch ( oleVariant
.vt
& VT_TYPEMASK
)
437 wxString
str(wxConvertStringFromOle(oleVariant
.bstrVal
));
446 VariantTimeToSystemTime(oleVariant
.date
, &st
);
449 date
.SetFromMSWSysTime(st
);
452 #endif // wxUSE_DATETIME
456 variant
= (long) oleVariant
.lVal
;
460 variant
= (long) oleVariant
.iVal
;
464 variant
= oleVariant
.boolVal
!= 0;
468 variant
= oleVariant
.dblVal
;
472 variant
= (void*) oleVariant
.pdispVal
;
480 break; // Ignore Empty Variant, used only during destruction of objects
483 wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: Unknown variant value type %X -> %X"),
484 oleVariant
.vt
,oleVariant
.vt
&VT_TYPEMASK
);
492 #endif // wxUSE_VARIANT
495 // ----------------------------------------------------------------------------
497 // ----------------------------------------------------------------------------
501 #if wxDEBUG_LEVEL && ( ( defined(__VISUALC__) && (__VISUALC__ > 1000) ) || defined(__MWERKS__) )
502 static wxString
GetIidName(REFIID riid
)
504 // an association between symbolic name and numeric value of an IID
507 const wxChar
*szName
;
510 // construct the table containing all known interfaces
511 #define ADD_KNOWN_IID(name) { &IID_I##name, wxT(#name) }
513 static const KNOWN_IID aKnownIids
[] = {
514 ADD_KNOWN_IID(AdviseSink
),
515 ADD_KNOWN_IID(AdviseSink2
),
516 ADD_KNOWN_IID(BindCtx
),
517 ADD_KNOWN_IID(ClassFactory
),
518 #if ( !defined( __VISUALC__) || (__VISUALC__!=1010) ) && !defined(__MWERKS__)
519 ADD_KNOWN_IID(ContinueCallback
),
520 ADD_KNOWN_IID(EnumOleDocumentViews
),
521 ADD_KNOWN_IID(OleCommandTarget
),
522 ADD_KNOWN_IID(OleDocument
),
523 ADD_KNOWN_IID(OleDocumentSite
),
524 ADD_KNOWN_IID(OleDocumentView
),
525 ADD_KNOWN_IID(Print
),
527 ADD_KNOWN_IID(DataAdviseHolder
),
528 ADD_KNOWN_IID(DataObject
),
529 ADD_KNOWN_IID(Debug
),
530 ADD_KNOWN_IID(DebugStream
),
531 ADD_KNOWN_IID(DfReserved1
),
532 ADD_KNOWN_IID(DfReserved2
),
533 ADD_KNOWN_IID(DfReserved3
),
534 ADD_KNOWN_IID(Dispatch
),
535 ADD_KNOWN_IID(DropSource
),
536 ADD_KNOWN_IID(DropTarget
),
537 ADD_KNOWN_IID(EnumCallback
),
538 ADD_KNOWN_IID(EnumFORMATETC
),
539 ADD_KNOWN_IID(EnumGeneric
),
540 ADD_KNOWN_IID(EnumHolder
),
541 ADD_KNOWN_IID(EnumMoniker
),
542 ADD_KNOWN_IID(EnumOLEVERB
),
543 ADD_KNOWN_IID(EnumSTATDATA
),
544 ADD_KNOWN_IID(EnumSTATSTG
),
545 ADD_KNOWN_IID(EnumString
),
546 ADD_KNOWN_IID(EnumUnknown
),
547 ADD_KNOWN_IID(EnumVARIANT
),
548 ADD_KNOWN_IID(ExternalConnection
),
549 ADD_KNOWN_IID(InternalMoniker
),
550 ADD_KNOWN_IID(LockBytes
),
551 ADD_KNOWN_IID(Malloc
),
552 ADD_KNOWN_IID(Marshal
),
553 ADD_KNOWN_IID(MessageFilter
),
554 ADD_KNOWN_IID(Moniker
),
555 ADD_KNOWN_IID(OleAdviseHolder
),
556 ADD_KNOWN_IID(OleCache
),
557 ADD_KNOWN_IID(OleCache2
),
558 ADD_KNOWN_IID(OleCacheControl
),
559 ADD_KNOWN_IID(OleClientSite
),
560 ADD_KNOWN_IID(OleContainer
),
561 ADD_KNOWN_IID(OleInPlaceActiveObject
),
562 ADD_KNOWN_IID(OleInPlaceFrame
),
563 ADD_KNOWN_IID(OleInPlaceObject
),
564 ADD_KNOWN_IID(OleInPlaceSite
),
565 ADD_KNOWN_IID(OleInPlaceUIWindow
),
566 ADD_KNOWN_IID(OleItemContainer
),
567 ADD_KNOWN_IID(OleLink
),
568 ADD_KNOWN_IID(OleManager
),
569 ADD_KNOWN_IID(OleObject
),
570 ADD_KNOWN_IID(OlePresObj
),
571 ADD_KNOWN_IID(OleWindow
),
572 ADD_KNOWN_IID(PSFactory
),
573 ADD_KNOWN_IID(ParseDisplayName
),
574 ADD_KNOWN_IID(Persist
),
575 ADD_KNOWN_IID(PersistFile
),
576 ADD_KNOWN_IID(PersistStorage
),
577 ADD_KNOWN_IID(PersistStream
),
578 ADD_KNOWN_IID(ProxyManager
),
579 ADD_KNOWN_IID(RootStorage
),
580 ADD_KNOWN_IID(RpcChannel
),
581 ADD_KNOWN_IID(RpcProxy
),
582 ADD_KNOWN_IID(RpcStub
),
583 ADD_KNOWN_IID(RunnableObject
),
584 ADD_KNOWN_IID(RunningObjectTable
),
585 ADD_KNOWN_IID(StdMarshalInfo
),
586 ADD_KNOWN_IID(Storage
),
587 ADD_KNOWN_IID(Stream
),
588 ADD_KNOWN_IID(StubManager
),
589 ADD_KNOWN_IID(Unknown
),
590 ADD_KNOWN_IID(ViewObject
),
591 ADD_KNOWN_IID(ViewObject2
),
594 // don't clobber preprocessor name space
597 // try to find the interface in the table
598 for ( size_t ui
= 0; ui
< WXSIZEOF(aKnownIids
); ui
++ ) {
599 if ( riid
== *aKnownIids
[ui
].pIid
) {
600 return aKnownIids
[ui
].szName
;
605 // unknown IID, just transform to string
607 return wxString((const wxChar
*)uuid
);
609 return wxEmptyString
;
613 void wxLogQueryInterface(const wxChar
*szInterface
, REFIID riid
)
615 wxLogTrace(wxTRACE_OleCalls
, wxT("%s::QueryInterface (iid = %s)"),
616 szInterface
, GetIidName(riid
).c_str());
619 void wxLogAddRef(const wxChar
*szInterface
, ULONG cRef
)
621 wxLogTrace(wxTRACE_OleCalls
, wxT("After %s::AddRef: m_cRef = %d"), szInterface
, cRef
+ 1);
624 void wxLogRelease(const wxChar
*szInterface
, ULONG cRef
)
626 wxLogTrace(wxTRACE_OleCalls
, wxT("After %s::Release: m_cRef = %d"), szInterface
, cRef
- 1);
629 #endif // wxDEBUG_LEVEL
631 #endif // wxUSE_DATAOBJ
633 #endif // __CYGWIN10__