1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/msw/ole/oleutils.cpp
3 // Purpose:     implementation of OLE helper functions
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     19.02.98
7 // RCS-ID:      $Id: oleutils.cpp 59208 2009-02-28 19:34:30Z VZ $
8 // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence:     wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 // ============================================================================
13 // Declarations
14 // ============================================================================
15 
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19 
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22 
23 #if defined(__BORLANDC__)
24     #pragma hdrstop
25 #endif
26 
27 #if wxUSE_OLE
28 
29 #ifndef WX_PRECOMP
30     #include "wx/log.h"
31 #endif
32 
33 #ifndef __CYGWIN10__
34 
35 #include "wx/msw/private.h"
36 
37 #ifdef __WXWINCE__
38     #include <winreg.h>
39     #include <ole2.h>
40 
41     #define GUID_DEFINED
42     #define UUID_DEFINED
43 #endif
44 
45 // OLE
46 #ifndef __WXWINCE__
47 #include  "wx/msw/ole/uuid.h"
48 #endif
49 
50 #include  "wx/msw/ole/oleutils.h"
51 
52 #if defined(__VISUALC__) && (__VISUALC__ > 1000)
53     #include  <docobj.h>
54 #endif
55 
56 // ============================================================================
57 // Implementation
58 // ============================================================================
59 
60 // return true if the iid is in the array
IsIidFromList(REFIID riid,const IID * aIids[],size_t nCount)61 bool IsIidFromList(REFIID riid, const IID *aIids[], size_t nCount)
62 {
63   for ( size_t i = 0; i < nCount; i++ ) {
64     if ( riid == *aIids[i] )
65       return true;
66   }
67 
68   return false;
69 }
70 
wxConvertStringToOle(const wxString & str)71 WXDLLEXPORT BSTR wxConvertStringToOle(const wxString& str)
72 {
73 /*
74     unsigned int len = strlen((const char*) str);
75     unsigned short* s = new unsigned short[len*2+2];
76     unsigned int i;
77     memset(s, 0, len*2+2);
78     for (i=0; i < len; i++)
79         s[i*2] = str[i];
80 */
81     wxBasicString bstr(str.mb_str());
82     return bstr.Get();
83 }
84 
wxConvertStringFromOle(BSTR bStr)85 WXDLLEXPORT wxString wxConvertStringFromOle(BSTR bStr)
86 {
87     // NULL BSTR is equivalent to an empty string (this is the convention used
88     // by VB and hence we must follow it)
89     if ( !bStr )
90         return wxString();
91 
92     const int len = SysStringLen(bStr);
93 
94 #if wxUSE_UNICODE
95     wxString str(bStr, len);
96 #else
97     wxString str;
98     if (len)
99     {
100         wxStringBufferLength buf(str, len); // asserts if len == 0
101         buf.SetLength(WideCharToMultiByte(CP_ACP, 0 /* no flags */,
102                                   bStr, len /* not necessarily NUL-terminated */,
103                                   buf, len,
104                                   NULL, NULL /* no default char */));
105     }
106 #endif
107 
108     return str;
109 }
110 
111 // ----------------------------------------------------------------------------
112 // wxBasicString
113 // ----------------------------------------------------------------------------
114 
115 // ctor takes an ANSI string and transforms it to Unicode
wxBasicString(const char * sz)116 wxBasicString::wxBasicString(const char *sz)
117 {
118     Init(sz);
119 }
120 
121 // ctor takes an ANSI or Unicode string and transforms it to Unicode
wxBasicString(const wxString & str)122 wxBasicString::wxBasicString(const wxString& str)
123 {
124 #if wxUSE_UNICODE
125     m_wzBuf = new OLECHAR[str.length() + 1];
126     memcpy(m_wzBuf, str.c_str(), str.length()*2);
127     m_wzBuf[str.length()] = L'\0';
128 #else
129     Init(str.c_str());
130 #endif
131 }
132 
133 // Takes an ANSI string and transforms it to Unicode
Init(const char * sz)134 void wxBasicString::Init(const char *sz)
135 {
136     // get the size of required buffer: MetroWerks and Cygwin crash if NULL is
137     // passed to mbstowcs()
138     UINT lenAnsi = strlen(sz);
139 #if defined(__MWERKS__) || defined(__CYGWIN__)
140     UINT lenWide = lenAnsi * 2 ;
141 #else
142     UINT lenWide = mbstowcs(NULL, sz, lenAnsi);
143 #endif
144 
145     if ( lenWide > 0 ) {
146         m_wzBuf = new OLECHAR[lenWide + 1];
147         mbstowcs(m_wzBuf, sz, lenAnsi);
148         m_wzBuf[lenWide] = L'\0';
149     }
150     else {
151         m_wzBuf = NULL;
152     }
153 }
154 
155 // dtor frees memory
~wxBasicString()156 wxBasicString::~wxBasicString()
157 {
158   delete [] m_wzBuf;
159 }
160 
161 #if wxUSE_DATAOBJ
162 
163 // ----------------------------------------------------------------------------
164 // Debug support
165 // ----------------------------------------------------------------------------
166 
167 #if defined(__WXDEBUG__) && ( ( defined(__VISUALC__) && (__VISUALC__ > 1000) ) || defined(__MWERKS__) )
GetIidName(REFIID riid)168 static wxString GetIidName(REFIID riid)
169 {
170   // an association between symbolic name and numeric value of an IID
171   struct KNOWN_IID {
172     const IID  *pIid;
173     const wxChar *szName;
174   };
175 
176   // construct the table containing all known interfaces
177   #define ADD_KNOWN_IID(name) { &IID_I##name, _T(#name) }
178 
179   static const KNOWN_IID aKnownIids[] = {
180     ADD_KNOWN_IID(AdviseSink),
181     ADD_KNOWN_IID(AdviseSink2),
182     ADD_KNOWN_IID(BindCtx),
183     ADD_KNOWN_IID(ClassFactory),
184 #if ( !defined( __VISUALC__) || (__VISUALC__!=1010) ) && !defined(__MWERKS__)
185     ADD_KNOWN_IID(ContinueCallback),
186     ADD_KNOWN_IID(EnumOleDocumentViews),
187     ADD_KNOWN_IID(OleCommandTarget),
188     ADD_KNOWN_IID(OleDocument),
189     ADD_KNOWN_IID(OleDocumentSite),
190     ADD_KNOWN_IID(OleDocumentView),
191     ADD_KNOWN_IID(Print),
192 #endif
193     ADD_KNOWN_IID(DataAdviseHolder),
194     ADD_KNOWN_IID(DataObject),
195     ADD_KNOWN_IID(Debug),
196     ADD_KNOWN_IID(DebugStream),
197     ADD_KNOWN_IID(DfReserved1),
198     ADD_KNOWN_IID(DfReserved2),
199     ADD_KNOWN_IID(DfReserved3),
200     ADD_KNOWN_IID(Dispatch),
201     ADD_KNOWN_IID(DropSource),
202     ADD_KNOWN_IID(DropTarget),
203     ADD_KNOWN_IID(EnumCallback),
204     ADD_KNOWN_IID(EnumFORMATETC),
205     ADD_KNOWN_IID(EnumGeneric),
206     ADD_KNOWN_IID(EnumHolder),
207     ADD_KNOWN_IID(EnumMoniker),
208     ADD_KNOWN_IID(EnumOLEVERB),
209     ADD_KNOWN_IID(EnumSTATDATA),
210     ADD_KNOWN_IID(EnumSTATSTG),
211     ADD_KNOWN_IID(EnumString),
212     ADD_KNOWN_IID(EnumUnknown),
213     ADD_KNOWN_IID(EnumVARIANT),
214     ADD_KNOWN_IID(ExternalConnection),
215     ADD_KNOWN_IID(InternalMoniker),
216     ADD_KNOWN_IID(LockBytes),
217     ADD_KNOWN_IID(Malloc),
218     ADD_KNOWN_IID(Marshal),
219     ADD_KNOWN_IID(MessageFilter),
220     ADD_KNOWN_IID(Moniker),
221     ADD_KNOWN_IID(OleAdviseHolder),
222     ADD_KNOWN_IID(OleCache),
223     ADD_KNOWN_IID(OleCache2),
224     ADD_KNOWN_IID(OleCacheControl),
225     ADD_KNOWN_IID(OleClientSite),
226     ADD_KNOWN_IID(OleContainer),
227     ADD_KNOWN_IID(OleInPlaceActiveObject),
228     ADD_KNOWN_IID(OleInPlaceFrame),
229     ADD_KNOWN_IID(OleInPlaceObject),
230     ADD_KNOWN_IID(OleInPlaceSite),
231     ADD_KNOWN_IID(OleInPlaceUIWindow),
232     ADD_KNOWN_IID(OleItemContainer),
233     ADD_KNOWN_IID(OleLink),
234     ADD_KNOWN_IID(OleManager),
235     ADD_KNOWN_IID(OleObject),
236     ADD_KNOWN_IID(OlePresObj),
237     ADD_KNOWN_IID(OleWindow),
238     ADD_KNOWN_IID(PSFactory),
239     ADD_KNOWN_IID(ParseDisplayName),
240     ADD_KNOWN_IID(Persist),
241     ADD_KNOWN_IID(PersistFile),
242     ADD_KNOWN_IID(PersistStorage),
243     ADD_KNOWN_IID(PersistStream),
244     ADD_KNOWN_IID(ProxyManager),
245     ADD_KNOWN_IID(RootStorage),
246     ADD_KNOWN_IID(RpcChannel),
247     ADD_KNOWN_IID(RpcProxy),
248     ADD_KNOWN_IID(RpcStub),
249     ADD_KNOWN_IID(RunnableObject),
250     ADD_KNOWN_IID(RunningObjectTable),
251     ADD_KNOWN_IID(StdMarshalInfo),
252     ADD_KNOWN_IID(Storage),
253     ADD_KNOWN_IID(Stream),
254     ADD_KNOWN_IID(StubManager),
255     ADD_KNOWN_IID(Unknown),
256     ADD_KNOWN_IID(ViewObject),
257     ADD_KNOWN_IID(ViewObject2),
258   };
259 
260   // don't clobber preprocessor name space
261   #undef ADD_KNOWN_IID
262 
263   // try to find the interface in the table
264   for ( size_t ui = 0; ui < WXSIZEOF(aKnownIids); ui++ ) {
265     if ( riid == *aKnownIids[ui].pIid ) {
266       return aKnownIids[ui].szName;
267     }
268   }
269 
270 #ifndef __WXWINCE__
271   // unknown IID, just transform to string
272   Uuid uuid(riid);
273   return wxString((const wxChar *)uuid);
274 #else
275   return wxEmptyString;
276 #endif
277 }
278 
wxLogQueryInterface(const wxChar * szInterface,REFIID riid)279 void wxLogQueryInterface(const wxChar *szInterface, REFIID riid)
280 {
281   wxLogTrace(wxTRACE_OleCalls, wxT("%s::QueryInterface (iid = %s)"),
282              szInterface, GetIidName(riid).c_str());
283 }
284 
wxLogAddRef(const wxChar * szInterface,ULONG cRef)285 void wxLogAddRef(const wxChar *szInterface, ULONG cRef)
286 {
287   wxLogTrace(wxTRACE_OleCalls, wxT("After %s::AddRef: m_cRef = %d"), szInterface, cRef + 1);
288 }
289 
wxLogRelease(const wxChar * szInterface,ULONG cRef)290 void wxLogRelease(const wxChar *szInterface, ULONG cRef)
291 {
292   wxLogTrace(wxTRACE_OleCalls, wxT("After %s::Release: m_cRef = %d"), szInterface, cRef - 1);
293 }
294 
295 #elif defined(__WXDEBUG__) && defined(__VISUALC__) && (__VISUALC__ <= 1000)
296 
297 // For VC++ 4
wxLogQueryInterface(const char * szInterface,REFIID riid)298 void wxLogQueryInterface(const char *szInterface, REFIID riid)
299 {
300   wxLogTrace("%s::QueryInterface", szInterface);
301 }
302 
wxLogAddRef(const char * szInterface,ULONG cRef)303 void wxLogAddRef(const char *szInterface, ULONG cRef)
304 {
305   wxLogTrace("After %s::AddRef: m_cRef = %d", szInterface, cRef + 1);
306 }
307 
wxLogRelease(const char * szInterface,ULONG cRef)308 void wxLogRelease(const char *szInterface, ULONG cRef)
309 {
310   wxLogTrace("After %s::Release: m_cRef = %d", szInterface, cRef - 1);
311 }
312 
313 #endif  // __WXDEBUG__
314 
315 #endif
316   // wxUSE_DRAG_AND_DROP
317 
318 #endif
319   // __CYGWIN10__
320 
321 #endif
322   // wxUSE_OLE
323