Leaked source code of windows server 2003
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.

1092 lines
30 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1999 **
  4. //*********************************************************************
  5. //
  6. // MSOBWEB.CPP - Implementation of CObWebBrowser
  7. //
  8. // HISTORY:
  9. //
  10. // 1/27/99 a-jaswed Created.
  11. //
  12. // Class which will call up an IOleSite and the WebOC
  13. // and provide external interfaces.
  14. #include <exdispid.h>
  15. #include <mshtml.h> // IHTMLElement, IHTMLDocument2, IHTMLWindow2
  16. #include <mshtmhst.h>
  17. #include <tchar.h>
  18. #include "msobweb.h"
  19. #include "appdefs.h"
  20. #include "zmouse.h"
  21. #include "util.h"
  22. const VARIANT c_vaEmpty = {0};
  23. #define PVAREMPTY ((VARIANT*)&c_vaEmpty)
  24. #define VK_N L'N'
  25. #define VK_P L'P'
  26. #define VK_Z L'Z'
  27. #define VK_ENTER 0x0D
  28. ///////////////////////////////////////////////////////////
  29. //
  30. // Creation function used by CFactory.
  31. //
  32. HRESULT CObWebBrowser::CreateInstance(IUnknown* pOuterUnknown,
  33. CUnknown** ppNewComponent)
  34. {
  35. CObWebBrowser* pcunk = NULL;
  36. if (pOuterUnknown != NULL)
  37. {
  38. // Don't allow aggregation. Just for the heck of it.
  39. return CLASS_E_NOAGGREGATION;
  40. }
  41. pcunk = new CObWebBrowser(pOuterUnknown);
  42. if (pcunk == NULL || pcunk->m_lpWebBrowser == NULL || pcunk->m_lpOleObject == NULL)
  43. {
  44. delete pcunk;
  45. return E_FAIL;
  46. }
  47. *ppNewComponent = pcunk;
  48. return S_OK;
  49. }
  50. ///////////////////////////////////////////////////////////
  51. //
  52. // NondelegatingQueryInterface
  53. //
  54. HRESULT __stdcall
  55. CObWebBrowser::NondelegatingQueryInterface(const IID& iid, void** ppv)
  56. {
  57. if (iid == IID_IObWebBrowser)
  58. {
  59. return FinishQI(static_cast<IObWebBrowser*>(this), ppv);
  60. }
  61. else if (iid == IID_IDispatch)
  62. {
  63. return FinishQI(static_cast<IDispatch*>(this), ppv);
  64. }
  65. else
  66. {
  67. return CUnknown::NondelegatingQueryInterface(iid, ppv);
  68. }
  69. }
  70. ///////////////////////////////////////////////////////////
  71. //
  72. // Constructor
  73. //
  74. CObWebBrowser::CObWebBrowser(IUnknown* pOuterUnknown)
  75. : CUnknown(pOuterUnknown),
  76. m_hMainWnd (NULL),
  77. m_pOleSite (NULL),
  78. m_lpOleObject (NULL),
  79. m_lpWebBrowser (NULL),
  80. m_dwDrawAspect (0),
  81. m_dwcpCookie (0),
  82. m_fInPlaceActive (FALSE),
  83. m_fOnErrorWasHooked(FALSE),
  84. m_pOleSiteWMP (NULL),
  85. m_lpOleObjectWMP (NULL),
  86. m_pWMPPlayer (NULL)
  87. {
  88. HRESULT hr = E_FAIL;
  89. FORMATETC fromAtetc;
  90. // Create a new OLE site w/ WebOC
  91. m_pOleSite = new COleSite();
  92. if (m_pOleSite == NULL)
  93. {
  94. // We're hosed if this happens.
  95. return;
  96. }
  97. SETDefFormatEtc(fromAtetc, 0, TYMED_NULL);
  98. hr = OleCreate(CLSID_WebBrowser,
  99. IID_IWebBrowser2,
  100. OLERENDER_DRAW,
  101. &fromAtetc,
  102. m_pOleSite->m_pOleClientSite,
  103. m_pOleSite->m_lpStorage,
  104. (LPVOID*)&m_lpWebBrowser);
  105. if(FAILED(hr) || m_lpWebBrowser == NULL)
  106. {
  107. // Note a recoverable error.
  108. TRACE1(L"OleCreating CLSID_WebBrowser failed with 0x%08lX", hr);
  109. return;
  110. }
  111. InitBrowserObject();
  112. // Create an extra control for the Windows Media Player
  113. m_pOleSiteWMP = new COleSite();
  114. if (m_pOleSiteWMP == NULL)
  115. {
  116. goto LFail;
  117. }
  118. if (FAILED(OleCreate(__uuidof(WMPOCX),
  119. __uuidof(IWMPPlayer),
  120. OLERENDER_NONE,
  121. NULL,
  122. NULL,
  123. m_pOleSiteWMP->m_lpStorage,
  124. (LPVOID*)&m_pWMPPlayer)))
  125. {
  126. goto LFail;
  127. }
  128. // Get An OleObject from the WebBrowser Interface
  129. if (FAILED(m_pWMPPlayer->QueryInterface(IID_IOleObject, (LPVOID*)&m_lpOleObjectWMP)))
  130. {
  131. goto LFail;
  132. }
  133. m_pOleSiteWMP->m_lpOleObject = m_lpOleObjectWMP;
  134. // inform object handler/DLL object that it is used in the embedding container's context
  135. OleSetContainedObject(m_lpOleObjectWMP, TRUE);
  136. return;
  137. LFail:
  138. if (m_pWMPPlayer != NULL)
  139. {
  140. m_pWMPPlayer->Release();
  141. m_pWMPPlayer = NULL;
  142. }
  143. if (m_pOleSiteWMP != NULL)
  144. {
  145. m_pOleSiteWMP->Release();
  146. m_pOleSiteWMP = NULL;
  147. }
  148. }
  149. ///////////////////////////////////////////////////////////
  150. //
  151. // Destructor
  152. //
  153. CObWebBrowser::~CObWebBrowser()
  154. {
  155. if (m_lpOleObjectWMP)
  156. {
  157. m_lpOleObjectWMP->Close(OLECLOSE_NOSAVE);
  158. m_pOleSiteWMP->m_hWnd = NULL;;
  159. m_lpOleObjectWMP->Release();
  160. m_lpOleObjectWMP = NULL;
  161. m_pOleSiteWMP->m_lpOleObject = NULL;
  162. }
  163. if (m_pWMPPlayer != NULL)
  164. {
  165. m_pWMPPlayer->Release();
  166. m_pWMPPlayer = NULL;
  167. }
  168. if (m_pOleSiteWMP != NULL)
  169. {
  170. m_pOleSiteWMP->Release();
  171. m_pOleSiteWMP = NULL;
  172. }
  173. if (m_lpOleObject)
  174. {
  175. LPVIEWOBJECT lpViewObject = NULL;
  176. // ensure object is closed;
  177. CloseOleObject();
  178. m_lpOleObject->QueryInterface(IID_IViewObject, (LPVOID*)&lpViewObject);
  179. if (lpViewObject)
  180. {
  181. // Remove the view advise
  182. lpViewObject->SetAdvise(m_dwDrawAspect, 0, NULL);
  183. lpViewObject->Release();
  184. }
  185. m_lpOleObject->Release();
  186. m_lpOleObject = NULL;
  187. m_pOleSite->m_lpOleObject = NULL;
  188. }
  189. if (m_lpWebBrowser)
  190. {
  191. m_lpWebBrowser->Release();
  192. m_lpWebBrowser = NULL;
  193. }
  194. if (m_lpOleObject)
  195. {
  196. m_lpOleObject->Release();
  197. m_lpOleObject = NULL;
  198. }
  199. if(m_pOleSite)
  200. {
  201. m_pOleSite->Release();
  202. m_pOleSite = NULL;
  203. }
  204. }
  205. ///////////////////////////////////////////////////////////
  206. //
  207. // FinalRelease -- Clean up the aggreated objects.
  208. //
  209. void CObWebBrowser::FinalRelease()
  210. {
  211. CUnknown::FinalRelease();
  212. }
  213. ///////////////////////////////////////////////////////////
  214. // IObWebBrowser Implementation
  215. ///////////////////////////////////////////////////////////
  216. ///////////////////////////////////////////////////////////
  217. // AttachToWindow
  218. //
  219. HRESULT CObWebBrowser::AttachToWindow(HWND hWnd)
  220. {
  221. if(m_hMainWnd)
  222. {
  223. CloseOleObject();
  224. }
  225. //Set the new hwnd
  226. m_hMainWnd = hWnd;
  227. m_pOleSite->m_hWnd = m_hMainWnd;
  228. InPlaceActivate();
  229. return S_OK;
  230. }
  231. ///////////////////////////////////////////////////////////
  232. // PreTranslateMessage -- Do not use with size parameters because addin the org...
  233. //
  234. HRESULT CObWebBrowser::PreTranslateMessage(LPMSG lpMsg)
  235. {
  236. HRESULT hr = S_FALSE;
  237. switch(lpMsg->message)
  238. {
  239. case WM_LBUTTONDOWN:
  240. {
  241. WPARAM dwKeys = lpMsg->wParam; // key flags
  242. if (MK_SHIFT & dwKeys)
  243. {
  244. return S_OK;
  245. }
  246. break;
  247. }
  248. case WM_MOUSEWHEEL:
  249. case WM_MBUTTONDOWN:
  250. {
  251. return S_OK;
  252. }
  253. case WM_RBUTTONDOWN :
  254. {
  255. VARIANT varg1;
  256. VARIANT varg2;
  257. IDispatch *pdisp = NULL;
  258. IDispatch* pDisp = NULL;
  259. IHTMLWindow2* pFrWin = NULL;
  260. IHTMLDocument2* pDoc = NULL;
  261. IHTMLElementCollection *pColl = NULL;
  262. IHTMLElement* pElement = NULL;
  263. IHTMLStyle* pStyle = NULL;
  264. BOOL bFilter = FALSE;
  265. HRESULT hrDoc = S_OK;
  266. VariantInit(&varg1);
  267. V_VT(&varg1) = VT_BSTR;
  268. varg1.bstrVal= SysAllocString(L"MovieFrame");
  269. VariantInit(&varg2);
  270. varg2.vt = VT_UINT;
  271. varg2.lVal= 0;
  272. if(SUCCEEDED(m_lpWebBrowser->get_Document(&pDisp))&& pDisp)
  273. {
  274. if(SUCCEEDED(pDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc)) && pDoc)
  275. {
  276. if(SUCCEEDED(pDoc->get_all( &pColl )) && pColl)
  277. {
  278. if(SUCCEEDED(pColl->item(varg1, varg2, &pdisp)) && pdisp)
  279. {
  280. if(SUCCEEDED(pdisp->QueryInterface(IID_IHTMLElement, (void**)&pElement)) && pElement)
  281. {
  282. if(SUCCEEDED(pElement->get_style(&pStyle)) && pStyle)
  283. {
  284. BSTR bstrVisibility = NULL;
  285. BSTR bstrDisplay = NULL;
  286. pStyle->get_visibility(&bstrVisibility);
  287. pStyle->get_display(&bstrDisplay);
  288. if (bstrDisplay)
  289. {
  290. if (lstrcmpi(bstrDisplay, L"none") != 0)
  291. bFilter = TRUE;
  292. }
  293. if (bstrVisibility)
  294. {
  295. if (lstrcmpi(bstrVisibility, L"hidden") != 0)
  296. bFilter = TRUE;
  297. }
  298. pStyle->Release();
  299. pStyle = NULL;
  300. }
  301. pElement->Release();
  302. pElement = NULL;
  303. }
  304. pdisp->Release();
  305. pdisp = NULL;
  306. }
  307. pColl->Release();
  308. pColl = NULL;
  309. }
  310. pDoc->Release();
  311. pDoc = NULL;
  312. }
  313. pDisp->Release();
  314. pDisp = NULL;
  315. }
  316. if (bFilter)
  317. return S_OK;
  318. break;
  319. }
  320. case WM_KEYDOWN:
  321. {
  322. if ( lpMsg->wParam == VK_F3 )
  323. {
  324. /* Convert keyboard messages came into WM_COMMANDs to
  325. * the found dialog. Return TRUE because we procecessed.
  326. */
  327. if ( (GetKeyState ( VK_SHIFT) & 0x8000) && (GetKeyState( VK_CONTROL) & 0x8000))
  328. {
  329. HWND hWnd = FindWindow(OOBE_MAIN_CLASSNAME, NULL);
  330. PostMessage(hWnd, WM_COMMAND, WM_SKIP, 0L); //MAKELPARAM(lpMsg->hwnd, BY_KEYBOARD));
  331. return S_FALSE;
  332. }
  333. }
  334. if(lpMsg->wParam == VK_F1)
  335. {
  336. HWND hWnd = FindWindow(OOBE_MAIN_CLASSNAME, DEFAULT_WINDOW_TEXT);
  337. if (hWnd)
  338. {
  339. PostMessage(hWnd, WM_COMMAND, WM_AGENT_HELP, 0L);
  340. return S_FALSE;
  341. }
  342. }
  343. if(
  344. #ifndef DBG
  345. (lpMsg->wParam == VK_F5) ||
  346. #endif
  347. (lpMsg->wParam == VK_F6) || // F6 key deletes the insertation point cursor when filling out the Registration info.
  348. (((lpMsg->wParam == VK_N) || (lpMsg->wParam == VK_Z) ||
  349. (lpMsg->wParam == VK_P)) && ((GetKeyState(VK_CONTROL) & 0x1000))))
  350. return S_OK;
  351. }
  352. //Fall through!!!
  353. case WM_SYSKEYDOWN:
  354. {
  355. if((((lpMsg->wParam == VK_LEFT) ||
  356. (lpMsg->wParam == VK_RIGHT) ||
  357. (lpMsg->wParam == VK_HOME)) && (GetKeyState(VK_MENU) & 0x1000)) ||
  358. ((lpMsg->wParam == VK_ENTER ) && (GetKeyState( VK_SHIFT) & 0x8000)) ||
  359. // Space +Shift +Ctrl is a Narrator key combination, don't diable this.
  360. ((lpMsg->wParam == VK_SPACE) && (GetKeyState( VK_SHIFT) & 0x8000) &&
  361. (GetKeyState( VK_CONTROL ) & 0x8000))
  362. )
  363. return S_OK;
  364. else if((lpMsg->wParam == VK_BACK) || (lpMsg->wParam == VK_SPACE))
  365. {
  366. VARIANT varRet;
  367. VARIANTARG varg;
  368. IDispatch* pDisp = NULL;
  369. IHTMLWindow2* pFrWin = NULL;
  370. IHTMLDocument2* pDoc = NULL;
  371. IHTMLDocument2* pFrDoc = NULL;
  372. IHTMLElement* pActElem = NULL;
  373. IHTMLFramesCollection2* pColl = NULL;
  374. BOOL bDontTA = TRUE;
  375. HRESULT hrDoc = S_OK;
  376. VariantInit(&varg);
  377. V_VT(&varg) = VT_BSTR;
  378. varg.bstrVal= SysAllocString(DEFAULT_FRAME_NAME);
  379. if(SUCCEEDED(m_lpWebBrowser->get_Document(&pDisp))&& pDisp)
  380. {
  381. if(SUCCEEDED(pDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc)) && pDoc)
  382. {
  383. if(SUCCEEDED(pDoc->get_frames(&pColl)) && pColl)
  384. {
  385. if(SUCCEEDED(pColl->item(&varg, &varRet)) && varRet.pdispVal)
  386. {
  387. if(SUCCEEDED(varRet.pdispVal->QueryInterface(IID_IHTMLWindow2, (void**)&pFrWin)) && pFrWin)
  388. {
  389. if(SUCCEEDED( hrDoc = pFrWin->get_document(&pFrDoc)) && pFrDoc)
  390. {
  391. if(SUCCEEDED(pFrDoc->get_activeElement(&pActElem)) && pActElem)
  392. {
  393. BSTR bstr = NULL;
  394. if (SUCCEEDED(pActElem->get_tagName(&bstr)))
  395. {
  396. LPWSTR lpszType = bstr;
  397. if ( (lstrcmpi(lpszType, L"TEXTAREA") == 0) ||
  398. (lstrcmpi(lpszType, L"INPUT") == 0) ||
  399. (lstrcmpi(lpszType, L"BUTTON") == 0) )
  400. bDontTA = FALSE;
  401. }
  402. pActElem->Release();
  403. pActElem = NULL;
  404. }
  405. pFrDoc->Release();
  406. pFrDoc = NULL;
  407. }
  408. }
  409. varRet.pdispVal->Release();
  410. varRet.pdispVal = NULL;
  411. }
  412. pColl->Release();
  413. pColl = NULL;
  414. }
  415. pDoc->Release();
  416. pDoc = NULL;
  417. }
  418. pDisp->Release();
  419. pDisp = NULL;
  420. }
  421. if(bDontTA)
  422. {
  423. if ( !SUCCEEDED(hrDoc) ) // cross frame access denied for server page.
  424. {
  425. return S_FALSE; // Send VK_BACK to the page.
  426. }
  427. return S_OK;
  428. }
  429. else
  430. {
  431. return S_FALSE;
  432. }
  433. }
  434. }
  435. default:
  436. break;
  437. }
  438. if(m_lpWebBrowser)
  439. {
  440. IOleInPlaceActiveObject* lpIPA;
  441. if(SUCCEEDED(m_lpWebBrowser->QueryInterface(IID_IOleInPlaceActiveObject,(void**)&lpIPA)))
  442. {
  443. hr = lpIPA->TranslateAccelerator(lpMsg);
  444. lpIPA->Release();
  445. }
  446. }
  447. return hr;
  448. }
  449. ///////////////////////////////////////////////////////////
  450. // Navigate
  451. HRESULT CObWebBrowser::Navigate(WCHAR* pszUrl, WCHAR* pszTarget)
  452. {
  453. VARIANT varURL;
  454. VARIANT varTarget;
  455. VARIANT v;
  456. IDispatch *pdisp = NULL;
  457. IHTMLWindow2 *pwin = NULL;
  458. IHTMLDocument2 *pdoc = NULL;
  459. TRACE2(L"Attempting to navigate: \n\tUrl: %s\n\tTarget: %s\n",
  460. (NULL != pszUrl) ? pszUrl : L"NONE",
  461. (NULL != pszTarget) ? pszTarget : L"NONE"
  462. );
  463. VariantInit(&varURL);
  464. VariantInit(&varTarget);
  465. VariantInit(&v);
  466. V_VT(&varURL) = VT_BSTR;
  467. V_VT(&varTarget) = VT_BSTR;
  468. varURL.bstrVal = SysAllocString(pszUrl);
  469. varTarget.bstrVal = SysAllocString(pszTarget);
  470. m_lpWebBrowser->Navigate2(&varURL, PVAREMPTY, &varTarget, PVAREMPTY, PVAREMPTY);
  471. if (FAILED(m_lpWebBrowser->get_Document(&pdisp)) || pdisp == NULL)
  472. {
  473. TRACE(L"Couldn't find the web browser's document object!");
  474. goto LCleanup;
  475. }
  476. if (FAILED(pdisp->QueryInterface(IID_IHTMLDocument2, (void**)&pdoc)))
  477. {
  478. TRACE(L"The web browser's document doesn't support IHTMLDocument2!");
  479. goto LCleanup;
  480. }
  481. if (FAILED(pdoc->get_parentWindow(&pwin)) || pwin == NULL)
  482. {
  483. TRACE(L"There's no window for the web browser's document object!");
  484. goto LCleanup;
  485. }
  486. V_VT(&v) = VT_DISPATCH;
  487. QueryInterface(IID_IDispatch, (void**)&V_DISPATCH(&v));
  488. if (FAILED(pwin->put_onerror(v)))
  489. {
  490. TRACE(L"Couldn't set the script error hook!");
  491. goto LCleanup;
  492. }
  493. m_fOnErrorWasHooked = TRUE;
  494. LCleanup:
  495. if (V_VT(&v) == VT_DISPATCH)
  496. {
  497. V_DISPATCH(&v)->Release();
  498. }
  499. if (pwin != NULL)
  500. {
  501. pwin->Release();
  502. pwin = NULL;
  503. }
  504. if (pdoc != NULL)
  505. {
  506. pdoc->Release();
  507. pdoc = NULL;
  508. }
  509. if (pdisp != NULL)
  510. {
  511. pdisp->Release();
  512. pdisp = NULL;
  513. }
  514. return S_OK;
  515. }
  516. ///////////////////////////////////////////////////////////
  517. // Stop
  518. HRESULT CObWebBrowser::Stop()
  519. {
  520. m_lpWebBrowser->Stop();
  521. return S_OK;
  522. }
  523. ///////////////////////////////////////////////////////////
  524. // PlayBackgroundMusic
  525. STDMETHODIMP
  526. CObWebBrowser::PlayBackgroundMusic()
  527. {
  528. IWMPSettings* psettings = NULL;
  529. IWMPControls* pcontrols = NULL;
  530. HRESULT hr;
  531. BSTR bstr = NULL;
  532. WCHAR szFile[MAX_PATH];
  533. if (m_pWMPPlayer == NULL)
  534. {
  535. TRACE(L"Couldn't access the media player control.");
  536. goto LExit;
  537. }
  538. ExpandEnvironmentStrings(
  539. L"%SystemRoot%\\system32\\oobe\\images\\title.wma",
  540. szFile,
  541. sizeof(szFile)/sizeof(szFile[0]));
  542. bstr = SysAllocString(szFile);
  543. if (bstr == NULL)
  544. {
  545. TRACE(L"Couldn't allocate the background sound file string.");
  546. goto LExit;
  547. }
  548. hr = m_pWMPPlayer->put_URL(bstr);
  549. SysFreeString(bstr);
  550. if (FAILED(hr))
  551. {
  552. TRACE(L"Couldn't set the movie file.");
  553. goto LExit;
  554. }
  555. // Turn off the WMP error dialogs
  556. hr = m_pWMPPlayer->QueryInterface(__uuidof(IWMPSettings), (LPVOID*)&psettings);
  557. if (FAILED(hr))
  558. {
  559. TRACE(L"Couldn't access WMP settings.");
  560. goto LExit;
  561. }
  562. hr = psettings->put_enableErrorDialogs(VARIANT_FALSE);
  563. if (FAILED(hr))
  564. {
  565. TRACE(L"Couldn't turn off WMP error dialogs.");
  566. goto LExit;
  567. }
  568. // Now, start playing
  569. hr = m_pWMPPlayer->QueryInterface(__uuidof(IWMPControls), (LPVOID*)&pcontrols);
  570. if (FAILED(hr))
  571. {
  572. TRACE(L"Couldn't access WMP controls.");
  573. goto LExit;
  574. }
  575. pcontrols->play();
  576. LExit:
  577. if (pcontrols != NULL)
  578. {
  579. pcontrols->Release();
  580. pcontrols = NULL;
  581. }
  582. if (psettings != NULL)
  583. {
  584. psettings->Release();
  585. psettings = NULL;
  586. }
  587. return S_OK;
  588. }
  589. ///////////////////////////////////////////////////////////
  590. // PlayBackgroundMusic
  591. STDMETHODIMP
  592. CObWebBrowser::StopBackgroundMusic()
  593. {
  594. IWMPControls* pcontrols = NULL;
  595. HRESULT hr;
  596. if (m_pWMPPlayer == NULL)
  597. {
  598. TRACE(L"Couldn't access the media player control.");
  599. goto LExit;
  600. }
  601. hr = m_pWMPPlayer->QueryInterface(__uuidof(IWMPControls), (LPVOID*)&pcontrols);
  602. if (FAILED(hr))
  603. {
  604. TRACE(L"Couldn't access WMP controls.");
  605. goto LExit;
  606. }
  607. pcontrols->stop();
  608. LExit:
  609. if (pcontrols != NULL)
  610. {
  611. pcontrols->Release();
  612. pcontrols = NULL;
  613. }
  614. return S_OK;
  615. }
  616. ///////////////////////////////////////////////////////////
  617. // UnhookScriptErrorHandler
  618. STDMETHODIMP
  619. CObWebBrowser::UnhookScriptErrorHandler()
  620. {
  621. VARIANT v;
  622. IDispatch *pdisp = NULL;
  623. IHTMLWindow2 *pwin = NULL;
  624. IHTMLDocument2 *pdoc = NULL;
  625. if (!m_fOnErrorWasHooked)
  626. {
  627. goto LCleanup;
  628. }
  629. if (FAILED(m_lpWebBrowser->get_Document(&pdisp)) || pdisp == NULL)
  630. {
  631. TRACE(L"Couldn't find the web browser's document object!");
  632. goto LCleanup;
  633. }
  634. if (FAILED(pdisp->QueryInterface(IID_IHTMLDocument2, (void**)&pdoc)))
  635. {
  636. TRACE(L"The web browser's document doesn't support IHTMLDocument2!");
  637. goto LCleanup;
  638. }
  639. if (FAILED(pdoc->get_parentWindow(&pwin)) || pwin == NULL)
  640. {
  641. TRACE(L"There's no window for the web browser's document object!");
  642. goto LCleanup;
  643. }
  644. VariantInit(&v);
  645. V_VT(&v) = VT_DISPATCH;
  646. V_DISPATCH(&v) = NULL;
  647. pwin->put_onerror(v);
  648. LCleanup:
  649. if (pwin != NULL)
  650. {
  651. pwin->Release();
  652. pwin = NULL;
  653. }
  654. if (pdoc != NULL)
  655. {
  656. pdoc->Release();
  657. pdoc = NULL;
  658. }
  659. if (pdisp != NULL)
  660. {
  661. pdisp->Release();
  662. pdisp = NULL;
  663. }
  664. return S_OK;
  665. }
  666. ///////////////////////////////////////////////////////////
  667. // IDispatch Implementation
  668. ///////////////////////////////////////////////////////////
  669. STDMETHODIMP CObWebBrowser::GetTypeInfoCount(UINT* pcInfo)
  670. {
  671. return E_NOTIMPL;
  672. }
  673. STDMETHODIMP CObWebBrowser::GetTypeInfo(UINT, LCID, ITypeInfo** )
  674. {
  675. return E_NOTIMPL;
  676. }
  677. /////////////////////////////////////////////////////////////
  678. // CObWebBrowser::GetIDsOfNames
  679. STDMETHODIMP CObWebBrowser::GetIDsOfNames(
  680. /* [in] */ REFIID riid,
  681. /* [size_is][in] */ OLECHAR** rgszNames,
  682. /* [in] */ UINT cNames,
  683. /* [in] */ LCID lcid,
  684. /* [size_is][out] */ DISPID* rgDispId)
  685. {
  686. return DISP_E_UNKNOWNNAME;
  687. }
  688. /////////////////////////////////////////////////////////////
  689. // CObWebBrowser::Invoke
  690. HRESULT CObWebBrowser::Invoke
  691. (
  692. DISPID dispidMember,
  693. REFIID riid,
  694. LCID lcid,
  695. WORD wFlags,
  696. DISPPARAMS* pdispparams,
  697. VARIANT* pvarResult,
  698. EXCEPINFO* pexcepinfo,
  699. UINT* puArgErr
  700. )
  701. {
  702. HRESULT hr = S_OK;
  703. switch(dispidMember)
  704. {
  705. case DISPID_VALUE:
  706. {
  707. if (pdispparams &&
  708. pdispparams->cArgs == 3)
  709. {
  710. VARIANT_BOOL f;
  711. onerror(&pdispparams[0].rgvarg[2],
  712. &pdispparams[0].rgvarg[1],
  713. &pdispparams[0].rgvarg[0],
  714. &f);
  715. if (pvarResult != NULL)
  716. {
  717. V_VT(pvarResult) = VT_BOOL;
  718. V_BOOL(pvarResult) = f;
  719. }
  720. }
  721. break;
  722. }
  723. default:
  724. {
  725. hr = DISP_E_MEMBERNOTFOUND;
  726. break;
  727. }
  728. }
  729. return hr;
  730. }
  731. ///////////////////////////////////////////////////////////
  732. // onerror
  733. STDMETHODIMP
  734. CObWebBrowser::onerror(IN VARIANT* pvarMsg,
  735. IN VARIANT* pvarUrl,
  736. IN VARIANT* pvarLine,
  737. OUT VARIANT_BOOL* pfResult)
  738. {
  739. BSTR bstrMsg, bstrUrl;
  740. int iLine;
  741. *pfResult = Bool2VarBool(FALSE);
  742. if (pvarMsg == NULL || V_VT(pvarMsg) != VT_BSTR)
  743. {
  744. return S_OK;
  745. }
  746. bstrMsg = V_BSTR(pvarMsg);
  747. if (pvarUrl == NULL || V_VT(pvarUrl) != VT_BSTR)
  748. {
  749. return S_OK;
  750. }
  751. bstrUrl = V_BSTR(pvarUrl);
  752. if (pvarLine == NULL || V_VT(pvarLine) != VT_I4)
  753. {
  754. return S_OK;
  755. }
  756. iLine = V_I4(pvarLine);
  757. TRACE3(L"%s: %s: Line %d", bstrMsg, bstrUrl, iLine);
  758. #ifdef PRERELEASE
  759. WCHAR wsz[MAX_PATH];
  760. wsprintf(wsz, L"%s\nLine %d\nPlease notify OOBEDEV.", bstrUrl, iLine);
  761. MessageBox(NULL, wsz, bstrMsg, MB_ICONERROR | MB_OK | MB_DEFAULT_DESKTOP_ONLY | MB_SETFOREGROUND);
  762. #endif
  763. *pfResult = Bool2VarBool(TRUE);
  764. return S_OK;
  765. }
  766. ///////////////////////////////////////////////////////////
  767. // get_WebBrowserDoc
  768. HRESULT CObWebBrowser::get_WebBrowserDoc(IDispatch** ppDisp)
  769. {
  770. m_lpWebBrowser->get_Document(ppDisp);
  771. return S_OK;
  772. }
  773. ///////////////////////////////////////////////////////////
  774. // ListenToWebBrowserEvents
  775. HRESULT CObWebBrowser::ListenToWebBrowserEvents(IUnknown* pUnk)
  776. {
  777. //first things first
  778. if (!pUnk)
  779. return E_FAIL;
  780. //Ok, everything looks OK, try to setup a connection point.
  781. // Setup to get WebBrowserEvents
  782. return ConnectToConnectionPoint(pUnk,
  783. DIID_DWebBrowserEvents2,
  784. TRUE,
  785. (IUnknown*)m_lpWebBrowser,
  786. &m_dwcpCookie,
  787. NULL);
  788. }
  789. ///////////////////////////////////////////////////////////
  790. // StopListeningToWebBrowserEvents
  791. HRESULT CObWebBrowser::StopListeningToWebBrowserEvents(IUnknown* pUnk)
  792. {
  793. //first things first
  794. if (!pUnk)
  795. return E_FAIL;
  796. //Ok, everything looks OK, try to setup a connection point.
  797. // Setup to get WebBrowserEvents
  798. return ConnectToConnectionPoint(pUnk,
  799. DIID_DWebBrowserEvents2,
  800. FALSE,
  801. (IUnknown*)m_lpWebBrowser,
  802. &m_dwcpCookie,
  803. NULL);
  804. }
  805. HRESULT CObWebBrowser::SetExternalInterface(IUnknown* pUnk)
  806. {
  807. m_pOleSite->SetExternalInterface((IDispatch*)pUnk);
  808. return S_OK;
  809. }
  810. /////////////////////////////////////////////////////////////
  811. /////////////////////////////////////////////////////////////
  812. /////////////////////////////////////////////////////////////
  813. ////// Methods
  814. //////
  815. //////
  816. //////
  817. /////////////////////////////////////////////////////////////
  818. // CObWebBrowser::CloseOleObject
  819. void CObWebBrowser::CloseOleObject (void)
  820. {
  821. if (m_lpOleObject)
  822. {
  823. if (m_fInPlaceActive)
  824. {
  825. LPOLEINPLACEOBJECT lpObject = NULL;
  826. LPVIEWOBJECT lpViewObject = NULL;
  827. m_lpOleObject->QueryInterface(IID_IOleInPlaceObject, (LPVOID*)&lpObject);
  828. lpObject->UIDeactivate();
  829. // don't need to worry about inside-out because the object
  830. // is going away.
  831. lpObject->InPlaceDeactivate();
  832. lpObject->Release();
  833. }
  834. m_lpOleObject->Close(OLECLOSE_NOSAVE);
  835. m_hMainWnd = NULL;
  836. m_pOleSite->m_hWnd = NULL;;
  837. }
  838. }
  839. /////////////////////////////////////////////////////////////
  840. // CObWebBrowser::InitBrowserObject
  841. void CObWebBrowser::InitBrowserObject()
  842. {
  843. // If we don't have a WebBrowser object to initialize, then bail
  844. if (!m_lpWebBrowser)
  845. return;
  846. // Get An OleObject from the WebBrowser Interface
  847. if(SUCCEEDED(m_lpWebBrowser->QueryInterface(IID_IOleObject, (LPVOID*)&m_lpOleObject)) && m_lpOleObject)
  848. {
  849. m_pOleSite->m_lpOleObject = m_lpOleObject;
  850. // inform object handler/DLL object that it is used in the embedding container's context
  851. OleSetContainedObject(m_lpOleObject, TRUE);
  852. // setup the client setup
  853. m_lpOleObject->SetClientSite(m_pOleSite->m_pOleClientSite);
  854. }
  855. }
  856. /////////////////////////////////////////////////////////////
  857. // CObWebBrowser::InPlaceActivate
  858. void CObWebBrowser::InPlaceActivate()
  859. {
  860. RECT rect;
  861. m_lpOleObject->DoVerb( OLEIVERB_INPLACEACTIVATE,
  862. NULL,
  863. m_pOleSite->m_pOleClientSite,
  864. -1,
  865. m_hMainWnd,
  866. &rect);
  867. }
  868. /////////////////////////////////////////////////////////////
  869. // CObWebBrowser::UIActivate
  870. void CObWebBrowser::UIActivate()
  871. {
  872. RECT rect;
  873. m_lpOleObject->DoVerb( OLEIVERB_UIACTIVATE,
  874. NULL,
  875. m_pOleSite->m_pOleClientSite,
  876. -1,
  877. m_hMainWnd,
  878. &rect);
  879. }
  880. /////////////////////////////////////////////////////////////
  881. // CObWebBrowser::ShowWindow
  882. HRESULT CObWebBrowser::ObWebShowWindow()
  883. {
  884. RECT rect;
  885. m_lpOleObject->DoVerb( OLEIVERB_SHOW,
  886. NULL,
  887. m_pOleSite->m_pOleClientSite,
  888. -1,
  889. m_hMainWnd,
  890. &rect);
  891. //InPlaceActivate();
  892. //UIActivate();
  893. return S_OK;
  894. }
  895. HRESULT CObWebBrowser::ConnectToConnectionPoint(IUnknown* punkThis,
  896. REFIID riidEvent,
  897. BOOL fConnect,
  898. IUnknown* punkTarget,
  899. DWORD* pdwCookie,
  900. IConnectionPoint** ppcpOut)
  901. {
  902. HRESULT hr = E_FAIL;
  903. IConnectionPointContainer* pcpContainer = NULL;
  904. // We always need punkTarget, we only need punkThis on connect
  905. if (!punkTarget || (fConnect && !punkThis))
  906. {
  907. return E_FAIL;
  908. }
  909. if (ppcpOut)
  910. *ppcpOut = NULL;
  911. if (SUCCEEDED(hr = punkTarget->QueryInterface(IID_IConnectionPointContainer, (void **)&pcpContainer)))
  912. {
  913. IConnectionPoint *pcp;
  914. if(SUCCEEDED(hr = pcpContainer->FindConnectionPoint(riidEvent, &pcp)))
  915. {
  916. if(fConnect)
  917. {
  918. // Add us to the list of people interested...
  919. hr = pcp->Advise(punkThis, pdwCookie);
  920. if (FAILED(hr))
  921. *pdwCookie = 0;
  922. }
  923. else
  924. {
  925. // Remove us from the list of people interested...
  926. hr = pcp->Unadvise(*pdwCookie);
  927. *pdwCookie = 0;
  928. }
  929. if (ppcpOut && SUCCEEDED(hr))
  930. *ppcpOut = pcp;
  931. else
  932. pcp->Release();
  933. pcp = NULL;
  934. }
  935. pcpContainer->Release();
  936. pcpContainer = NULL;
  937. }
  938. return hr;
  939. }