UIWebViewImpl-win32.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. #include "platform/CCPlatformConfig.h"
  2. #if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
  3. #ifndef APIENTRY
  4. #define APIENTRY __stdcall
  5. #endif // !APIENTRY
  6. #undef MessageBox
  7. #define MessageBox MessageBoxW
  8. //#define NOMB
  9. #ifndef NTDDI_WIN8
  10. #define NTDDI_WIN8 0x06020000
  11. #endif
  12. #include <atlbase.h>
  13. #include <atlwin.h>
  14. #include <ExDispid.h>
  15. #include <ExDisp.h>
  16. #include <UrlMon.h>
  17. #include <comutil.h>
  18. #pragma comment(lib,"comsuppw")
  19. #include "UIWebViewImpl-win32.h"
  20. #include "UIWebView.h"
  21. #include "base/CCDirector.h"
  22. #include "platform/CCFileUtils.h"
  23. #include "platform/CCGLView.h"
  24. class Win32WebControl : public DWebBrowserEvents2
  25. {
  26. public:
  27. Win32WebControl();
  28. bool createWebView(
  29. const std::function<bool (const std::string &)> &shouldStartLoading,
  30. const std::function<void (const std::string &)> &didFinishLoading,
  31. const std::function<void (const std::string &)> &didFailLoading,
  32. const std::function<void (const std::string &)> &onJsCallback);
  33. void removeWebView();
  34. void setWebViewRect(const int left, const int top, const int width, const int height);
  35. void setJavascriptInterfaceScheme(const std::string &scheme) const;
  36. void loadData(const std::string &data, const std::string &MIMEType, const std::string &encoding, const std::string &baseURL) const;
  37. void loadHTMLString(const std::string &html, const std::string &baseURL);
  38. void loadUrl(const std::string &url) const;
  39. void loadFile(const std::string &filePath) const;
  40. void postUrl(const std::string &url, const std::string& data, uint32_t len) const;
  41. void stopLoading() const;
  42. void reload() const;
  43. bool canGoBack() const;
  44. bool canGoForward() const;
  45. void goBack() const;
  46. void goForward() const;
  47. void evaluateJS(const std::string &js) const;
  48. void setScalesPageToFit(const bool scalesPageToFit) const;
  49. void setWebViewVisible(const bool visible) const;
  50. // Implement IUnknown
  51. virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
  52. virtual ULONG STDMETHODCALLTYPE AddRef(void);
  53. virtual ULONG STDMETHODCALLTYPE Release(void);
  54. // Implement IDispatch
  55. virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo);
  56. virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo);
  57. virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(
  58. REFIID riid,
  59. LPOLESTR *rgszNames,
  60. UINT cNames,
  61. LCID lcid,
  62. DISPID *rgDispId);
  63. virtual HRESULT STDMETHODCALLTYPE Invoke(
  64. DISPID dispIdMember,
  65. REFIID riid,
  66. LCID lcid,
  67. WORD wFlags,
  68. DISPPARAMS *pDispParams,
  69. VARIANT *pVarResult,
  70. EXCEPINFO *pExcepInfo,
  71. UINT *puArgErr);
  72. private:
  73. CAxWindow _winContainer;
  74. IWebBrowser2 *_webBrowser2;
  75. IConnectionPoint *_connectionPoint;
  76. IDispatch *_htmlDoc;
  77. bool _goBackEnabled;
  78. bool _goForwardEnabled;
  79. DWORD _cookie;
  80. ULONG _reference;
  81. std::function<bool (const std::string &)> _shouldStartLoading;
  82. std::function<void (const std::string &)> _didFinishLoading;
  83. std::function<void (const std::string &)> _didFailLoading;
  84. std::function<void (const std::string &)> _onJsCallback;
  85. std::string _htmlWillLoad;
  86. static bool s_isInitialized;
  87. static CComModule s_module;
  88. static void lazyInit();
  89. void _loadHTMLString(const std::string &html) const;
  90. void loadUrl(BSTR url) const;
  91. void loadUrl(const std::wstring &url) const;
  92. };
  93. namespace cocos2d {
  94. namespace experimental {
  95. namespace ui {
  96. WebViewImpl::WebViewImpl(WebView *webView) : _createSucceeded(false), _systemWebControl(nullptr), _webView(webView)
  97. {
  98. _systemWebControl = new Win32WebControl();
  99. if (_systemWebControl == nullptr)
  100. {
  101. return;
  102. }
  103. _createSucceeded = _systemWebControl->createWebView(
  104. [this](const std::string &url)->bool {
  105. if (_webView->_onShouldStartLoading != nullptr)
  106. {
  107. return _webView->_onShouldStartLoading(_webView, url);
  108. }
  109. return true;
  110. },
  111. [this](const std::string &url) {
  112. if (_webView->_onDidFinishLoading != nullptr)
  113. {
  114. _webView->_onDidFinishLoading(_webView, url);
  115. }
  116. },
  117. [this](const std::string &url) {
  118. if (_webView->_onDidFailLoading != nullptr)
  119. {
  120. _webView->_onDidFailLoading(_webView, url);
  121. }
  122. },
  123. [this](const std::string &url) {
  124. if (_webView->_onJSCallback != nullptr)
  125. {
  126. _webView->_onJSCallback(_webView, url);
  127. }
  128. });
  129. }
  130. WebViewImpl::~WebViewImpl()
  131. {
  132. if (_systemWebControl != nullptr)
  133. {
  134. _systemWebControl->removeWebView();
  135. delete _systemWebControl;
  136. _systemWebControl = nullptr;
  137. }
  138. }
  139. void WebViewImpl::loadData(const Data &data, const std::string &MIMEType, const std::string &encoding, const std::string &baseURL)
  140. {
  141. if (_createSucceeded)
  142. {
  143. std::string dataString(reinterpret_cast<char *>(data.getBytes()), static_cast<unsigned int>(data.getSize()));
  144. _systemWebControl->loadData(dataString, MIMEType, encoding, baseURL);
  145. }
  146. }
  147. void WebViewImpl::loadHTMLString(const std::string &string, const std::string &baseURL)
  148. {
  149. if (_createSucceeded)
  150. {
  151. _systemWebControl->loadHTMLString(string, baseURL);
  152. }
  153. }
  154. void WebViewImpl::loadURL(const std::string &url)
  155. {
  156. if (_createSucceeded)
  157. {
  158. _systemWebControl->loadUrl(url);
  159. }
  160. }
  161. void WebViewImpl::loadURL(const std::string &url, bool cleanCachedData)
  162. {
  163. if (_createSucceeded)
  164. {
  165. _systemWebControl->loadUrl(url);
  166. }
  167. }
  168. void WebViewImpl::loadFile(const std::string &fileName)
  169. {
  170. if (_createSucceeded)
  171. {
  172. std::string fullPath = FileUtils::getInstance()->fullPathForFilename(fileName);
  173. _systemWebControl->loadFile(fullPath);
  174. }
  175. }
  176. void WebViewImpl::PostURL(const std::string &url, const std::string &data)
  177. {
  178. if (_createSucceeded)
  179. {
  180. _systemWebControl->postUrl(url, data, data.length());
  181. }
  182. }
  183. void WebViewImpl::stopLoading()
  184. {
  185. if (_createSucceeded)
  186. {
  187. _systemWebControl->stopLoading();
  188. }
  189. }
  190. void WebViewImpl::reload()
  191. {
  192. if (_createSucceeded)
  193. {
  194. _systemWebControl->reload();
  195. }
  196. }
  197. bool WebViewImpl::canGoBack()
  198. {
  199. if (_createSucceeded)
  200. {
  201. return _systemWebControl->canGoBack();
  202. }
  203. return false;
  204. }
  205. bool WebViewImpl::canGoForward()
  206. {
  207. if (_createSucceeded)
  208. {
  209. return _systemWebControl->canGoForward();
  210. }
  211. return false;
  212. }
  213. void WebViewImpl::goBack()
  214. {
  215. if (_createSucceeded)
  216. {
  217. _systemWebControl->goBack();
  218. }
  219. }
  220. void WebViewImpl::goForward()
  221. {
  222. if (_createSucceeded)
  223. {
  224. _systemWebControl->goForward();
  225. }
  226. }
  227. void WebViewImpl::setJavascriptInterfaceScheme(const std::string &scheme)
  228. {
  229. if (_createSucceeded)
  230. {
  231. _systemWebControl->setJavascriptInterfaceScheme(scheme);
  232. }
  233. }
  234. void WebViewImpl::evaluateJS(const std::string &js)
  235. {
  236. if (_createSucceeded)
  237. {
  238. _systemWebControl->evaluateJS(js);
  239. }
  240. }
  241. void WebViewImpl::setScalesPageToFit(const bool scalesPageToFit)
  242. {
  243. if (_createSucceeded)
  244. {
  245. _systemWebControl->setScalesPageToFit(scalesPageToFit);
  246. }
  247. }
  248. void WebViewImpl::draw(Renderer *renderer, Mat4 const &transform, uint32_t flags)
  249. {
  250. if (_createSucceeded && (flags & Node::FLAGS_TRANSFORM_DIRTY))
  251. {
  252. Director *directorInstance = cocos2d::Director::getInstance();
  253. GLView *glView = directorInstance->getOpenGLView();
  254. const Size &frameSize = glView->getFrameSize();
  255. const Size &winSize = directorInstance->getWinSize();
  256. Vec2 leftBottom = this->_webView->convertToWorldSpace(Point::ZERO);
  257. Vec2 rightTop = this->_webView->convertToWorldSpace(Point(_webView->getContentSize().width, _webView->getContentSize().height));
  258. float uiLeft = frameSize.width / 2 + (leftBottom.x - winSize.width / 2) * glView->getScaleX();
  259. float uiTop = frameSize.height / 2 - (rightTop.y - winSize.height / 2) * glView->getScaleY();
  260. _systemWebControl->setWebViewRect(uiLeft, uiTop,
  261. (rightTop.x - leftBottom.x) * glView->getScaleX(),
  262. (rightTop.y - leftBottom.y) * glView->getScaleY());
  263. }
  264. }
  265. void WebViewImpl::setVisible(bool visible)
  266. {
  267. if (_createSucceeded)
  268. {
  269. _systemWebControl->setWebViewVisible(visible);
  270. }
  271. }
  272. void WebViewImpl::setOpacityWebView(const float opacity){
  273. // empty function as this was mainly a fix for iOS
  274. };
  275. float WebViewImpl::getOpacityWebView()const{
  276. // empty function as this was mainly a fix for iOS
  277. return 1.0;
  278. };
  279. void WebViewImpl::setBackgroundTransparent(){
  280. // empty function as this was mainly a fix for iOS
  281. };
  282. void WebViewImpl::setBounces(bool bounces) {
  283. // empty function as this was mainly a fix for iOS
  284. }
  285. } // namespace ui
  286. } // namespace experimental
  287. } //namespace cocos2d
  288. //
  289. // Implement Win32WebControl;
  290. //
  291. bool Win32WebControl::s_isInitialized = false;
  292. CComModule Win32WebControl::s_module;
  293. void Win32WebControl::lazyInit()
  294. {
  295. HWND hwnd = cocos2d::Director::getInstance()->getOpenGLView()->getWin32Window();
  296. LONG style = GetWindowLong(hwnd, GWL_STYLE);
  297. SetWindowLong(hwnd, GWL_STYLE, style | WS_CLIPCHILDREN);
  298. HINSTANCE hInstance = GetModuleHandle(NULL);
  299. CoInitialize(NULL);
  300. s_module.Init(NULL, hInstance);
  301. AtlAxWinInit();
  302. }
  303. static HGLOBAL globalAllocWstringFromString(const std::string &str)
  304. {
  305. // int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
  306. // if (len <= 0)
  307. // {
  308. // return NULL;
  309. // }
  310. // HGLOBAL wstr = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, (len + 1) * sizeof(WCHAR));
  311. // if (wstr == NULL)
  312. // {
  313. // return NULL;
  314. // }
  315. // MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, (WCHAR *)wstr, len);
  316. HGLOBAL wstr = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,str.length()+1);
  317. BYTE* pmem = (BYTE*)GlobalLock(wstr);
  318. memcpy(pmem, str.c_str(), str.length());
  319. GlobalUnlock(wstr);
  320. return wstr;
  321. }
  322. static std::string bstr2string(BSTR bstr)
  323. {
  324. wchar_t *str = OLE2W(bstr);
  325. std::string ret;
  326. int len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
  327. if (len > 0)
  328. {
  329. HGLOBAL utf8Str = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, len + 1);
  330. if (utf8Str != NULL)
  331. {
  332. WideCharToMultiByte(CP_UTF8, 0, str, -1, (char *)utf8Str, len, NULL, NULL);
  333. ret.assign((char *)utf8Str);
  334. GlobalFree(utf8Str);
  335. }
  336. }
  337. return ret;
  338. }
  339. static bool isUrlJs(BSTR url)
  340. {
  341. return wcsncmp(OLE2W(url), L"javascript:", 11) == 0;
  342. }
  343. Win32WebControl::Win32WebControl()
  344. : _webBrowser2(NULL)
  345. , _connectionPoint(NULL)
  346. , _htmlDoc(NULL)
  347. , _goBackEnabled(true)
  348. , _goForwardEnabled(true)
  349. , _cookie(0)
  350. , _reference(0)
  351. , _shouldStartLoading(nullptr)
  352. , _didFinishLoading(nullptr)
  353. , _didFailLoading(nullptr)
  354. {
  355. if (!s_isInitialized)
  356. {
  357. lazyInit();
  358. }
  359. }
  360. bool Win32WebControl::createWebView(
  361. const std::function<bool (const std::string &)> &shouldStartLoading,
  362. const std::function<void (const std::string &)> &didFinishLoading,
  363. const std::function<void (const std::string &)> &didFailLoading,
  364. const std::function<void (const std::string &)> &onJsCallback)
  365. {
  366. bool ret = false;
  367. IConnectionPointContainer *container = NULL;
  368. do
  369. {
  370. HWND hwnd = cocos2d::Director::getInstance()->getOpenGLView()->getWin32Window();
  371. _winContainer.Create(hwnd, NULL, NULL, WS_CHILD | WS_VISIBLE);
  372. HRESULT hr;
  373. hr = _winContainer.CreateControl(L"shell.Explorer.2");
  374. CC_BREAK_IF(FAILED(hr));
  375. hr = _winContainer.QueryControl(__uuidof(IWebBrowser2), (void **)&_webBrowser2);
  376. CC_BREAK_IF(FAILED(hr) || _webBrowser2 == NULL);
  377. _webBrowser2->put_Silent(VARIANT_TRUE);
  378. VARIANT var;
  379. VariantInit(&var);
  380. var.vt = VT_BSTR;
  381. var.bstrVal = SysAllocString(L"about:blank");
  382. hr = _webBrowser2->Navigate2(&var, NULL, NULL, NULL, NULL);
  383. SysFreeString(var.bstrVal);
  384. VariantClear(&var);
  385. CC_BREAK_IF(FAILED(hr));
  386. hr = _webBrowser2->QueryInterface(IID_IConnectionPointContainer, (void **)&container);
  387. CC_BREAK_IF(FAILED(hr));
  388. hr = container->FindConnectionPoint(DIID_DWebBrowserEvents2, &_connectionPoint);
  389. CC_BREAK_IF(FAILED(hr));
  390. hr = _connectionPoint->Advise(this, &_cookie);
  391. CC_BREAK_IF(FAILED(hr));
  392. hr = _webBrowser2->get_Document(&_htmlDoc);
  393. CC_BREAK_IF(FAILED(hr));
  394. ret = true;
  395. } while (0);
  396. if (!ret)
  397. {
  398. removeWebView();
  399. }
  400. if (container != NULL)
  401. {
  402. container->Release();
  403. container = NULL;
  404. }
  405. _shouldStartLoading = shouldStartLoading;
  406. _didFinishLoading = didFinishLoading;
  407. _didFailLoading = didFailLoading;
  408. _onJsCallback = onJsCallback;
  409. return ret;
  410. }
  411. void Win32WebControl::removeWebView()
  412. {
  413. if (_connectionPoint != NULL)
  414. {
  415. _connectionPoint->Unadvise(_cookie);
  416. _connectionPoint->Release();
  417. _connectionPoint = NULL;
  418. }
  419. if (_htmlDoc != NULL)
  420. {
  421. _htmlDoc->Release();
  422. _htmlDoc = NULL;
  423. }
  424. if (_webBrowser2 != NULL)
  425. {
  426. _webBrowser2->Release();
  427. _webBrowser2 = NULL;
  428. }
  429. _winContainer.DestroyWindow();
  430. }
  431. void Win32WebControl::setWebViewRect(const int left, const int top, const int width, const int height)
  432. {
  433. _winContainer.MoveWindow(left, top, width, height);
  434. }
  435. void Win32WebControl::setJavascriptInterfaceScheme(const std::string &scheme) const
  436. {
  437. }
  438. void Win32WebControl::loadData(const std::string &data, const std::string &MIMEType, const std::string &encoding, const std::string &baseURL) const
  439. {
  440. }
  441. void Win32WebControl::loadHTMLString(const std::string &html, const std::string &baseURL)
  442. {
  443. //if (baseURL.empty())
  444. //{
  445. _loadHTMLString(html);
  446. //}
  447. //else
  448. //{
  449. // _htmlWillLoad = html;
  450. // loadUrl(baseURL);
  451. //}
  452. }
  453. void Win32WebControl::_loadHTMLString(const std::string &html) const
  454. {
  455. bool flag = false;
  456. HGLOBAL htmlText = globalAllocWstringFromString(html);
  457. if (htmlText != NULL)
  458. {
  459. IStream *stream = NULL;
  460. if (SUCCEEDED(CreateStreamOnHGlobal(htmlText, FALSE, &stream)))
  461. {
  462. IPersistStreamInit *persistStreamInit = NULL;
  463. if (SUCCEEDED(_htmlDoc->QueryInterface(IID_IPersistStreamInit, (void **)&persistStreamInit)))
  464. {
  465. if (SUCCEEDED(persistStreamInit->InitNew()) && SUCCEEDED(persistStreamInit->Load(stream)))
  466. {
  467. flag = true;
  468. }
  469. persistStreamInit->Release();
  470. }
  471. stream->Release();
  472. }
  473. GlobalFree(htmlText);
  474. }
  475. if (flag)
  476. {
  477. if (_didFinishLoading != nullptr)
  478. {
  479. std::string str("data:text/html,");
  480. str.append(html);
  481. _didFinishLoading(str);
  482. }
  483. }
  484. else
  485. {
  486. if (_didFailLoading != nullptr)
  487. {
  488. std::string str("data:text/html,");
  489. str.append(html);
  490. _didFailLoading(str);
  491. }
  492. }
  493. }
  494. void Win32WebControl::loadUrl(BSTR url) const
  495. {
  496. VARIANT var;
  497. VariantInit(&var);
  498. var.vt = VT_BSTR;
  499. var.bstrVal = url;
  500. _webBrowser2->Navigate2(&var, NULL, NULL, NULL, NULL);
  501. VariantClear(&var);
  502. }
  503. void Win32WebControl::loadUrl(const std::wstring &url) const
  504. {
  505. BSTR bstr = SysAllocString(url.c_str());
  506. loadUrl(bstr);
  507. SysFreeString(bstr);
  508. }
  509. void Win32WebControl::loadUrl(const std::string &url) const
  510. {
  511. // HGLOBAL unicodeStr = globalAllocWstringFromString(url);
  512. // if (unicodeStr != NULL)
  513. // {
  514. // loadUrl(std::wstring((WCHAR *)unicodeStr));
  515. // GlobalFree(unicodeStr);
  516. // }
  517. _bstr_t bstr_t(url.c_str());
  518. BSTR bstr = bstr_t.GetBSTR();
  519. loadUrl(bstr);
  520. }
  521. void Win32WebControl::loadFile(const std::string &filePath) const
  522. {
  523. // HGLOBAL unicodeStr = globalAllocWstringFromString(filePath);
  524. // if (unicodeStr != NULL)
  525. // {
  526. // loadUrl(std::wstring((WCHAR *)unicodeStr));
  527. // GlobalFree(unicodeStr);
  528. // }
  529. _bstr_t bstr_t(filePath.c_str());
  530. BSTR bstr = bstr_t.GetBSTR();
  531. loadUrl(bstr);
  532. }
  533. void Win32WebControl::postUrl(const std::string &url, const std::string& data, uint32_t len) const
  534. {
  535. _bstr_t bstr_t(url.c_str()), bstr_data(data.c_str());
  536. BSTR bstr = bstr_t.GetBSTR();
  537. VARIANT var;
  538. VARIANT vFlags;
  539. VARIANT vPostData;
  540. VARIANT vHeaders;
  541. VARIANT vNull;
  542. VariantInit(&var);
  543. VariantInit(&vFlags);
  544. VariantInit(&vPostData);
  545. VariantInit(&vHeaders);
  546. VariantInit(&vNull);
  547. var.vt = VT_BSTR;
  548. var.bstrVal = bstr;
  549. //vHeaders.vt = VT_BSTR;
  550. //vHeaders.bstrVal = SysAllocString(L"Content-Type: application/x-www-form-urlencoded\r\n");
  551. //vFlags.vt = VT_I4;
  552. //vFlags.lVal = navNoReadFromCache | navNoWriteToCache;
  553. vPostData.vt = VT_BSTR;
  554. vPostData.bstrVal = bstr_data.GetBSTR();
  555. /*SAFEARRAYBOUND bound;
  556. bound.cElements = len;
  557. bound.lLbound = 0;
  558. SAFEARRAY FAR* sfPost = SafeArrayCreate(VT_UI1, 1, &bound);
  559. const char* pChar = bstr_data;
  560. for (long lIndex = 0; lIndex < (signed)bound.cElements; lIndex++) {
  561. SafeArrayPutElement(sfPost, &lIndex, (void*)((pChar++)));
  562. }
  563. vPostData.vt = VT_ARRAY | VT_UI1;
  564. vPostData.parray = sfPost;*/
  565. _webBrowser2->Navigate2(&var, &vFlags, &vNull, &vPostData, &vHeaders);
  566. VariantClear(&var);
  567. }
  568. void Win32WebControl::stopLoading() const
  569. {
  570. _webBrowser2->Stop();
  571. }
  572. void Win32WebControl::reload() const
  573. {
  574. _webBrowser2->Refresh();
  575. }
  576. bool Win32WebControl::canGoBack() const
  577. {
  578. return _goBackEnabled;
  579. }
  580. bool Win32WebControl::canGoForward() const
  581. {
  582. return _goForwardEnabled;
  583. }
  584. void Win32WebControl::goBack() const
  585. {
  586. _webBrowser2->GoBack();
  587. }
  588. void Win32WebControl::goForward() const
  589. {
  590. _webBrowser2->GoForward();
  591. }
  592. void Win32WebControl::evaluateJS(const std::string &js) const
  593. {
  594. std::string url("javascript:");
  595. url.append(js);
  596. loadUrl(url);
  597. }
  598. void Win32WebControl::setScalesPageToFit(const bool scalesPageToFit) const
  599. {
  600. }
  601. void Win32WebControl::setWebViewVisible(const bool visible) const
  602. {
  603. if (visible)
  604. {
  605. ::ShowWindow(_winContainer.m_hWnd, SW_SHOW);
  606. //_winContainer.ShowWindow(SW_SHOW);
  607. }
  608. else
  609. {
  610. ::ShowWindow(_winContainer.m_hWnd, SW_HIDE);
  611. //_winContainer.ShowWindow(SW_HIDE);
  612. }
  613. //_webBrowser2->put_Visible(visible ? VARIANT_TRUE : VARIANT_FALSE);
  614. }
  615. // Implement IUnknown
  616. HRESULT STDMETHODCALLTYPE Win32WebControl::QueryInterface(REFIID riid, void **ppvObject)
  617. {
  618. if (IsBadWritePtr(ppvObject, sizeof(void *)))
  619. {
  620. return E_POINTER;
  621. }
  622. *ppvObject = NULL;
  623. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDispatch) || IsEqualIID(riid, DIID_DWebBrowserEvents2))
  624. {
  625. AddRef();
  626. *ppvObject = this;
  627. return S_OK;
  628. }
  629. return E_NOINTERFACE;
  630. }
  631. ULONG STDMETHODCALLTYPE Win32WebControl::AddRef(void)
  632. {
  633. InterlockedIncrement(&_reference);
  634. return _reference;
  635. }
  636. ULONG STDMETHODCALLTYPE Win32WebControl::Release(void)
  637. {
  638. CCASSERT(_reference > 0, "reference count should greater than 0");
  639. InterlockedDecrement(&_reference);
  640. // do not delete this if _reference == 0, otherwise, it will crash when call removeWebView
  641. return _reference;
  642. }
  643. // Implement IDispatch
  644. HRESULT STDMETHODCALLTYPE Win32WebControl::GetTypeInfoCount(UINT *pctinfo)
  645. {
  646. *pctinfo = 0;
  647. return S_OK;
  648. }
  649. HRESULT STDMETHODCALLTYPE Win32WebControl::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
  650. {
  651. UNREFERENCED_PARAMETER(iTInfo);
  652. UNREFERENCED_PARAMETER(lcid);
  653. *ppTInfo = NULL;
  654. return E_NOTIMPL;
  655. }
  656. HRESULT STDMETHODCALLTYPE Win32WebControl::GetIDsOfNames(
  657. REFIID riid,
  658. LPOLESTR *rgszNames,
  659. UINT cNames,
  660. LCID lcid,
  661. DISPID *rgDispId)
  662. {
  663. UNREFERENCED_PARAMETER(riid);
  664. UNREFERENCED_PARAMETER(rgszNames);
  665. UNREFERENCED_PARAMETER(cNames);
  666. UNREFERENCED_PARAMETER(lcid);
  667. UNREFERENCED_PARAMETER(rgDispId);
  668. return E_NOTIMPL;
  669. }
  670. HRESULT STDMETHODCALLTYPE Win32WebControl::Invoke(
  671. DISPID dispIdMember,
  672. REFIID riid,
  673. LCID lcid,
  674. WORD wFlags,
  675. DISPPARAMS *pDispParams,
  676. VARIANT *pVarResult,
  677. EXCEPINFO *pExcepInfo,
  678. UINT *puArgErr)
  679. {
  680. if (!IsEqualIID(riid, IID_NULL)) // riid should always be IID_NULL
  681. {
  682. return DISP_E_UNKNOWNINTERFACE;
  683. }
  684. switch (dispIdMember)
  685. {
  686. case DISPID_COMMANDSTATECHANGE:
  687. if (pDispParams != NULL && pDispParams->cArgs == 2)
  688. {
  689. const VARIANTARG *rgvarg = pDispParams->rgvarg;
  690. if (rgvarg[0].vt == VT_BOOL && rgvarg[1].vt == VT_I4)
  691. {
  692. switch (rgvarg[1].intVal)
  693. {
  694. case CSC_NAVIGATEFORWARD:
  695. _goForwardEnabled = (rgvarg[0].boolVal != VARIANT_FALSE); // VARIANT_TRUE is -1
  696. return S_OK;
  697. case CSC_NAVIGATEBACK:
  698. _goBackEnabled = (rgvarg[0].boolVal != VARIANT_FALSE); // VARIANT_TRUE is -1
  699. return S_OK;
  700. default:
  701. break;
  702. }
  703. }
  704. }
  705. break;
  706. case DISPID_BEFORENAVIGATE2:
  707. if (pDispParams != NULL && pDispParams->cArgs == 7)
  708. {
  709. VARIANTARG *rgvarg = pDispParams->rgvarg;
  710. if (rgvarg[6].vt == VT_DISPATCH && rgvarg[6].pdispVal == _webBrowser2)
  711. {
  712. if (rgvarg[0].vt == (VT_BYREF | VT_BOOL) && rgvarg[5].vt == (VT_BYREF | VT_VARIANT))
  713. {
  714. VARIANT_BOOL *cancel = rgvarg[0].pboolVal;
  715. BSTR url = rgvarg[5].pvarVal->bstrVal;
  716. *cancel = VARIANT_FALSE;
  717. if (isUrlJs(url))
  718. {
  719. if (_onJsCallback != nullptr)
  720. {
  721. _onJsCallback(bstr2string(url));
  722. }
  723. }
  724. else
  725. {
  726. if (_shouldStartLoading != nullptr)
  727. {
  728. *cancel = _shouldStartLoading(bstr2string(url)) ? VARIANT_FALSE : VARIANT_TRUE; // VARIANT_TRUE is -1
  729. }
  730. }
  731. return S_OK;
  732. }
  733. }
  734. }
  735. break;
  736. case DISPID_DOCUMENTCOMPLETE:
  737. if (pDispParams != NULL && pDispParams->cArgs == 2)
  738. {
  739. const VARIANTARG *rgvarg = pDispParams->rgvarg;
  740. if (rgvarg[1].vt == VT_DISPATCH && rgvarg[1].pdispVal == _webBrowser2 && rgvarg[0].vt == (VT_BYREF | VT_VARIANT))
  741. {
  742. READYSTATE state;
  743. if (SUCCEEDED(_webBrowser2->get_ReadyState(&state)) && state == READYSTATE_COMPLETE)
  744. {
  745. BSTR url = rgvarg[0].pvarVal->bstrVal;
  746. if (_didFinishLoading != nullptr && !isUrlJs(url)) // ignore js
  747. {
  748. _didFinishLoading(bstr2string(url));
  749. }
  750. if (!_htmlWillLoad.empty())
  751. {
  752. _loadHTMLString(_htmlWillLoad);
  753. _htmlWillLoad.clear();
  754. }
  755. return S_OK;
  756. }
  757. }
  758. }
  759. break;
  760. case DISPID_NAVIGATECOMPLETE2:
  761. if (pDispParams != NULL && pDispParams->cArgs == 2)
  762. {
  763. const VARIANTARG *rgvarg = pDispParams->rgvarg;
  764. if (rgvarg[1].vt == VT_DISPATCH && rgvarg[1].pdispVal == _webBrowser2)
  765. {
  766. if (rgvarg[0].vt == (VT_BYREF | VT_VARIANT))
  767. {
  768. BSTR url = rgvarg[0].pvarVal->bstrVal;
  769. return S_OK;
  770. }
  771. }
  772. }
  773. break;
  774. case DISPID_NAVIGATEERROR:
  775. if (pDispParams != NULL && pDispParams->cArgs == 5)
  776. {
  777. const VARIANTARG *rgvarg = pDispParams->rgvarg;
  778. if (rgvarg[4].vt == VT_DISPATCH && rgvarg[4].pdispVal == _webBrowser2)
  779. {
  780. if (rgvarg[3].vt == (VT_BYREF | VT_VARIANT) && rgvarg[1].vt == (VT_BYREF | VT_VARIANT) && rgvarg[0].vt == (VT_BYREF | VT_BOOL))
  781. {
  782. VARIANT_BOOL *cancel = rgvarg[0].pboolVal;
  783. HRESULT codes = rgvarg[1].pvarVal->lVal;
  784. BSTR url = rgvarg[3].pvarVal->bstrVal;
  785. if (_didFailLoading != nullptr && !isUrlJs(url)) // ignore js
  786. {
  787. _didFailLoading(bstr2string(url));
  788. }
  789. *cancel = VARIANT_FALSE;
  790. return S_OK;
  791. }
  792. }
  793. }
  794. break;
  795. case DISPID_PROGRESSCHANGE:
  796. if (pDispParams != NULL && pDispParams->cArgs == 2)
  797. {
  798. const VARIANTARG *rgvarg = pDispParams->rgvarg;
  799. if (rgvarg[0].vt == VT_I4 && rgvarg[1].vt == VT_I4)
  800. {
  801. LONG maxProgress = rgvarg[0].lVal;
  802. LONG curProgress = rgvarg[1].lVal;
  803. return S_OK;
  804. }
  805. }
  806. break;
  807. case DISPID_NEWWINDOW2:
  808. if (pDispParams != NULL && pDispParams->cArgs == 2)
  809. {
  810. const VARIANTARG *rgvarg = pDispParams->rgvarg;
  811. if (rgvarg[0].vt == (VT_BYREF | VT_BOOL) && rgvarg[1].vt == (VT_BYREF | VT_DISPATCH))
  812. {
  813. VARIANT_BOOL *cancel = rgvarg[0].pboolVal;
  814. IDispatch **dis = rgvarg[1].ppdispVal;
  815. *dis = NULL;
  816. *cancel = VARIANT_TRUE; // forbit to create new window
  817. return S_OK;
  818. }
  819. }
  820. break;
  821. case DISPID_NEWWINDOW3:
  822. if (pDispParams != NULL && pDispParams->cArgs == 5)
  823. {
  824. const VARIANTARG *rgvarg = pDispParams->rgvarg;
  825. if (rgvarg[0].vt == VT_BSTR && rgvarg[1].vt == VT_BSTR && rgvarg[2].vt == VT_I4
  826. && rgvarg[3].vt == (VT_BYREF | VT_BOOL) && rgvarg[4].vt == (VT_BYREF | VT_DISPATCH))
  827. {
  828. BSTR url = rgvarg[0].bstrVal;
  829. BSTR urlContext = rgvarg[1].bstrVal;
  830. LONG flags = rgvarg[2].lVal;
  831. VARIANT_BOOL *cancel = rgvarg[3].pboolVal;
  832. IDispatch **dis = rgvarg[4].ppdispVal;
  833. *dis = NULL;
  834. *cancel = VARIANT_TRUE; // forbit to create new window
  835. loadUrl(url);
  836. return S_OK;
  837. }
  838. }
  839. break;
  840. default:
  841. break;
  842. }
  843. return E_NOTIMPL;
  844. }
  845. #endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32