browser.cpp 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579
  1. #include "main.h"
  2. #include "./browser.h"
  3. #include "./browserRegistry.h"
  4. #include "./graphics.h"
  5. #include "./resource.h"
  6. #include "../winamp/wa_dlg.h"
  7. #include "../Plugins/General/gen_ml/colors.h"
  8. #include "../winamp/IWasabiDispatchable.h"
  9. #include "../winamp/JSAPI_Info.h"
  10. #include "./obj_ombrowser.h"
  11. #include "./ifc_skinhelper.h"
  12. #include "./ifc_skinnedbrowser.h"
  13. #include "./ifc_wasabihelper.h"
  14. #include "./ifc_omservice.h"
  15. #include "./ifc_omdebugconfig.h"
  16. #include "./travelLogHelper.h"
  17. #include "./menu.h"
  18. #include <wininet.h>
  19. #include <exdisp.h>
  20. #include <exdispid.h>
  21. #include <mshtmdid.h>
  22. #include <mshtml.h>
  23. #include <shlwapi.h>
  24. #include <strsafe.h>
  25. #define CONTROL_DOWNLOADFLAGS ( DLCTL_DLIMAGES | \
  26. DLCTL_VIDEOS | \
  27. /*DLCTL_PRAGMA_NO_CACHE |*/ \
  28. /*DLCTL_NO_CLIENTPULL | */ \
  29. DLCTL_RESYNCHRONIZE | \
  30. 0)
  31. #define CONTROL_HOSTINFOFLAGS ( DOCHOSTUIFLAG_DISABLE_HELP_MENU | \
  32. DOCHOSTUIFLAG_NO3DBORDER | \
  33. DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE | \
  34. DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY | \
  35. DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION | \
  36. DOCHOSTUIFLAG_THEME | \
  37. DOCHOSTUIFLAG_NOPICS | \
  38. DOCHOSTUIFLAG_NO3DOUTERBORDER | \
  39. DOCHOSTUIFLAG_DISABLE_UNTRUSTEDPROTOCOL | \
  40. DOCHOSTUIFLAG_ENABLE_REDIRECT_NOTIFICATION | \
  41. DOCHOSTUIFLAG_USE_WINDOWLESS_SELECTCONTROL | \
  42. DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE | \
  43. DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION | \
  44. 0)
  45. #ifndef LOAD_LIBRARY_AS_IMAGE_RESOURCE
  46. #define LOAD_LIBRARY_AS_IMAGE_RESOURCE 0x000000020
  47. #endif //LOAD_LIBRARY_AS_IMAGE_RESOURCE
  48. /*BHNAVCOMPLETECALLBACK EventDocumentReady;
  49. BHNAVCOMPLETECALLBACK EventNavigateComplete;
  50. BHCALLBACK EventDownloadBegin;
  51. BHCALLBACK EventDownloadComplete;
  52. BHCALLBACK EventContainerDestroyed;
  53. BHCMDSTATECALLBACK EventCommandStateChange;
  54. BHTEXTCALLBACK EventStatusChange;
  55. BHTEXTCALLBACK EventTitleChange;
  56. BHCALLBACK EventSecureLockIconChange;
  57. BHCREATEPOPUPCALLBACK EventCreatePopup;
  58. BHBOOLCALLBACK EventVisible;
  59. BHBOOLCALLBACK EventSetResizable;
  60. BHCLOSECALLBACK EventWindowClosing;
  61. BHSHOWUICALLBACK EventShowUiElement;
  62. BHCLIENTTOHOSTCALLBACK EventClientToHost;
  63. BHWINDOWPOSCALLBACK EventSetWindowPos;
  64. BHFOCUSCHANGECALLBACK EventFocusChange;
  65. BHBOOLCALLBACK EventSetFullscreen;
  66. BHCALLBACK EventClosePopup;*/
  67. Browser::Browser(obj_ombrowser *browserMngr, HWND winampWindow, HWND hParent)
  68. : HTMLContainer2(winampWindow, hParent),
  69. EventDocumentReady(NULL),
  70. EventNavigateComplete(NULL),
  71. EventDownloadBegin(NULL),
  72. EventDownloadComplete(NULL),
  73. EventContainerDestroyed(NULL),
  74. EventCommandStateChange(NULL),
  75. EventStatusChange(NULL),
  76. EventTitleChange(NULL),
  77. EventSecureLockIconChange(NULL),
  78. EventCreatePopup(NULL),
  79. EventVisible(NULL),
  80. EventSetResizable(NULL),
  81. EventWindowClosing(NULL),
  82. EventShowUiElement(NULL),
  83. EventClientToHost(NULL),
  84. EventSetWindowPos(NULL),
  85. EventFocusChange(NULL),
  86. EventSetFullscreen(NULL),
  87. EventClosePopup(NULL),
  88. CallbackGetOmService(NULL),
  89. CallbackRedirectKey(NULL),
  90. browserManager(browserMngr), externalDisp(NULL),
  91. pDropTargetHerlper(NULL), navigationState(0),
  92. secureLockIcon(secureLockIconUnsecure),
  93. pszUserAgent(NULL), uiFlags(0)
  94. {
  95. memset(szDone, 0, sizeof(szDone));
  96. if (NULL != externalDisp)
  97. externalDisp->AddRef();
  98. if (NULL != browserManager)
  99. browserManager->AddRef();
  100. }
  101. Browser::~Browser()
  102. {
  103. if (NULL != EventContainerDestroyed)
  104. EventContainerDestroyed(this);
  105. if (NULL != externalDisp)
  106. externalDisp->Release();
  107. if (NULL != pszUserAgent)
  108. Plugin_FreeString(pszUserAgent);
  109. if (NULL != pDropTargetHerlper)
  110. pDropTargetHerlper->Release();
  111. if (NULL != browserManager)
  112. browserManager->Release();
  113. }
  114. HRESULT Browser::SetExternal(IDispatch *pDispatch)
  115. {
  116. if (NULL != externalDisp)
  117. externalDisp->Release();
  118. externalDisp = pDispatch;
  119. if (NULL != externalDisp)
  120. externalDisp->AddRef();
  121. return S_OK;
  122. }
  123. Browser *Browser::CreateInstance(obj_ombrowser *browserManager, HWND winampWindow, HWND hParent)
  124. {
  125. Browser *instance = new Browser(browserManager, winampWindow, hParent);
  126. return instance;
  127. }
  128. ULONG Browser::AddRef(void)
  129. {
  130. return HTMLContainer2::AddRef();
  131. }
  132. ULONG Browser::Release(void)
  133. {
  134. return HTMLContainer2::Release();
  135. }
  136. STDMETHODIMP Browser::Initialize(BOOL fRegisterAsBrowser)
  137. {
  138. HRESULT hr = __super::Initialize();
  139. if (SUCCEEDED(hr))
  140. {
  141. if (FALSE != fRegisterAsBrowser)
  142. {
  143. IWebBrowser2 *pWeb2 = NULL;
  144. if (SUCCEEDED(GetIWebBrowser2(&pWeb2)) && pWeb2 != NULL)
  145. {
  146. pWeb2->put_RegisterAsBrowser(VARIANT_TRUE);
  147. pWeb2->Release();
  148. }
  149. }
  150. szDone[0] = L'\0';
  151. HINSTANCE hModule;
  152. if (L'\0' == szDone[0] && NULL != (hModule = LoadLibraryExW(L"ieframe.dll.mui", NULL,
  153. LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)))
  154. {
  155. LoadString(hModule, 8169, szDone, ARRAYSIZE(szDone));
  156. FreeLibrary(hModule);
  157. }
  158. if (L'\0' == szDone[0] && NULL != (hModule = LoadLibraryExW(L"shdoclc.dll", NULL,
  159. LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)))
  160. {
  161. LoadString(hModule, 8169, szDone, ARRAYSIZE(szDone));
  162. FreeLibrary(hModule);
  163. }
  164. if (L'\0' == szDone[0])
  165. StringCchPrintf(szDone, ARRAYSIZE(szDone), L"Done");
  166. }
  167. return hr;
  168. }
  169. STDMETHODIMP Browser::Finish(void)
  170. {
  171. IWebBrowser2 *pWeb2 = NULL;
  172. if (SUCCEEDED(GetIWebBrowser2(&pWeb2)) && pWeb2 != NULL)
  173. {
  174. pWeb2->put_RegisterAsBrowser(VARIANT_FALSE);
  175. pWeb2->Release();
  176. }
  177. return HTMLContainer2::Finish();
  178. }
  179. STDMETHODIMP Browser::QueryInterface(REFIID riid, PVOID *ppvObject)
  180. {
  181. if (!ppvObject)
  182. return E_POINTER;
  183. if (IsEqualIID(riid, IID_IDropTarget))
  184. {
  185. *ppvObject = (IDropTarget*)this;
  186. ((IUnknown*)*ppvObject)->AddRef();
  187. return S_OK;
  188. }
  189. else if (IsEqualIID(riid, IID_IProtectFocus))
  190. {
  191. *ppvObject = (IProtectFocus*)this;
  192. ((IUnknown*)*ppvObject)->AddRef();
  193. return S_OK;
  194. }
  195. return HTMLContainer2::QueryInterface(riid, ppvObject);
  196. }
  197. STDMETHODIMP Browser::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect)
  198. {
  199. *pdwEffect = (0x00FFFFFF & ~(*pdwEffect));
  200. if (NULL == pDropTargetHerlper &&
  201. FAILED(CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, (PVOID*)&pDropTargetHerlper)))
  202. {
  203. pDropTargetHerlper = NULL;
  204. }
  205. if (NULL != pDropTargetHerlper)
  206. {
  207. POINT pt = { ptl.x, ptl.y};
  208. HWND hwnd = this->GetHostHWND();
  209. pDropTargetHerlper->DragEnter(hwnd, pDataObject, &pt, *pdwEffect);
  210. }
  211. return S_OK;
  212. }
  213. STDMETHODIMP Browser::DragOver(DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect)
  214. {
  215. *pdwEffect = (0x00FFFFFF & ~(*pdwEffect));
  216. if (NULL != pDropTargetHerlper)
  217. {
  218. POINT pt = { ptl.x, ptl.y};
  219. pDropTargetHerlper->DragOver(&pt, *pdwEffect);
  220. }
  221. return S_OK;
  222. }
  223. STDMETHODIMP Browser::DragLeave(void)
  224. {
  225. if (NULL != pDropTargetHerlper)
  226. pDropTargetHerlper->DragLeave();
  227. return S_OK;
  228. }
  229. STDMETHODIMP Browser::Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect)
  230. {
  231. *pdwEffect = (0x00FFFFFF & ~(*pdwEffect));
  232. if (NULL != pDropTargetHerlper)
  233. {
  234. POINT pt = { ptl.x, ptl.y};
  235. pDropTargetHerlper->Drop(pDataObject, &pt, *pdwEffect);
  236. }
  237. return S_OK;
  238. }
  239. STDMETHODIMP Browser::GetDropTarget(IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
  240. {
  241. if (NULL == ppDropTarget)
  242. return E_POINTER;
  243. HRESULT hr = QueryInterface(IID_IDropTarget, (void**)ppDropTarget);
  244. if (SUCCEEDED(hr))
  245. return S_OK;
  246. return HTMLContainer2::GetDropTarget(pDropTarget, ppDropTarget);
  247. }
  248. STDMETHODIMP Browser::GetOverrideKeyPath(LPOLESTR __RPC_FAR *pchKey, DWORD dw)
  249. {
  250. HRESULT hr;
  251. size_t cbBuffer = 0;
  252. ifc_ombrowserregistry *browserRegistry = NULL;
  253. if (NULL != browserManager && SUCCEEDED(browserManager->GetRegistry(&browserRegistry)) && browserRegistry != NULL)
  254. {
  255. WCHAR szBuffer[256] = {0};
  256. if (SUCCEEDED(browserRegistry->GetPath(szBuffer, ARRAYSIZE(szBuffer))) &&
  257. SUCCEEDED(StringCbLengthW(szBuffer, ARRAYSIZE(szBuffer), &cbBuffer)))
  258. {
  259. cbBuffer += sizeof(WCHAR);
  260. *pchKey = (LPOLESTR)CoTaskMemAlloc(cbBuffer);
  261. if (NULL != *pchKey)
  262. {
  263. hr = StringCbCopyW(*pchKey, cbBuffer, szBuffer);
  264. if (FAILED(hr))
  265. {
  266. CoTaskMemFree(*pchKey);
  267. }
  268. }
  269. else
  270. {
  271. hr = E_OUTOFMEMORY;
  272. }
  273. }
  274. else
  275. {
  276. hr = E_INVALIDARG;
  277. }
  278. browserRegistry->Release();
  279. }
  280. else
  281. {
  282. hr = E_INVALIDARG;
  283. }
  284. if (FAILED(hr))
  285. {
  286. *pchKey = NULL;
  287. }
  288. return hr;
  289. }
  290. STDMETHODIMP Browser::GetExternal(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch)
  291. {
  292. if (ppDispatch && NULL != externalDisp)
  293. {
  294. externalDisp->AddRef();
  295. *ppDispatch = externalDisp;
  296. return S_OK;
  297. }
  298. return HTMLContainer2::GetExternal(ppDispatch);
  299. }
  300. STDMETHODIMP Browser::ShowContextMenu(DWORD dwID, POINT __RPC_FAR *ppt, IUnknown __RPC_FAR *pcmdtReserved, IDispatch __RPC_FAR *pdispReserved)
  301. {
  302. if (0 != (flagUiDisableContextMenu & uiFlags))
  303. return S_OK;
  304. return S_FALSE;
  305. }
  306. STDMETHODIMP Browser::ShowMessage(HWND hwnd, LPOLESTR lpstrText, LPOLESTR lpstrCaption, DWORD dwType, LPOLESTR lpstrHelpFile, DWORD dwHelpContext, LRESULT *plResult)
  307. {
  308. wchar_t szBuffer[256] = {0};
  309. lpstrCaption = (LPOLESTR)Plugin_LoadString(IDS_OMBROWSER_TITLE, szBuffer, ARRAYSIZE(szBuffer));
  310. *plResult = MessageBoxW(hwnd, lpstrText, lpstrCaption, dwType);
  311. return S_OK;
  312. }
  313. STDMETHODIMP Browser::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut)
  314. {
  315. HRESULT hr = S_OK;
  316. if (NULL != pguidCmdGroup)
  317. {
  318. if (IsEqualGUID(*pguidCmdGroup, CGID_DocHostCommandHandler))
  319. {
  320. switch (nCmdID)
  321. {
  322. case OLECMDID_SHOWSCRIPTERROR:
  323. {
  324. ifc_omdebugconfig *debugConfig = NULL;
  325. HRESULT showError = GetDebugConfig(&debugConfig);
  326. if (SUCCEEDED(showError) && debugConfig != NULL)
  327. {
  328. showError = debugConfig->GetScriptErrorEnabled();
  329. debugConfig->Release();
  330. }
  331. if (S_FALSE == showError)
  332. {
  333. OutputDebugStringA("~~<<=== script error\r\n");
  334. (*pvaOut).vt = VT_BOOL;
  335. (*pvaOut).boolVal = VARIANT_TRUE;
  336. }
  337. else
  338. {
  339. hr = OLECMDERR_E_NOTSUPPORTED;
  340. }
  341. }
  342. break;
  343. default:
  344. hr = OLECMDERR_E_NOTSUPPORTED;
  345. break;
  346. }
  347. }
  348. else if (IsEqualGUID(*pguidCmdGroup, CGID_ShellDocView))
  349. {
  350. switch (nCmdID)
  351. {
  352. case 53 /*SHDVID_ADDMENUEXTENSIONS*/:
  353. return S_OK;
  354. }
  355. }
  356. else
  357. {
  358. hr = OLECMDERR_E_UNKNOWNGROUP;
  359. }
  360. }
  361. else
  362. {
  363. hr = OLECMDERR_E_UNKNOWNGROUP;
  364. }
  365. return hr;
  366. }
  367. STDMETHODIMP Browser::QueryService(REFGUID guidService, REFIID riid, void **ppv)
  368. {
  369. if (IsEqualIID(riid, SID_SProtectFocus))
  370. {
  371. *ppv = (IProtectFocus*)this;
  372. this->AddRef();
  373. return S_OK;
  374. }
  375. else if (IsEqualIID(guidService, SID_SHTMLOMWindowServices))
  376. {
  377. if (IsEqualIID(riid, IID_IHTMLOMWindowServices))
  378. {
  379. *ppv = (IHTMLOMWindowServices*)this;
  380. this->AddRef();
  381. return S_OK;
  382. }
  383. }
  384. else if (IsEqualIID(riid, IID_INewWindowManager))
  385. {
  386. *ppv = (INewWindowManager*)this;
  387. this->AddRef();
  388. return S_OK;
  389. }
  390. return HTMLContainer2::QueryService(guidService, riid, ppv);
  391. }
  392. STDMETHODIMP Browser::AllowFocusChange(BOOL *pfAllow)
  393. {
  394. if (NULL == pfAllow)
  395. return E_POINTER;
  396. if (NULL != EventFocusChange)
  397. {
  398. VARIANT_BOOL Allow = VARIANT_TRUE;
  399. EventFocusChange(this, &Allow);
  400. if (VARIANT_FALSE == Allow)
  401. {
  402. *pfAllow = FALSE;
  403. }
  404. }
  405. return S_OK;
  406. }
  407. STDMETHODIMP Browser::moveTo(LONG x, LONG y)
  408. {
  409. if (NULL == EventSetWindowPos)
  410. return E_FAIL;
  411. EventSetWindowPos(this, HTMLContainer2::wndLeft | HTMLContainer2::wndTop, x, y, 0, 0);
  412. return S_OK;
  413. }
  414. STDMETHODIMP Browser::moveBy(LONG x, LONG y)
  415. {
  416. if (NULL == EventSetWindowPos)
  417. return E_FAIL;
  418. EventSetWindowPos(this, HTMLContainer2::wndLeft | HTMLContainer2::wndTop | HTMLContainer2::wndRelative, x, y, 0, 0);
  419. return S_OK;
  420. }
  421. STDMETHODIMP Browser::resizeTo(LONG x, LONG y)
  422. {
  423. if (NULL == EventSetWindowPos)
  424. return E_FAIL;
  425. EventSetWindowPos(this, HTMLContainer2::wndWidth | HTMLContainer2::wndHeight, 0, 0, x, y);
  426. return S_OK;
  427. }
  428. STDMETHODIMP Browser::resizeBy(LONG x, LONG y)
  429. {
  430. if (NULL == EventSetWindowPos)
  431. return E_FAIL;
  432. EventSetWindowPos(this, HTMLContainer2::wndWidth | HTMLContainer2::wndHeight | HTMLContainer2::wndRelative, 0, 0, x, y);
  433. return S_OK;
  434. }
  435. STDMETHODIMP Browser::EvaluateNewWindow(LPCWSTR pszUrl, LPCWSTR pszName, LPCWSTR pszUrlContext, LPCWSTR pszFeatures, BOOL fReplace, DWORD dwFlags, DWORD dwUserActionTime)
  436. {
  437. #ifdef _DEBUG
  438. char szBuffer[2048] = {0}, szFlags[128] = {0};
  439. LPSTR cursor = szFlags;
  440. size_t remaining = ARRAYSIZE(szFlags);
  441. if (0 != (NWMF_UNLOADING & dwFlags)) StringCchCopyExA(cursor, remaining, " unloading |", &cursor, &remaining, 0);
  442. if (0 != (NWMF_USERINITED & dwFlags)) StringCchCopyExA(cursor, remaining, " userInited |", &cursor, &remaining, 0);
  443. if (0 != (0x0004/*NWMF_FIRST_USERINITED*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " first |", &cursor, &remaining, 0);
  444. if (0 != (NWMF_OVERRIDEKEY & dwFlags)) StringCchCopyExA(cursor, remaining, " overrideKey |", &cursor, &remaining, 0);
  445. if (0 != (NWMF_SHOWHELP & dwFlags)) StringCchCopyExA(cursor, remaining, " showHelp |", &cursor, &remaining, 0);
  446. if (0 != (NWMF_HTMLDIALOG & dwFlags)) StringCchCopyExA(cursor, remaining, " htmlDialog |", &cursor, &remaining, 0);
  447. if (0 != (0x80/*NWMF_USERREQUESTED*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " userRequested |", &cursor, &remaining, 0);
  448. if (0 != (0x100/*NWMF_USERALLOWED*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " userAllowed |", &cursor, &remaining, 0);
  449. if (0 != (0x10000/*NWMF_FORCEWINDOW*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " forceWindow |", &cursor, &remaining, 0);
  450. if (0 != (0x20000/*NWMF_FORCETAB*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " forceTab |", &cursor, &remaining, 0);
  451. if (0 != (0x40000/*NWMF_SUGGESTWINDOW*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " suggestWindow |", &cursor, &remaining, 0);
  452. if (0 != (0x80000/*NWMF_SUGGESTTAB*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " suggestTab |", &cursor, &remaining, 0);
  453. if (0 != (0x100000/*NWMF_INACTIVETAB*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " inactiveTab |", &cursor, &remaining, 0);
  454. if (cursor != szFlags)
  455. {
  456. cursor -= 2;
  457. *cursor = '\0';
  458. }
  459. else
  460. {
  461. StringCchCopyExA(cursor, remaining, " <none>", &cursor, &remaining, 0);
  462. }
  463. StringCchPrintfA(szBuffer, ARRAYSIZE(szBuffer), "EvaluateNewWindow:\r\n\turlContext: %S,\r\n\turl: %S,\r\n\tflags:%s\r\n",
  464. ((NULL == pszUrlContext || L'\0' == *pszUrlContext) ? L"<empty>" : pszUrlContext),
  465. ((NULL == pszUrl || L'\0' == *pszUrl) ? L"<empty>" : pszUrl),
  466. szFlags);
  467. OutputDebugStringA(szBuffer);
  468. #endif // _DEBUG
  469. if (0 != (NWMF_UNLOADING & dwFlags))
  470. {
  471. return S_FALSE;
  472. }
  473. return S_OK;
  474. }
  475. OLECHAR *Browser::OnGetHostCSS(void)
  476. {
  477. if (0 != (flagUiDisableHostCss & uiFlags))
  478. return NULL;
  479. ifc_skinnedbrowser *skinnedBrowser = NULL;
  480. if (FAILED(Plugin_GetBrowserSkin(&skinnedBrowser)))
  481. return NULL;
  482. OLECHAR *hostCss = NULL;
  483. if (FAILED(skinnedBrowser->GetHostCss(&hostCss)))
  484. hostCss = NULL;
  485. skinnedBrowser->Release();
  486. return hostCss;
  487. }
  488. COLORREF Browser::OnGetHostBkColor(void)
  489. {
  490. if (0 != (flagUiDisableHostCss & uiFlags))
  491. return GetSysColor(COLOR_WINDOW);
  492. COLORREF rgbBk;
  493. ifc_skinhelper *skin = NULL;
  494. if (SUCCEEDED(Plugin_GetSkinHelper(&skin)) && skin != NULL)
  495. {
  496. skin->GetColor(WADLG_ITEMBG, &rgbBk);
  497. skin->Release();
  498. }
  499. if (FAILED(rgbBk))
  500. rgbBk = GetSysColor(COLOR_WINDOW);
  501. return rgbBk;
  502. }
  503. DWORD Browser::OnGetHostInfoFlags(void)
  504. {
  505. DWORD flags = CONTROL_HOSTINFOFLAGS;
  506. if (0 != (flagUiDisableScroll & uiFlags))
  507. flags |= DOCHOSTUIFLAG_SCROLL_NO;
  508. if (0 != (flagUiDialogMode & uiFlags))
  509. flags |= DOCHOSTUIFLAG_DIALOG;
  510. return flags;
  511. }
  512. DWORD Browser::OnGetDownlodFlags(void)
  513. {
  514. return CONTROL_DOWNLOADFLAGS;
  515. }
  516. HRESULT Browser::GetExternalName(LPWSTR pszBuffer, INT cchBufferMax)
  517. {
  518. if (NULL == pszBuffer)
  519. return E_POINTER;
  520. pszBuffer[0] = L'\0';
  521. IDocHostUIHandler *pHandler = NULL;
  522. HRESULT hr = QueryInterface(IID_IDocHostUIHandler, (void**)&pHandler);
  523. if (SUCCEEDED(hr) && pHandler != NULL)
  524. {
  525. IDispatch *pDispatch = NULL;
  526. hr = pHandler->GetExternal(&pDispatch);
  527. if (SUCCEEDED(hr) && NULL != pDispatch)
  528. {
  529. IWasabiDispatchable *pWasabi = NULL;
  530. hr = pDispatch->QueryInterface(IID_IWasabiDispatchable, (void**)&pWasabi);
  531. if (SUCCEEDED(hr) && pWasabi != NULL)
  532. {
  533. JSAPI::ifc_info *pInfo = NULL;
  534. hr = pWasabi->QueryDispatchable(JSAPI::IID_JSAPI_ifc_info, (Dispatchable**)&pInfo);
  535. if (SUCCEEDED(hr) && pInfo != NULL)
  536. {
  537. LPCWSTR p = pInfo->GetUserAgent();
  538. if (NULL != p && L'\0' != *p)
  539. StringCchCopy(pszBuffer, cchBufferMax, p);
  540. pInfo->Release();
  541. }
  542. pWasabi->Release();
  543. }
  544. pDispatch->Release();
  545. }
  546. pHandler->Release();
  547. }
  548. return S_OK;
  549. }
  550. LPCWSTR Browser::OnGetUserAgent(void)
  551. {
  552. if (NULL == pszUserAgent)
  553. {
  554. BSTR version = NULL;
  555. if (SUCCEEDED(GetUserAgent(&version)) && NULL != version)
  556. {
  557. WCHAR szExternal[128] = {0};
  558. size_t cchExternal = 0;
  559. if (FAILED(GetExternalName(szExternal, ARRAYSIZE(szExternal)))
  560. || FAILED(StringCchLength(szExternal, ARRAYSIZE(szExternal), &cchExternal)))
  561. {
  562. cchExternal = 0;
  563. }
  564. INT cchVersion = (NULL != version) ? SysStringLen(version) : 0;
  565. INT cchBufferMax = cchVersion + (INT)cchExternal;
  566. if (0 != cchExternal)
  567. cchBufferMax += 4; // for ", "
  568. if (cchBufferMax > 0)
  569. {
  570. pszUserAgent = Plugin_MallocString(cchBufferMax);
  571. if (NULL != pszUserAgent)
  572. {
  573. HRESULT hr = S_OK;
  574. LPWSTR cursor = pszUserAgent;
  575. size_t remaining = cchBufferMax;
  576. if (L'\0' != *version && SUCCEEDED(hr))
  577. {
  578. hr = StringCchCopyEx(cursor, remaining,
  579. version, &cursor,
  580. &remaining,
  581. STRSAFE_NULL_ON_FAILURE);
  582. }
  583. if (SUCCEEDED(hr) && 0 != cchExternal)
  584. {
  585. BOOL needCloseBracket = FALSE;
  586. if (cursor > pszUserAgent)
  587. {
  588. if (L')' == *(cursor - 1))
  589. {
  590. *(cursor - 1) = L',';
  591. needCloseBracket = TRUE;
  592. }
  593. hr = StringCchCopyEx(cursor, remaining,
  594. L" ", &cursor,
  595. &remaining,
  596. STRSAFE_NULL_ON_FAILURE);
  597. }
  598. if (SUCCEEDED(hr))
  599. {
  600. hr = StringCchCopyEx(cursor, remaining,
  601. szExternal, &cursor,
  602. &remaining,
  603. STRSAFE_NULL_ON_FAILURE);
  604. }
  605. if (SUCCEEDED(hr) && FALSE != needCloseBracket)
  606. {
  607. hr = StringCchCopyEx(cursor, remaining, L")",
  608. &cursor, &remaining,
  609. STRSAFE_NULL_ON_FAILURE);
  610. }
  611. if (FAILED(hr))
  612. {
  613. hr = S_OK;
  614. }
  615. }
  616. if (FAILED(hr))
  617. {
  618. Plugin_FreeString(pszUserAgent);
  619. pszUserAgent = NULL;
  620. }
  621. }
  622. }
  623. if (NULL != version)
  624. SysFreeString(version);
  625. }
  626. }
  627. return pszUserAgent;
  628. }
  629. HRESULT Browser::SendCommand(INT commandId)
  630. {
  631. IWebBrowser2 *pWeb2 = NULL;
  632. HRESULT hr = GetIWebBrowser2(&pWeb2);
  633. if (SUCCEEDED(hr) && pWeb2 != NULL)
  634. {
  635. switch(commandId)
  636. {
  637. case Browser::commandBack:
  638. hr = pWeb2->GoBack();
  639. break;
  640. case Browser::commandForward:
  641. hr = pWeb2->GoForward();
  642. break;
  643. case Browser::commandStop:
  644. hr = pWeb2->Stop();
  645. break;
  646. case Browser::commandRefresh:
  647. hr = pWeb2->Refresh();
  648. break;
  649. case Browser::commandRefreshCompletely:
  650. {
  651. VARIANT param;
  652. VariantInit(&param);
  653. V_VT(&param) = VT_I4;
  654. V_I4(&param) = REFRESH_COMPLETELY;
  655. hr = pWeb2->Refresh2(&param);
  656. }
  657. break;
  658. default:
  659. hr = E_INVALIDARG;
  660. break;
  661. }
  662. pWeb2->Release();
  663. }
  664. return hr;
  665. }
  666. #define POSTAPPCMD(/*HWND*/ __hwndTarget, /*HWND*/__hwndSource, /*INT*/__commandId)\
  667. (PostMessage((__hwndTarget), WM_APPCOMMAND, (WPARAM)(__hwndSource), MAKELPARAM(0, FAPPCOMMAND_KEY | (__commandId))))
  668. BOOL Browser::TranslateKey(LPMSG pMsg)
  669. {
  670. UINT vKey = (UINT)pMsg->wParam;
  671. BOOL redirectKey = TRUE;
  672. if (0 != (0x8000 & GetAsyncKeyState(VK_MENU)))
  673. {
  674. if (0 != (0x8000 & GetAsyncKeyState(VK_CONTROL)))
  675. {
  676. redirectKey = FALSE;
  677. }
  678. else
  679. {
  680. switch(vKey)
  681. {
  682. case VK_TAB:
  683. case VK_BACK:
  684. case VK_UP:
  685. case VK_DOWN:
  686. case VK_LEFT:
  687. case VK_RIGHT:
  688. case VK_NEXT:
  689. case VK_PRIOR:
  690. case VK_END:
  691. case VK_INSERT:
  692. case VK_DELETE:
  693. redirectKey = FALSE;
  694. break;
  695. }
  696. }
  697. }
  698. else if (0 != (0x8000 & GetAsyncKeyState(VK_CONTROL)))
  699. {
  700. switch(vKey)
  701. {
  702. case VK_BACK:
  703. case VK_UP:
  704. case VK_DOWN:
  705. case VK_LEFT:
  706. case VK_RIGHT:
  707. case VK_NEXT:
  708. case VK_PRIOR:
  709. case VK_HOME:
  710. case VK_END:
  711. case VK_INSERT:
  712. case VK_DELETE:
  713. case VK_F5:
  714. case 'R':
  715. case 'X':
  716. case 'C':
  717. case 'V':
  718. case 'A':
  719. case 'Z':
  720. case 'Y':
  721. redirectKey = FALSE;
  722. break;
  723. }
  724. }
  725. else
  726. {
  727. if (WM_KEYDOWN == pMsg->message && VK_ESCAPE == vKey)
  728. {
  729. POSTAPPCMD(hParent, pMsg->hwnd, APPCOMMAND_BROWSER_STOP);
  730. return TRUE;
  731. }
  732. redirectKey = FALSE;
  733. }
  734. if (FALSE != redirectKey && NULL != CallbackRedirectKey && FALSE != CallbackRedirectKey(this, pMsg))
  735. {
  736. return TRUE;
  737. }
  738. return __super::TranslateKey(pMsg);
  739. }
  740. STDMETHODIMP Browser::TranslateAccelerator(LPMSG lpMsg, const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID)
  741. {
  742. return E_NOTIMPL; // override HtmlContainer2 cause we already filtered keys
  743. }
  744. static INT OLECMDFTOCOMMANDSTATE(OLECMDF cmdf)
  745. {
  746. INT state = 0;
  747. if ( 0 != (OLECMDF_SUPPORTED & cmdf))
  748. state |= Browser::commandStateSupported;
  749. if ( 0 != (OLECMDF_ENABLED & cmdf))
  750. state |= Browser::commandStateEnabled;
  751. if ( 0 != (OLECMDF_LATCHED & cmdf))
  752. state |= Browser::commandStateLatched;
  753. return state;
  754. }
  755. HRESULT Browser::QueryCommandState(INT commandId, INT *commandState)
  756. {
  757. if (NULL == commandState)
  758. return E_INVALIDARG;
  759. HRESULT hr(S_OK);
  760. *commandState = 0;
  761. IWebBrowser2 *pWeb2 = NULL;
  762. OLECMDF cmdf = (OLECMDF)0;
  763. switch(commandId)
  764. {
  765. case Browser::commandBack:
  766. if (0 != (Browser::navigationBackEnabled & navigationState))
  767. *commandState |= (Browser::commandStateSupported | Browser::commandStateEnabled);
  768. break;
  769. case Browser::commandForward:
  770. if (0 != (Browser::navigationForwardEnabled & navigationState))
  771. *commandState |= (Browser::commandStateSupported | Browser::commandStateEnabled);
  772. break;
  773. case Browser::commandStop:
  774. hr = GetIWebBrowser2(&pWeb2);
  775. if (SUCCEEDED(hr) && pWeb2 != NULL)
  776. {
  777. hr = pWeb2->QueryStatusWB(OLECMDID_STOP, &cmdf);
  778. if (SUCCEEDED(hr))
  779. *commandState = OLECMDFTOCOMMANDSTATE(cmdf);
  780. pWeb2->Release();
  781. }
  782. break;
  783. case Browser::commandRefresh:
  784. hr = GetIWebBrowser2(&pWeb2);
  785. if (SUCCEEDED(hr) && pWeb2 != NULL)
  786. {
  787. hr = pWeb2->QueryStatusWB(OLECMDID_REFRESH, &cmdf);
  788. if (SUCCEEDED(hr))
  789. *commandState = OLECMDFTOCOMMANDSTATE(cmdf);
  790. pWeb2->Release();
  791. }
  792. break;
  793. }
  794. return hr;
  795. }
  796. void Browser::OnBeforeNavigate(IDispatch *pDispatch, VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers, VARIANT_BOOL *Cancel)
  797. {
  798. HTMLContainer2::OnBeforeNavigate(pDispatch, URL, Flags, TargetFrameName, PostData, Headers, Cancel);
  799. }
  800. void Browser::OnDownloadBegin(void)
  801. {
  802. HTMLContainer2::OnDownloadBegin();
  803. if (NULL != EventDownloadBegin)
  804. EventDownloadBegin(this);
  805. }
  806. void Browser::OnDownloadComplete(void)
  807. {
  808. HTMLContainer2::OnDownloadComplete();
  809. if (NULL != EventDownloadComplete)
  810. EventDownloadComplete(this);
  811. }
  812. void Browser::OnNavigateComplete(IDispatch *pDispatch, VARIANT *URL)
  813. {
  814. HTMLContainer2::OnNavigateComplete(pDispatch, URL);
  815. if (NULL != EventNavigateComplete)
  816. EventNavigateComplete(this, pDispatch, URL);
  817. }
  818. HRESULT Browser::GetErrorPageName(LPWSTR pszBuffer, HRESULT cchBufferMax, UINT errorCode, BOOL fCancel)
  819. {
  820. WCHAR szPath[MAX_PATH] = {0}, szTemp[MAX_PATH] = {0};
  821. LPCWSTR pszFile = NULL;
  822. ifc_omdebugconfig *debugConfig = NULL;
  823. if (SUCCEEDED(GetDebugConfig(&debugConfig)) && debugConfig != NULL)
  824. {
  825. debugConfig->GetBrowserPath(szPath, ARRAYSIZE(szPath));
  826. debugConfig->Release();
  827. }
  828. if (FALSE == fCancel)
  829. {
  830. pszFile = (errorCode < 0x800C0000) ? L"httpError.htm" : L"dnsError.htm";
  831. }
  832. else
  833. {
  834. pszFile = (errorCode == -1 ? L"inetDisabled.htm" : L"navCancel.htm");
  835. }
  836. if (L'0' != szPath[0] &&
  837. FALSE != PathCombine(szTemp, szPath, pszFile) &&
  838. FALSE != PathFileExists(szTemp))
  839. {
  840. return StringCchCopy(pszBuffer, cchBufferMax, szTemp);
  841. }
  842. HINSTANCE hModule = Plugin_GetLangInstance();
  843. if (NULL != hModule &&
  844. NULL == FindResource(hModule, pszFile, /*RT_HTML*/MAKEINTRESOURCEW(23)))
  845. {
  846. hModule = NULL;
  847. }
  848. if (NULL == hModule)
  849. {
  850. hModule = Plugin_GetInstance();
  851. if (NULL != hModule &&
  852. NULL == FindResource(hModule, pszFile, /*RT_HTML*/MAKEINTRESOURCEW(23)))
  853. {
  854. hModule = NULL;
  855. }
  856. }
  857. if (NULL != hModule)
  858. {
  859. if (0 == GetModuleFileName(hModule, szPath, ARRAYSIZE(szPath)))
  860. return E_FAIL;
  861. return StringCchPrintf(pszBuffer, cchBufferMax, L"res://%s/%s", szPath, pszFile);
  862. }
  863. return E_NOTIMPL;
  864. }
  865. static HRESULT Browser_FormatDefaultErrorMessage(LPWSTR pszBuffer, INT cchBufferMax, UINT errorCode, LPCWSTR pszUrl, BOOL fCancel)
  866. {
  867. HRESULT hr;
  868. if (FALSE != fCancel)
  869. {
  870. hr = StringCchCopy(pszBuffer, cchBufferMax,
  871. L"about:<HEAD><title>Service page load cancelled</title></Head><Body><H3>Service page load canncelled</H3></Body>");
  872. }
  873. else
  874. {
  875. WCHAR szStatus[32] = {0};
  876. hr = StringCchPrintf(szStatus, ARRAYSIZE(szStatus), ((errorCode < 0x800C0000) ? L"HTTP-%d" : L"0x%08X"), errorCode);
  877. if (FAILED(hr))
  878. szStatus[0] = L'\0';
  879. hr = StringCchPrintf(pszBuffer, cchBufferMax,
  880. L"about:<HEAD><title>Service load error</title></Head><Body><H3>Online Media cannot load service page</H3><p>URL: %s<br>Code: %s</p></Body>",
  881. ((NULL != pszUrl && L'\0' != *pszUrl) ? pszUrl : L"Unknown"), szStatus);
  882. }
  883. return hr;
  884. }
  885. HRESULT Browser::FormatErrorParam(LPWSTR pszBuffer, INT cchBufferMax, UINT errorCode, LPCWSTR pszUrl)
  886. {
  887. LPWSTR cursor = pszBuffer;
  888. size_t remaining = cchBufferMax;
  889. StringCchCopyEx(cursor, remaining, L"#", &cursor,&remaining, STRSAFE_NULL_ON_FAILURE);
  890. if (((UINT)-1) != errorCode)
  891. StringCchPrintfEx(cursor, remaining, &cursor,&remaining, STRSAFE_NULL_ON_FAILURE, L"errorcode=%d&", errorCode);
  892. if (NULL != pszUrl && L'\0' != *pszUrl)
  893. StringCchPrintfEx(cursor, remaining, &cursor,&remaining, STRSAFE_NULL_ON_FAILURE, L"url=%s&", pszUrl);
  894. ifc_omservice *service = NULL;
  895. if (NULL == CallbackGetOmService || FAILED(CallbackGetOmService(this, &service)))
  896. service = NULL;
  897. if (NULL != service)
  898. {
  899. StringCchPrintfEx(cursor, remaining, &cursor,&remaining, STRSAFE_NULL_ON_FAILURE, L"svcid=%d&", service->GetId());
  900. WCHAR szName[256] = {0};
  901. if (SUCCEEDED(service->GetName(szName, ARRAYSIZE(szName))) && L'\0' != *szName)
  902. {
  903. WCHAR szNameEscaped[ARRAYSIZE(szName)] = {0};
  904. DWORD cchName = ARRAYSIZE(szNameEscaped);
  905. if (SUCCEEDED(UrlEscape(szName, szNameEscaped, &cchName, URL_ESCAPE_SEGMENT_ONLY | URL_ESCAPE_PERCENT)) && 0 != cchName)
  906. StringCchPrintfEx(cursor, remaining, &cursor,&remaining, STRSAFE_NULL_ON_FAILURE, L"servicename=%s&", szNameEscaped);
  907. }
  908. service->Release();
  909. }
  910. WCHAR szClient[128] = {0};
  911. if (NULL != browserManager && SUCCEEDED(browserManager->GetClientId(szClient, ARRAYSIZE(szClient))))
  912. StringCchPrintfEx(cursor, remaining, &cursor,&remaining, STRSAFE_NULL_ON_FAILURE, L"uniqueid=%s&", szClient);
  913. if (cursor > pszBuffer)
  914. *(--cursor) = L'\0';
  915. return S_OK;
  916. }
  917. void Browser::OnNavigateError(IDispatch *pDispatch, VARIANT *URL, VARIANT *TargetFrameName, VARIANT *StatusCode, VARIANT_BOOL *Cancel)
  918. {
  919. UINT errorCode = (NULL != StatusCode && VT_I4 == StatusCode->vt) ? StatusCode->lVal : 0;
  920. if (200 == errorCode || 0 == errorCode)
  921. {
  922. return;
  923. }
  924. HTMLContainer2::OnNavigateError(pDispatch, URL, TargetFrameName, StatusCode, Cancel);
  925. WCHAR szUrl[INTERNET_MAX_URL_LENGTH] = {0};
  926. WCHAR szBuffer[INTERNET_MAX_URL_LENGTH] = {0};
  927. DWORD cchUrl = ARRAYSIZE(szUrl);
  928. DWORD cchBuffer = ARRAYSIZE(szBuffer);
  929. if (FAILED(GetErrorPageName(szUrl, ARRAYSIZE(szUrl), errorCode, FALSE)) ||
  930. FAILED(UrlEscape(szUrl, szBuffer, &cchBuffer, URL_ESCAPE_SPACES_ONLY | URL_DONT_ESCAPE_EXTRA_INFO)))
  931. {
  932. szBuffer[0] = L'\0';
  933. cchBuffer = 0;
  934. }
  935. if (NULL == URL || VT_BSTR != URL->vt || NULL == URL->bstrVal || L'\0' == *URL->bstrVal ||
  936. FAILED(UrlEscape(URL->bstrVal, szUrl, &cchUrl, URL_ESCAPE_SEGMENT_ONLY | URL_ESCAPE_PERCENT)))
  937. {
  938. szUrl[0] = L'\0';
  939. }
  940. if (0 != cchBuffer)
  941. {
  942. FormatErrorParam(szBuffer + cchBuffer, ARRAYSIZE(szBuffer) - cchBuffer, errorCode, szUrl);
  943. }
  944. else
  945. {
  946. if(FAILED(Browser_FormatDefaultErrorMessage(szBuffer, ARRAYSIZE(szBuffer), errorCode, szUrl, FALSE)))
  947. return;
  948. }
  949. IWebBrowser2 *pWeb2 = NULL;
  950. if (FAILED(GetIWebBrowser2(&pWeb2)))
  951. return;
  952. INT frameCount = 0;
  953. if (FAILED(GetFramesCount(pWeb2, &frameCount)))
  954. frameCount = 0;
  955. BOOL invokeDlComplete = FALSE;
  956. if (0 == frameCount)
  957. {
  958. pWeb2->Stop();
  959. BSTR currentUrl;
  960. if (FAILED(pWeb2->get_LocationURL(&currentUrl)))
  961. currentUrl = NULL;
  962. if (NULL != currentUrl &&
  963. CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, currentUrl, -1, szBuffer, -1))
  964. {
  965. *Cancel = VARIANT_TRUE;
  966. invokeDlComplete = TRUE;
  967. }
  968. else
  969. {
  970. if (FAILED(PostNavigateToName(szBuffer, navNoHistory)))
  971. NavigateToName(szBuffer, navNoHistory);
  972. }
  973. if (NULL != currentUrl)
  974. SysFreeString(currentUrl);
  975. }
  976. else
  977. {
  978. *Cancel = VARIANT_TRUE;
  979. invokeDlComplete = TRUE;
  980. IWebBrowser2* pWebActive;
  981. if (NULL != pDispatch &&
  982. SUCCEEDED(pDispatch->QueryInterface(IID_IWebBrowser2, (void**)&pWebActive)))
  983. {
  984. NavigateToNameEx(pWebActive, szBuffer, navNoHistory);
  985. invokeDlComplete = FALSE;
  986. pWebActive->Release();
  987. }
  988. }
  989. if (FALSE != invokeDlComplete)
  990. {
  991. DISPPARAMS params;
  992. ZeroMemory(&params, sizeof(DISPPARAMS));
  993. Invoke(DISPID_DOWNLOADCOMPLETE, GUID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, NULL);
  994. }
  995. pWeb2->Release();
  996. }
  997. void Browser::OnNavigateCancelled(LPCWSTR pszUrl, VARIANT_BOOL *Cancel)
  998. {
  999. HTMLContainer2::OnNavigateCancelled(pszUrl, Cancel);
  1000. WCHAR szBuffer[2048] = {0};
  1001. if (SUCCEEDED(GetErrorPageName(szBuffer, ARRAYSIZE(szBuffer), (*Cancel == ((VARIANT_BOOL)-2) ? -1 : 0), TRUE)))
  1002. {
  1003. INT cchLen = lstrlen(szBuffer);
  1004. FormatErrorParam(szBuffer + cchLen, ARRAYSIZE(szBuffer) - cchLen, 0, pszUrl);
  1005. }
  1006. else
  1007. {
  1008. if(FAILED(Browser_FormatDefaultErrorMessage(szBuffer, ARRAYSIZE(szBuffer), 0, pszUrl, TRUE)))
  1009. return;
  1010. }
  1011. *Cancel = VARIANT_TRUE;
  1012. NavigateToName(szBuffer, navNoHistory);
  1013. }
  1014. void Browser::OnDocumentReady(IDispatch *pDispatch, VARIANT *URL)
  1015. {
  1016. HTMLContainer2::OnDocumentReady(pDispatch, URL);
  1017. if (NULL != EventDocumentReady)
  1018. EventDocumentReady(this, pDispatch, URL);
  1019. }
  1020. void Browser::OnCommandStateChange(LONG commandId, VARIANT_BOOL Enable)
  1021. {
  1022. HTMLContainer2::OnCommandStateChange(commandId, Enable);
  1023. switch(commandId)
  1024. {
  1025. case CSC_NAVIGATEBACK:
  1026. if (VARIANT_TRUE == Enable)
  1027. navigationState |= navigationBackEnabled;
  1028. else
  1029. navigationState &= ~3;
  1030. if (NULL != EventCommandStateChange)
  1031. EventCommandStateChange(this, commandBack, 0 != (navigationBackEnabled & navigationState));
  1032. break;
  1033. case CSC_NAVIGATEFORWARD:
  1034. if (VARIANT_TRUE == Enable)
  1035. navigationState |= navigationForwardEnabled;
  1036. else
  1037. navigationState &= ~navigationForwardEnabled;
  1038. if (NULL != EventCommandStateChange)
  1039. EventCommandStateChange(this, commandForward, 0 != (navigationForwardEnabled & navigationState));
  1040. break;
  1041. case CSC_UPDATECOMMANDS:
  1042. if (NULL != EventCommandStateChange)
  1043. {
  1044. INT state = 0;
  1045. if (SUCCEEDED(QueryCommandState(commandStop, &state)) && 0 != (commandStateSupported & state))
  1046. EventCommandStateChange(this, commandStop, 0 != (commandStateEnabled & state));
  1047. if (SUCCEEDED(QueryCommandState(commandRefresh, &state)) && 0 != (commandStateSupported & state))
  1048. EventCommandStateChange(this, commandRefresh, 0 != (commandStateEnabled & state));
  1049. }
  1050. break;
  1051. }
  1052. }
  1053. void Browser::OnStatusTextChange(LPCWSTR pszText)
  1054. {
  1055. HTMLContainer2::OnStatusTextChange(pszText);
  1056. if (NULL != EventStatusChange)
  1057. {
  1058. if (NULL != pszText &&
  1059. CSTR_EQUAL == CompareString(CSTR_INVARIANT, 0, szDone, -1, pszText, -1))
  1060. {
  1061. pszText = NULL;
  1062. }
  1063. EventStatusChange(this, pszText);
  1064. }
  1065. }
  1066. void Browser::OnSetSecureLockIcon(UINT secureLockIcon)
  1067. {
  1068. HTMLContainer2::OnSetSecureLockIcon(secureLockIcon);
  1069. this->secureLockIcon = secureLockIcon;
  1070. if (NULL != EventSecureLockIconChange)
  1071. EventSecureLockIconChange(this);
  1072. }
  1073. void Browser::OnTitleChange(BSTR pszText)
  1074. {
  1075. if (NULL != EventTitleChange)
  1076. EventTitleChange(this, pszText);
  1077. }
  1078. void Browser::OnNewWindow3(IDispatch **ppDisp, VARIANT_BOOL *Cancel, DWORD dwFlags, BSTR bstrUrlContext, BSTR bstrUrl)
  1079. {
  1080. #ifdef _DEBUG
  1081. char szBuffer[2048], szFlags[128] = {0};
  1082. LPSTR cursor = szFlags;
  1083. size_t remaining = ARRAYSIZE(szFlags);
  1084. if (0 != (NWMF_UNLOADING & dwFlags)) StringCchCopyExA(cursor, remaining, " unloading |", &cursor, &remaining, 0);
  1085. if (0 != (NWMF_USERINITED & dwFlags)) StringCchCopyExA(cursor, remaining, " userInited |", &cursor, &remaining, 0);
  1086. if (0 != (0x0004/*NWMF_FIRST_USERINITED*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " first |", &cursor, &remaining, 0);
  1087. if (0 != (NWMF_OVERRIDEKEY & dwFlags)) StringCchCopyExA(cursor, remaining, " overrideKey |", &cursor, &remaining, 0);
  1088. if (0 != (NWMF_SHOWHELP & dwFlags)) StringCchCopyExA(cursor, remaining, " showHelp |", &cursor, &remaining, 0);
  1089. if (0 != (NWMF_HTMLDIALOG & dwFlags)) StringCchCopyExA(cursor, remaining, " htmlDialog |", &cursor, &remaining, 0);
  1090. if (0 != (0x80/*NWMF_USERREQUESTED*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " userRequested |", &cursor, &remaining, 0);
  1091. if (0 != (0x100/*NWMF_USERALLOWED*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " userAllowed |", &cursor, &remaining, 0);
  1092. if (0 != (0x10000/*NWMF_FORCEWINDOW*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " forceWindow |", &cursor, &remaining, 0);
  1093. if (0 != (0x20000/*NWMF_FORCETAB*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " forceTab |", &cursor, &remaining, 0);
  1094. if (0 != (0x40000/*NWMF_SUGGESTWINDOW*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " suggestWindow |", &cursor, &remaining, 0);
  1095. if (0 != (0x80000/*NWMF_SUGGESTTAB*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " suggestTab |", &cursor, &remaining, 0);
  1096. if (0 != (0x100000/*NWMF_INACTIVETAB*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " inactiveTab |", &cursor, &remaining, 0);
  1097. if (cursor != szFlags)
  1098. {
  1099. cursor -= 2;
  1100. *cursor = '\0';
  1101. }
  1102. else
  1103. {
  1104. StringCchCopyExA(cursor, remaining, " <none>", &cursor, &remaining, 0);
  1105. }
  1106. StringCchPrintfA(szBuffer, ARRAYSIZE(szBuffer), "NewWindow3:\r\n\turlContext: %S,\r\n\turl: %S,\r\n\tflags:%s\r\n",
  1107. ((NULL == bstrUrlContext || L'\0' == *bstrUrlContext) ? L"<empty>" : bstrUrlContext),
  1108. ((NULL == bstrUrl || L'\0' == *bstrUrl) ? L"<empty>" : bstrUrl), szFlags);
  1109. OutputDebugStringA(szBuffer);
  1110. #endif // _DEBUG
  1111. }
  1112. void Browser::OnNewWindow2(IDispatch **ppDisp, VARIANT_BOOL *Cancel)
  1113. {
  1114. if (NULL != EventCreatePopup)
  1115. {
  1116. EventCreatePopup(this, ppDisp, Cancel);
  1117. }
  1118. else if (NULL != Cancel)
  1119. {
  1120. *Cancel = VARIANT_TRUE;
  1121. }
  1122. }
  1123. void Browser::OnVisibleChange(VARIANT_BOOL Visible)
  1124. {
  1125. if (NULL != EventVisible)
  1126. {
  1127. EventVisible(this, Visible);
  1128. }
  1129. }
  1130. void Browser::OnWindowClosing(VARIANT_BOOL IsChildWindow, VARIANT_BOOL *Cancel)
  1131. {
  1132. if (NULL != EventWindowClosing)
  1133. {
  1134. EventWindowClosing(this, IsChildWindow, Cancel);
  1135. }
  1136. }
  1137. void Browser::OnShowUiElement(UINT elementId, VARIANT_BOOL fShow)
  1138. {
  1139. HTMLContainer2::OnShowUiElement(elementId, fShow);
  1140. if (NULL != EventShowUiElement)
  1141. {
  1142. EventShowUiElement(this, elementId, fShow);
  1143. }
  1144. }
  1145. void Browser::OnWindowSetResizable(VARIANT_BOOL Enable)
  1146. {
  1147. if (NULL != EventSetResizable)
  1148. {
  1149. EventSetResizable(this, Enable);
  1150. }
  1151. }
  1152. void Browser::OnEnableFullscreen(VARIANT_BOOL Enable)
  1153. {
  1154. if (NULL != EventSetFullscreen)
  1155. {
  1156. EventSetFullscreen(this, Enable);
  1157. }
  1158. }
  1159. void Browser::OnClientToHostWindow(LONG *CX, LONG *CY)
  1160. {
  1161. if (NULL != EventClientToHost)
  1162. {
  1163. EventClientToHost(this, CX, CY);
  1164. }
  1165. }
  1166. void Browser::OnSetWindowPos(UINT Flags, LONG X, LONG Y, LONG CX, LONG CY)
  1167. {
  1168. if (NULL != EventSetWindowPos)
  1169. {
  1170. EventSetWindowPos(this, Flags, X, Y, CX, CY);
  1171. }
  1172. }
  1173. HANDLE Browser::InitializePopupHook(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1174. {
  1175. HANDLE hHook = NULL;
  1176. BSTR version = NULL;
  1177. if (SUCCEEDED(GetAppVersion(&version)) && NULL != version)
  1178. {
  1179. // if (NULL == StrStrIW(version, L"Trident/4.0") /*IE8*/ &&
  1180. // NULL == StrStrIW(version, L"Trident/5.0") /*IE9*/)
  1181. {
  1182. hHook = Menu_InitializeHook(hwnd, NULL);
  1183. }
  1184. SysFreeString(version);
  1185. }
  1186. return hHook;
  1187. }
  1188. void Browser::DeletePopupHook(HANDLE hHook)
  1189. {
  1190. Menu_RemoveHook(hHook);
  1191. }
  1192. void Browser::InitializeMenuPopup(HWND hwnd, HMENU hMenu, INT iPos, BOOL fWindowMenu)
  1193. {
  1194. UINT szItems[] = { 2263 /*Save Background As...*/,
  1195. 2264 /*Set as Background*/,
  1196. 2265 /*Copy Background*/,
  1197. 2266 /*Create Shortcut*/,
  1198. 2261 /*Add to Favorite*/,
  1199. 2268 /*Save Target As...*/,
  1200. 2269 /*Show Picture*/,
  1201. 2270 /*Save Picture As...*/,
  1202. 2288 /*Email Picture*/,
  1203. 2289 /*Print Picture*/,
  1204. 2287 /*Goto My Picures*/,
  1205. 2278 /*Set as Desktop Item...*/,
  1206. 2435 /*Open in New Tab*/,
  1207. };
  1208. if (NULL == hMenu)
  1209. return;
  1210. ifc_omdebugconfig *debugConfig = NULL;
  1211. if (SUCCEEDED(GetDebugConfig(&debugConfig)) && debugConfig != NULL)
  1212. {
  1213. HRESULT hr = debugConfig->GetMenuFilterEnabled();
  1214. debugConfig->Release();
  1215. if (S_FALSE == hr) return;
  1216. }
  1217. // remove known items
  1218. INT i;
  1219. for (i = 0; i < ARRAYSIZE(szItems); i++)
  1220. {
  1221. DeleteMenu(hMenu, szItems[i], MF_BYCOMMAND);
  1222. }
  1223. // fix separators and remove extensions
  1224. i = GetMenuItemCount(hMenu);
  1225. MENUITEMINFOW mi = {0};
  1226. mi.cbSize = sizeof(MENUITEMINFO);
  1227. mi.fMask = MIIM_ID | MIIM_FTYPE | MIIM_SUBMENU;
  1228. INT separatorIndex = i;
  1229. while(i--)
  1230. {
  1231. if (GetMenuItemInfoW(hMenu, i, TRUE, &mi))
  1232. {
  1233. if (0 != (MFT_SEPARATOR & mi.fType))
  1234. {
  1235. if ((i + 1) == separatorIndex)
  1236. {
  1237. DeleteMenu(hMenu, i, MF_BYPOSITION);
  1238. }
  1239. separatorIndex = i;
  1240. }
  1241. else if (mi.wID >= 3700 && NULL == mi.hSubMenu)
  1242. {
  1243. DeleteMenu(hMenu, i, MF_BYPOSITION);
  1244. if (separatorIndex > i)
  1245. separatorIndex--;
  1246. }
  1247. }
  1248. }
  1249. }
  1250. void Browser::SetUiFlags(UINT flags, UINT mask)
  1251. {
  1252. uiFlags = (uiFlags & ~mask) | (flags & mask);
  1253. }
  1254. UINT Browser::GetUiFlags(UINT mask)
  1255. {
  1256. return (mask & uiFlags);
  1257. }
  1258. HRESULT Browser::ToggleFullscreen()
  1259. {
  1260. IWebBrowser2 *pWeb2 = NULL;
  1261. HRESULT hr = GetIWebBrowser2(&pWeb2);
  1262. if (FAILED(hr)) return hr;
  1263. VARIANT_BOOL fullscreenMode;
  1264. hr = pWeb2->get_FullScreen(&fullscreenMode);
  1265. if (SUCCEEDED(hr))
  1266. {
  1267. if (VARIANT_FALSE == fullscreenMode) fullscreenMode = VARIANT_TRUE;
  1268. else if (VARIANT_TRUE == fullscreenMode) fullscreenMode = VARIANT_FALSE;
  1269. else hr = E_UNEXPECTED;
  1270. if (SUCCEEDED(hr))
  1271. {
  1272. hr = pWeb2->put_FullScreen(fullscreenMode);
  1273. if (SUCCEEDED(hr))
  1274. {
  1275. }
  1276. }
  1277. }
  1278. pWeb2->Release();
  1279. return hr;
  1280. }
  1281. HRESULT Browser::GetDebugConfig(ifc_omdebugconfig **debugConfig)
  1282. {
  1283. if (NULL == debugConfig) return E_POINTER;
  1284. if (NULL == browserManager || FAILED(browserManager->GetConfig(&IFC_OmDebugConfig, (void**)debugConfig)))
  1285. {
  1286. *debugConfig = NULL;
  1287. return E_NOINTERFACE;
  1288. }
  1289. return S_OK;
  1290. }
  1291. HRESULT Browser::GetTravelLog(ifc_travelloghelper **travelLog)
  1292. {
  1293. if (NULL == travelLog) return E_POINTER;
  1294. IWebBrowser2 *pWeb2 = NULL;
  1295. HRESULT hr = GetIWebBrowser2(&pWeb2);
  1296. if (FAILED(hr))
  1297. {
  1298. *travelLog = NULL;
  1299. return hr;
  1300. }
  1301. hr = TravelLogHelper::CreateInstance(pWeb2, (TravelLogHelper**)travelLog);
  1302. pWeb2->Release();
  1303. return hr;
  1304. }
  1305. BOOL Browser::InputLangChangeRequest(HWND hwnd, UINT flags, HKL hkl)
  1306. {
  1307. HWND hTarget = GetParent(hwnd);
  1308. if (NULL != hTarget)
  1309. {
  1310. SendMessage(hTarget, WM_INPUTLANGCHANGEREQUEST, (WPARAM)flags, (LPARAM)hkl);
  1311. return TRUE;
  1312. }
  1313. return FALSE;
  1314. }
  1315. void Browser::InputLangChange(UINT charset, HKL hkl)
  1316. {
  1317. ActivateKeyboardLayout(hkl, KLF_SETFORPROCESS);
  1318. }
  1319. void Browser::OnClosePopupInternal()
  1320. {
  1321. if(NULL != EventClosePopup)
  1322. EventClosePopup(this);
  1323. }
  1324. #ifdef _DEBUG
  1325. void BrowserDebug_PrintRefs(Browser *browser)
  1326. {
  1327. if (NULL == browser)
  1328. {
  1329. aTRACE_LINE("browser object is NULL");
  1330. return;
  1331. }
  1332. browser->AddRef();
  1333. ULONG refBrowser, refUnknown, refWeb;
  1334. IUnknown *pUnk = NULL;
  1335. if (SUCCEEDED(browser->GetIUnknown(&pUnk)) && pUnk != NULL)
  1336. {
  1337. refUnknown = pUnk->Release();
  1338. }
  1339. else
  1340. {
  1341. refUnknown = ((ULONG)(0 - 2));
  1342. }
  1343. IWebBrowser2 *pWeb2 = NULL;
  1344. if (SUCCEEDED(browser->GetIWebBrowser2(&pWeb2)) && pWeb2 != NULL)
  1345. {
  1346. refWeb = pWeb2->Release();
  1347. }
  1348. else
  1349. {
  1350. refWeb = ((ULONG)(0 - 2));
  1351. }
  1352. refBrowser = browser->Release();
  1353. aTRACE_FMT("Browser Stats: Instance=%d, IUnknown=%d, IWebBrowser2=%d\r\n", refBrowser, refUnknown, refWeb);
  1354. }
  1355. #endif // _DEBUG