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.

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