Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

782 lines
19 KiB

  1. // Copyright (C) 1996-1997 Microsoft Corporation. All rights reserved.
  2. #include "header.h"
  3. #include "web.h"
  4. #include "secwin.h"
  5. #include <exdispid.h>
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static const char THIS_FILE[] = __FILE__;
  9. #endif
  10. void OurVariantInit(LPVARIANT pVar);
  11. COleDispatchDriver::COleDispatchDriver()
  12. {
  13. m_lpDispatch = NULL;
  14. m_bAutoRelease = TRUE;
  15. }
  16. COleDispatchDriver::COleDispatchDriver(LPDISPATCH lpDispatch, BOOL bAutoRelease)
  17. {
  18. m_lpDispatch = lpDispatch;
  19. m_bAutoRelease = bAutoRelease;
  20. }
  21. COleDispatchDriver::COleDispatchDriver(const COleDispatchDriver& dispatchSrc)
  22. {
  23. ASSERT(this != &dispatchSrc); // constructing from self?
  24. m_lpDispatch = dispatchSrc.m_lpDispatch;
  25. if (m_lpDispatch != NULL)
  26. m_lpDispatch->AddRef();
  27. m_bAutoRelease = TRUE;
  28. }
  29. void IWebBrowserAppImpl::GoBack()
  30. {
  31. InvokeHelper(0x64, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
  32. }
  33. void IWebBrowserAppImpl::GoForward()
  34. {
  35. InvokeHelper(0x65, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
  36. }
  37. void IWebBrowserAppImpl::GoHome()
  38. {
  39. InvokeHelper(0x66, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
  40. }
  41. void IWebBrowserAppImpl::GoSearch()
  42. {
  43. InvokeHelper(0x67, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
  44. }
  45. void IWebBrowserAppImpl::Navigate(LPCTSTR pszUrl, VARIANT* pFlags,
  46. VARIANT* TargetFrameName, VARIANT* pPostData, VARIANT* Headers)
  47. {
  48. static BYTE parms[] =
  49. VTS_BSTR VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT;
  50. InvokeHelper(0x68, DISPATCH_METHOD, VT_EMPTY, NULL, parms,pszUrl, pFlags, TargetFrameName, pPostData, Headers);
  51. }
  52. void IWebBrowserAppImpl::Refresh()
  53. {
  54. InvokeHelper(DISPID_REFRESH, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
  55. }
  56. void IWebBrowserAppImpl::Refresh2(VARIANT* Level)
  57. {
  58. static BYTE parms[] = VTS_PVARIANT;
  59. InvokeHelper(0x69, DISPATCH_METHOD, VT_EMPTY, NULL, parms, Level);
  60. }
  61. void IWebBrowserAppImpl::Stop()
  62. {
  63. InvokeHelper(0x6a, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
  64. }
  65. LPDISPATCH IWebBrowserAppImpl::GetApplication()
  66. {
  67. LPDISPATCH result;
  68. InvokeHelper(0xc8, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL);
  69. return result;
  70. }
  71. LPDISPATCH IWebBrowserAppImpl::GetParent()
  72. {
  73. LPDISPATCH result;
  74. InvokeHelper(0xc9, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL);
  75. return result;
  76. }
  77. LPDISPATCH IWebBrowserAppImpl::GetContainer()
  78. {
  79. LPDISPATCH result;
  80. InvokeHelper(0xca, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL);
  81. return result;
  82. }
  83. LPDISPATCH IWebBrowserAppImpl::GetDocument()
  84. {
  85. LPDISPATCH result;
  86. InvokeHelper(0xcb, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL);
  87. return result;
  88. }
  89. BOOL IWebBrowserAppImpl::GetTopLevelContainer()
  90. {
  91. BOOL result;
  92. InvokeHelper(0xcc, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL);
  93. return result;
  94. }
  95. CStr* IWebBrowserAppImpl::GetType()
  96. {
  97. CStr* presult = new CStr;
  98. InvokeHelper(0xcd, DISPATCH_PROPERTYGET, VT_BSTR, (void*)presult, NULL);
  99. return presult;
  100. }
  101. long IWebBrowserAppImpl::GetLeft()
  102. {
  103. long result;
  104. InvokeHelper(0xce, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
  105. return result;
  106. }
  107. void IWebBrowserAppImpl::SetLeft(long nNewValue)
  108. {
  109. static BYTE parms[] = VTS_I4;
  110. InvokeHelper(0xce, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, nNewValue);
  111. }
  112. long IWebBrowserAppImpl::GetTop()
  113. {
  114. long result;
  115. InvokeHelper(0xcf, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
  116. return result;
  117. }
  118. void IWebBrowserAppImpl::SetTop(long nNewValue)
  119. {
  120. static BYTE parms[] = VTS_I4;
  121. #if 0
  122. DISPID dispid;
  123. LPWSTR pszDispMethod = L"put_Top";
  124. HRESULT hr = m_lpDispatch->GetIDsOfNames(IID_NULL, &pszDispMethod, 1, g_lcidSystem, &dispid);
  125. #endif
  126. InvokeHelper(0xcf, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, nNewValue);
  127. }
  128. long IWebBrowserAppImpl::GetWidth()
  129. {
  130. long result;
  131. InvokeHelper(0xd0, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
  132. return result;
  133. }
  134. void IWebBrowserAppImpl::SetWidth(long nNewValue)
  135. {
  136. static BYTE parms[] = VTS_I4;
  137. InvokeHelper(0xd0, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, nNewValue);
  138. }
  139. long IWebBrowserAppImpl::GetHeight()
  140. {
  141. long result;
  142. InvokeHelper(0xd1, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
  143. return result;
  144. }
  145. void IWebBrowserAppImpl::SetHeight(long nNewValue)
  146. {
  147. static BYTE parms[] = VTS_I4;
  148. InvokeHelper(0xd1, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, nNewValue);
  149. }
  150. void IWebBrowserAppImpl::GetLocationName(CStr* pcsz)
  151. {
  152. InvokeHelper(0xd2, DISPATCH_PROPERTYGET, VT_BSTR, (void*) pcsz, NULL);
  153. }
  154. void IWebBrowserAppImpl::GetLocationURL(CStr* pcsz)
  155. {
  156. InvokeHelper(0xd3, DISPATCH_PROPERTYGET, VT_BSTR, (void*) pcsz, NULL);
  157. }
  158. BOOL IWebBrowserAppImpl::GetBusy()
  159. {
  160. BOOL result;
  161. InvokeHelper(0xd4, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL);
  162. return result;
  163. }
  164. void IWebBrowserAppImpl::Quit()
  165. {
  166. // InvokeHelper(0x12c, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
  167. }
  168. void IWebBrowserAppImpl::ClientToWindow(long* pcx, long* pcy)
  169. {
  170. static BYTE parms[] = VTS_PI4 VTS_PI4;
  171. InvokeHelper(0x12d, DISPATCH_METHOD, VT_EMPTY, NULL, parms, pcx, pcy);
  172. }
  173. void IWebBrowserAppImpl::PutProperty(LPCTSTR szProperty, const VARIANT& vtValue)
  174. {
  175. static BYTE parms[] = VTS_BSTR VTS_VARIANT;
  176. InvokeHelper(0x12e, DISPATCH_METHOD, VT_EMPTY, NULL, parms, szProperty, &vtValue);
  177. }
  178. VARIANT IWebBrowserAppImpl::GetProperty_(LPCTSTR szProperty)
  179. {
  180. VARIANT result;
  181. static BYTE parms[] = VTS_BSTR;
  182. InvokeHelper(0x12f, DISPATCH_METHOD, VT_VARIANT, (void*)&result, parms,
  183. szProperty);
  184. return result;
  185. }
  186. CStr* IWebBrowserAppImpl::GetName()
  187. {
  188. CStr* presult = new CStr;
  189. InvokeHelper(0x0, DISPATCH_PROPERTYGET, VT_BSTR, (void*) presult, NULL);
  190. return presult;
  191. }
  192. HWND IWebBrowserAppImpl::GetHwnd()
  193. {
  194. #if 0
  195. // initialize EXCEPINFO struct
  196. EXCEPINFO excepInfo;
  197. ZERO_STRUCTURE(excepInfo);
  198. UINT nArgErr = (UINT)-1; // initialize to invalid arg
  199. VARIANT vaResult;
  200. OurVariantInit(&vaResult);
  201. DISPPARAMS dispparams;
  202. ZERO_STRUCTURE(dispparams);
  203. SCODE sc = m_lpDispatch->Invoke(DISPID_HWND, IID_NULL, 0,
  204. DISPATCH_PROPERTYGET,
  205. &dispparams, &vaResult, &excepInfo, &nArgErr);
  206. if (FAILED(sc)) {
  207. VariantClear(&vaResult);
  208. // BUGBUG: need to notify caller
  209. return 0;
  210. }
  211. return vaResult.lVal;
  212. #endif
  213. HWND hwnd = NULL;
  214. InvokeHelper(DISPID_HWND, DISPATCH_PROPERTYGET, VT_I4, (void*)&hwnd, NULL);
  215. return hwnd;
  216. }
  217. CStr* IWebBrowserAppImpl::GetFullName()
  218. {
  219. CStr* presult = new CStr;
  220. InvokeHelper(0x190, DISPATCH_PROPERTYGET, VT_BSTR, (void*) presult, NULL);
  221. return presult;
  222. }
  223. CStr* IWebBrowserAppImpl::GetPath()
  224. {
  225. CStr* presult = new CStr;
  226. InvokeHelper(0x191, DISPATCH_PROPERTYGET, VT_BSTR, (void*) presult, NULL);
  227. return presult;
  228. }
  229. BOOL IWebBrowserAppImpl::GetVisible()
  230. {
  231. BOOL result;
  232. InvokeHelper(0x192, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL);
  233. return result;
  234. }
  235. void IWebBrowserAppImpl::SetVisible(BOOL bNewValue)
  236. {
  237. static BYTE parms[] = VTS_BOOL;
  238. InvokeHelper(0x192, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
  239. bNewValue);
  240. }
  241. BOOL IWebBrowserAppImpl::GetStatusBar()
  242. {
  243. BOOL result;
  244. InvokeHelper(0x193, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL);
  245. return result;
  246. }
  247. void IWebBrowserAppImpl::SetStatusBar(BOOL bNewValue)
  248. {
  249. static BYTE parms[] = VTS_BOOL;
  250. InvokeHelper(0x193, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, bNewValue);
  251. }
  252. CStr* IWebBrowserAppImpl::GetStatusText()
  253. {
  254. CStr* presult = new CStr;
  255. InvokeHelper(0x194, DISPATCH_PROPERTYGET, VT_BSTR, (void*) presult, NULL);
  256. return presult;
  257. }
  258. void IWebBrowserAppImpl::SetStatusText(LPCTSTR lpszNewValue)
  259. {
  260. static BYTE parms[] = VTS_BSTR;
  261. InvokeHelper(0x194, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
  262. lpszNewValue);
  263. }
  264. long IWebBrowserAppImpl::GetToolBar()
  265. {
  266. long result;
  267. InvokeHelper(0x195, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
  268. return result;
  269. }
  270. void IWebBrowserAppImpl::SetToolBar(long nNewValue)
  271. {
  272. static BYTE parms[] = VTS_I4;
  273. InvokeHelper(0x195, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, nNewValue);
  274. }
  275. BOOL IWebBrowserAppImpl::GetMenuBar()
  276. {
  277. BOOL result;
  278. InvokeHelper(0x196, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL);
  279. return result;
  280. }
  281. void IWebBrowserAppImpl::SetMenuBar(BOOL bNewValue)
  282. {
  283. static BYTE parms[] = VTS_BOOL;
  284. InvokeHelper(0x196, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, bNewValue);
  285. }
  286. BOOL IWebBrowserAppImpl::GetFullScreen()
  287. {
  288. BOOL result;
  289. InvokeHelper(0x197, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL);
  290. return result;
  291. }
  292. void IWebBrowserAppImpl::SetFullScreen(BOOL bNewValue)
  293. {
  294. static BYTE parms[] = VTS_BOOL;
  295. InvokeHelper(0x197, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, bNewValue);
  296. }
  297. void DWebBrowserEventsImpl::BeforeNavigate(LPCTSTR URL, long Flags, LPCTSTR TargetFrameName, VARIANT* PostData, LPCTSTR Headers, BOOL* Cancel)
  298. {
  299. static BYTE parms[] = VTS_BSTR VTS_I4 VTS_BSTR VTS_PVARIANT VTS_BSTR VTS_PBOOL;
  300. InvokeHelper(DISPID_BEFORENAVIGATE, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
  301. URL, Flags, TargetFrameName, PostData, Headers, Cancel);
  302. }
  303. void DWebBrowserEventsImpl::NavigateComplete(LPCTSTR URL)
  304. {
  305. static BYTE parms[] = VTS_BSTR;
  306. InvokeHelper(DISPID_NAVIGATECOMPLETE, DISPATCH_METHOD, VT_EMPTY, NULL, parms, URL);
  307. }
  308. void DWebBrowserEventsImpl::StatusTextChange(LPCTSTR Text)
  309. {
  310. #if 0
  311. static BYTE parms[] = VTS_BSTR;
  312. InvokeHelper(DISPID_STATUSTEXTCHANGE, DISPATCH_METHOD, VT_EMPTY, NULL, parms, Text);
  313. #endif
  314. }
  315. void DWebBrowserEventsImpl::ProgressChange(long Progress, long ProgressMax)
  316. {
  317. #if 0
  318. static BYTE parms[] = VTS_I4 VTS_I4;
  319. InvokeHelper(DISPID_PROGRESSCHANGE, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
  320. Progress, ProgressMax);
  321. #endif
  322. }
  323. void DWebBrowserEventsImpl::DownloadComplete()
  324. {
  325. #if 0
  326. DBWIN("*** DWebBrowserEventsImpl::DownloadComplete() ***");
  327. InvokeHelper(DISPID_DOWNLOADCOMPLETE, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
  328. #endif
  329. }
  330. void DWebBrowserEventsImpl::CommandStateChange(long Command, BOOL Enable)
  331. {
  332. #if 0
  333. static BYTE parms[] = VTS_I4 VTS_BOOL;
  334. InvokeHelper(DISPID_COMMANDSTATECHANGE, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
  335. Command, Enable);
  336. #endif
  337. }
  338. void DWebBrowserEventsImpl::DownloadBegin()
  339. {
  340. #if 0
  341. InvokeHelper(DISPID_DOWNLOADBEGIN, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
  342. #endif
  343. }
  344. void DWebBrowserEventsImpl::NewWindow(LPCTSTR URL, long Flags, LPCTSTR TargetFrameName, VARIANT* PostData, LPCTSTR Headers, BOOL* Processed)
  345. {
  346. static BYTE parms[] = VTS_BSTR VTS_I4 VTS_BSTR VTS_PVARIANT VTS_BSTR VTS_PBOOL;
  347. InvokeHelper(DISPID_NEWWINDOW, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
  348. URL, Flags, TargetFrameName, PostData, Headers, Processed);
  349. }
  350. void DWebBrowserEventsImpl::TitleChange(LPCTSTR Text)
  351. {
  352. static BYTE parms[] = VTS_BSTR;
  353. InvokeHelper(DISPID_TITLECHANGE, DISPATCH_METHOD, VT_EMPTY, NULL, parms, Text);
  354. }
  355. void DWebBrowserEventsImpl::FrameBeforeNavigate(LPCTSTR URL, long Flags, LPCTSTR TargetFrameName, VARIANT* PostData, LPCTSTR Headers, BOOL* Cancel)
  356. {
  357. static BYTE parms[] = VTS_BSTR VTS_I4 VTS_BSTR VTS_PVARIANT VTS_BSTR VTS_PBOOL;
  358. InvokeHelper(DISPID_FRAMEBEFORENAVIGATE, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
  359. URL, Flags, TargetFrameName, PostData, Headers, Cancel);
  360. }
  361. void DWebBrowserEventsImpl::FrameNavigateComplete(LPCTSTR URL)
  362. {
  363. static BYTE parms[] = VTS_BSTR;
  364. InvokeHelper(DISPID_FRAMENAVIGATECOMPLETE, DISPATCH_METHOD, VT_EMPTY, NULL, parms, URL);
  365. }
  366. void DWebBrowserEventsImpl::FrameNewWindow(LPCTSTR URL, long Flags, LPCTSTR TargetFrameName, VARIANT* PostData, LPCTSTR Headers, BOOL* Processed)
  367. {
  368. static BYTE parms[] = VTS_BSTR VTS_I4 VTS_BSTR VTS_PVARIANT VTS_BSTR VTS_PBOOL;
  369. InvokeHelper(DISPID_FRAMENEWWINDOW, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
  370. URL, Flags, TargetFrameName, PostData, Headers, Processed);
  371. }
  372. void DWebBrowserEventsImpl::Quit(BOOL* Cancel)
  373. {
  374. static BYTE parms[] = VTS_PBOOL;
  375. InvokeHelper(DISPID_QUIT, DISPATCH_METHOD, VT_EMPTY, NULL, parms, Cancel);
  376. }
  377. void DWebBrowserEventsImpl::WindowMove()
  378. {
  379. InvokeHelper(DISPID_WINDOWMOVE, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
  380. }
  381. void DWebBrowserEventsImpl::WindowResize()
  382. {
  383. InvokeHelper(DISPID_WINDOWRESIZE, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
  384. }
  385. void DWebBrowserEventsImpl::WindowActivate()
  386. {
  387. InvokeHelper(DISPID_WINDOWACTIVATE, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
  388. }
  389. void DWebBrowserEventsImpl::PropertyChange(LPCTSTR szProperty)
  390. {
  391. #if 0
  392. static BYTE parms[] = VTS_BSTR;
  393. InvokeHelper(DISPID_PROPERTYCHANGE, DISPATCH_METHOD, VT_EMPTY, NULL, parms, szProperty);
  394. #endif
  395. }
  396. void __cdecl COleDispatchDriver::InvokeHelper(DISPID dwDispID, WORD wFlags,
  397. VARTYPE vtRet, void* pvRet, const BYTE* pbParamInfo, ...)
  398. {
  399. va_list argList;
  400. va_start(argList, pbParamInfo);
  401. InvokeHelperV(dwDispID, wFlags, vtRet, pvRet, pbParamInfo, argList);
  402. va_end(argList);
  403. }
  404. void OurVariantInit(LPVARIANT pVar)
  405. {
  406. memset(pVar, 0, sizeof(*pVar));
  407. }
  408. void COleDispatchDriver::InvokeHelperV(DISPID dwDispID, WORD wFlags,
  409. VARTYPE vtRet, void* pvRet, const BYTE* pbParamInfo, va_list argList)
  410. {
  411. ASSERT(m_lpDispatch);
  412. if (m_lpDispatch == NULL)
  413. {
  414. DBWIN("Warning: attempt to call Invoke with NULL m_lpDispatch!\n");
  415. return;
  416. }
  417. DISPPARAMS dispparams;
  418. memset(&dispparams, 0, sizeof dispparams);
  419. // determine number of arguments
  420. if (pbParamInfo != NULL)
  421. dispparams.cArgs = lstrlenA((LPCSTR)pbParamInfo);
  422. DISPID dispidNamed = DISPID_PROPERTYPUT;
  423. if (wFlags & (DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF))
  424. {
  425. ASSERT(dispparams.cArgs > 0);
  426. dispparams.cNamedArgs = 1;
  427. dispparams.rgdispidNamedArgs = &dispidNamed;
  428. }
  429. if (dispparams.cArgs != 0)
  430. {
  431. // allocate memory for all VARIANT parameters
  432. VARIANT* pArg = new VARIANT[dispparams.cArgs];
  433. ASSERT(pArg != NULL); // should have thrown exception
  434. dispparams.rgvarg = pArg;
  435. memset(pArg, 0, sizeof(VARIANT) * dispparams.cArgs);
  436. // get ready to walk vararg list
  437. const BYTE* pb = pbParamInfo;
  438. pArg += dispparams.cArgs - 1; // params go in opposite order
  439. while (*pb != 0)
  440. {
  441. ASSERT(pArg >= dispparams.rgvarg);
  442. pArg->vt = *pb; // set the variant type
  443. if (pArg->vt & VT_MFCBYREF)
  444. {
  445. pArg->vt &= ~VT_MFCBYREF;
  446. pArg->vt |= VT_BYREF;
  447. }
  448. switch (pArg->vt)
  449. {
  450. case VT_UI1:
  451. pArg->bVal = va_arg(argList, BYTE);
  452. break;
  453. case VT_I2:
  454. pArg->iVal = va_arg(argList, short);
  455. break;
  456. case VT_I4:
  457. pArg->lVal = va_arg(argList, long);
  458. break;
  459. case VT_R4:
  460. pArg->fltVal = (float)va_arg(argList, double);
  461. break;
  462. case VT_R8:
  463. pArg->dblVal = va_arg(argList, double);
  464. break;
  465. case VT_DATE:
  466. pArg->date = va_arg(argList, DATE);
  467. break;
  468. case VT_CY:
  469. pArg->cyVal = *va_arg(argList, CY*);
  470. break;
  471. case VT_BSTR:
  472. {
  473. LPCOLESTR lpsz = va_arg(argList, LPOLESTR);
  474. pArg->bstrVal = ::SysAllocString(lpsz);
  475. if (lpsz != NULL && pArg->bstrVal == NULL)
  476. {
  477. OOM();
  478. return;
  479. }
  480. }
  481. break;
  482. case VT_BSTRA:
  483. {
  484. LPCSTR lpsz = va_arg(argList, LPSTR);
  485. CWStr csz(lpsz);
  486. pArg->bstrVal = ::SysAllocString(csz);
  487. if (lpsz != NULL && pArg->bstrVal == NULL)
  488. {
  489. OOM();
  490. return;
  491. }
  492. pArg->vt = VT_BSTR;
  493. }
  494. break;
  495. case VT_DISPATCH:
  496. pArg->pdispVal = va_arg(argList, LPDISPATCH);
  497. break;
  498. case VT_ERROR:
  499. pArg->scode = va_arg(argList, SCODE);
  500. break;
  501. case VT_BOOL:
  502. V_BOOL(pArg) = (VARIANT_BOOL)(va_arg(argList, BOOL) ? -1 : 0);
  503. break;
  504. case VT_VARIANT:
  505. *pArg = *va_arg(argList, VARIANT*);
  506. break;
  507. case VT_UNKNOWN:
  508. pArg->punkVal = va_arg(argList, LPUNKNOWN);
  509. break;
  510. case VT_I2|VT_BYREF:
  511. pArg->piVal = va_arg(argList, short*);
  512. break;
  513. case VT_UI1|VT_BYREF:
  514. pArg->pbVal = va_arg(argList, BYTE*);
  515. break;
  516. case VT_I4|VT_BYREF:
  517. pArg->plVal = va_arg(argList, long*);
  518. break;
  519. case VT_R4|VT_BYREF:
  520. pArg->pfltVal = va_arg(argList, float*);
  521. break;
  522. case VT_R8|VT_BYREF:
  523. pArg->pdblVal = va_arg(argList, double*);
  524. break;
  525. case VT_DATE|VT_BYREF:
  526. pArg->pdate = va_arg(argList, DATE*);
  527. break;
  528. case VT_CY|VT_BYREF:
  529. pArg->pcyVal = va_arg(argList, CY*);
  530. break;
  531. case VT_BSTR|VT_BYREF:
  532. pArg->pbstrVal = va_arg(argList, BSTR*);
  533. break;
  534. case VT_DISPATCH|VT_BYREF:
  535. pArg->ppdispVal = va_arg(argList, LPDISPATCH*);
  536. break;
  537. case VT_ERROR|VT_BYREF:
  538. pArg->pscode = va_arg(argList, SCODE*);
  539. break;
  540. case VT_BOOL|VT_BYREF:
  541. {
  542. // coerce BOOL into VARIANT_BOOL
  543. BOOL* pboolVal = va_arg(argList, BOOL*);
  544. *pboolVal = *pboolVal ? MAKELONG(-1, 0) : 0;
  545. pArg->pboolVal = (VARIANT_BOOL*)pboolVal;
  546. }
  547. break;
  548. case VT_VARIANT|VT_BYREF:
  549. pArg->pvarVal = va_arg(argList, VARIANT*);
  550. break;
  551. case VT_UNKNOWN|VT_BYREF:
  552. pArg->ppunkVal = va_arg(argList, LPUNKNOWN*);
  553. break;
  554. default:
  555. ASSERT(FALSE); // unknown type!
  556. break;
  557. }
  558. --pArg; // get ready to fill next argument
  559. ++pb;
  560. }
  561. }
  562. // initialize return value
  563. VARIANT* pvarResult = NULL;
  564. VARIANT vaResult;
  565. OurVariantInit(&vaResult);
  566. if (vtRet != VT_EMPTY)
  567. pvarResult = &vaResult;
  568. // initialize EXCEPINFO struct
  569. EXCEPINFO excepInfo;
  570. memset(&excepInfo, 0, sizeof excepInfo);
  571. UINT nArgErr = (UINT)-1; // initialize to invalid arg
  572. // make the call
  573. SCODE sc = m_lpDispatch->Invoke(dwDispID, IID_NULL, 0, wFlags,
  574. &dispparams, pvarResult, &excepInfo, &nArgErr);
  575. // cleanup any arguments that need cleanup
  576. if (dispparams.cArgs != 0)
  577. {
  578. VARIANT* pArg = dispparams.rgvarg + dispparams.cArgs - 1;
  579. const BYTE* pb = pbParamInfo;
  580. while (*pb != 0)
  581. {
  582. switch ((VARTYPE)*pb)
  583. {
  584. #if !defined(_UNICODE) && !defined(OLE2ANSI)
  585. case VT_BSTRA:
  586. #endif
  587. case VT_BSTR:
  588. VariantClear(pArg);
  589. break;
  590. }
  591. --pArg;
  592. ++pb;
  593. }
  594. }
  595. delete[] dispparams.rgvarg;
  596. if (FAILED(sc))
  597. {
  598. VariantClear(&vaResult);
  599. if (pvRet)
  600. *(long*)pvRet = 0;
  601. // BUGBUG: need to notify caller
  602. return;
  603. }
  604. if (vtRet != VT_EMPTY)
  605. {
  606. // convert return value
  607. if (vtRet != VT_VARIANT)
  608. {
  609. SCODE sc = VariantChangeType(&vaResult, &vaResult, 0, vtRet);
  610. if (FAILED(sc))
  611. {
  612. DBWIN("Warning: automation return value coercion failed.");
  613. VariantClear(&vaResult);
  614. // BUGBUG: notify caller
  615. return;
  616. }
  617. ASSERT(vtRet == vaResult.vt);
  618. }
  619. // copy return value into return spot!
  620. switch (vtRet)
  621. {
  622. case VT_UI1:
  623. *(BYTE*)pvRet = vaResult.bVal;
  624. break;
  625. case VT_I2:
  626. *(short*)pvRet = vaResult.iVal;
  627. break;
  628. case VT_I4:
  629. *(long*)pvRet = vaResult.lVal;
  630. break;
  631. #if 0
  632. 26-Sep-1997 [ralphw] Enable as necessary
  633. case VT_R4:
  634. *(_AFX_FLOAT*)pvRet = *(_AFX_FLOAT*)&vaResult.fltVal;
  635. break;
  636. case VT_R8:
  637. *(_AFX_DOUBLE*)pvRet = *(_AFX_DOUBLE*)&vaResult.dblVal;
  638. break;
  639. case VT_DATE:
  640. *(_AFX_DOUBLE*)pvRet = *(_AFX_DOUBLE*)&vaResult.date;
  641. break;
  642. #endif
  643. case VT_CY:
  644. *(CY*)pvRet = vaResult.cyVal;
  645. break;
  646. case VT_BSTR:
  647. *((CStr*) pvRet) = (WCHAR*) vaResult.bstrVal;
  648. break;
  649. case VT_DISPATCH:
  650. *(LPDISPATCH*)pvRet = vaResult.pdispVal;
  651. break;
  652. case VT_ERROR:
  653. *(SCODE*)pvRet = vaResult.scode;
  654. break;
  655. case VT_BOOL:
  656. *(BOOL*)pvRet = (V_BOOL(&vaResult) != 0);
  657. break;
  658. case VT_VARIANT:
  659. *(VARIANT*)pvRet = vaResult;
  660. break;
  661. case VT_UNKNOWN:
  662. *(LPUNKNOWN*)pvRet = vaResult.punkVal;
  663. break;
  664. default:
  665. ASSERT_COMMENT(FALSE, "invalid return type specified");
  666. }
  667. }
  668. }
  669. void COleDispatchDriver::ReleaseDispatch()
  670. {
  671. if (m_lpDispatch != NULL)
  672. {
  673. if (m_bAutoRelease)
  674. m_lpDispatch->Release();
  675. m_lpDispatch = NULL;
  676. }
  677. }