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.

473 lines
13 KiB

  1. // wvcoord.cpp : Implementation of CWebViewCoord
  2. #include "priv.h"
  3. #include "wvcoord.h"
  4. const CLSID CLSID_WebViewOld = {0x7a707490,0x260a,0x11d1,{0x83,0xdf,0x00,0xa0,0xc9,0x0d,0xc8,0x49}}; // retired from service, so made private
  5. /////////////////////////////////////////////////////////////////////////////
  6. // CWebViewCoord
  7. /////////////////////////////////////////////////////////////////////////////
  8. CWebViewCoord::CWebViewCoord()
  9. {
  10. m_pFileListWrapper = NULL;
  11. m_pThumbNailWrapper = NULL;
  12. m_pdispWindow = NULL;
  13. m_dwFileListAdviseCookie = 0;
  14. m_dwThumbNailAdviseCookie = 0;
  15. m_dwHtmlWindowAdviseCookie = 0;
  16. m_dwCSCHotTrackCookie = 0;
  17. }
  18. CWebViewCoord::~CWebViewCoord()
  19. {
  20. ReleaseFolderObjects();
  21. }
  22. STDMETHODIMP CWebViewCoord::Invoke(DISPID dispidMember, REFIID riid, LCID lcid,
  23. WORD wFlags, DISPPARAMS *pDispParams,
  24. VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
  25. UINT *puArgErr)
  26. {
  27. HRESULT hr = S_OK;
  28. switch (dispidMember)
  29. {
  30. case DISPID_HTMLWINDOWEVENTS_ONLOAD:
  31. hr = OnWindowLoad();
  32. break;
  33. case DISPID_HTMLWINDOWEVENTS_ONUNLOAD:
  34. hr = OnWindowUnLoad();
  35. break;
  36. case DISPID_HTMLWINDOWEVENTS_ONRESIZE:
  37. hr = OnFixSize();
  38. break;
  39. case DISPID_EVMETH_ONMOUSEOVER:
  40. hr = OnCSCMouseOver();
  41. break;
  42. case DISPID_EVMETH_ONMOUSEOUT:
  43. hr = OnCSCMouseOut();
  44. break;
  45. case DISPID_EVMETH_ONKEYPRESS:
  46. case DISPID_EVMETH_ONCLICK:
  47. hr = OnCSCClick();
  48. break;
  49. default:
  50. hr = IDispatchImpl<IWebView, &IID_IWebView, &LIBID_WEBVWLib>::
  51. Invoke(dispidMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
  52. break;
  53. }
  54. return hr;
  55. }
  56. STDMETHODIMP CWebViewCoord::OnCSCClick()
  57. {
  58. HRESULT hres = S_OK;
  59. if (m_pFileListWrapper)
  60. {
  61. hres = m_pFileListWrapper->OnCSCClick();
  62. }
  63. return hres;
  64. }
  65. STDMETHODIMP CWebViewCoord::OnCSCMouseOver()
  66. {
  67. HRESULT hres = S_OK;
  68. if (m_pFileListWrapper)
  69. {
  70. hres = m_pFileListWrapper->OnCSCMouseOnOff(TRUE);
  71. }
  72. return hres;
  73. }
  74. STDMETHODIMP CWebViewCoord::OnCSCMouseOut()
  75. {
  76. HRESULT hres = S_OK;
  77. if (m_pFileListWrapper)
  78. {
  79. hres = m_pFileListWrapper->OnCSCMouseOnOff(FALSE);
  80. }
  81. return hres;
  82. }
  83. STDMETHODIMP CWebViewCoord::CSCSynchronize()
  84. {
  85. HRESULT hres = S_OK;
  86. if (m_pFileListWrapper)
  87. {
  88. hres = m_pFileListWrapper->CSCSynchronize();
  89. }
  90. return hres;
  91. }
  92. STDMETHODIMP CWebViewCoord::SetSite(IUnknown *punkSite)
  93. {
  94. HRESULT hr;
  95. if (punkSite == NULL && m_pdispWindow)
  96. {
  97. DisconnectHtmlEvents(m_pdispWindow, m_dwHtmlWindowAdviseCookie);
  98. m_dwHtmlWindowAdviseCookie = 0;
  99. }
  100. hr = IObjectWithSiteImpl<CWebViewCoord>::SetSite(punkSite);
  101. m_spClientSite = NULL; // Release client site pointer
  102. ReleaseFolderObjects();
  103. if (punkSite != NULL && SUCCEEDED(hr))
  104. {
  105. hr = punkSite->QueryInterface(IID_IOleClientSite, (void **)&m_spClientSite);
  106. if (SUCCEEDED(hr))
  107. {
  108. hr = ConnectHtmlEvents(this, m_spClientSite, &m_pdispWindow, &m_dwHtmlWindowAdviseCookie);
  109. }
  110. }
  111. return hr;
  112. }
  113. HRESULT CWebViewCoord::InitFolderObjects()
  114. {
  115. HRESULT hr;
  116. CComPtr<IOleContainer> spContainer;
  117. CComPtr<IDispatch> spdispItem;
  118. CComVariant vEmpty;
  119. CComPtr<IThumbCtl> spThumbNail;
  120. CComPtr<IHTMLElement> spElement;
  121. CComPtr<IHTMLElement> spInfo;
  122. CComPtr<IHTMLElement> spLinks;
  123. CComPtr<IHTMLElement> spMediaPlayerSpan;
  124. CComPtr<IShellFolderViewDual> spFileList;
  125. CComPtr<IHTMLElement> spCSCPlusMin;
  126. CComPtr<IHTMLElement> spCSCText;
  127. CComPtr<IHTMLElement> spCSCDetail;
  128. CComPtr<IHTMLElement> spCSCButton;
  129. CComPtr<IHTMLStyle> spCSCStyle;
  130. CComPtr<IHTMLStyle> spCSCDetailStyle;
  131. CComPtr<IHTMLStyle> spCSCButtonStyle;
  132. CComPtr<IHTMLWindow2> spWindow;
  133. // Get some document level objects
  134. IfFailRet(m_spClientSite->GetContainer(&spContainer));
  135. IfFailRet(spContainer->QueryInterface(IID_IHTMLDocument2, (void **)&m_spDocument));
  136. IfFailRet(IUnknown_QueryService(m_spClientSite, SID_SHTMLWindow, IID_IHTMLWindow2, (LPVOID*)&spWindow));
  137. IfFailRet(m_spDocument->get_all(&m_spDocAll));
  138. hr = m_spDocument->get_body(&spElement);
  139. if (SUCCEEDED(hr))
  140. {
  141. spElement->QueryInterface(IID_IHTMLControlElement, (void **)&m_spDocBody);
  142. }
  143. //
  144. // Init Info
  145. //
  146. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("Info")), vEmpty, &spdispItem)) && spdispItem)
  147. {
  148. spdispItem->QueryInterface(IID_IHTMLElement, (void **)&spInfo);
  149. spdispItem = NULL;
  150. }
  151. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("Links")), vEmpty, &spdispItem)) && spdispItem)
  152. {
  153. spdispItem->QueryInterface(IID_IHTMLElement, (void **)&spLinks);
  154. spdispItem = NULL;
  155. }
  156. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("MediaPlayerSpan")), vEmpty, &spdispItem)) && spdispItem)
  157. {
  158. spdispItem->QueryInterface(IID_IHTMLElement, (void **)&spMediaPlayerSpan);
  159. spdispItem = NULL;
  160. }
  161. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("panel")), vEmpty, &spdispItem)) && spdispItem)
  162. {
  163. FindObjectStyle(spdispItem, m_spPanelStyle);
  164. spdispItem = NULL;
  165. }
  166. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("CSC")), vEmpty, &spdispItem)) && spdispItem)
  167. {
  168. FindObjectStyle(spdispItem, spCSCStyle);
  169. spdispItem = NULL;
  170. }
  171. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("CSCHotTrack")), vEmpty, &spdispItem)) && spdispItem)
  172. {
  173. //
  174. // Set up sink for CSC UI notifications to implement hot tracking and expand/collapse
  175. //
  176. AtlAdvise(spdispItem, GetUnknown(), IID_IDispatch, &m_dwCSCHotTrackCookie);
  177. spdispItem = NULL;
  178. }
  179. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("CSCPlusMin")), vEmpty, &spdispItem)) && spdispItem)
  180. {
  181. spdispItem->QueryInterface(IID_IHTMLElement, (void **)&spCSCPlusMin);
  182. spdispItem = NULL;
  183. }
  184. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("CSCText")), vEmpty, &spdispItem)) && spdispItem)
  185. {
  186. spdispItem->QueryInterface(IID_IHTMLElement, (void **)&spCSCText);
  187. spdispItem = NULL;
  188. }
  189. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("CSCDetail")), vEmpty, &spdispItem)) && spdispItem)
  190. {
  191. spdispItem->QueryInterface(IID_IHTMLElement, (void **)&spCSCDetail);
  192. FindObjectStyle(spdispItem, spCSCDetailStyle);
  193. spdispItem = NULL;
  194. }
  195. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("CSCButton")), vEmpty, &spdispItem)) && spdispItem)
  196. {
  197. spdispItem->QueryInterface(IID_IHTMLElement, (void **)&spCSCButton);
  198. FindObjectStyle(spdispItem, spCSCButtonStyle);
  199. spdispItem = NULL;
  200. }
  201. //
  202. // Init the thumbnail wrapper object
  203. //
  204. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("ThumbNail")), vEmpty, &spdispItem)) && spdispItem)
  205. {
  206. if (SUCCEEDED(spdispItem->QueryInterface(IID_IThumbCtl, (void **)&spThumbNail)))
  207. {
  208. m_pThumbNailWrapper = new CThumbNailWrapper;
  209. if (m_pThumbNailWrapper == NULL)
  210. {
  211. return E_OUTOFMEMORY;
  212. }
  213. CComPtr<IDispatch> spdispItem2;
  214. CComPtr<IHTMLElement> spThumbnailLabel;
  215. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("ThumbnailLabel")), vEmpty, &spdispItem2)) && spdispItem2)
  216. {
  217. spdispItem2->QueryInterface(IID_IHTMLElement, (void **)&spThumbnailLabel);
  218. spdispItem2 = NULL;
  219. }
  220. m_pThumbNailWrapper->Init(spThumbNail, spThumbnailLabel);
  221. AtlAdvise(spdispItem, m_pThumbNailWrapper, IID_IDispatch, &m_dwThumbNailAdviseCookie);
  222. }
  223. spdispItem = NULL;
  224. }
  225. //
  226. // Init the file list object
  227. //
  228. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("Filelist")), vEmpty, &spdispItem)) && spdispItem)
  229. {
  230. if (SUCCEEDED(spdispItem->QueryInterface(IID_IShellFolderViewDual, (void **)&spFileList)))
  231. {
  232. m_pFileListWrapper = new CFileListWrapper;
  233. if (m_pFileListWrapper == NULL)
  234. {
  235. AtlUnadvise(spdispItem, IID_IDispatch, m_dwThumbNailAdviseCookie);
  236. m_dwThumbNailAdviseCookie = 0;
  237. delete m_pThumbNailWrapper;
  238. return E_OUTOFMEMORY;
  239. }
  240. m_pFileListWrapper->Init(spFileList, spInfo, spLinks, m_spPanelStyle, spMediaPlayerSpan,
  241. spCSCPlusMin, spCSCText, spCSCDetail, spCSCButton, spCSCStyle,
  242. spCSCDetailStyle, spCSCButtonStyle, m_spDocument, spWindow, m_pThumbNailWrapper);
  243. AtlAdvise(spdispItem, m_pFileListWrapper, IID_IDispatch,
  244. &m_dwFileListAdviseCookie);
  245. }
  246. spdispItem = NULL;
  247. }
  248. //
  249. // Init onsize properties
  250. //
  251. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("Banner")), vEmpty, &spdispItem)) && spdispItem)
  252. {
  253. spdispItem->QueryInterface(IID_IHTMLElement, (void **)&m_spHeading);
  254. FindObjectStyle(spdispItem, m_spHeadingStyle);
  255. spdispItem = NULL;
  256. }
  257. m_bRTLDocument = IsRTLDocument(m_spDocument);
  258. if (!m_bRTLDocument && m_spPanelStyle)
  259. {
  260. m_spPanelStyle->put_overflow(OLESTR("auto"));
  261. }
  262. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("FileList")), vEmpty, &spdispItem)) && spdispItem)
  263. {
  264. FindObjectStyle(spdispItem, m_spFileListStyle);
  265. spdispItem = NULL;
  266. }
  267. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("rule")), vEmpty, &spdispItem)) && spdispItem)
  268. {
  269. FindObjectStyle(spdispItem, m_spRuleStyle);
  270. spdispItem = NULL;
  271. }
  272. return S_OK;
  273. }
  274. HRESULT CWebViewCoord::ReleaseFolderObjects()
  275. {
  276. CComPtr<IDispatch> spdisp;
  277. //
  278. // Do the unadvise
  279. //
  280. if (m_dwCSCHotTrackCookie)
  281. {
  282. CComVariant vEmpty;
  283. if (SUCCEEDED(m_spDocAll->item(CComVariant(OLESTR("CSCHotTrack")), vEmpty, &spdisp)) && spdisp)
  284. {
  285. AtlUnadvise(spdisp, IID_IDispatch, m_dwCSCHotTrackCookie);
  286. m_dwCSCHotTrackCookie = 0;
  287. spdisp = NULL;
  288. }
  289. }
  290. if (m_dwFileListAdviseCookie != 0) {
  291. spdisp = m_pFileListWrapper->Control();
  292. if (spdisp != NULL) {
  293. AtlUnadvise(spdisp, IID_IDispatch, m_dwFileListAdviseCookie);
  294. m_dwFileListAdviseCookie = 0;
  295. spdisp = NULL;
  296. }
  297. }
  298. if (m_dwThumbNailAdviseCookie != 0) {
  299. spdisp = (IThumbCtl *)(m_pThumbNailWrapper->Control());
  300. if (spdisp != NULL) {
  301. AtlUnadvise(spdisp, IID_IDispatch, m_dwThumbNailAdviseCookie);
  302. m_dwThumbNailAdviseCookie = 0;
  303. spdisp = NULL;
  304. }
  305. }
  306. //
  307. // Free the file list wrapper
  308. //
  309. if (m_pFileListWrapper != NULL) {
  310. // Need to unadvise from WV links before releasing
  311. m_pFileListWrapper->AdviseWebviewLinks( FALSE );
  312. m_pFileListWrapper->Release();
  313. m_pFileListWrapper = NULL;
  314. }
  315. if (m_pThumbNailWrapper != NULL) {
  316. m_pThumbNailWrapper->Release();
  317. m_pThumbNailWrapper = NULL;
  318. }
  319. //
  320. // Free any references we may have
  321. //
  322. m_spDocAll = NULL;
  323. m_spDocBody = NULL;
  324. m_spDocument = NULL;
  325. m_spFileListStyle = NULL;
  326. m_spHeading = NULL;
  327. m_spHeadingStyle = NULL;
  328. m_spPanelStyle = NULL;
  329. m_spRuleStyle = NULL;
  330. return S_OK;
  331. }
  332. HRESULT CWebViewCoord::OnWindowLoad()
  333. {
  334. HRESULT hr;
  335. ReleaseFolderObjects();
  336. InitFolderObjects();
  337. hr = OnFixSize();
  338. return hr;
  339. }
  340. HRESULT CWebViewCoord::OnWindowUnLoad()
  341. {
  342. return ReleaseFolderObjects();
  343. }
  344. HRESULT CWebViewCoord::OnFixSize()
  345. {
  346. HRESULT hr = S_OK;
  347. LONG lClientWidth;
  348. if (m_spFileListStyle && m_spDocBody && SUCCEEDED(m_spDocBody->get_clientWidth(&lClientWidth)))
  349. {
  350. LONG lPanelWidth;
  351. if (!m_spPanelStyle || FAILED(m_spPanelStyle->get_pixelWidth(&lPanelWidth)))
  352. {
  353. lPanelWidth = 0;
  354. }
  355. CComBSTR bstrPanelVisibility;
  356. LONG lFileListLeft, lFileListWidth = -1;
  357. if (lClientWidth < (lPanelWidth * 2))
  358. {
  359. bstrPanelVisibility = OLESTR("hidden");
  360. lFileListLeft = 0;
  361. }
  362. else
  363. {
  364. bstrPanelVisibility = OLESTR("visible");
  365. if (m_bRTLDocument)
  366. {
  367. lFileListLeft = 0;
  368. lFileListWidth = lClientWidth - lPanelWidth;
  369. if (m_spPanelStyle)
  370. {
  371. m_spPanelStyle->put_pixelLeft(lClientWidth - lPanelWidth);
  372. }
  373. }
  374. else
  375. {
  376. lFileListLeft = lPanelWidth;
  377. }
  378. }
  379. if (m_spPanelStyle)
  380. {
  381. m_spPanelStyle->put_visibility(bstrPanelVisibility);
  382. }
  383. m_spFileListStyle->put_pixelLeft(lFileListLeft);
  384. m_spFileListStyle->put_pixelWidth((lFileListWidth == -1) ?
  385. (lClientWidth - lFileListLeft) : lFileListWidth);
  386. }
  387. return hr;
  388. }