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-7 by Raw Material Software ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the
  7. GNU General Public License, as published by the Free Software Foundation;
  8. either version 2 of the License, or (at your option) any later version.
  9. JUCE is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with JUCE; if not, visit www.gnu.org/licenses or write to the
  15. Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  16. Boston, MA 02111-1307 USA
  17. ------------------------------------------------------------------------------
  18. If you'd like to release a closed-source product which uses JUCE, commercial
  19. licenses are also available: visit www.rawmaterialsoftware.com/juce for
  20. more information.
  21. ==============================================================================
  22. */
  23. // (This file gets included by juce_win32_NativeCode.cpp, rather than being
  24. // compiled on its own).
  25. #if JUCE_INCLUDED_FILE && JUCE_WEB_BROWSER
  26. //==============================================================================
  27. class WebBrowserComponentInternal : public ActiveXControlComponent
  28. {
  29. public:
  30. //==============================================================================
  31. WebBrowserComponentInternal()
  32. : browser (0),
  33. connectionPoint (0),
  34. adviseCookie (0)
  35. {
  36. }
  37. ~WebBrowserComponentInternal()
  38. {
  39. if (connectionPoint != 0)
  40. connectionPoint->Unadvise (adviseCookie);
  41. if (browser != 0)
  42. browser->Release();
  43. }
  44. void createBrowser()
  45. {
  46. createControl (&CLSID_WebBrowser);
  47. browser = (IWebBrowser2*) queryInterface (&IID_IWebBrowser2);
  48. IConnectionPointContainer* connectionPointContainer = (IConnectionPointContainer*) queryInterface (&IID_IConnectionPointContainer);
  49. if (connectionPointContainer != 0)
  50. {
  51. connectionPointContainer->FindConnectionPoint (DIID_DWebBrowserEvents2,
  52. &connectionPoint);
  53. if (connectionPoint != 0)
  54. {
  55. WebBrowserComponent* const owner = dynamic_cast <WebBrowserComponent*> (getParentComponent());
  56. jassert (owner != 0);
  57. EventHandler* handler = new EventHandler (owner);
  58. connectionPoint->Advise (handler, &adviseCookie);
  59. }
  60. }
  61. }
  62. void goToURL (const String& url,
  63. const StringArray* headers,
  64. const MemoryBlock* postData)
  65. {
  66. if (browser != 0)
  67. {
  68. LPSAFEARRAY sa = 0;
  69. _variant_t flags, frame, postDataVar, headersVar;
  70. if (headers != 0)
  71. headersVar = (const tchar*) headers->joinIntoString ("\r\n");
  72. if (postData != 0 && postData->getSize() > 0)
  73. {
  74. LPSAFEARRAY sa = SafeArrayCreateVector (VT_UI1, 0, postData->getSize());
  75. if (sa != 0)
  76. {
  77. void* data = 0;
  78. SafeArrayAccessData (sa, &data);
  79. jassert (data != 0);
  80. if (data != 0)
  81. {
  82. postData->copyTo (data, 0, postData->getSize());
  83. SafeArrayUnaccessData (sa);
  84. VARIANT postDataVar2;
  85. VariantInit (&postDataVar2);
  86. V_VT (&postDataVar2) = VT_ARRAY | VT_UI1;
  87. V_ARRAY (&postDataVar2) = sa;
  88. postDataVar = postDataVar2;
  89. }
  90. }
  91. }
  92. browser->Navigate ((BSTR) (const OLECHAR*) url,
  93. &flags, &frame,
  94. &postDataVar, &headersVar);
  95. if (sa != 0)
  96. SafeArrayDestroy (sa);
  97. }
  98. }
  99. //==============================================================================
  100. IWebBrowser2* browser;
  101. //==============================================================================
  102. juce_UseDebuggingNewOperator
  103. private:
  104. IConnectionPoint* connectionPoint;
  105. DWORD adviseCookie;
  106. //==============================================================================
  107. class EventHandler : public IDispatch
  108. {
  109. public:
  110. EventHandler (WebBrowserComponent* owner_)
  111. : owner (owner_),
  112. refCount (0)
  113. {
  114. }
  115. ~EventHandler()
  116. {
  117. }
  118. //==============================================================================
  119. HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
  120. {
  121. if (id == IID_IUnknown || id == IID_IDispatch || id == DIID_DWebBrowserEvents2)
  122. {
  123. AddRef();
  124. *result = this;
  125. return S_OK;
  126. }
  127. *result = 0;
  128. return E_NOINTERFACE;
  129. }
  130. ULONG __stdcall AddRef() { return ++refCount; }
  131. ULONG __stdcall Release() { jassert (refCount > 0); const int r = --refCount; if (r == 0) delete this; return r; }
  132. HRESULT __stdcall GetTypeInfoCount (UINT __RPC_FAR*) { return E_NOTIMPL; }
  133. HRESULT __stdcall GetTypeInfo (UINT, LCID, ITypeInfo __RPC_FAR *__RPC_FAR*) { return E_NOTIMPL; }
  134. HRESULT __stdcall GetIDsOfNames (REFIID, LPOLESTR __RPC_FAR*, UINT, LCID, DISPID __RPC_FAR*) { return E_NOTIMPL; }
  135. HRESULT __stdcall Invoke (DISPID dispIdMember, REFIID /*riid*/, LCID /*lcid*/,
  136. WORD /*wFlags*/, DISPPARAMS __RPC_FAR* pDispParams,
  137. VARIANT __RPC_FAR* /*pVarResult*/, EXCEPINFO __RPC_FAR* /*pExcepInfo*/,
  138. UINT __RPC_FAR* /*puArgErr*/)
  139. {
  140. switch (dispIdMember)
  141. {
  142. case DISPID_BEFORENAVIGATE2:
  143. {
  144. VARIANT* const vurl = pDispParams->rgvarg[5].pvarVal;
  145. String url;
  146. if ((vurl->vt & VT_BYREF) != 0)
  147. url = *vurl->pbstrVal;
  148. else
  149. url = vurl->bstrVal;
  150. *pDispParams->rgvarg->pboolVal
  151. = owner->pageAboutToLoad (url) ? VARIANT_FALSE
  152. : VARIANT_TRUE;
  153. return S_OK;
  154. }
  155. default:
  156. break;
  157. }
  158. return E_NOTIMPL;
  159. }
  160. //==============================================================================
  161. juce_UseDebuggingNewOperator
  162. private:
  163. WebBrowserComponent* const owner;
  164. int refCount;
  165. EventHandler (const EventHandler&);
  166. const EventHandler& operator= (const EventHandler&);
  167. };
  168. };
  169. //==============================================================================
  170. WebBrowserComponent::WebBrowserComponent()
  171. : browser (0),
  172. blankPageShown (false)
  173. {
  174. setOpaque (true);
  175. addAndMakeVisible (browser = new WebBrowserComponentInternal());
  176. }
  177. WebBrowserComponent::~WebBrowserComponent()
  178. {
  179. delete browser;
  180. }
  181. //==============================================================================
  182. void WebBrowserComponent::goToURL (const String& url,
  183. const StringArray* headers,
  184. const MemoryBlock* postData)
  185. {
  186. lastURL = url;
  187. lastHeaders.clear();
  188. if (headers != 0)
  189. lastHeaders = *headers;
  190. lastPostData.setSize (0);
  191. if (postData != 0)
  192. lastPostData = *postData;
  193. blankPageShown = false;
  194. browser->goToURL (url, headers, postData);
  195. }
  196. void WebBrowserComponent::stop()
  197. {
  198. if (browser->browser != 0)
  199. browser->browser->Stop();
  200. }
  201. void WebBrowserComponent::goBack()
  202. {
  203. lastURL = String::empty;
  204. blankPageShown = false;
  205. if (browser->browser != 0)
  206. browser->browser->GoBack();
  207. }
  208. void WebBrowserComponent::goForward()
  209. {
  210. lastURL = String::empty;
  211. if (browser->browser != 0)
  212. browser->browser->GoForward();
  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