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.

686 lines
18 KiB

  1. // WebCtrl.cpp : implementation file
  2. //
  3. //+-------------------------------------------------------------------------
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 1999
  7. //
  8. // File: amcwebviewctrl.cpp
  9. //
  10. // Contents: AMC Private web view control hosting IE 3.x and 4.x
  11. //
  12. // History: 16-Jul-96 WayneSc Created
  13. //
  14. //
  15. //--------------------------------------------------------------------------
  16. #include "stdafx.h"
  17. #include "amc.h"
  18. #include "amcview.h"
  19. #include "histlist.h"
  20. #include "exdisp.h" // for the IE dispatch interfaces.
  21. #include "websnk.h"
  22. #include "evtsink.h"
  23. #include "WebCtrl.h"
  24. #include "atliface.h"
  25. #include "mainfrm.h"
  26. #include "statbar.h"
  27. #ifdef DBG
  28. CTraceTag tagVivekDefaultWebContextMenu (_T("Vivek"), _T("Use default web context menu"));
  29. #endif
  30. /*+-------------------------------------------------------------------------*
  31. * class CDocHostUIHandlerDispatch
  32. *
  33. *
  34. * PURPOSE: Implements the interface required by ATL to find out about
  35. * UI hosting.
  36. *
  37. *+-------------------------------------------------------------------------*/
  38. class CDocHostUIHandlerDispatch :
  39. public IDocHostUIHandlerDispatch,
  40. public CComObjectRoot
  41. {
  42. private:
  43. ViewPtr m_spView; // a pointer to the parent AMCView's dispatch interface
  44. public:
  45. BEGIN_COM_MAP(CDocHostUIHandlerDispatch)
  46. COM_INTERFACE_ENTRY(IDispatch)
  47. COM_INTERFACE_ENTRY(IDocHostUIHandlerDispatch)
  48. END_COM_MAP()
  49. DECLARE_NOT_AGGREGATABLE(CDocHostUIHandlerDispatch)
  50. // initialization
  51. SC ScInitialize(PVIEW pView)
  52. {
  53. DECLARE_SC(sc, TEXT("CDocHostUIHandlerDispatch::ScInitialize"));
  54. sc = ScCheckPointers(pView);
  55. if(sc)
  56. return sc;
  57. // should not initialize twice
  58. if(m_spView)
  59. return (sc=E_UNEXPECTED);
  60. m_spView = pView;
  61. return sc;
  62. }
  63. // IDispatch
  64. STDMETHOD(GetTypeInfoCount)(UINT* pctinfo) {return E_NOTIMPL;}
  65. STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) {return E_NOTIMPL;}
  66. STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
  67. LCID lcid, DISPID* rgdispid) {return E_NOTIMPL;}
  68. STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid,
  69. LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
  70. EXCEPINFO* pexcepinfo, UINT* puArgErr) {return E_NOTIMPL;}
  71. // IDocHostUIHandlerDispatch
  72. STDMETHODIMP ShowContextMenu (DWORD dwID, DWORD x, DWORD y, IUnknown* pcmdtReserved,
  73. IDispatch* pdispReserved, HRESULT* dwRetVal);
  74. STDMETHODIMP GetHostInfo( DWORD* pdwFlags, DWORD* pdwDoubleClick);
  75. // a helper function for all the methods that return S_FALSE;
  76. SC ScFalse(HRESULT* dwRetVal)
  77. {
  78. DECLARE_SC(sc, TEXT("CDocHostUIHandlerDispatch::ScFalse"));
  79. sc = ScCheckPointers(dwRetVal);
  80. if(sc)
  81. return sc.ToHr();
  82. *dwRetVal = S_FALSE;
  83. return sc.ToHr();
  84. }
  85. STDMETHODIMP ShowUI(DWORD dwID, IUnknown* pActiveObject, IUnknown* pCommandTarget,
  86. IUnknown* pFrame, IUnknown* pDoc, HRESULT* dwRetVal)
  87. {return ScFalse(dwRetVal).ToHr();}
  88. STDMETHODIMP HideUI() {return S_OK;}
  89. STDMETHODIMP UpdateUI() {return S_OK;}
  90. STDMETHODIMP EnableModeless(VARIANT_BOOL fEnable) {return E_NOTIMPL;}
  91. STDMETHODIMP OnDocWindowActivate(VARIANT_BOOL fActivate) {return S_OK;}
  92. STDMETHODIMP OnFrameWindowActivate(VARIANT_BOOL fActivate) {return S_OK;}
  93. STDMETHODIMP ResizeBorder(long left, long top, long right,
  94. long bottom, IUnknown* pUIWindow,
  95. VARIANT_BOOL fFrameWindow) {return E_NOTIMPL;}
  96. STDMETHODIMP TranslateAccelerator( DWORD hWnd, DWORD nMessage,
  97. DWORD wParam, DWORD lParam,
  98. BSTR bstrGuidCmdGroup,
  99. DWORD nCmdID,
  100. HRESULT* dwRetVal) {return ScFalse(dwRetVal).ToHr();}
  101. STDMETHODIMP GetOptionKeyPath( BSTR* pbstrKey, DWORD dw)
  102. {
  103. DECLARE_SC(sc, TEXT("CDocHostUIHandlerDispatch::GetOptionKeyPath"));
  104. sc = ScCheckPointers(pbstrKey);
  105. if(sc)
  106. return sc.ToHr();
  107. *pbstrKey = NULL;
  108. return S_FALSE;
  109. }
  110. STDMETHODIMP GetDropTarget( IUnknown* pDropTarget, IUnknown** ppDropTarget) {return E_NOTIMPL;}
  111. STDMETHODIMP GetExternal( IDispatch **ppDispatch) // returns a pointer to the view.
  112. {
  113. DECLARE_SC(sc, TEXT("CDocHostUIHandlerDispatch::GetExternal"));
  114. // set up the connection to the external object.
  115. sc = ScCheckPointers(m_spView, E_UNEXPECTED);
  116. if(sc)
  117. return sc.ToHr();
  118. *ppDispatch = m_spView;
  119. (*ppDispatch)->AddRef(); // addref for the client.
  120. return sc.ToHr();
  121. }
  122. STDMETHODIMP TranslateUrl( DWORD dwTranslate, BSTR bstrURLIn, BSTR* pbstrURLOut)
  123. {
  124. DECLARE_SC(sc, TEXT("CDocHostUIHandlerDispatch::TranslateUrl"));
  125. sc = ScCheckPointers(pbstrURLOut);
  126. if(sc)
  127. return sc.ToHr();
  128. *pbstrURLOut = NULL;
  129. return S_FALSE;
  130. }
  131. STDMETHODIMP FilterDataObject(IUnknown*pDO, IUnknown**ppDORet)
  132. {
  133. DECLARE_SC(sc, TEXT("CDocHostUIHandlerDispatch::FilterDataObject"));
  134. sc = ScCheckPointers(ppDORet);
  135. if(sc)
  136. return sc.ToHr();
  137. *ppDORet = NULL;
  138. return S_FALSE;
  139. }
  140. };
  141. /*+-------------------------------------------------------------------------*
  142. * ShouldShowDefaultWebContextMenu
  143. *
  144. * Returns true if we should display the default MSHTML context menu,
  145. * false if we want to display our own (or suppress it altogether)
  146. *--------------------------------------------------------------------------*/
  147. bool IsDefaultWebContextMenuDesired ()
  148. {
  149. #ifdef DBG
  150. return (tagVivekDefaultWebContextMenu.FAny());
  151. #else
  152. return (false);
  153. #endif
  154. }
  155. /*+-------------------------------------------------------------------------*
  156. *
  157. * CDocHostUIHandlerDispatch::ShowContextMenu
  158. *
  159. * PURPOSE: Handles IE's hook to display context menus. Does not do anything
  160. * and returns to IE with the code to not display menus.
  161. *
  162. * PARAMETERS:
  163. * DWORD dwID :
  164. * DWORD x :
  165. * DWORD y :
  166. * IUnknown* pcmdtReserved :
  167. * IDispatch* pdispReserved :
  168. * HRESULT* dwRetVal :
  169. *
  170. * RETURNS:
  171. * STDMETHODIMP
  172. *
  173. *+-------------------------------------------------------------------------*/
  174. STDMETHODIMP
  175. CDocHostUIHandlerDispatch::ShowContextMenu (DWORD dwID, DWORD x, DWORD y, IUnknown* pcmdtReserved,
  176. IDispatch* pdispReserved, HRESULT* dwRetVal)
  177. {
  178. DECLARE_SC(sc, TEXT("CDocHostUIHandlerDispatch::ShowContextMenu"));
  179. // validate input
  180. sc = ScCheckPointers(dwRetVal);
  181. if(sc)
  182. return sc.ToHr();
  183. *dwRetVal = S_OK; // default: don't display.
  184. // Create context menu for console taskpads.
  185. // must be in author mode for a menu to show up.
  186. if (AMCGetApp()->GetMode() != eMode_Author)
  187. return sc.ToHr(); // prevent browser from displaying its menus.
  188. // Is it a console taskpad
  189. CMainFrame* pFrame = AMCGetMainWnd();
  190. sc = ScCheckPointers (pFrame, E_UNEXPECTED);
  191. if (sc)
  192. return (sc.ToHr());
  193. CConsoleView* pConsoleView;
  194. sc = pFrame->ScGetActiveConsoleView (pConsoleView);
  195. if (sc)
  196. return sc.ToHr();
  197. /*
  198. * ScGetActiveConsoleView will return success (S_FALSE) even if there's no
  199. * active view. This is a valid case, occuring when there's no console
  200. * file open. In this particular circumstance, it is an unexpected
  201. * failure since we shouldn't get to this point in the code if there's
  202. * no view.
  203. */
  204. sc = ScCheckPointers (pConsoleView, E_UNEXPECTED);
  205. if (sc)
  206. return (sc.ToHr());
  207. /*
  208. * it we want to let the web browser show it own context menu, return
  209. * S_FALSE so it will do so; otherwise, display the context menu we want
  210. */
  211. sc = (IsDefaultWebContextMenuDesired())
  212. ? SC(S_FALSE)
  213. : pConsoleView->ScShowWebContextMenu ();
  214. // the real return value is in the out parameter.
  215. *dwRetVal = sc.ToHr();
  216. return sc.ToHr();
  217. }
  218. /*+-------------------------------------------------------------------------*
  219. *
  220. * CDocHostUIHandlerDispatch::GetHostInfo
  221. *
  222. * PURPOSE: Indicates to IE not to display context menus.
  223. *
  224. * PARAMETERS:
  225. * DWORD* pdwFlags :
  226. * DWORD* pdwDoubleClick :
  227. *
  228. * RETURNS:
  229. * STDMETHODIMP
  230. *
  231. *+-------------------------------------------------------------------------*/
  232. STDMETHODIMP
  233. CDocHostUIHandlerDispatch::GetHostInfo( DWORD* pdwFlags, DWORD* pdwDoubleClick)
  234. {
  235. DECLARE_SC(sc, TEXT("CDocHostUIHandlerDispatch::GetHostInfo"));
  236. sc = ScCheckPointers(pdwFlags, pdwDoubleClick);
  237. if(sc)
  238. return sc.ToHr();
  239. // Disable context menus
  240. *pdwFlags = DOCHOSTUIFLAG_DISABLE_HELP_MENU;
  241. *pdwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
  242. return sc.ToHr();
  243. }
  244. /////////////////////////////////////////////////////////////////////////////
  245. // CAMCWebViewCtrl
  246. IMPLEMENT_DYNCREATE(CAMCWebViewCtrl, COCXHostView)
  247. CAMCWebViewCtrl::CAMCWebViewCtrl() : m_dwAdviseCookie(0)
  248. {
  249. }
  250. LPUNKNOWN CAMCWebViewCtrl::GetIUnknown(void)
  251. {
  252. return m_spWebBrowser2;
  253. }
  254. CAMCWebViewCtrl::~CAMCWebViewCtrl()
  255. {
  256. }
  257. BEGIN_MESSAGE_MAP(CAMCWebViewCtrl, CAMCWebViewCtrl::BaseClass)
  258. //{{AFX_MSG_MAP(CAMCWebViewCtrl)
  259. ON_WM_CREATE()
  260. ON_WM_DESTROY()
  261. //}}AFX_MSG_MAP
  262. END_MESSAGE_MAP()
  263. /////////////////////////////////////////////////////////////////////////////
  264. // CAMCWebViewCtrl message handlers
  265. void CAMCWebViewCtrl::OnDraw(CDC* pDC)
  266. {
  267. }
  268. void
  269. CAMCWebViewCtrl::OnDestroy()
  270. {
  271. if(m_spWebBrowser2)
  272. {
  273. if (m_dwAdviseCookie != 0)
  274. {
  275. AtlUnadvise(m_spWebBrowser2, DIID_DWebBrowserEvents, m_dwAdviseCookie /*the connection ID*/);
  276. m_dwAdviseCookie = 0;
  277. }
  278. m_spWebBrowser2.Release();
  279. }
  280. BaseClass::OnDestroy();
  281. }
  282. /*+-------------------------------------------------------------------------*
  283. *
  284. * CAMCWebViewCtrl::ScCreateWebBrowser
  285. *
  286. * PURPOSE: Creates the IWebBrowser2 object, and sets up the external UI
  287. * handler and event sink.
  288. *
  289. * RETURNS:
  290. * SC
  291. *
  292. *+-------------------------------------------------------------------------*/
  293. SC
  294. CAMCWebViewCtrl::ScCreateWebBrowser()
  295. {
  296. DECLARE_SC(sc, TEXT("CAMCWebViewCtrl::ScCreateWebBrowser"));
  297. sc = ScCheckPointers(GetAMCView(), GetAxWindow());
  298. if(sc)
  299. return sc;
  300. // create the OCX host window
  301. RECT rcClient;
  302. GetClientRect(&rcClient);
  303. GetAxWindow()->Create(m_hWnd, rcClient, _T(""), (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) );
  304. // create the web control
  305. CCoTaskMemPtr<OLECHAR> spstrWebBrowser;
  306. sc = StringFromCLSID(CLSID_WebBrowser, &spstrWebBrowser);
  307. if (sc)
  308. return sc;
  309. sc = GetAxWindow()->CreateControl(spstrWebBrowser);
  310. if(sc)
  311. return sc;
  312. // get a pointer to the web browser control.
  313. sc = GetAxWindow()->QueryControl(IID_IWebBrowser2, (void **) &m_spWebBrowser2);
  314. if(sc)
  315. return sc;
  316. sc = ScCheckPointers((IWebBrowser2 *)m_spWebBrowser2);
  317. if(sc)
  318. return sc;
  319. // attach the control to the history list, if history is enabled
  320. if (IsHistoryEnabled())
  321. {
  322. sc = ScCheckPointers(GetAMCView()->GetHistoryList());
  323. if(sc)
  324. return sc;
  325. GetAMCView()->GetHistoryList()->Attach (this);
  326. }
  327. // get a pointer to the view object
  328. ViewPtr spView;
  329. sc = GetAMCView()->ScGetMMCView(&spView);
  330. if(sc)
  331. return sc;
  332. // Set up the External UI Handler.
  333. typedef CComObject<CDocHostUIHandlerDispatch> CDocHandler;
  334. CDocHandler *pDocHandler = NULL;
  335. sc = CDocHandler::CreateInstance(&pDocHandler);
  336. if(sc)
  337. return sc;
  338. if(!pDocHandler)
  339. return (sc = E_UNEXPECTED);
  340. CComPtr<IDocHostUIHandlerDispatch> spIDocHostUIHandlerDispatch = pDocHandler;
  341. if(!spIDocHostUIHandlerDispatch)
  342. return (sc = E_UNEXPECTED);
  343. // initialize the dochandler
  344. sc = pDocHandler->ScInitialize(spView);
  345. if(sc)
  346. return sc;
  347. sc = GetAxWindow()->SetExternalUIHandler(spIDocHostUIHandlerDispatch); // no need to addref.
  348. if(sc)
  349. return sc;
  350. // set up the Web Event Sink, if requested
  351. if (IsSinkEventsEnabled())
  352. {
  353. typedef CComObject<CWebEventSink> CEventSink;
  354. CEventSink *pEventSink;
  355. sc = CEventSink::CreateInstance(&pEventSink);
  356. if(sc)
  357. return sc;
  358. sc = pEventSink->ScInitialize(this);
  359. if(sc)
  360. return sc;
  361. m_spWebSink = pEventSink; // addref's it.
  362. // create the connection
  363. sc = AtlAdvise(m_spWebBrowser2, (LPDISPATCH)(IWebSink *)m_spWebSink,
  364. DIID_DWebBrowserEvents, &m_dwAdviseCookie/*the connection ID*/);
  365. if(sc)
  366. return sc;
  367. if (m_dwAdviseCookie == 0)
  368. return (sc = E_UNEXPECTED);
  369. }
  370. return sc;
  371. }
  372. /*+-------------------------------------------------------------------------*
  373. *
  374. * CAMCWebViewCtrl::OnCreate
  375. *
  376. * PURPOSE:
  377. *
  378. * PARAMETERS:
  379. * LPCREATESTRUCT lpCreateStruct :
  380. *
  381. * RETURNS:
  382. * int
  383. *
  384. *+-------------------------------------------------------------------------*/
  385. int
  386. CAMCWebViewCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
  387. {
  388. DECLARE_SC(sc, TEXT("CAMCWebViewCtrl::OnCreate"));
  389. if (BaseClass::OnCreate(lpCreateStruct) == -1)
  390. return -1;
  391. sc = ScCreateWebBrowser();
  392. if(sc)
  393. return 0;
  394. /*
  395. * The client edge is supplied by the OCX host view now. We do this so
  396. * we can give a nice edge to OCX's that don't support IDispatch (like
  397. * CMessageView). ModifyStyleEx for OCX's is implemented as a change
  398. * to the Border Style stock property, which is done via IDispatch.
  399. * If the OCX doesn't support IDispatch, we can't change its border.
  400. * If the client edge is supplied by the OCX host view, we don't need
  401. * to change the OCX's border
  402. */
  403. ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
  404. return 0;
  405. }
  406. // REVIEW add other members from old file
  407. void CAMCWebViewCtrl::Navigate(LPCTSTR lpszWebSite, LPCTSTR lpszFrameTarget)
  408. {
  409. DECLARE_SC(sc, TEXT("CAMCWebViewCtrl::ScNavigate"));
  410. USES_CONVERSION;
  411. sc = ScCheckPointers(m_spWebBrowser2, GetAMCView());
  412. if(sc)
  413. return;
  414. CHistoryList *pHistoryList = NULL;
  415. if (IsHistoryEnabled())
  416. {
  417. pHistoryList = GetAMCView()->GetHistoryList();
  418. if(!pHistoryList)
  419. {
  420. sc = E_POINTER;
  421. return;
  422. }
  423. }
  424. CComBSTR bstrURL (T2COLE(lpszWebSite));
  425. CComVariant vtFlags ( (long) 0);
  426. CComVariant vtTarget (T2COLE(lpszFrameTarget));
  427. CComVariant vtPostData;
  428. CComVariant vtHeaders;
  429. // What does this DoVerb do?
  430. /*
  431. if (FAILED((hr=DoVerb(OLEIVERB_PRIMARY))))
  432. {
  433. TRACE(_T("DoVerb failed: %X\n"), hr);
  434. return hr;
  435. } */
  436. sc = m_spWebBrowser2->Navigate(bstrURL, &vtFlags, &vtTarget, &vtPostData, &vtHeaders);
  437. if(sc)
  438. return;
  439. // check errors here.
  440. if (pHistoryList != NULL)
  441. pHistoryList->UpdateWebBar (HB_STOP, TRUE); // turn on "stop" button
  442. }
  443. void CAMCWebViewCtrl::Back()
  444. {
  445. DECLARE_SC(sc, TEXT("CAMCWebViewCtrl::Back"));
  446. /*
  447. * if history isn't enabled, we can't go back
  448. */
  449. if (!IsHistoryEnabled())
  450. {
  451. sc = E_FAIL;
  452. return;
  453. }
  454. // check parameters.
  455. sc = ScCheckPointers(m_spWebBrowser2, GetAMCView());
  456. if(sc)
  457. return;
  458. CHistoryList *pHistoryList = GetAMCView()->GetHistoryList();
  459. if(!pHistoryList)
  460. {
  461. sc = E_POINTER;
  462. return;
  463. }
  464. Stop();
  465. // give a chance to History to handle the Back notification.
  466. // If not handled, use the web browser
  467. bool bHandled = false;
  468. pHistoryList->Back (bHandled);
  469. if(!bHandled)
  470. {
  471. sc = m_spWebBrowser2->GoBack();
  472. if(sc)
  473. return;
  474. }
  475. }
  476. void CAMCWebViewCtrl::Forward()
  477. {
  478. DECLARE_SC(sc, TEXT("CAMCWebViewCtrl::Forward"));
  479. /*
  480. * if history isn't enabled, we can't go forward
  481. */
  482. if (!IsHistoryEnabled())
  483. {
  484. sc = E_FAIL;
  485. return;
  486. }
  487. // check parameters.
  488. sc = ScCheckPointers(m_spWebBrowser2, GetAMCView());
  489. if(sc)
  490. return;
  491. CHistoryList *pHistoryList = GetAMCView()->GetHistoryList();
  492. if(!pHistoryList)
  493. {
  494. sc = E_POINTER;
  495. return;
  496. }
  497. Stop();
  498. // give a chance to History to handle the Forward notification.
  499. // If not handled, use the web browser
  500. bool bHandled = false;
  501. pHistoryList->Forward (bHandled);
  502. if(!bHandled)
  503. {
  504. sc = m_spWebBrowser2->GoForward();
  505. if(sc)
  506. return;
  507. }
  508. }
  509. void CAMCWebViewCtrl::Stop()
  510. {
  511. DECLARE_SC(sc, TEXT("CAMCWebViewCtrl::Stop"));
  512. // check parameters.
  513. sc = ScCheckPointers(m_spWebBrowser2, GetAMCView());
  514. if(sc)
  515. return;
  516. CHistoryList *pHistoryList = NULL;
  517. if (IsHistoryEnabled())
  518. {
  519. pHistoryList = GetAMCView()->GetHistoryList();
  520. if(!pHistoryList)
  521. {
  522. sc = E_POINTER;
  523. return;
  524. }
  525. }
  526. sc = m_spWebBrowser2->Stop();
  527. if(sc)
  528. return;
  529. if (pHistoryList != NULL)
  530. pHistoryList->UpdateWebBar (HB_STOP, FALSE); // turn off "stop" button
  531. }
  532. void CAMCWebViewCtrl::Refresh()
  533. {
  534. DECLARE_SC(sc, TEXT("CAMCWebViewCtrl::Refresh"));
  535. sc = ScCheckPointers(m_spWebBrowser2);
  536. if(sc)
  537. return;
  538. sc = m_spWebBrowser2->Refresh();
  539. if(sc)
  540. return;
  541. }
  542. SC CAMCWebViewCtrl::ScGetReadyState(READYSTATE& readyState)
  543. {
  544. DECLARE_SC (sc, _T("CAMCWebViewCtrl::ScGetReadyState"));
  545. readyState = READYSTATE_UNINITIALIZED;
  546. sc = ScCheckPointers(m_spWebBrowser2);
  547. if(sc)
  548. return sc;
  549. sc = m_spWebBrowser2->get_ReadyState(&readyState);
  550. if(sc)
  551. return sc;
  552. return sc;
  553. }