Mercurial > vim
annotate src/VisVim/OleAut.cpp @ 21709:16d6b626aa8f v8.2.1404
patch 8.2.1404: Vim9: script test fails in the GUI
Commit: https://github.com/vim/vim/commit/b3ca98240761d8f320c5a49e077d1aac6496bb21
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Aug 9 14:43:58 2020 +0200
patch 8.2.1404: Vim9: script test fails in the GUI
Problem: Vim9: script test fails in the GUI.
Solution: Use another key to map. Improve cleanup.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 09 Aug 2020 14:45:04 +0200 |
parents | 1759d0ec0a6f |
children |
rev | line source |
---|---|
7 | 1 // |
2 // Class for creating OLE automation controllers. | |
3 // | |
4 // CreateObject() creates an automation object | |
5 // Invoke() will call a property or method of the automation object. | |
6 // GetProperty() returns a property | |
7 // SetProperty() changes a property | |
8 // Method() invokes a method | |
9 // | |
10 // For example, the following VB code will control Microsoft Word: | |
11 // | |
12 // Private Sub Form_Load() | |
13 // Dim wb As Object | |
14 // Set wb = CreateObject("Word.Basic") | |
15 // wb.AppShow | |
16 // wb.FileNewDefault | |
17 // wb.Insert "This is a test" | |
18 // wb.FileSaveAs "c:\sample.doc)" | |
19 // End Sub | |
20 // | |
21 // A C++ automation controller that does the same can be written as follows: | |
22 // the helper functions: | |
23 // | |
24 // Void FormLoad () | |
25 // { | |
26 // COleAutomationControl Aut; | |
27 // Aut.CreateObject("Word.Basic"); | |
28 // Aut.Method ("AppShow"); | |
29 // Aut.Method ("FileNewDefault"); | |
30 // Aut.Method ("Insert", "s", (LPOLESTR) OLESTR ("This is a test")); | |
31 // Aut.Method ("FileSaveAs", "s", OLESTR ("c:\\sample.doc")); | |
32 // } | |
33 // | |
34 // | |
35 | |
36 #include "stdafx.h" | |
37 #include <stdarg.h> | |
38 #include "oleaut.h" | |
39 | |
40 #ifdef _DEBUG | |
41 #define new DEBUG_NEW | |
42 #undef THIS_FILE | |
43 static char THIS_FILE[] = __FILE__; | |
44 #endif | |
45 | |
46 | |
47 static bool CountArgsInFormat (LPCTSTR Format, UINT* nArgs); | |
48 static LPCTSTR GetNextVarType (LPCTSTR Format, VARTYPE* pVarType); | |
49 | |
50 | |
51 COleAutomationControl::COleAutomationControl () | |
52 { | |
53 m_pDispatch = NULL; | |
54 m_hResult = NOERROR; | |
55 m_nErrArg = 0; | |
56 VariantInit (&m_VariantResult); | |
57 } | |
58 | |
59 COleAutomationControl::~COleAutomationControl () | |
60 { | |
61 DeleteObject (); | |
62 } | |
63 | |
64 void COleAutomationControl::DeleteObject () | |
65 { | |
66 if (m_pDispatch) | |
67 { | |
68 m_pDispatch->Release (); | |
69 m_pDispatch = NULL; | |
70 } | |
71 } | |
72 | |
73 // Creates an instance of the Automation object and | |
16356
1759d0ec0a6f
patch 8.1.1183: typos in VisVim comments
Bram Moolenaar <Bram@vim.org>
parents:
4352
diff
changeset
|
74 // obtains its IDispatch interface. |
7 | 75 // |
76 // Parameters: | |
77 // ProgId ProgID of Automation object | |
78 // | |
79 bool COleAutomationControl::CreateObject (char* ProgId) | |
80 { | |
81 CLSID ClsId; // CLSID of automation object | |
82 LPUNKNOWN pUnknown = NULL; // IUnknown of automation object | |
83 | |
84 // Retrieve CLSID from the progID that the user specified | |
85 LPOLESTR OleProgId = TO_OLE_STR (ProgId); | |
86 m_hResult = CLSIDFromProgID (OleProgId, &ClsId); | |
87 if (FAILED (m_hResult)) | |
88 goto error; | |
89 | |
90 // Create an instance of the automation object and ask for the | |
91 // IDispatch interface | |
92 m_hResult = CoCreateInstance (ClsId, NULL, CLSCTX_SERVER, | |
93 IID_IUnknown, (void**) &pUnknown); | |
94 if (FAILED (m_hResult)) | |
95 goto error; | |
96 | |
97 m_hResult = pUnknown->QueryInterface (IID_IDispatch, (void**) &m_pDispatch); | |
98 if (FAILED (m_hResult)) | |
99 goto error; | |
100 | |
101 pUnknown->Release (); | |
102 return true; | |
103 | |
104 error: | |
105 if (pUnknown) | |
106 pUnknown->Release (); | |
107 if (m_pDispatch) | |
108 m_pDispatch->Release (); | |
109 return false; | |
110 } | |
111 | |
112 // Return the dispatch id of a named service | |
113 // This id can be used in subsequent calls to GetProperty (), SetProperty () and | |
1207 | 114 // Method (). This is the preferred method when performance is important. |
7 | 115 // |
116 DISPID COleAutomationControl::GetDispatchId (char* Name) | |
117 { | |
118 DISPID DispatchId; | |
119 | |
120 ASSERT (m_pDispatch); | |
121 | |
122 // Get DISPID of property/method | |
123 LPOLESTR OleName = TO_OLE_STR (Name); | |
124 m_hResult = m_pDispatch->GetIDsOfNames (IID_NULL, &OleName, 1, | |
125 LOCALE_USER_DEFAULT, &DispatchId); | |
126 if (FAILED (m_hResult)) | |
127 return NULL; | |
128 return DispatchId; | |
129 } | |
130 | |
131 // The following functions use these parameters: | |
132 // | |
133 // Parameters: | |
134 // | |
135 // Name Name of property or method. | |
136 // | |
137 // Format Format string that describes the variable list of parameters that | |
1207 | 138 // follows. The format string can contain the following characters. |
7 | 139 // & = mark the following format character as VT_BYREF |
140 // B = VT_BOOL | |
141 // i = VT_I2 | |
142 // I = VT_I4 | |
143 // r = VT_R2 | |
144 // R = VT_R4 | |
145 // c = VT_CY | |
146 // s = VT_BSTR (string pointer can be passed, | |
147 // BSTR will be allocated by this function). | |
148 // e = VT_ERROR | |
149 // d = VT_DATE | |
150 // v = VT_VARIANT. Use this to pass data types that are not described | |
151 // in the format string. (For example SafeArrays). | |
152 // D = VT_DISPATCH | |
153 // U = VT_UNKNOWN | |
154 // | |
155 // ... Arguments of the property or method. | |
156 // Arguments are described by Format. | |
157 // | |
158 | |
159 bool COleAutomationControl::GetProperty (char* Name) | |
160 { | |
161 return Invoke (DISPATCH_PROPERTYGET, Name, NULL, NULL); | |
162 } | |
163 | |
164 bool COleAutomationControl::GetProperty (DISPID DispatchId) | |
165 { | |
166 return Invoke (DISPATCH_PROPERTYGET, DispatchId, NULL, NULL); | |
167 } | |
168 | |
169 bool COleAutomationControl::PutProperty (char* Name, LPCTSTR Format, ...) | |
170 { | |
171 va_list ArgList; | |
172 | |
173 va_start (ArgList, Format); | |
174 bool bRet = Invoke (DISPATCH_PROPERTYPUT, Name, Format, ArgList); | |
175 va_end (ArgList); | |
176 return bRet; | |
177 } | |
178 | |
179 bool COleAutomationControl::PutProperty (DISPID DispatchId, LPCTSTR Format, ...) | |
180 { | |
181 va_list ArgList; | |
182 | |
183 va_start (ArgList, Format); | |
184 bool bRet = Invoke (DISPATCH_PROPERTYPUT, DispatchId, Format, ArgList); | |
185 va_end (ArgList); | |
186 return bRet; | |
187 } | |
188 | |
189 bool COleAutomationControl::Method (char* Name, LPCTSTR Format, ...) | |
190 { | |
191 va_list ArgList; | |
192 | |
193 va_start (ArgList, Format); | |
194 bool bRet = Invoke (DISPATCH_METHOD, Name, Format, ArgList); | |
195 va_end (ArgList); | |
196 return bRet; | |
197 } | |
198 | |
199 bool COleAutomationControl::Method (DISPID DispatchId, LPCTSTR Format, ...) | |
200 { | |
201 va_list ArgList; | |
202 | |
203 va_start (ArgList, Format); | |
204 bool bRet = Invoke (DISPATCH_METHOD, DispatchId, Format, ArgList); | |
205 va_end (ArgList); | |
206 return bRet; | |
207 } | |
208 | |
209 bool COleAutomationControl::Invoke (WORD Flags, char* Name, | |
210 LPCTSTR Format, va_list ArgList) | |
211 { | |
212 DISPID DispatchId = GetDispatchId (Name); | |
213 if (! DispatchId) | |
214 return false; | |
215 return Invoke (Flags, DispatchId, Format, ArgList); | |
216 } | |
217 | |
218 bool COleAutomationControl::Invoke (WORD Flags, DISPID DispatchId, | |
219 LPCTSTR Format, va_list ArgList) | |
220 { | |
221 UINT ArgCount = 0; | |
222 VARIANTARG* ArgVector = NULL; | |
223 | |
224 ASSERT (m_pDispatch); | |
225 | |
226 DISPPARAMS DispatchParams; | |
227 memset (&DispatchParams, 0, sizeof (DispatchParams)); | |
228 | |
229 // Determine number of arguments | |
230 if (Format) | |
231 CountArgsInFormat (Format, &ArgCount); | |
232 | |
233 // Property puts have a named argument that represents the value that | |
234 // the property is being assigned. | |
235 DISPID DispIdNamed = DISPID_PROPERTYPUT; | |
236 if (Flags & DISPATCH_PROPERTYPUT) | |
237 { | |
238 if (ArgCount == 0) | |
239 { | |
240 m_hResult = ResultFromScode (E_INVALIDARG); | |
241 return false; | |
242 } | |
243 DispatchParams.cNamedArgs = 1; | |
244 DispatchParams.rgdispidNamedArgs = &DispIdNamed; | |
245 } | |
246 | |
247 if (ArgCount) | |
248 { | |
249 // Allocate memory for all VARIANTARG parameters | |
250 ArgVector = (VARIANTARG*) CoTaskMemAlloc ( | |
251 ArgCount * sizeof (VARIANTARG)); | |
252 if (! ArgVector) | |
253 { | |
254 m_hResult = ResultFromScode (E_OUTOFMEMORY); | |
255 return false; | |
256 } | |
257 memset (ArgVector, 0, sizeof (VARIANTARG) * ArgCount); | |
258 | |
259 // Get ready to walk vararg list | |
260 LPCTSTR s = Format; | |
261 | |
262 VARIANTARG *p = ArgVector + ArgCount - 1; // Params go in opposite order | |
263 | |
264 for (;;) | |
265 { | |
266 VariantInit (p); | |
267 if (! (s = GetNextVarType (s, &p->vt))) | |
268 break; | |
269 | |
270 if (p < ArgVector) | |
271 { | |
272 m_hResult = ResultFromScode (E_INVALIDARG); | |
273 goto Cleanup; | |
274 } | |
275 switch (p->vt) | |
276 { | |
277 case VT_I2: | |
278 V_I2 (p) = va_arg (ArgList, short); | |
279 break; | |
280 case VT_I4: | |
281 V_I4 (p) = va_arg (ArgList, long); | |
282 break; | |
283 case VT_R4: | |
284 V_R4 (p) = va_arg (ArgList, float); | |
285 break; | |
286 case VT_DATE: | |
287 case VT_R8: | |
288 V_R8 (p) = va_arg (ArgList, double); | |
289 break; | |
290 case VT_CY: | |
291 V_CY (p) = va_arg (ArgList, CY); | |
292 break; | |
293 case VT_BSTR: | |
294 V_BSTR (p) = SysAllocString (va_arg (ArgList, | |
295 OLECHAR*)); | |
296 if (! p->bstrVal) | |
297 { | |
298 m_hResult = ResultFromScode (E_OUTOFMEMORY); | |
299 p->vt = VT_EMPTY; | |
300 goto Cleanup; | |
301 } | |
302 break; | |
303 case VT_DISPATCH: | |
304 V_DISPATCH (p) = va_arg (ArgList, LPDISPATCH); | |
305 break; | |
306 case VT_ERROR: | |
307 V_ERROR (p) = va_arg (ArgList, SCODE); | |
308 break; | |
309 case VT_BOOL: | |
310 V_BOOL (p) = va_arg (ArgList, BOOL) ? -1 : 0; | |
311 break; | |
312 case VT_VARIANT: | |
313 *p = va_arg (ArgList, VARIANTARG); | |
314 break; | |
315 case VT_UNKNOWN: | |
316 V_UNKNOWN (p) = va_arg (ArgList, LPUNKNOWN); | |
317 break; | |
318 | |
319 case VT_I2 | VT_BYREF: | |
320 V_I2REF (p) = va_arg (ArgList, short*); | |
321 break; | |
322 case VT_I4 | VT_BYREF: | |
323 V_I4REF (p) = va_arg (ArgList, long*); | |
324 break; | |
325 case VT_R4 | VT_BYREF: | |
326 V_R4REF (p) = va_arg (ArgList, float*); | |
327 break; | |
328 case VT_R8 | VT_BYREF: | |
329 V_R8REF (p) = va_arg (ArgList, double*); | |
330 break; | |
331 case VT_DATE | VT_BYREF: | |
332 V_DATEREF (p) = va_arg (ArgList, DATE*); | |
333 break; | |
334 case VT_CY | VT_BYREF: | |
335 V_CYREF (p) = va_arg (ArgList, CY*); | |
336 break; | |
337 case VT_BSTR | VT_BYREF: | |
338 V_BSTRREF (p) = va_arg (ArgList, BSTR*); | |
339 break; | |
340 case VT_DISPATCH | VT_BYREF: | |
341 V_DISPATCHREF (p) = va_arg (ArgList, LPDISPATCH*); | |
342 break; | |
343 case VT_ERROR | VT_BYREF: | |
344 V_ERRORREF (p) = va_arg (ArgList, SCODE*); | |
345 break; | |
346 case VT_BOOL | VT_BYREF: | |
347 { | |
348 BOOL* pBool = va_arg (ArgList, BOOL*); | |
349 | |
350 *pBool = 0; | |
351 V_BOOLREF (p) = (VARIANT_BOOL*) pBool; | |
352 } | |
353 break; | |
354 case VT_VARIANT | VT_BYREF: | |
355 V_VARIANTREF (p) = va_arg (ArgList, VARIANTARG*); | |
356 break; | |
357 case VT_UNKNOWN | VT_BYREF: | |
358 V_UNKNOWNREF (p) = va_arg (ArgList, LPUNKNOWN*); | |
359 break; | |
360 | |
361 default: | |
362 { | |
363 m_hResult = ResultFromScode (E_INVALIDARG); | |
364 goto Cleanup; | |
365 } | |
366 break; | |
367 } | |
368 | |
369 --p; // Get ready to fill next argument | |
370 } | |
371 } | |
372 | |
373 DispatchParams.cArgs = ArgCount; | |
374 DispatchParams.rgvarg = ArgVector; | |
375 | |
376 // Initialize return variant, in case caller forgot. Caller can pass | |
377 // NULL if return value is not expected. | |
378 VariantInit (&m_VariantResult); | |
379 | |
380 // Make the call | |
381 m_hResult = m_pDispatch->Invoke (DispatchId, IID_NULL, LOCALE_USER_DEFAULT, | |
382 Flags, &DispatchParams, &m_VariantResult, | |
383 &m_ExceptionInfo, &m_nErrArg); | |
384 | |
385 Cleanup: | |
386 // Cleanup any arguments that need cleanup | |
387 if (ArgCount) | |
388 { | |
389 VARIANTARG* p = ArgVector; | |
390 | |
391 while (ArgCount--) | |
392 { | |
393 switch (p->vt) | |
394 { | |
395 case VT_BSTR: | |
396 VariantClear (p); | |
397 break; | |
398 } | |
399 ++p; | |
400 } | |
401 CoTaskMemFree (ArgVector); | |
402 } | |
403 | |
404 return FAILED (m_hResult) ? false : true; | |
405 } | |
406 | |
407 #define CASE_SCODE(sc) \ | |
408 case sc: \ | |
409 lstrcpy((char*)ErrName, (char*)#sc); \ | |
410 break; | |
411 | |
412 void COleAutomationControl::ErrDiag () | |
413 { | |
414 char ErrName[200]; | |
415 | |
416 SCODE sc = GetScode (m_hResult); | |
417 switch (sc) | |
418 { | |
419 // SCODE's defined in SCODE.H | |
420 CASE_SCODE (S_OK) | |
421 CASE_SCODE (S_FALSE) | |
422 CASE_SCODE (E_UNEXPECTED) | |
423 CASE_SCODE (E_OUTOFMEMORY) | |
424 CASE_SCODE (E_INVALIDARG) | |
425 CASE_SCODE (E_NOINTERFACE) | |
426 CASE_SCODE (E_POINTER) | |
427 CASE_SCODE (E_HANDLE) | |
428 CASE_SCODE (E_ABORT) | |
429 CASE_SCODE (E_FAIL) | |
430 CASE_SCODE (E_ACCESSDENIED) | |
431 | |
432 // SCODE's defined in OLE2.H | |
433 CASE_SCODE (OLE_E_OLEVERB) | |
434 CASE_SCODE (OLE_E_ADVF) | |
435 CASE_SCODE (OLE_E_ENUM_NOMORE) | |
436 CASE_SCODE (OLE_E_ADVISENOTSUPPORTED) | |
437 CASE_SCODE (OLE_E_NOCONNECTION) | |
438 CASE_SCODE (OLE_E_NOTRUNNING) | |
439 CASE_SCODE (OLE_E_NOCACHE) | |
440 CASE_SCODE (OLE_E_BLANK) | |
441 CASE_SCODE (OLE_E_CLASSDIFF) | |
442 CASE_SCODE (OLE_E_CANT_GETMONIKER) | |
443 CASE_SCODE (OLE_E_CANT_BINDTOSOURCE) | |
444 CASE_SCODE (OLE_E_STATIC) | |
445 CASE_SCODE (OLE_E_PROMPTSAVECANCELLED) | |
446 CASE_SCODE (OLE_E_INVALIDRECT) | |
447 CASE_SCODE (OLE_E_WRONGCOMPOBJ) | |
448 CASE_SCODE (OLE_E_INVALIDHWND) | |
449 CASE_SCODE (OLE_E_NOT_INPLACEACTIVE) | |
450 CASE_SCODE (OLE_E_CANTCONVERT) | |
451 CASE_SCODE (OLE_E_NOSTORAGE) | |
452 | |
453 CASE_SCODE (DV_E_FORMATETC) | |
454 CASE_SCODE (DV_E_DVTARGETDEVICE) | |
455 CASE_SCODE (DV_E_STGMEDIUM) | |
456 CASE_SCODE (DV_E_STATDATA) | |
457 CASE_SCODE (DV_E_LINDEX) | |
458 CASE_SCODE (DV_E_TYMED) | |
459 CASE_SCODE (DV_E_CLIPFORMAT) | |
460 CASE_SCODE (DV_E_DVASPECT) | |
461 CASE_SCODE (DV_E_DVTARGETDEVICE_SIZE) | |
462 CASE_SCODE (DV_E_NOIVIEWOBJECT) | |
463 | |
464 CASE_SCODE (OLE_S_USEREG) | |
465 CASE_SCODE (OLE_S_STATIC) | |
466 CASE_SCODE (OLE_S_MAC_CLIPFORMAT) | |
467 | |
468 CASE_SCODE (CONVERT10_E_OLESTREAM_GET) | |
469 CASE_SCODE (CONVERT10_E_OLESTREAM_PUT) | |
470 CASE_SCODE (CONVERT10_E_OLESTREAM_FMT) | |
471 CASE_SCODE (CONVERT10_E_OLESTREAM_BITMAP_TO_DIB) | |
472 CASE_SCODE (CONVERT10_E_STG_FMT) | |
473 CASE_SCODE (CONVERT10_E_STG_NO_STD_STREAM) | |
474 CASE_SCODE (CONVERT10_E_STG_DIB_TO_BITMAP) | |
475 CASE_SCODE (CONVERT10_S_NO_PRESENTATION) | |
476 | |
477 CASE_SCODE (CLIPBRD_E_CANT_OPEN) | |
478 CASE_SCODE (CLIPBRD_E_CANT_EMPTY) | |
479 CASE_SCODE (CLIPBRD_E_CANT_SET) | |
480 CASE_SCODE (CLIPBRD_E_BAD_DATA) | |
481 CASE_SCODE (CLIPBRD_E_CANT_CLOSE) | |
482 | |
483 CASE_SCODE (DRAGDROP_E_NOTREGISTERED) | |
484 CASE_SCODE (DRAGDROP_E_ALREADYREGISTERED) | |
485 CASE_SCODE (DRAGDROP_E_INVALIDHWND) | |
486 CASE_SCODE (DRAGDROP_S_DROP) | |
487 CASE_SCODE (DRAGDROP_S_CANCEL) | |
488 CASE_SCODE (DRAGDROP_S_USEDEFAULTCURSORS) | |
489 | |
490 CASE_SCODE (OLEOBJ_E_NOVERBS) | |
491 CASE_SCODE (OLEOBJ_E_INVALIDVERB) | |
492 CASE_SCODE (OLEOBJ_S_INVALIDVERB) | |
493 CASE_SCODE (OLEOBJ_S_CANNOT_DOVERB_NOW) | |
494 CASE_SCODE (OLEOBJ_S_INVALIDHWND) | |
495 CASE_SCODE (INPLACE_E_NOTUNDOABLE) | |
496 CASE_SCODE (INPLACE_E_NOTOOLSPACE) | |
497 CASE_SCODE (INPLACE_S_TRUNCATED) | |
498 | |
499 // SCODE's defined in COMPOBJ.H | |
500 CASE_SCODE (CO_E_NOTINITIALIZED) | |
501 CASE_SCODE (CO_E_ALREADYINITIALIZED) | |
502 CASE_SCODE (CO_E_CANTDETERMINECLASS) | |
503 CASE_SCODE (CO_E_CLASSSTRING) | |
504 CASE_SCODE (CO_E_IIDSTRING) | |
505 CASE_SCODE (CO_E_APPNOTFOUND) | |
506 CASE_SCODE (CO_E_APPSINGLEUSE) | |
507 CASE_SCODE (CO_E_ERRORINAPP) | |
508 CASE_SCODE (CO_E_DLLNOTFOUND) | |
509 CASE_SCODE (CO_E_ERRORINDLL) | |
510 CASE_SCODE (CO_E_WRONGOSFORAPP) | |
511 CASE_SCODE (CO_E_OBJNOTREG) | |
512 CASE_SCODE (CO_E_OBJISREG) | |
513 CASE_SCODE (CO_E_OBJNOTCONNECTED) | |
514 CASE_SCODE (CO_E_APPDIDNTREG) | |
515 CASE_SCODE (CLASS_E_NOAGGREGATION) | |
516 CASE_SCODE (CLASS_E_CLASSNOTAVAILABLE) | |
517 CASE_SCODE (REGDB_E_READREGDB) | |
518 CASE_SCODE (REGDB_E_WRITEREGDB) | |
519 CASE_SCODE (REGDB_E_KEYMISSING) | |
520 CASE_SCODE (REGDB_E_INVALIDVALUE) | |
521 CASE_SCODE (REGDB_E_CLASSNOTREG) | |
522 CASE_SCODE (REGDB_E_IIDNOTREG) | |
523 CASE_SCODE (RPC_E_CALL_REJECTED) | |
524 CASE_SCODE (RPC_E_CALL_CANCELED) | |
525 CASE_SCODE (RPC_E_CANTPOST_INSENDCALL) | |
526 CASE_SCODE (RPC_E_CANTCALLOUT_INASYNCCALL) | |
527 CASE_SCODE (RPC_E_CANTCALLOUT_INEXTERNALCALL) | |
528 CASE_SCODE (RPC_E_CONNECTION_TERMINATED) | |
529 CASE_SCODE (RPC_E_SERVER_DIED) | |
530 CASE_SCODE (RPC_E_CLIENT_DIED) | |
531 CASE_SCODE (RPC_E_INVALID_DATAPACKET) | |
532 CASE_SCODE (RPC_E_CANTTRANSMIT_CALL) | |
533 CASE_SCODE (RPC_E_CLIENT_CANTMARSHAL_DATA) | |
534 CASE_SCODE (RPC_E_CLIENT_CANTUNMARSHAL_DATA) | |
535 CASE_SCODE (RPC_E_SERVER_CANTMARSHAL_DATA) | |
536 CASE_SCODE (RPC_E_SERVER_CANTUNMARSHAL_DATA) | |
537 CASE_SCODE (RPC_E_INVALID_DATA) | |
538 CASE_SCODE (RPC_E_INVALID_PARAMETER) | |
539 CASE_SCODE (RPC_E_CANTCALLOUT_AGAIN) | |
540 CASE_SCODE (RPC_E_UNEXPECTED) | |
541 | |
542 // SCODE's defined in DVOBJ.H | |
543 CASE_SCODE (DATA_S_SAMEFORMATETC) | |
544 CASE_SCODE (VIEW_E_DRAW) | |
545 CASE_SCODE (VIEW_S_ALREADY_FROZEN) | |
546 CASE_SCODE (CACHE_E_NOCACHE_UPDATED) | |
547 CASE_SCODE (CACHE_S_FORMATETC_NOTSUPPORTED) | |
548 CASE_SCODE (CACHE_S_SAMECACHE) | |
549 CASE_SCODE (CACHE_S_SOMECACHES_NOTUPDATED) | |
550 | |
551 // SCODE's defined in STORAGE.H | |
552 CASE_SCODE (STG_E_INVALIDFUNCTION) | |
553 CASE_SCODE (STG_E_FILENOTFOUND) | |
554 CASE_SCODE (STG_E_PATHNOTFOUND) | |
555 CASE_SCODE (STG_E_TOOMANYOPENFILES) | |
556 CASE_SCODE (STG_E_ACCESSDENIED) | |
557 CASE_SCODE (STG_E_INVALIDHANDLE) | |
558 CASE_SCODE (STG_E_INSUFFICIENTMEMORY) | |
559 CASE_SCODE (STG_E_INVALIDPOINTER) | |
560 CASE_SCODE (STG_E_NOMOREFILES) | |
561 CASE_SCODE (STG_E_DISKISWRITEPROTECTED) | |
562 CASE_SCODE (STG_E_SEEKERROR) | |
563 CASE_SCODE (STG_E_WRITEFAULT) | |
564 CASE_SCODE (STG_E_READFAULT) | |
565 CASE_SCODE (STG_E_SHAREVIOLATION) | |
566 CASE_SCODE (STG_E_LOCKVIOLATION) | |
567 CASE_SCODE (STG_E_FILEALREADYEXISTS) | |
568 CASE_SCODE (STG_E_INVALIDPARAMETER) | |
569 CASE_SCODE (STG_E_MEDIUMFULL) | |
570 CASE_SCODE (STG_E_ABNORMALAPIEXIT) | |
571 CASE_SCODE (STG_E_INVALIDHEADER) | |
572 CASE_SCODE (STG_E_INVALIDNAME) | |
573 CASE_SCODE (STG_E_UNKNOWN) | |
574 CASE_SCODE (STG_E_UNIMPLEMENTEDFUNCTION) | |
575 CASE_SCODE (STG_E_INVALIDFLAG) | |
576 CASE_SCODE (STG_E_INUSE) | |
577 CASE_SCODE (STG_E_NOTCURRENT) | |
578 CASE_SCODE (STG_E_REVERTED) | |
579 CASE_SCODE (STG_E_CANTSAVE) | |
580 CASE_SCODE (STG_E_OLDFORMAT) | |
581 CASE_SCODE (STG_E_OLDDLL) | |
582 CASE_SCODE (STG_E_SHAREREQUIRED) | |
583 CASE_SCODE (STG_E_NOTFILEBASEDSTORAGE) | |
584 CASE_SCODE (STG_E_EXTANTMARSHALLINGS) | |
585 CASE_SCODE (STG_S_CONVERTED) | |
586 | |
587 // SCODE's defined in STORAGE.H | |
588 CASE_SCODE (MK_E_CONNECTMANUALLY) | |
589 CASE_SCODE (MK_E_EXCEEDEDDEADLINE) | |
590 CASE_SCODE (MK_E_NEEDGENERIC) | |
591 CASE_SCODE (MK_E_UNAVAILABLE) | |
592 CASE_SCODE (MK_E_SYNTAX) | |
593 CASE_SCODE (MK_E_NOOBJECT) | |
594 CASE_SCODE (MK_E_INVALIDEXTENSION) | |
595 CASE_SCODE (MK_E_INTERMEDIATEINTERFACENOTSUPPORTED) | |
596 CASE_SCODE (MK_E_NOTBINDABLE) | |
597 CASE_SCODE (MK_E_NOTBOUND) | |
598 CASE_SCODE (MK_E_CANTOPENFILE) | |
599 CASE_SCODE (MK_E_MUSTBOTHERUSER) | |
600 CASE_SCODE (MK_E_NOINVERSE) | |
601 CASE_SCODE (MK_E_NOSTORAGE) | |
602 CASE_SCODE (MK_E_NOPREFIX) | |
603 CASE_SCODE (MK_S_REDUCED_TO_SELF) | |
604 CASE_SCODE (MK_S_ME) | |
605 CASE_SCODE (MK_S_HIM) | |
606 CASE_SCODE (MK_S_US) | |
607 CASE_SCODE (MK_S_MONIKERALREADYREGISTERED) | |
608 | |
609 // SCODE's defined in DISPATCH.H | |
610 CASE_SCODE (DISP_E_UNKNOWNINTERFACE) | |
611 CASE_SCODE (DISP_E_MEMBERNOTFOUND) | |
612 CASE_SCODE (DISP_E_PARAMNOTFOUND) | |
613 CASE_SCODE (DISP_E_TYPEMISMATCH) | |
614 CASE_SCODE (DISP_E_UNKNOWNNAME) | |
615 CASE_SCODE (DISP_E_NONAMEDARGS) | |
616 CASE_SCODE (DISP_E_BADVARTYPE) | |
617 CASE_SCODE (DISP_E_EXCEPTION) | |
618 CASE_SCODE (DISP_E_OVERFLOW) | |
619 CASE_SCODE (DISP_E_BADINDEX) | |
620 CASE_SCODE (DISP_E_UNKNOWNLCID) | |
621 CASE_SCODE (DISP_E_ARRAYISLOCKED) | |
622 CASE_SCODE (DISP_E_BADPARAMCOUNT) | |
623 CASE_SCODE (DISP_E_PARAMNOTOPTIONAL) | |
624 CASE_SCODE (DISP_E_BADCALLEE) | |
625 CASE_SCODE (DISP_E_NOTACOLLECTION) | |
626 | |
627 CASE_SCODE (TYPE_E_BUFFERTOOSMALL) | |
628 CASE_SCODE (TYPE_E_INVDATAREAD) | |
629 CASE_SCODE (TYPE_E_UNSUPFORMAT) | |
630 CASE_SCODE (TYPE_E_REGISTRYACCESS) | |
631 CASE_SCODE (TYPE_E_LIBNOTREGISTERED) | |
632 CASE_SCODE (TYPE_E_UNDEFINEDTYPE) | |
633 CASE_SCODE (TYPE_E_QUALIFIEDNAMEDISALLOWED) | |
634 CASE_SCODE (TYPE_E_INVALIDSTATE) | |
635 CASE_SCODE (TYPE_E_WRONGTYPEKIND) | |
636 CASE_SCODE (TYPE_E_ELEMENTNOTFOUND) | |
637 CASE_SCODE (TYPE_E_AMBIGUOUSNAME) | |
638 CASE_SCODE (TYPE_E_NAMECONFLICT) | |
639 CASE_SCODE (TYPE_E_UNKNOWNLCID) | |
640 CASE_SCODE (TYPE_E_DLLFUNCTIONNOTFOUND) | |
641 CASE_SCODE (TYPE_E_BADMODULEKIND) | |
642 CASE_SCODE (TYPE_E_SIZETOOBIG) | |
643 CASE_SCODE (TYPE_E_DUPLICATEID) | |
644 CASE_SCODE (TYPE_E_TYPEMISMATCH) | |
645 CASE_SCODE (TYPE_E_OUTOFBOUNDS) | |
646 CASE_SCODE (TYPE_E_IOERROR) | |
647 CASE_SCODE (TYPE_E_CANTCREATETMPFILE) | |
648 CASE_SCODE (TYPE_E_CANTLOADLIBRARY) | |
649 CASE_SCODE (TYPE_E_INCONSISTENTPROPFUNCS) | |
650 CASE_SCODE (TYPE_E_CIRCULARTYPE) | |
651 | |
652 default: | |
653 lstrcpy (ErrName, "UNKNOWN SCODE"); | |
654 } | |
655 | |
656 char Buf[256]; | |
4352 | 657 sprintf (Buf, "An OLE error occurred:\r\nCode = %s\r\nResult = %lx.", |
7 | 658 (char*) ErrName, m_hResult); |
659 MessageBox (NULL, Buf, "OLE Error", MB_OK); | |
660 } | |
661 | |
662 | |
663 static bool CountArgsInFormat (LPCTSTR Format, UINT* pArgCount) | |
664 { | |
665 *pArgCount = 0; | |
666 | |
667 if (! Format) | |
668 return true; | |
669 | |
670 while (*Format) | |
671 { | |
672 if (*Format == '&') | |
673 Format++; | |
674 | |
675 switch (*Format) | |
676 { | |
677 case 'b': | |
678 case 'i': | |
679 case 'I': | |
680 case 'r': | |
681 case 'R': | |
682 case 'c': | |
683 case 's': | |
684 case 'e': | |
685 case 'd': | |
686 case 'v': | |
687 case 'D': | |
688 case 'U': | |
689 ++ (*pArgCount); | |
690 Format++; | |
691 break; | |
692 case '\0': | |
693 default: | |
694 return false; | |
695 } | |
696 } | |
697 return true; | |
698 } | |
699 | |
700 static LPCTSTR GetNextVarType (LPCTSTR Format, VARTYPE* pVarType) | |
701 { | |
702 *pVarType = 0; | |
703 if (*Format == '&') | |
704 { | |
705 *pVarType = VT_BYREF; | |
706 Format++; | |
707 if (!*Format) | |
708 return NULL; | |
709 } | |
710 switch (*Format) | |
711 { | |
712 case 'b': | |
713 *pVarType |= VT_BOOL; | |
714 break; | |
715 case 'i': | |
716 *pVarType |= VT_I2; | |
717 break; | |
718 case 'I': | |
719 *pVarType |= VT_I4; | |
720 break; | |
721 case 'r': | |
722 *pVarType |= VT_R4; | |
723 break; | |
724 case 'R': | |
725 *pVarType |= VT_R8; | |
726 break; | |
727 case 'c': | |
728 *pVarType |= VT_CY; | |
729 break; | |
730 case 's': | |
731 *pVarType |= VT_BSTR; | |
732 break; | |
733 case 'e': | |
734 *pVarType |= VT_ERROR; | |
735 break; | |
736 case 'd': | |
737 *pVarType |= VT_DATE; | |
738 break; | |
739 case 'v': | |
740 *pVarType |= VT_VARIANT; | |
741 break; | |
742 case 'U': | |
743 *pVarType |= VT_UNKNOWN; | |
744 break; | |
745 case 'D': | |
746 *pVarType |= VT_DISPATCH; | |
747 break; | |
748 case '\0': | |
749 return NULL; // End of Format string | |
750 default: | |
751 return NULL; | |
752 } | |
753 return ++Format; | |
754 } | |
755 | |
756 #ifndef UNICODE | |
757 char* ConvertToAnsi (OLECHAR* sUnicode) | |
758 { | |
759 static char BufAscii[MAX_OLE_STR]; | |
760 return ConvertToAnsiBuf (sUnicode, BufAscii); | |
761 } | |
762 | |
763 char* ConvertToAnsiBuf (OLECHAR* sUnicode, char* BufAscii) | |
764 { | |
765 WideCharToMultiByte (CP_ACP, 0, sUnicode, -1, BufAscii, MAX_OLE_STR, NULL, NULL); | |
766 return BufAscii; | |
767 } | |
768 | |
769 OLECHAR* ConvertToUnicode (char* sAscii) | |
770 { | |
771 static OLECHAR BufUnicode[MAX_OLE_STR]; | |
772 return ConvertToUnicodeBuf (sAscii, BufUnicode); | |
773 } | |
774 | |
775 OLECHAR* ConvertToUnicodeBuf (char* sAscii, OLECHAR* BufUnicode) | |
776 { | |
777 MultiByteToWideChar (CP_ACP, 0, sAscii, -1, BufUnicode, MAX_OLE_STR); | |
778 return BufUnicode; | |
779 } | |
780 #endif | |
781 |