]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/ole/oleutils.cpp
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 WXDLLEXPORT
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 // ----------------------------------------------------------------------------
134 WXDLLEXPORT
bool wxConvertVariantToOle(const wxVariant
& variant
, VARIANTARG
& oleVariant
)
136 VariantInit(&oleVariant
);
137 if (variant
.IsNull())
139 oleVariant
.vt
= VT_NULL
;
143 wxString
type(variant
.GetType());
146 if (type
== wxT("long"))
148 oleVariant
.vt
= VT_I4
;
149 oleVariant
.lVal
= variant
.GetLong() ;
151 // Original VC6 came with SDK too old to contain VARIANT::llVal declaration
152 // and there doesn't seem to be any way to test for it as Microsoft simply
153 // added it to the later version of oaidl.h without changing anything else.
154 // So assume it's not present for VC6, even though it might be if an
155 // updated SDK is used. In this case the user would need to disable this
157 #if wxUSE_LONGLONG && !defined(__VISUALC6__)
158 else if (type
== wxT("longlong"))
160 oleVariant
.vt
= VT_I8
;
161 oleVariant
.llVal
= variant
.GetLongLong().GetValue();
164 else if (type
== wxT("char"))
166 oleVariant
.vt
=VT_I1
; // Signed Char
167 oleVariant
.cVal
=variant
.GetChar();
169 else if (type
== wxT("double"))
171 oleVariant
.vt
= VT_R8
;
172 oleVariant
.dblVal
= variant
.GetDouble();
174 else if (type
== wxT("bool"))
176 oleVariant
.vt
= VT_BOOL
;
177 oleVariant
.boolVal
= variant
.GetBool() ? VARIANT_TRUE
: VARIANT_FALSE
;
179 else if (type
== wxT("string"))
181 wxString
str( variant
.GetString() );
182 oleVariant
.vt
= VT_BSTR
;
183 oleVariant
.bstrVal
= wxConvertStringToOle(str
);
186 else if (type
== wxT("datetime"))
188 wxDateTime
date( variant
.GetDateTime() );
189 oleVariant
.vt
= VT_DATE
;
192 date
.GetAsMSWSysTime(&st
);
194 SystemTimeToVariantTime(&st
, &oleVariant
.date
);
197 else if (type
== wxT("void*"))
199 oleVariant
.vt
= VT_DISPATCH
;
200 oleVariant
.pdispVal
= (IDispatch
*) variant
.GetVoidPtr();
202 else if (type
== wxT("list") || type
== wxT("arrstring"))
205 SAFEARRAYBOUND saBound
;
206 bool isArrString
= type
== wxT("arrstring");
207 wxArrayString strings
;
210 strings
= variant
.GetArrayString();
211 oleVariant
.vt
= (isArrString
? VT_BSTR
: VT_VARIANT
) | VT_ARRAY
;
213 long lCount
= isArrString
? strings
.GetCount() : variant
.GetCount();
215 saBound
.cElements
= lCount
;
216 psa
= SafeArrayCreate(isArrString
? VT_BSTR
: VT_VARIANT
, 1, &saBound
);
221 for (i
= 0; i
< lCount
; i
++)
225 wxBasicString
bstr(strings
[i
]);
226 if ( !bstr
&& !strings
[i
].empty() )
228 // BSTR can be NULL for empty strings but if the string was
229 // not empty, it means we failed to allocate memory for it.
233 if ( FAILED(SafeArrayPutElement(psa
, &i
, (BSTR
)bstr
)) )
236 else // list of wxVariants
239 if ( !wxConvertVariantToOle(variant
[i
], v
) )
242 HRESULT hr
= SafeArrayPutElement(psa
, &i
, &v
);
244 // SafeArrayPutElement makes a copy of an added element, so
253 if (i
< lCount
) // the iteration was exited prematurely because of an error
255 SafeArrayDestroy(psa
);
259 oleVariant
.parray
= psa
;
263 oleVariant
.vt
= VT_NULL
;
270 #define VT_TYPEMASK 0xfff
274 wxConvertOleToVariant(const VARIANTARG
& oleVariant
, wxVariant
& variant
)
277 if ( oleVariant
.vt
& VT_ARRAY
)
280 // Compute the total number of elements in all array dimensions
282 for ( int cDims
= 0; cDims
< oleVariant
.parray
->cDims
; cDims
++ )
283 cElements
*= oleVariant
.parray
->rgsabound
[cDims
].cElements
;
285 // Get a pointer to the data
287 HRESULT hr
= SafeArrayAccessData(oleVariant
.parray
, &pvdata
);
291 switch (oleVariant
.vt
& VT_TYPEMASK
)
296 VARIANTARG
*variant_data
=(VARIANTARG
*)pvdata
;
297 for ( int i
= 0; i
< cElements
; i
++ )
299 VARIANTARG
& oleElement
= variant_data
[i
];
301 if ( !wxConvertOleToVariant(oleElement
, vElement
) )
308 variant
.Append(vElement
);
315 wxArrayString strings
;
316 BSTR
*string_val
=(BSTR
*)pvdata
;
317 for ( int i
= 0; i
< cElements
; ++i
)
319 wxString str
=wxConvertStringFromOle(*string_val
);
328 wxLogDebug(wxT("unhandled VT_ARRAY type %x in wxConvertOleToVariant"),
329 oleVariant
.vt
& VT_TYPEMASK
);
330 variant
= wxVariant();
335 SafeArrayUnaccessData(oleVariant
.parray
);
337 else if ( oleVariant
.vt
& VT_BYREF
)
339 switch ( oleVariant
.vt
& VT_TYPEMASK
)
343 VARIANTARG
& oleReference
= *((LPVARIANT
)oleVariant
.byref
);
344 if (!wxConvertOleToVariant(oleReference
,variant
))
350 wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: [as yet] unhandled reference %X"),
355 else // simply type (not array or reference)
357 switch ( oleVariant
.vt
& VT_TYPEMASK
)
361 wxString
str(wxConvertStringFromOle(oleVariant
.bstrVal
));
370 VariantTimeToSystemTime(oleVariant
.date
, &st
);
373 date
.SetFromMSWSysTime(st
);
376 #endif // wxUSE_DATETIME
379 // See the comment before the __VISUALC6__ test above.
380 #if wxUSE_LONGLONG && !defined(__VISUALC6__)
382 variant
= wxLongLong(oleVariant
.llVal
);
384 #endif // wxUSE_LONGLONG
387 variant
= (long) oleVariant
.lVal
;
391 variant
= (long) oleVariant
.iVal
;
395 variant
= oleVariant
.boolVal
!= 0;
399 variant
= oleVariant
.fltVal
;
403 variant
= oleVariant
.dblVal
;
407 variant
= (void*) oleVariant
.pdispVal
;
415 break; // Ignore Empty Variant, used only during destruction of objects
418 wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: Unknown variant value type %X -> %X"),
419 oleVariant
.vt
,oleVariant
.vt
&VT_TYPEMASK
);
427 #endif // wxUSE_VARIANT
430 // ----------------------------------------------------------------------------
432 // ----------------------------------------------------------------------------
436 #if wxDEBUG_LEVEL && (( defined(__VISUALC__) && (__VISUALC__ > 1000) ))
437 static wxString
GetIidName(REFIID riid
)
439 // an association between symbolic name and numeric value of an IID
442 const wxChar
*szName
;
445 // construct the table containing all known interfaces
446 #define ADD_KNOWN_IID(name) { &IID_I##name, wxT(#name) }
448 static const KNOWN_IID aKnownIids
[] = {
449 ADD_KNOWN_IID(AdviseSink
),
450 ADD_KNOWN_IID(AdviseSink2
),
451 ADD_KNOWN_IID(BindCtx
),
452 ADD_KNOWN_IID(ClassFactory
),
453 #if ( !defined( __VISUALC__) || (__VISUALC__!=1010) )
454 ADD_KNOWN_IID(ContinueCallback
),
455 ADD_KNOWN_IID(EnumOleDocumentViews
),
456 ADD_KNOWN_IID(OleCommandTarget
),
457 ADD_KNOWN_IID(OleDocument
),
458 ADD_KNOWN_IID(OleDocumentSite
),
459 ADD_KNOWN_IID(OleDocumentView
),
460 ADD_KNOWN_IID(Print
),
462 ADD_KNOWN_IID(DataAdviseHolder
),
463 ADD_KNOWN_IID(DataObject
),
464 ADD_KNOWN_IID(Debug
),
465 ADD_KNOWN_IID(DebugStream
),
466 ADD_KNOWN_IID(DfReserved1
),
467 ADD_KNOWN_IID(DfReserved2
),
468 ADD_KNOWN_IID(DfReserved3
),
469 ADD_KNOWN_IID(Dispatch
),
470 ADD_KNOWN_IID(DropSource
),
471 ADD_KNOWN_IID(DropTarget
),
472 ADD_KNOWN_IID(EnumCallback
),
473 ADD_KNOWN_IID(EnumFORMATETC
),
474 ADD_KNOWN_IID(EnumGeneric
),
475 ADD_KNOWN_IID(EnumHolder
),
476 ADD_KNOWN_IID(EnumMoniker
),
477 ADD_KNOWN_IID(EnumOLEVERB
),
478 ADD_KNOWN_IID(EnumSTATDATA
),
479 ADD_KNOWN_IID(EnumSTATSTG
),
480 ADD_KNOWN_IID(EnumString
),
481 ADD_KNOWN_IID(EnumUnknown
),
482 ADD_KNOWN_IID(EnumVARIANT
),
483 ADD_KNOWN_IID(ExternalConnection
),
484 ADD_KNOWN_IID(InternalMoniker
),
485 ADD_KNOWN_IID(LockBytes
),
486 ADD_KNOWN_IID(Malloc
),
487 ADD_KNOWN_IID(Marshal
),
488 ADD_KNOWN_IID(MessageFilter
),
489 ADD_KNOWN_IID(Moniker
),
490 ADD_KNOWN_IID(OleAdviseHolder
),
491 ADD_KNOWN_IID(OleCache
),
492 ADD_KNOWN_IID(OleCache2
),
493 ADD_KNOWN_IID(OleCacheControl
),
494 ADD_KNOWN_IID(OleClientSite
),
495 ADD_KNOWN_IID(OleContainer
),
496 ADD_KNOWN_IID(OleInPlaceActiveObject
),
497 ADD_KNOWN_IID(OleInPlaceFrame
),
498 ADD_KNOWN_IID(OleInPlaceObject
),
499 ADD_KNOWN_IID(OleInPlaceSite
),
500 ADD_KNOWN_IID(OleInPlaceUIWindow
),
501 ADD_KNOWN_IID(OleItemContainer
),
502 ADD_KNOWN_IID(OleLink
),
503 ADD_KNOWN_IID(OleManager
),
504 ADD_KNOWN_IID(OleObject
),
505 ADD_KNOWN_IID(OlePresObj
),
506 ADD_KNOWN_IID(OleWindow
),
507 ADD_KNOWN_IID(PSFactory
),
508 ADD_KNOWN_IID(ParseDisplayName
),
509 ADD_KNOWN_IID(Persist
),
510 ADD_KNOWN_IID(PersistFile
),
511 ADD_KNOWN_IID(PersistStorage
),
512 ADD_KNOWN_IID(PersistStream
),
513 ADD_KNOWN_IID(ProxyManager
),
514 ADD_KNOWN_IID(RootStorage
),
515 ADD_KNOWN_IID(RpcChannel
),
516 ADD_KNOWN_IID(RpcProxy
),
517 ADD_KNOWN_IID(RpcStub
),
518 ADD_KNOWN_IID(RunnableObject
),
519 ADD_KNOWN_IID(RunningObjectTable
),
520 ADD_KNOWN_IID(StdMarshalInfo
),
521 ADD_KNOWN_IID(Storage
),
522 ADD_KNOWN_IID(Stream
),
523 ADD_KNOWN_IID(StubManager
),
524 ADD_KNOWN_IID(Unknown
),
525 ADD_KNOWN_IID(ViewObject
),
526 ADD_KNOWN_IID(ViewObject2
),
529 // don't clobber preprocessor name space
532 // try to find the interface in the table
533 for ( size_t ui
= 0; ui
< WXSIZEOF(aKnownIids
); ui
++ ) {
534 if ( riid
== *aKnownIids
[ui
].pIid
) {
535 return aKnownIids
[ui
].szName
;
540 // unknown IID, just transform to string
542 return wxString((const wxChar
*)uuid
);
544 return wxEmptyString
;
548 WXDLLEXPORT
void wxLogQueryInterface(const wxChar
*szInterface
, REFIID riid
)
550 wxLogTrace(wxTRACE_OleCalls
, wxT("%s::QueryInterface (iid = %s)"),
551 szInterface
, GetIidName(riid
).c_str());
554 WXDLLEXPORT
void wxLogAddRef(const wxChar
*szInterface
, ULONG cRef
)
556 wxLogTrace(wxTRACE_OleCalls
, wxT("After %s::AddRef: m_cRef = %d"), szInterface
, cRef
+ 1);
559 WXDLLEXPORT
void wxLogRelease(const wxChar
*szInterface
, ULONG cRef
)
561 wxLogTrace(wxTRACE_OleCalls
, wxT("After %s::Release: m_cRef = %d"), szInterface
, cRef
- 1);
564 #endif // wxDEBUG_LEVEL
566 #endif // wxUSE_DATAOBJ
568 #endif // __CYGWIN10__