The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

341 lines
10KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-9 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. // (This file gets included by juce_win32_NativeCode.cpp, rather than being
  19. // compiled on its own).
  20. #if JUCE_INCLUDED_FILE && JUCE_WEB_BROWSER
  21. //==============================================================================
  22. class WebBrowserComponentInternal : public ActiveXControlComponent
  23. {
  24. public:
  25. //==============================================================================
  26. WebBrowserComponentInternal()
  27. : browser (0),
  28. connectionPoint (0),
  29. adviseCookie (0)
  30. {
  31. }
  32. ~WebBrowserComponentInternal()
  33. {
  34. if (connectionPoint != 0)
  35. connectionPoint->Unadvise (adviseCookie);
  36. if (browser != 0)
  37. browser->Release();
  38. }
  39. void createBrowser()
  40. {
  41. createControl (&CLSID_WebBrowser);
  42. browser = (IWebBrowser2*) queryInterface (&IID_IWebBrowser2);
  43. IConnectionPointContainer* connectionPointContainer = (IConnectionPointContainer*) queryInterface (&IID_IConnectionPointContainer);
  44. if (connectionPointContainer != 0)
  45. {
  46. connectionPointContainer->FindConnectionPoint (DIID_DWebBrowserEvents2,
  47. &connectionPoint);
  48. if (connectionPoint != 0)
  49. {
  50. WebBrowserComponent* const owner = dynamic_cast <WebBrowserComponent*> (getParentComponent());
  51. jassert (owner != 0);
  52. EventHandler* handler = new EventHandler (owner);
  53. connectionPoint->Advise (handler, &adviseCookie);
  54. }
  55. }
  56. }
  57. void goToURL (const String& url,
  58. const StringArray* headers,
  59. const MemoryBlock* postData)
  60. {
  61. if (browser != 0)
  62. {
  63. LPSAFEARRAY sa = 0;
  64. _variant_t flags, frame, postDataVar, headersVar;
  65. if (headers != 0)
  66. headersVar = (const tchar*) headers->joinIntoString ("\r\n");
  67. if (postData != 0 && postData->getSize() > 0)
  68. {
  69. LPSAFEARRAY sa = SafeArrayCreateVector (VT_UI1, 0, postData->getSize());
  70. if (sa != 0)
  71. {
  72. void* data = 0;
  73. SafeArrayAccessData (sa, &data);
  74. jassert (data != 0);
  75. if (data != 0)
  76. {
  77. postData->copyTo (data, 0, postData->getSize());
  78. SafeArrayUnaccessData (sa);
  79. VARIANT postDataVar2;
  80. VariantInit (&postDataVar2);
  81. V_VT (&postDataVar2) = VT_ARRAY | VT_UI1;
  82. V_ARRAY (&postDataVar2) = sa;
  83. postDataVar = postDataVar2;
  84. }
  85. }
  86. }
  87. browser->Navigate ((BSTR) (const OLECHAR*) url,
  88. &flags, &frame,
  89. &postDataVar, &headersVar);
  90. if (sa != 0)
  91. SafeArrayDestroy (sa);
  92. }
  93. }
  94. //==============================================================================
  95. IWebBrowser2* browser;
  96. //==============================================================================
  97. juce_UseDebuggingNewOperator
  98. private:
  99. IConnectionPoint* connectionPoint;
  100. DWORD adviseCookie;
  101. //==============================================================================
  102. class EventHandler : public IDispatch
  103. {
  104. public:
  105. EventHandler (WebBrowserComponent* owner_)
  106. : owner (owner_),
  107. refCount (0)
  108. {
  109. }
  110. ~EventHandler()
  111. {
  112. }
  113. //==============================================================================
  114. HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
  115. {
  116. if (id == IID_IUnknown || id == IID_IDispatch || id == DIID_DWebBrowserEvents2)
  117. {
  118. AddRef();
  119. *result = this;
  120. return S_OK;
  121. }
  122. *result = 0;
  123. return E_NOINTERFACE;
  124. }
  125. ULONG __stdcall AddRef() { return ++refCount; }
  126. ULONG __stdcall Release() { jassert (refCount > 0); const int r = --refCount; if (r == 0) delete this; return r; }
  127. HRESULT __stdcall GetTypeInfoCount (UINT __RPC_FAR*) { return E_NOTIMPL; }
  128. HRESULT __stdcall GetTypeInfo (UINT, LCID, ITypeInfo __RPC_FAR *__RPC_FAR*) { return E_NOTIMPL; }
  129. HRESULT __stdcall GetIDsOfNames (REFIID, LPOLESTR __RPC_FAR*, UINT, LCID, DISPID __RPC_FAR*) { return E_NOTIMPL; }
  130. HRESULT __stdcall Invoke (DISPID dispIdMember, REFIID /*riid*/, LCID /*lcid*/,
  131. WORD /*wFlags*/, DISPPARAMS __RPC_FAR* pDispParams,
  132. VARIANT __RPC_FAR* /*pVarResult*/, EXCEPINFO __RPC_FAR* /*pExcepInfo*/,
  133. UINT __RPC_FAR* /*puArgErr*/)
  134. {
  135. switch (dispIdMember)
  136. {
  137. case DISPID_BEFORENAVIGATE2:
  138. {
  139. VARIANT* const vurl = pDispParams->rgvarg[5].pvarVal;
  140. String url;
  141. if ((vurl->vt & VT_BYREF) != 0)
  142. url = *vurl->pbstrVal;
  143. else
  144. url = vurl->bstrVal;
  145. *pDispParams->rgvarg->pboolVal
  146. = owner->pageAboutToLoad (url) ? VARIANT_FALSE
  147. : VARIANT_TRUE;
  148. return S_OK;
  149. }
  150. default:
  151. break;
  152. }
  153. return E_NOTIMPL;
  154. }
  155. //==============================================================================
  156. juce_UseDebuggingNewOperator
  157. private:
  158. WebBrowserComponent* const owner;
  159. int refCount;
  160. EventHandler (const EventHandler&);
  161. const EventHandler& operator= (const EventHandler&);
  162. };
  163. };
  164. //==============================================================================
  165. WebBrowserComponent::WebBrowserComponent()
  166. : browser (0),
  167. blankPageShown (false)
  168. {
  169. setOpaque (true);
  170. addAndMakeVisible (browser = new WebBrowserComponentInternal());
  171. }
  172. WebBrowserComponent::~WebBrowserComponent()
  173. {
  174. delete browser;
  175. }
  176. //==============================================================================
  177. void WebBrowserComponent::goToURL (const String& url,
  178. const StringArray* headers,
  179. const MemoryBlock* postData)
  180. {
  181. lastURL = url;
  182. lastHeaders.clear();
  183. if (headers != 0)
  184. lastHeaders = *headers;
  185. lastPostData.setSize (0);
  186. if (postData != 0)
  187. lastPostData = *postData;
  188. blankPageShown = false;
  189. browser->goToURL (url, headers, postData);
  190. }
  191. void WebBrowserComponent::stop()
  192. {
  193. if (browser->browser != 0)
  194. browser->browser->Stop();
  195. }
  196. void WebBrowserComponent::goBack()
  197. {
  198. lastURL = String::empty;
  199. blankPageShown = false;
  200. if (browser->browser != 0)
  201. browser->browser->GoBack();
  202. }
  203. void WebBrowserComponent::goForward()
  204. {
  205. lastURL = String::empty;
  206. if (browser->browser != 0)
  207. browser->browser->GoForward();
  208. }
  209. void WebBrowserComponent::refresh()
  210. {
  211. if (browser->browser != 0)
  212. browser->browser->Refresh();
  213. }
  214. //==============================================================================
  215. void WebBrowserComponent::paint (Graphics& g)
  216. {
  217. if (browser->browser == 0)
  218. g.fillAll (Colours::white);
  219. }
  220. void WebBrowserComponent::checkWindowAssociation()
  221. {
  222. if (isShowing())
  223. {
  224. if (browser->browser == 0 && getPeer() != 0)
  225. {
  226. browser->createBrowser();
  227. reloadLastURL();
  228. }
  229. else
  230. {
  231. if (blankPageShown)
  232. goBack();
  233. }
  234. }
  235. else
  236. {
  237. if (browser != 0 && ! blankPageShown)
  238. {
  239. // when the component becomes invisible, some stuff like flash
  240. // carries on playing audio, so we need to force it onto a blank
  241. // page to avoid this..
  242. blankPageShown = true;
  243. browser->goToURL ("about:blank", 0, 0);
  244. }
  245. }
  246. }
  247. void WebBrowserComponent::reloadLastURL()
  248. {
  249. if (lastURL.isNotEmpty())
  250. {
  251. goToURL (lastURL, &lastHeaders, &lastPostData);
  252. lastURL = String::empty;
  253. }
  254. }
  255. void WebBrowserComponent::parentHierarchyChanged()
  256. {
  257. checkWindowAssociation();
  258. }
  259. void WebBrowserComponent::resized()
  260. {
  261. browser->setSize (getWidth(), getHeight());
  262. }
  263. void WebBrowserComponent::visibilityChanged()
  264. {
  265. checkWindowAssociation();
  266. }
  267. bool WebBrowserComponent::pageAboutToLoad (const String&)
  268. {
  269. return true;
  270. }
  271. #endif