aboutsummaryrefslogtreecommitdiff
path: root/Src/omBrowser/browser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/omBrowser/browser.cpp')
-rw-r--r--Src/omBrowser/browser.cpp1579
1 files changed, 1579 insertions, 0 deletions
diff --git a/Src/omBrowser/browser.cpp b/Src/omBrowser/browser.cpp
new file mode 100644
index 00000000..8e955d3d
--- /dev/null
+++ b/Src/omBrowser/browser.cpp
@@ -0,0 +1,1579 @@
+#include "main.h"
+#include "./browser.h"
+#include "./browserRegistry.h"
+#include "./graphics.h"
+#include "./resource.h"
+
+#include "../winamp/wa_dlg.h"
+#include "../Plugins/General/gen_ml/colors.h"
+#include "../winamp/IWasabiDispatchable.h"
+#include "../winamp/JSAPI_Info.h"
+
+#include "./obj_ombrowser.h"
+#include "./ifc_skinhelper.h"
+#include "./ifc_skinnedbrowser.h"
+#include "./ifc_wasabihelper.h"
+#include "./ifc_omservice.h"
+#include "./ifc_omdebugconfig.h"
+#include "./travelLogHelper.h"
+#include "./menu.h"
+
+#include <wininet.h>
+#include <exdisp.h>
+#include <exdispid.h>
+#include <mshtmdid.h>
+#include <mshtml.h>
+
+#include <shlwapi.h>
+#include <strsafe.h>
+
+#define CONTROL_DOWNLOADFLAGS ( DLCTL_DLIMAGES | \
+ DLCTL_VIDEOS | \
+ /*DLCTL_PRAGMA_NO_CACHE |*/ \
+ /*DLCTL_NO_CLIENTPULL | */ \
+ DLCTL_RESYNCHRONIZE | \
+ 0)
+
+
+#define CONTROL_HOSTINFOFLAGS ( DOCHOSTUIFLAG_DISABLE_HELP_MENU | \
+ DOCHOSTUIFLAG_NO3DBORDER | \
+ DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE | \
+ DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY | \
+ DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION | \
+ DOCHOSTUIFLAG_THEME | \
+ DOCHOSTUIFLAG_NOPICS | \
+ DOCHOSTUIFLAG_NO3DOUTERBORDER | \
+ DOCHOSTUIFLAG_DISABLE_UNTRUSTEDPROTOCOL | \
+ DOCHOSTUIFLAG_ENABLE_REDIRECT_NOTIFICATION | \
+ DOCHOSTUIFLAG_USE_WINDOWLESS_SELECTCONTROL | \
+ DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE | \
+ DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION | \
+ 0)
+
+#ifndef LOAD_LIBRARY_AS_IMAGE_RESOURCE
+ #define LOAD_LIBRARY_AS_IMAGE_RESOURCE 0x000000020
+#endif //LOAD_LIBRARY_AS_IMAGE_RESOURCE
+
+ /*BHNAVCOMPLETECALLBACK EventDocumentReady;
+ BHNAVCOMPLETECALLBACK EventNavigateComplete;
+ BHCALLBACK EventDownloadBegin;
+ BHCALLBACK EventDownloadComplete;
+ BHCALLBACK EventContainerDestroyed;
+ BHCMDSTATECALLBACK EventCommandStateChange;
+ BHTEXTCALLBACK EventStatusChange;
+ BHTEXTCALLBACK EventTitleChange;
+ BHCALLBACK EventSecureLockIconChange;
+ BHCREATEPOPUPCALLBACK EventCreatePopup;
+ BHBOOLCALLBACK EventVisible;
+ BHBOOLCALLBACK EventSetResizable;
+ BHCLOSECALLBACK EventWindowClosing;
+ BHSHOWUICALLBACK EventShowUiElement;
+ BHCLIENTTOHOSTCALLBACK EventClientToHost;
+ BHWINDOWPOSCALLBACK EventSetWindowPos;
+ BHFOCUSCHANGECALLBACK EventFocusChange;
+ BHBOOLCALLBACK EventSetFullscreen;
+ BHCALLBACK EventClosePopup;*/
+
+Browser::Browser(obj_ombrowser *browserMngr, HWND winampWindow, HWND hParent)
+ : HTMLContainer2(winampWindow, hParent),
+ EventDocumentReady(NULL),
+ EventNavigateComplete(NULL),
+ EventDownloadBegin(NULL),
+ EventDownloadComplete(NULL),
+ EventContainerDestroyed(NULL),
+ EventCommandStateChange(NULL),
+ EventStatusChange(NULL),
+ EventTitleChange(NULL),
+ EventSecureLockIconChange(NULL),
+ EventCreatePopup(NULL),
+ EventVisible(NULL),
+ EventSetResizable(NULL),
+ EventWindowClosing(NULL),
+ EventShowUiElement(NULL),
+ EventClientToHost(NULL),
+ EventSetWindowPos(NULL),
+ EventFocusChange(NULL),
+ EventSetFullscreen(NULL),
+ EventClosePopup(NULL),
+ CallbackGetOmService(NULL),
+ CallbackRedirectKey(NULL),
+ browserManager(browserMngr), externalDisp(NULL),
+ pDropTargetHerlper(NULL), navigationState(0),
+ secureLockIcon(secureLockIconUnsecure),
+ pszUserAgent(NULL), uiFlags(0)
+{
+ memset(szDone, 0, sizeof(szDone));
+
+ if (NULL != externalDisp)
+ externalDisp->AddRef();
+
+ if (NULL != browserManager)
+ browserManager->AddRef();
+}
+
+Browser::~Browser()
+{
+ if (NULL != EventContainerDestroyed)
+ EventContainerDestroyed(this);
+
+ if (NULL != externalDisp)
+ externalDisp->Release();
+
+ if (NULL != pszUserAgent)
+ Plugin_FreeString(pszUserAgent);
+
+ if (NULL != pDropTargetHerlper)
+ pDropTargetHerlper->Release();
+
+ if (NULL != browserManager)
+ browserManager->Release();
+}
+
+HRESULT Browser::SetExternal(IDispatch *pDispatch)
+{
+ if (NULL != externalDisp)
+ externalDisp->Release();
+
+ externalDisp = pDispatch;
+
+ if (NULL != externalDisp)
+ externalDisp->AddRef();
+
+ return S_OK;
+}
+
+Browser *Browser::CreateInstance(obj_ombrowser *browserManager, HWND winampWindow, HWND hParent)
+{
+ Browser *instance = new Browser(browserManager, winampWindow, hParent);
+ return instance;
+}
+
+ULONG Browser::AddRef(void)
+{
+ return HTMLContainer2::AddRef();
+}
+
+ULONG Browser::Release(void)
+{
+ return HTMLContainer2::Release();
+}
+
+STDMETHODIMP Browser::Initialize(BOOL fRegisterAsBrowser)
+{
+ HRESULT hr = __super::Initialize();
+ if (SUCCEEDED(hr))
+ {
+ if (FALSE != fRegisterAsBrowser)
+ {
+ IWebBrowser2 *pWeb2 = NULL;
+ if (SUCCEEDED(GetIWebBrowser2(&pWeb2)) && pWeb2 != NULL)
+ {
+ pWeb2->put_RegisterAsBrowser(VARIANT_TRUE);
+ pWeb2->Release();
+ }
+ }
+
+ szDone[0] = L'\0';
+ HINSTANCE hModule;
+
+ if (L'\0' == szDone[0] && NULL != (hModule = LoadLibraryExW(L"ieframe.dll.mui", NULL,
+ LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)))
+ {
+ LoadString(hModule, 8169, szDone, ARRAYSIZE(szDone));
+ FreeLibrary(hModule);
+ }
+
+ if (L'\0' == szDone[0] && NULL != (hModule = LoadLibraryExW(L"shdoclc.dll", NULL,
+ LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)))
+ {
+ LoadString(hModule, 8169, szDone, ARRAYSIZE(szDone));
+ FreeLibrary(hModule);
+ }
+
+ if (L'\0' == szDone[0])
+ StringCchPrintf(szDone, ARRAYSIZE(szDone), L"Done");
+ }
+ return hr;
+}
+
+STDMETHODIMP Browser::Finish(void)
+{
+ IWebBrowser2 *pWeb2 = NULL;
+ if (SUCCEEDED(GetIWebBrowser2(&pWeb2)) && pWeb2 != NULL)
+ {
+ pWeb2->put_RegisterAsBrowser(VARIANT_FALSE);
+ pWeb2->Release();
+ }
+ return HTMLContainer2::Finish();
+}
+
+STDMETHODIMP Browser::QueryInterface(REFIID riid, PVOID *ppvObject)
+{
+ if (!ppvObject)
+ return E_POINTER;
+
+ if (IsEqualIID(riid, IID_IDropTarget))
+ {
+ *ppvObject = (IDropTarget*)this;
+ ((IUnknown*)*ppvObject)->AddRef();
+ return S_OK;
+ }
+ else if (IsEqualIID(riid, IID_IProtectFocus))
+ {
+ *ppvObject = (IProtectFocus*)this;
+ ((IUnknown*)*ppvObject)->AddRef();
+ return S_OK;
+ }
+
+ return HTMLContainer2::QueryInterface(riid, ppvObject);
+}
+
+STDMETHODIMP Browser::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect)
+{
+ *pdwEffect = (0x00FFFFFF & ~(*pdwEffect));
+
+ if (NULL == pDropTargetHerlper &&
+ FAILED(CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, (PVOID*)&pDropTargetHerlper)))
+ {
+ pDropTargetHerlper = NULL;
+ }
+
+ if (NULL != pDropTargetHerlper)
+ {
+ POINT pt = { ptl.x, ptl.y};
+ HWND hwnd = this->GetHostHWND();
+ pDropTargetHerlper->DragEnter(hwnd, pDataObject, &pt, *pdwEffect);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP Browser::DragOver(DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect)
+{
+ *pdwEffect = (0x00FFFFFF & ~(*pdwEffect));
+
+ if (NULL != pDropTargetHerlper)
+ {
+ POINT pt = { ptl.x, ptl.y};
+ pDropTargetHerlper->DragOver(&pt, *pdwEffect);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP Browser::DragLeave(void)
+{
+ if (NULL != pDropTargetHerlper)
+ pDropTargetHerlper->DragLeave();
+
+ return S_OK;
+}
+
+STDMETHODIMP Browser::Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect)
+{
+ *pdwEffect = (0x00FFFFFF & ~(*pdwEffect));
+
+ if (NULL != pDropTargetHerlper)
+ {
+ POINT pt = { ptl.x, ptl.y};
+ pDropTargetHerlper->Drop(pDataObject, &pt, *pdwEffect);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP Browser::GetDropTarget(IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
+{
+ if (NULL == ppDropTarget)
+ return E_POINTER;
+
+ HRESULT hr = QueryInterface(IID_IDropTarget, (void**)ppDropTarget);
+ if (SUCCEEDED(hr))
+ return S_OK;
+
+ return HTMLContainer2::GetDropTarget(pDropTarget, ppDropTarget);
+}
+
+STDMETHODIMP Browser::GetOverrideKeyPath(LPOLESTR __RPC_FAR *pchKey, DWORD dw)
+{
+ HRESULT hr;
+ size_t cbBuffer = 0;
+ ifc_ombrowserregistry *browserRegistry = NULL;
+ if (NULL != browserManager && SUCCEEDED(browserManager->GetRegistry(&browserRegistry)) && browserRegistry != NULL)
+ {
+ WCHAR szBuffer[256] = {0};
+ if (SUCCEEDED(browserRegistry->GetPath(szBuffer, ARRAYSIZE(szBuffer))) &&
+ SUCCEEDED(StringCbLengthW(szBuffer, ARRAYSIZE(szBuffer), &cbBuffer)))
+ {
+ cbBuffer += sizeof(WCHAR);
+ *pchKey = (LPOLESTR)CoTaskMemAlloc(cbBuffer);
+ if (NULL != *pchKey)
+ {
+ hr = StringCbCopyW(*pchKey, cbBuffer, szBuffer);
+ if (FAILED(hr))
+ {
+ CoTaskMemFree(*pchKey);
+ }
+ }
+ else
+ {
+ hr = E_OUTOFMEMORY;
+ }
+ }
+ else
+ {
+ hr = E_INVALIDARG;
+ }
+
+ browserRegistry->Release();
+ }
+ else
+ {
+ hr = E_INVALIDARG;
+ }
+
+ if (FAILED(hr))
+ {
+ *pchKey = NULL;
+ }
+ return hr;
+}
+
+STDMETHODIMP Browser::GetExternal(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch)
+{
+ if (ppDispatch && NULL != externalDisp)
+ {
+ externalDisp->AddRef();
+ *ppDispatch = externalDisp;
+ return S_OK;
+ }
+ return HTMLContainer2::GetExternal(ppDispatch);
+}
+
+STDMETHODIMP Browser::ShowContextMenu(DWORD dwID, POINT __RPC_FAR *ppt, IUnknown __RPC_FAR *pcmdtReserved, IDispatch __RPC_FAR *pdispReserved)
+{
+ if (0 != (flagUiDisableContextMenu & uiFlags))
+ return S_OK;
+
+ return S_FALSE;
+}
+
+STDMETHODIMP Browser::ShowMessage(HWND hwnd, LPOLESTR lpstrText, LPOLESTR lpstrCaption, DWORD dwType, LPOLESTR lpstrHelpFile, DWORD dwHelpContext, LRESULT *plResult)
+{
+ wchar_t szBuffer[256] = {0};
+ lpstrCaption = (LPOLESTR)Plugin_LoadString(IDS_OMBROWSER_TITLE, szBuffer, ARRAYSIZE(szBuffer));
+ *plResult = MessageBoxW(hwnd, lpstrText, lpstrCaption, dwType);
+ return S_OK;
+}
+
+STDMETHODIMP Browser::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut)
+{
+ HRESULT hr = S_OK;
+
+ if (NULL != pguidCmdGroup)
+ {
+ if (IsEqualGUID(*pguidCmdGroup, CGID_DocHostCommandHandler))
+ {
+ switch (nCmdID)
+ {
+ case OLECMDID_SHOWSCRIPTERROR:
+ {
+ ifc_omdebugconfig *debugConfig = NULL;
+ HRESULT showError = GetDebugConfig(&debugConfig);
+ if (SUCCEEDED(showError) && debugConfig != NULL)
+ {
+ showError = debugConfig->GetScriptErrorEnabled();
+ debugConfig->Release();
+ }
+
+ if (S_FALSE == showError)
+ {
+ OutputDebugStringA("~~<<=== script error\r\n");
+ (*pvaOut).vt = VT_BOOL;
+ (*pvaOut).boolVal = VARIANT_TRUE;
+ }
+ else
+ {
+ hr = OLECMDERR_E_NOTSUPPORTED;
+ }
+ }
+ break;
+ default:
+ hr = OLECMDERR_E_NOTSUPPORTED;
+ break;
+ }
+ }
+ else if (IsEqualGUID(*pguidCmdGroup, CGID_ShellDocView))
+ {
+ switch (nCmdID)
+ {
+ case 53 /*SHDVID_ADDMENUEXTENSIONS*/:
+ return S_OK;
+ }
+ }
+ else
+ {
+ hr = OLECMDERR_E_UNKNOWNGROUP;
+ }
+ }
+ else
+ {
+ hr = OLECMDERR_E_UNKNOWNGROUP;
+ }
+
+ return hr;
+}
+
+STDMETHODIMP Browser::QueryService(REFGUID guidService, REFIID riid, void **ppv)
+{
+ if (IsEqualIID(riid, SID_SProtectFocus))
+ {
+ *ppv = (IProtectFocus*)this;
+ this->AddRef();
+ return S_OK;
+ }
+ else if (IsEqualIID(guidService, SID_SHTMLOMWindowServices))
+ {
+ if (IsEqualIID(riid, IID_IHTMLOMWindowServices))
+ {
+ *ppv = (IHTMLOMWindowServices*)this;
+ this->AddRef();
+ return S_OK;
+ }
+ }
+ else if (IsEqualIID(riid, IID_INewWindowManager))
+ {
+ *ppv = (INewWindowManager*)this;
+ this->AddRef();
+ return S_OK;
+ }
+ return HTMLContainer2::QueryService(guidService, riid, ppv);
+}
+
+STDMETHODIMP Browser::AllowFocusChange(BOOL *pfAllow)
+{
+ if (NULL == pfAllow)
+ return E_POINTER;
+
+ if (NULL != EventFocusChange)
+ {
+ VARIANT_BOOL Allow = VARIANT_TRUE;
+ EventFocusChange(this, &Allow);
+ if (VARIANT_FALSE == Allow)
+ {
+ *pfAllow = FALSE;
+ }
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP Browser::moveTo(LONG x, LONG y)
+{
+ if (NULL == EventSetWindowPos)
+ return E_FAIL;
+
+ EventSetWindowPos(this, HTMLContainer2::wndLeft | HTMLContainer2::wndTop, x, y, 0, 0);
+ return S_OK;
+}
+
+STDMETHODIMP Browser::moveBy(LONG x, LONG y)
+{
+ if (NULL == EventSetWindowPos)
+ return E_FAIL;
+
+ EventSetWindowPos(this, HTMLContainer2::wndLeft | HTMLContainer2::wndTop | HTMLContainer2::wndRelative, x, y, 0, 0);
+ return S_OK;
+}
+
+STDMETHODIMP Browser::resizeTo(LONG x, LONG y)
+{
+ if (NULL == EventSetWindowPos)
+ return E_FAIL;
+
+ EventSetWindowPos(this, HTMLContainer2::wndWidth | HTMLContainer2::wndHeight, 0, 0, x, y);
+ return S_OK;
+}
+
+STDMETHODIMP Browser::resizeBy(LONG x, LONG y)
+{
+ if (NULL == EventSetWindowPos)
+ return E_FAIL;
+
+ EventSetWindowPos(this, HTMLContainer2::wndWidth | HTMLContainer2::wndHeight | HTMLContainer2::wndRelative, 0, 0, x, y);
+ return S_OK;
+}
+
+STDMETHODIMP Browser::EvaluateNewWindow(LPCWSTR pszUrl, LPCWSTR pszName, LPCWSTR pszUrlContext, LPCWSTR pszFeatures, BOOL fReplace, DWORD dwFlags, DWORD dwUserActionTime)
+{
+ #ifdef _DEBUG
+ char szBuffer[2048] = {0}, szFlags[128] = {0};
+ LPSTR cursor = szFlags;
+ size_t remaining = ARRAYSIZE(szFlags);
+ if (0 != (NWMF_UNLOADING & dwFlags)) StringCchCopyExA(cursor, remaining, " unloading |", &cursor, &remaining, 0);
+ if (0 != (NWMF_USERINITED & dwFlags)) StringCchCopyExA(cursor, remaining, " userInited |", &cursor, &remaining, 0);
+ if (0 != (0x0004/*NWMF_FIRST_USERINITED*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " first |", &cursor, &remaining, 0);
+ if (0 != (NWMF_OVERRIDEKEY & dwFlags)) StringCchCopyExA(cursor, remaining, " overrideKey |", &cursor, &remaining, 0);
+ if (0 != (NWMF_SHOWHELP & dwFlags)) StringCchCopyExA(cursor, remaining, " showHelp |", &cursor, &remaining, 0);
+ if (0 != (NWMF_HTMLDIALOG & dwFlags)) StringCchCopyExA(cursor, remaining, " htmlDialog |", &cursor, &remaining, 0);
+ if (0 != (0x80/*NWMF_USERREQUESTED*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " userRequested |", &cursor, &remaining, 0);
+ if (0 != (0x100/*NWMF_USERALLOWED*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " userAllowed |", &cursor, &remaining, 0);
+ if (0 != (0x10000/*NWMF_FORCEWINDOW*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " forceWindow |", &cursor, &remaining, 0);
+ if (0 != (0x20000/*NWMF_FORCETAB*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " forceTab |", &cursor, &remaining, 0);
+ if (0 != (0x40000/*NWMF_SUGGESTWINDOW*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " suggestWindow |", &cursor, &remaining, 0);
+ if (0 != (0x80000/*NWMF_SUGGESTTAB*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " suggestTab |", &cursor, &remaining, 0);
+ if (0 != (0x100000/*NWMF_INACTIVETAB*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " inactiveTab |", &cursor, &remaining, 0);
+
+ if (cursor != szFlags)
+ {
+ cursor -= 2;
+ *cursor = '\0';
+ }
+ else
+ {
+ StringCchCopyExA(cursor, remaining, " <none>", &cursor, &remaining, 0);
+ }
+
+ StringCchPrintfA(szBuffer, ARRAYSIZE(szBuffer), "EvaluateNewWindow:\r\n\turlContext: %S,\r\n\turl: %S,\r\n\tflags:%s\r\n",
+ ((NULL == pszUrlContext || L'\0' == *pszUrlContext) ? L"<empty>" : pszUrlContext),
+ ((NULL == pszUrl || L'\0' == *pszUrl) ? L"<empty>" : pszUrl),
+ szFlags);
+
+ OutputDebugStringA(szBuffer);
+#endif // _DEBUG
+
+ if (0 != (NWMF_UNLOADING & dwFlags))
+ {
+ return S_FALSE;
+ }
+
+ return S_OK;
+}
+
+OLECHAR *Browser::OnGetHostCSS(void)
+{
+ if (0 != (flagUiDisableHostCss & uiFlags))
+ return NULL;
+
+ ifc_skinnedbrowser *skinnedBrowser = NULL;
+ if (FAILED(Plugin_GetBrowserSkin(&skinnedBrowser)))
+ return NULL;
+
+ OLECHAR *hostCss = NULL;
+ if (FAILED(skinnedBrowser->GetHostCss(&hostCss)))
+ hostCss = NULL;
+
+ skinnedBrowser->Release();
+ return hostCss;
+}
+
+COLORREF Browser::OnGetHostBkColor(void)
+{
+ if (0 != (flagUiDisableHostCss & uiFlags))
+ return GetSysColor(COLOR_WINDOW);
+
+ COLORREF rgbBk;
+ ifc_skinhelper *skin = NULL;
+ if (SUCCEEDED(Plugin_GetSkinHelper(&skin)) && skin != NULL)
+ {
+ skin->GetColor(WADLG_ITEMBG, &rgbBk);
+ skin->Release();
+ }
+
+ if (FAILED(rgbBk))
+ rgbBk = GetSysColor(COLOR_WINDOW);
+
+ return rgbBk;
+}
+
+DWORD Browser::OnGetHostInfoFlags(void)
+{
+ DWORD flags = CONTROL_HOSTINFOFLAGS;
+
+ if (0 != (flagUiDisableScroll & uiFlags))
+ flags |= DOCHOSTUIFLAG_SCROLL_NO;
+
+ if (0 != (flagUiDialogMode & uiFlags))
+ flags |= DOCHOSTUIFLAG_DIALOG;
+
+ return flags;
+}
+
+DWORD Browser::OnGetDownlodFlags(void)
+{
+ return CONTROL_DOWNLOADFLAGS;
+}
+
+HRESULT Browser::GetExternalName(LPWSTR pszBuffer, INT cchBufferMax)
+{
+ if (NULL == pszBuffer)
+ return E_POINTER;
+
+ pszBuffer[0] = L'\0';
+
+ IDocHostUIHandler *pHandler = NULL;
+ HRESULT hr = QueryInterface(IID_IDocHostUIHandler, (void**)&pHandler);
+ if (SUCCEEDED(hr) && pHandler != NULL)
+ {
+ IDispatch *pDispatch = NULL;
+ hr = pHandler->GetExternal(&pDispatch);
+ if (SUCCEEDED(hr) && NULL != pDispatch)
+ {
+ IWasabiDispatchable *pWasabi = NULL;
+ hr = pDispatch->QueryInterface(IID_IWasabiDispatchable, (void**)&pWasabi);
+ if (SUCCEEDED(hr) && pWasabi != NULL)
+ {
+ JSAPI::ifc_info *pInfo = NULL;
+ hr = pWasabi->QueryDispatchable(JSAPI::IID_JSAPI_ifc_info, (Dispatchable**)&pInfo);
+ if (SUCCEEDED(hr) && pInfo != NULL)
+ {
+ LPCWSTR p = pInfo->GetUserAgent();
+ if (NULL != p && L'\0' != *p)
+ StringCchCopy(pszBuffer, cchBufferMax, p);
+
+ pInfo->Release();
+ }
+ pWasabi->Release();
+ }
+ pDispatch->Release();
+ }
+ pHandler->Release();
+ }
+ return S_OK;
+}
+
+LPCWSTR Browser::OnGetUserAgent(void)
+{
+ if (NULL == pszUserAgent)
+ {
+ BSTR version = NULL;
+
+ if (SUCCEEDED(GetUserAgent(&version)) && NULL != version)
+ {
+ WCHAR szExternal[128] = {0};
+ size_t cchExternal = 0;
+
+ if (FAILED(GetExternalName(szExternal, ARRAYSIZE(szExternal)))
+ || FAILED(StringCchLength(szExternal, ARRAYSIZE(szExternal), &cchExternal)))
+ {
+ cchExternal = 0;
+ }
+
+ INT cchVersion = (NULL != version) ? SysStringLen(version) : 0;
+ INT cchBufferMax = cchVersion + (INT)cchExternal;
+ if (0 != cchExternal)
+ cchBufferMax += 4; // for ", "
+
+ if (cchBufferMax > 0)
+ {
+ pszUserAgent = Plugin_MallocString(cchBufferMax);
+ if (NULL != pszUserAgent)
+ {
+ HRESULT hr = S_OK;
+ LPWSTR cursor = pszUserAgent;
+ size_t remaining = cchBufferMax;
+
+ if (L'\0' != *version && SUCCEEDED(hr))
+ {
+ hr = StringCchCopyEx(cursor, remaining,
+ version, &cursor,
+ &remaining,
+ STRSAFE_NULL_ON_FAILURE);
+ }
+
+ if (SUCCEEDED(hr) && 0 != cchExternal)
+ {
+ BOOL needCloseBracket = FALSE;
+
+ if (cursor > pszUserAgent)
+ {
+ if (L')' == *(cursor - 1))
+ {
+ *(cursor - 1) = L',';
+ needCloseBracket = TRUE;
+ }
+
+ hr = StringCchCopyEx(cursor, remaining,
+ L" ", &cursor,
+ &remaining,
+ STRSAFE_NULL_ON_FAILURE);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = StringCchCopyEx(cursor, remaining,
+ szExternal, &cursor,
+ &remaining,
+ STRSAFE_NULL_ON_FAILURE);
+ }
+
+ if (SUCCEEDED(hr) && FALSE != needCloseBracket)
+ {
+ hr = StringCchCopyEx(cursor, remaining, L")",
+ &cursor, &remaining,
+ STRSAFE_NULL_ON_FAILURE);
+ }
+
+ if (FAILED(hr))
+ {
+ hr = S_OK;
+ }
+ }
+
+ if (FAILED(hr))
+ {
+ Plugin_FreeString(pszUserAgent);
+ pszUserAgent = NULL;
+ }
+ }
+ }
+
+ if (NULL != version)
+ SysFreeString(version);
+ }
+ }
+
+ return pszUserAgent;
+}
+
+HRESULT Browser::SendCommand(INT commandId)
+{
+ IWebBrowser2 *pWeb2 = NULL;
+ HRESULT hr = GetIWebBrowser2(&pWeb2);
+ if (SUCCEEDED(hr) && pWeb2 != NULL)
+ {
+ switch(commandId)
+ {
+ case Browser::commandBack:
+ hr = pWeb2->GoBack();
+ break;
+ case Browser::commandForward:
+ hr = pWeb2->GoForward();
+ break;
+ case Browser::commandStop:
+ hr = pWeb2->Stop();
+ break;
+ case Browser::commandRefresh:
+ hr = pWeb2->Refresh();
+ break;
+ case Browser::commandRefreshCompletely:
+ {
+ VARIANT param;
+ VariantInit(&param);
+ V_VT(&param) = VT_I4;
+ V_I4(&param) = REFRESH_COMPLETELY;
+ hr = pWeb2->Refresh2(&param);
+ }
+ break;
+ default:
+ hr = E_INVALIDARG;
+ break;
+ }
+ pWeb2->Release();
+ }
+ return hr;
+}
+
+#define POSTAPPCMD(/*HWND*/ __hwndTarget, /*HWND*/__hwndSource, /*INT*/__commandId)\
+ (PostMessage((__hwndTarget), WM_APPCOMMAND, (WPARAM)(__hwndSource), MAKELPARAM(0, FAPPCOMMAND_KEY | (__commandId))))
+
+BOOL Browser::TranslateKey(LPMSG pMsg)
+{
+ UINT vKey = (UINT)pMsg->wParam;
+ BOOL redirectKey = TRUE;
+ if (0 != (0x8000 & GetAsyncKeyState(VK_MENU)))
+ {
+ if (0 != (0x8000 & GetAsyncKeyState(VK_CONTROL)))
+ {
+ redirectKey = FALSE;
+ }
+ else
+ {
+ switch(vKey)
+ {
+ case VK_TAB:
+ case VK_BACK:
+ case VK_UP:
+ case VK_DOWN:
+ case VK_LEFT:
+ case VK_RIGHT:
+ case VK_NEXT:
+ case VK_PRIOR:
+ case VK_END:
+ case VK_INSERT:
+ case VK_DELETE:
+ redirectKey = FALSE;
+ break;
+ }
+ }
+ }
+ else if (0 != (0x8000 & GetAsyncKeyState(VK_CONTROL)))
+ {
+ switch(vKey)
+ {
+ case VK_BACK:
+ case VK_UP:
+ case VK_DOWN:
+ case VK_LEFT:
+ case VK_RIGHT:
+ case VK_NEXT:
+ case VK_PRIOR:
+ case VK_HOME:
+ case VK_END:
+ case VK_INSERT:
+ case VK_DELETE:
+ case VK_F5:
+ case 'R':
+ case 'X':
+ case 'C':
+ case 'V':
+ case 'A':
+ case 'Z':
+ case 'Y':
+ redirectKey = FALSE;
+ break;
+ }
+ }
+ else
+ {
+ if (WM_KEYDOWN == pMsg->message && VK_ESCAPE == vKey)
+ {
+ POSTAPPCMD(hParent, pMsg->hwnd, APPCOMMAND_BROWSER_STOP);
+ return TRUE;
+ }
+
+ redirectKey = FALSE;
+ }
+
+ if (FALSE != redirectKey && NULL != CallbackRedirectKey && FALSE != CallbackRedirectKey(this, pMsg))
+ {
+ return TRUE;
+ }
+
+ return __super::TranslateKey(pMsg);
+}
+
+STDMETHODIMP Browser::TranslateAccelerator(LPMSG lpMsg, const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID)
+{
+ return E_NOTIMPL; // override HtmlContainer2 cause we already filtered keys
+}
+
+static INT OLECMDFTOCOMMANDSTATE(OLECMDF cmdf)
+{
+ INT state = 0;
+ if ( 0 != (OLECMDF_SUPPORTED & cmdf))
+ state |= Browser::commandStateSupported;
+ if ( 0 != (OLECMDF_ENABLED & cmdf))
+ state |= Browser::commandStateEnabled;
+ if ( 0 != (OLECMDF_LATCHED & cmdf))
+ state |= Browser::commandStateLatched;
+
+ return state;
+}
+
+HRESULT Browser::QueryCommandState(INT commandId, INT *commandState)
+{
+ if (NULL == commandState)
+ return E_INVALIDARG;
+
+ HRESULT hr(S_OK);
+ *commandState = 0;
+ IWebBrowser2 *pWeb2 = NULL;
+ OLECMDF cmdf = (OLECMDF)0;
+
+ switch(commandId)
+ {
+ case Browser::commandBack:
+ if (0 != (Browser::navigationBackEnabled & navigationState))
+ *commandState |= (Browser::commandStateSupported | Browser::commandStateEnabled);
+ break;
+ case Browser::commandForward:
+ if (0 != (Browser::navigationForwardEnabled & navigationState))
+ *commandState |= (Browser::commandStateSupported | Browser::commandStateEnabled);
+ break;
+ case Browser::commandStop:
+ hr = GetIWebBrowser2(&pWeb2);
+ if (SUCCEEDED(hr) && pWeb2 != NULL)
+ {
+ hr = pWeb2->QueryStatusWB(OLECMDID_STOP, &cmdf);
+ if (SUCCEEDED(hr))
+ *commandState = OLECMDFTOCOMMANDSTATE(cmdf);
+ pWeb2->Release();
+ }
+ break;
+ case Browser::commandRefresh:
+ hr = GetIWebBrowser2(&pWeb2);
+ if (SUCCEEDED(hr) && pWeb2 != NULL)
+ {
+ hr = pWeb2->QueryStatusWB(OLECMDID_REFRESH, &cmdf);
+ if (SUCCEEDED(hr))
+ *commandState = OLECMDFTOCOMMANDSTATE(cmdf);
+ pWeb2->Release();
+ }
+ break;
+ }
+
+ return hr;
+}
+
+void Browser::OnBeforeNavigate(IDispatch *pDispatch, VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers, VARIANT_BOOL *Cancel)
+{
+ HTMLContainer2::OnBeforeNavigate(pDispatch, URL, Flags, TargetFrameName, PostData, Headers, Cancel);
+}
+
+void Browser::OnDownloadBegin(void)
+{
+ HTMLContainer2::OnDownloadBegin();
+
+ if (NULL != EventDownloadBegin)
+ EventDownloadBegin(this);
+}
+
+void Browser::OnDownloadComplete(void)
+{
+ HTMLContainer2::OnDownloadComplete();
+
+ if (NULL != EventDownloadComplete)
+ EventDownloadComplete(this);
+}
+
+void Browser::OnNavigateComplete(IDispatch *pDispatch, VARIANT *URL)
+{
+ HTMLContainer2::OnNavigateComplete(pDispatch, URL);
+
+ if (NULL != EventNavigateComplete)
+ EventNavigateComplete(this, pDispatch, URL);
+}
+
+HRESULT Browser::GetErrorPageName(LPWSTR pszBuffer, HRESULT cchBufferMax, UINT errorCode, BOOL fCancel)
+{
+ WCHAR szPath[MAX_PATH] = {0}, szTemp[MAX_PATH] = {0};
+ LPCWSTR pszFile = NULL;
+
+ ifc_omdebugconfig *debugConfig = NULL;
+ if (SUCCEEDED(GetDebugConfig(&debugConfig)) && debugConfig != NULL)
+ {
+ debugConfig->GetBrowserPath(szPath, ARRAYSIZE(szPath));
+ debugConfig->Release();
+ }
+
+ if (FALSE == fCancel)
+ {
+ pszFile = (errorCode < 0x800C0000) ? L"httpError.htm" : L"dnsError.htm";
+ }
+ else
+ {
+ pszFile = (errorCode == -1 ? L"inetDisabled.htm" : L"navCancel.htm");
+ }
+
+ if (L'0' != szPath[0] &&
+ FALSE != PathCombine(szTemp, szPath, pszFile) &&
+ FALSE != PathFileExists(szTemp))
+ {
+ return StringCchCopy(pszBuffer, cchBufferMax, szTemp);
+ }
+
+ HINSTANCE hModule = Plugin_GetLangInstance();
+ if (NULL != hModule &&
+ NULL == FindResource(hModule, pszFile, /*RT_HTML*/MAKEINTRESOURCEW(23)))
+ {
+ hModule = NULL;
+ }
+
+ if (NULL == hModule)
+ {
+ hModule = Plugin_GetInstance();
+ if (NULL != hModule &&
+ NULL == FindResource(hModule, pszFile, /*RT_HTML*/MAKEINTRESOURCEW(23)))
+ {
+ hModule = NULL;
+ }
+ }
+
+ if (NULL != hModule)
+ {
+ if (0 == GetModuleFileName(hModule, szPath, ARRAYSIZE(szPath)))
+ return E_FAIL;
+
+ return StringCchPrintf(pszBuffer, cchBufferMax, L"res://%s/%s", szPath, pszFile);
+ }
+
+ return E_NOTIMPL;
+}
+
+static HRESULT Browser_FormatDefaultErrorMessage(LPWSTR pszBuffer, INT cchBufferMax, UINT errorCode, LPCWSTR pszUrl, BOOL fCancel)
+{
+ HRESULT hr;
+ if (FALSE != fCancel)
+ {
+ hr = StringCchCopy(pszBuffer, cchBufferMax,
+ L"about:<HEAD><title>Service page load cancelled</title></Head><Body><H3>Service page load canncelled</H3></Body>");
+ }
+ else
+ {
+ WCHAR szStatus[32] = {0};
+ hr = StringCchPrintf(szStatus, ARRAYSIZE(szStatus), ((errorCode < 0x800C0000) ? L"HTTP-%d" : L"0x%08X"), errorCode);
+
+ if (FAILED(hr))
+ szStatus[0] = L'\0';
+
+ hr = StringCchPrintf(pszBuffer, cchBufferMax,
+ 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>",
+ ((NULL != pszUrl && L'\0' != *pszUrl) ? pszUrl : L"Unknown"), szStatus);
+ }
+ return hr;
+}
+
+HRESULT Browser::FormatErrorParam(LPWSTR pszBuffer, INT cchBufferMax, UINT errorCode, LPCWSTR pszUrl)
+{
+ LPWSTR cursor = pszBuffer;
+ size_t remaining = cchBufferMax;
+
+ StringCchCopyEx(cursor, remaining, L"#", &cursor,&remaining, STRSAFE_NULL_ON_FAILURE);
+
+ if (((UINT)-1) != errorCode)
+ StringCchPrintfEx(cursor, remaining, &cursor,&remaining, STRSAFE_NULL_ON_FAILURE, L"errorcode=%d&", errorCode);
+
+ if (NULL != pszUrl && L'\0' != *pszUrl)
+ StringCchPrintfEx(cursor, remaining, &cursor,&remaining, STRSAFE_NULL_ON_FAILURE, L"url=%s&", pszUrl);
+
+ ifc_omservice *service = NULL;
+ if (NULL == CallbackGetOmService || FAILED(CallbackGetOmService(this, &service)))
+ service = NULL;
+
+ if (NULL != service)
+ {
+ StringCchPrintfEx(cursor, remaining, &cursor,&remaining, STRSAFE_NULL_ON_FAILURE, L"svcid=%d&", service->GetId());
+
+ WCHAR szName[256] = {0};
+ if (SUCCEEDED(service->GetName(szName, ARRAYSIZE(szName))) && L'\0' != *szName)
+ {
+ WCHAR szNameEscaped[ARRAYSIZE(szName)] = {0};
+ DWORD cchName = ARRAYSIZE(szNameEscaped);
+ if (SUCCEEDED(UrlEscape(szName, szNameEscaped, &cchName, URL_ESCAPE_SEGMENT_ONLY | URL_ESCAPE_PERCENT)) && 0 != cchName)
+ StringCchPrintfEx(cursor, remaining, &cursor,&remaining, STRSAFE_NULL_ON_FAILURE, L"servicename=%s&", szNameEscaped);
+ }
+
+ service->Release();
+ }
+
+ WCHAR szClient[128] = {0};
+ if (NULL != browserManager && SUCCEEDED(browserManager->GetClientId(szClient, ARRAYSIZE(szClient))))
+ StringCchPrintfEx(cursor, remaining, &cursor,&remaining, STRSAFE_NULL_ON_FAILURE, L"uniqueid=%s&", szClient);
+
+ if (cursor > pszBuffer)
+ *(--cursor) = L'\0';
+
+ return S_OK;
+}
+
+void Browser::OnNavigateError(IDispatch *pDispatch, VARIANT *URL, VARIANT *TargetFrameName, VARIANT *StatusCode, VARIANT_BOOL *Cancel)
+{
+ UINT errorCode = (NULL != StatusCode && VT_I4 == StatusCode->vt) ? StatusCode->lVal : 0;
+ if (200 == errorCode || 0 == errorCode)
+ {
+ return;
+ }
+
+ HTMLContainer2::OnNavigateError(pDispatch, URL, TargetFrameName, StatusCode, Cancel);
+
+ WCHAR szUrl[INTERNET_MAX_URL_LENGTH] = {0};
+ WCHAR szBuffer[INTERNET_MAX_URL_LENGTH] = {0};
+
+ DWORD cchUrl = ARRAYSIZE(szUrl);
+ DWORD cchBuffer = ARRAYSIZE(szBuffer);
+
+ if (FAILED(GetErrorPageName(szUrl, ARRAYSIZE(szUrl), errorCode, FALSE)) ||
+ FAILED(UrlEscape(szUrl, szBuffer, &cchBuffer, URL_ESCAPE_SPACES_ONLY | URL_DONT_ESCAPE_EXTRA_INFO)))
+ {
+ szBuffer[0] = L'\0';
+ cchBuffer = 0;
+ }
+
+ if (NULL == URL || VT_BSTR != URL->vt || NULL == URL->bstrVal || L'\0' == *URL->bstrVal ||
+ FAILED(UrlEscape(URL->bstrVal, szUrl, &cchUrl, URL_ESCAPE_SEGMENT_ONLY | URL_ESCAPE_PERCENT)))
+ {
+ szUrl[0] = L'\0';
+ }
+
+ if (0 != cchBuffer)
+ {
+ FormatErrorParam(szBuffer + cchBuffer, ARRAYSIZE(szBuffer) - cchBuffer, errorCode, szUrl);
+ }
+ else
+ {
+ if(FAILED(Browser_FormatDefaultErrorMessage(szBuffer, ARRAYSIZE(szBuffer), errorCode, szUrl, FALSE)))
+ return;
+ }
+
+ IWebBrowser2 *pWeb2 = NULL;
+ if (FAILED(GetIWebBrowser2(&pWeb2)))
+ return;
+
+ INT frameCount = 0;
+ if (FAILED(GetFramesCount(pWeb2, &frameCount)))
+ frameCount = 0;
+
+ BOOL invokeDlComplete = FALSE;
+
+ if (0 == frameCount)
+ {
+ pWeb2->Stop();
+ BSTR currentUrl;
+ if (FAILED(pWeb2->get_LocationURL(&currentUrl)))
+ currentUrl = NULL;
+
+ if (NULL != currentUrl &&
+ CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, currentUrl, -1, szBuffer, -1))
+ {
+ *Cancel = VARIANT_TRUE;
+ invokeDlComplete = TRUE;
+ }
+ else
+ {
+ if (FAILED(PostNavigateToName(szBuffer, navNoHistory)))
+ NavigateToName(szBuffer, navNoHistory);
+ }
+
+ if (NULL != currentUrl)
+ SysFreeString(currentUrl);
+ }
+ else
+ {
+ *Cancel = VARIANT_TRUE;
+ invokeDlComplete = TRUE;
+
+ IWebBrowser2* pWebActive;
+ if (NULL != pDispatch &&
+ SUCCEEDED(pDispatch->QueryInterface(IID_IWebBrowser2, (void**)&pWebActive)))
+ {
+ NavigateToNameEx(pWebActive, szBuffer, navNoHistory);
+ invokeDlComplete = FALSE;
+ pWebActive->Release();
+ }
+ }
+
+ if (FALSE != invokeDlComplete)
+ {
+ DISPPARAMS params;
+ ZeroMemory(&params, sizeof(DISPPARAMS));
+ Invoke(DISPID_DOWNLOADCOMPLETE, GUID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, NULL);
+ }
+
+ pWeb2->Release();
+}
+
+void Browser::OnNavigateCancelled(LPCWSTR pszUrl, VARIANT_BOOL *Cancel)
+{
+ HTMLContainer2::OnNavigateCancelled(pszUrl, Cancel);
+
+ WCHAR szBuffer[2048] = {0};
+ if (SUCCEEDED(GetErrorPageName(szBuffer, ARRAYSIZE(szBuffer), (*Cancel == ((VARIANT_BOOL)-2) ? -1 : 0), TRUE)))
+ {
+ INT cchLen = lstrlen(szBuffer);
+ FormatErrorParam(szBuffer + cchLen, ARRAYSIZE(szBuffer) - cchLen, 0, pszUrl);
+ }
+ else
+ {
+ if(FAILED(Browser_FormatDefaultErrorMessage(szBuffer, ARRAYSIZE(szBuffer), 0, pszUrl, TRUE)))
+ return;
+ }
+
+ *Cancel = VARIANT_TRUE;
+ NavigateToName(szBuffer, navNoHistory);
+}
+
+void Browser::OnDocumentReady(IDispatch *pDispatch, VARIANT *URL)
+{
+ HTMLContainer2::OnDocumentReady(pDispatch, URL);
+ if (NULL != EventDocumentReady)
+ EventDocumentReady(this, pDispatch, URL);
+}
+
+void Browser::OnCommandStateChange(LONG commandId, VARIANT_BOOL Enable)
+{
+ HTMLContainer2::OnCommandStateChange(commandId, Enable);
+
+ switch(commandId)
+ {
+ case CSC_NAVIGATEBACK:
+ if (VARIANT_TRUE == Enable)
+ navigationState |= navigationBackEnabled;
+ else
+ navigationState &= ~3;
+
+ if (NULL != EventCommandStateChange)
+ EventCommandStateChange(this, commandBack, 0 != (navigationBackEnabled & navigationState));
+ break;
+
+ case CSC_NAVIGATEFORWARD:
+ if (VARIANT_TRUE == Enable)
+ navigationState |= navigationForwardEnabled;
+ else
+ navigationState &= ~navigationForwardEnabled;
+
+ if (NULL != EventCommandStateChange)
+ EventCommandStateChange(this, commandForward, 0 != (navigationForwardEnabled & navigationState));
+ break;
+
+ case CSC_UPDATECOMMANDS:
+ if (NULL != EventCommandStateChange)
+ {
+ INT state = 0;
+
+ if (SUCCEEDED(QueryCommandState(commandStop, &state)) && 0 != (commandStateSupported & state))
+ EventCommandStateChange(this, commandStop, 0 != (commandStateEnabled & state));
+ if (SUCCEEDED(QueryCommandState(commandRefresh, &state)) && 0 != (commandStateSupported & state))
+ EventCommandStateChange(this, commandRefresh, 0 != (commandStateEnabled & state));
+ }
+ break;
+ }
+}
+
+void Browser::OnStatusTextChange(LPCWSTR pszText)
+{
+ HTMLContainer2::OnStatusTextChange(pszText);
+
+ if (NULL != EventStatusChange)
+ {
+ if (NULL != pszText &&
+ CSTR_EQUAL == CompareString(CSTR_INVARIANT, 0, szDone, -1, pszText, -1))
+ {
+ pszText = NULL;
+ }
+ EventStatusChange(this, pszText);
+ }
+}
+
+void Browser::OnSetSecureLockIcon(UINT secureLockIcon)
+{
+ HTMLContainer2::OnSetSecureLockIcon(secureLockIcon);
+
+ this->secureLockIcon = secureLockIcon;
+
+ if (NULL != EventSecureLockIconChange)
+ EventSecureLockIconChange(this);
+}
+
+void Browser::OnTitleChange(BSTR pszText)
+{
+ if (NULL != EventTitleChange)
+ EventTitleChange(this, pszText);
+}
+
+void Browser::OnNewWindow3(IDispatch **ppDisp, VARIANT_BOOL *Cancel, DWORD dwFlags, BSTR bstrUrlContext, BSTR bstrUrl)
+{
+#ifdef _DEBUG
+ char szBuffer[2048], szFlags[128] = {0};
+ LPSTR cursor = szFlags;
+ size_t remaining = ARRAYSIZE(szFlags);
+ if (0 != (NWMF_UNLOADING & dwFlags)) StringCchCopyExA(cursor, remaining, " unloading |", &cursor, &remaining, 0);
+ if (0 != (NWMF_USERINITED & dwFlags)) StringCchCopyExA(cursor, remaining, " userInited |", &cursor, &remaining, 0);
+ if (0 != (0x0004/*NWMF_FIRST_USERINITED*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " first |", &cursor, &remaining, 0);
+ if (0 != (NWMF_OVERRIDEKEY & dwFlags)) StringCchCopyExA(cursor, remaining, " overrideKey |", &cursor, &remaining, 0);
+ if (0 != (NWMF_SHOWHELP & dwFlags)) StringCchCopyExA(cursor, remaining, " showHelp |", &cursor, &remaining, 0);
+ if (0 != (NWMF_HTMLDIALOG & dwFlags)) StringCchCopyExA(cursor, remaining, " htmlDialog |", &cursor, &remaining, 0);
+ if (0 != (0x80/*NWMF_USERREQUESTED*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " userRequested |", &cursor, &remaining, 0);
+ if (0 != (0x100/*NWMF_USERALLOWED*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " userAllowed |", &cursor, &remaining, 0);
+ if (0 != (0x10000/*NWMF_FORCEWINDOW*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " forceWindow |", &cursor, &remaining, 0);
+ if (0 != (0x20000/*NWMF_FORCETAB*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " forceTab |", &cursor, &remaining, 0);
+ if (0 != (0x40000/*NWMF_SUGGESTWINDOW*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " suggestWindow |", &cursor, &remaining, 0);
+ if (0 != (0x80000/*NWMF_SUGGESTTAB*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " suggestTab |", &cursor, &remaining, 0);
+ if (0 != (0x100000/*NWMF_INACTIVETAB*/ & dwFlags)) StringCchCopyExA(cursor, remaining, " inactiveTab |", &cursor, &remaining, 0);
+
+ if (cursor != szFlags)
+ {
+ cursor -= 2;
+ *cursor = '\0';
+ }
+ else
+ {
+ StringCchCopyExA(cursor, remaining, " <none>", &cursor, &remaining, 0);
+ }
+
+ StringCchPrintfA(szBuffer, ARRAYSIZE(szBuffer), "NewWindow3:\r\n\turlContext: %S,\r\n\turl: %S,\r\n\tflags:%s\r\n",
+ ((NULL == bstrUrlContext || L'\0' == *bstrUrlContext) ? L"<empty>" : bstrUrlContext),
+ ((NULL == bstrUrl || L'\0' == *bstrUrl) ? L"<empty>" : bstrUrl), szFlags);
+
+ OutputDebugStringA(szBuffer);
+#endif // _DEBUG
+}
+
+void Browser::OnNewWindow2(IDispatch **ppDisp, VARIANT_BOOL *Cancel)
+{
+ if (NULL != EventCreatePopup)
+ {
+ EventCreatePopup(this, ppDisp, Cancel);
+ }
+ else if (NULL != Cancel)
+ {
+ *Cancel = VARIANT_TRUE;
+ }
+}
+
+void Browser::OnVisibleChange(VARIANT_BOOL Visible)
+{
+ if (NULL != EventVisible)
+ {
+ EventVisible(this, Visible);
+ }
+}
+
+void Browser::OnWindowClosing(VARIANT_BOOL IsChildWindow, VARIANT_BOOL *Cancel)
+{
+ if (NULL != EventWindowClosing)
+ {
+ EventWindowClosing(this, IsChildWindow, Cancel);
+ }
+}
+
+void Browser::OnShowUiElement(UINT elementId, VARIANT_BOOL fShow)
+{
+ HTMLContainer2::OnShowUiElement(elementId, fShow);
+ if (NULL != EventShowUiElement)
+ {
+ EventShowUiElement(this, elementId, fShow);
+ }
+}
+
+void Browser::OnWindowSetResizable(VARIANT_BOOL Enable)
+{
+ if (NULL != EventSetResizable)
+ {
+ EventSetResizable(this, Enable);
+ }
+}
+
+void Browser::OnEnableFullscreen(VARIANT_BOOL Enable)
+{
+ if (NULL != EventSetFullscreen)
+ {
+ EventSetFullscreen(this, Enable);
+ }
+}
+
+void Browser::OnClientToHostWindow(LONG *CX, LONG *CY)
+{
+ if (NULL != EventClientToHost)
+ {
+ EventClientToHost(this, CX, CY);
+ }
+}
+
+void Browser::OnSetWindowPos(UINT Flags, LONG X, LONG Y, LONG CX, LONG CY)
+{
+ if (NULL != EventSetWindowPos)
+ {
+ EventSetWindowPos(this, Flags, X, Y, CX, CY);
+ }
+}
+
+HANDLE Browser::InitializePopupHook(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hHook = NULL;
+ BSTR version = NULL;
+ if (SUCCEEDED(GetAppVersion(&version)) && NULL != version)
+ {
+ // if (NULL == StrStrIW(version, L"Trident/4.0") /*IE8*/ &&
+ // NULL == StrStrIW(version, L"Trident/5.0") /*IE9*/)
+ {
+ hHook = Menu_InitializeHook(hwnd, NULL);
+ }
+
+ SysFreeString(version);
+ }
+ return hHook;
+}
+
+void Browser::DeletePopupHook(HANDLE hHook)
+{
+ Menu_RemoveHook(hHook);
+}
+
+void Browser::InitializeMenuPopup(HWND hwnd, HMENU hMenu, INT iPos, BOOL fWindowMenu)
+{
+ UINT szItems[] = { 2263 /*Save Background As...*/,
+ 2264 /*Set as Background*/,
+ 2265 /*Copy Background*/,
+ 2266 /*Create Shortcut*/,
+ 2261 /*Add to Favorite*/,
+ 2268 /*Save Target As...*/,
+ 2269 /*Show Picture*/,
+ 2270 /*Save Picture As...*/,
+ 2288 /*Email Picture*/,
+ 2289 /*Print Picture*/,
+ 2287 /*Goto My Picures*/,
+ 2278 /*Set as Desktop Item...*/,
+ 2435 /*Open in New Tab*/,
+ };
+
+ if (NULL == hMenu)
+ return;
+
+ ifc_omdebugconfig *debugConfig = NULL;
+ if (SUCCEEDED(GetDebugConfig(&debugConfig)) && debugConfig != NULL)
+ {
+ HRESULT hr = debugConfig->GetMenuFilterEnabled();
+ debugConfig->Release();
+ if (S_FALSE == hr) return;
+ }
+
+ // remove known items
+ INT i;
+ for (i = 0; i < ARRAYSIZE(szItems); i++)
+ {
+ DeleteMenu(hMenu, szItems[i], MF_BYCOMMAND);
+ }
+
+ // fix separators and remove extensions
+ i = GetMenuItemCount(hMenu);
+
+ MENUITEMINFOW mi = {0};
+ mi.cbSize = sizeof(MENUITEMINFO);
+ mi.fMask = MIIM_ID | MIIM_FTYPE | MIIM_SUBMENU;
+
+ INT separatorIndex = i;
+ while(i--)
+ {
+ if (GetMenuItemInfoW(hMenu, i, TRUE, &mi))
+ {
+ if (0 != (MFT_SEPARATOR & mi.fType))
+ {
+ if ((i + 1) == separatorIndex)
+ {
+ DeleteMenu(hMenu, i, MF_BYPOSITION);
+ }
+ separatorIndex = i;
+ }
+ else if (mi.wID >= 3700 && NULL == mi.hSubMenu)
+ {
+ DeleteMenu(hMenu, i, MF_BYPOSITION);
+ if (separatorIndex > i)
+ separatorIndex--;
+ }
+ }
+ }
+}
+
+void Browser::SetUiFlags(UINT flags, UINT mask)
+{
+ uiFlags = (uiFlags & ~mask) | (flags & mask);
+}
+
+UINT Browser::GetUiFlags(UINT mask)
+{
+ return (mask & uiFlags);
+}
+
+HRESULT Browser::ToggleFullscreen()
+{
+ IWebBrowser2 *pWeb2 = NULL;
+ HRESULT hr = GetIWebBrowser2(&pWeb2);
+ if (FAILED(hr)) return hr;
+
+ VARIANT_BOOL fullscreenMode;
+
+ hr = pWeb2->get_FullScreen(&fullscreenMode);
+ if (SUCCEEDED(hr))
+ {
+ if (VARIANT_FALSE == fullscreenMode) fullscreenMode = VARIANT_TRUE;
+ else if (VARIANT_TRUE == fullscreenMode) fullscreenMode = VARIANT_FALSE;
+ else hr = E_UNEXPECTED;
+
+ if (SUCCEEDED(hr))
+ {
+ hr = pWeb2->put_FullScreen(fullscreenMode);
+ if (SUCCEEDED(hr))
+ {
+ }
+ }
+ }
+
+ pWeb2->Release();
+ return hr;
+}
+
+HRESULT Browser::GetDebugConfig(ifc_omdebugconfig **debugConfig)
+{
+ if (NULL == debugConfig) return E_POINTER;
+ if (NULL == browserManager || FAILED(browserManager->GetConfig(&IFC_OmDebugConfig, (void**)debugConfig)))
+ {
+ *debugConfig = NULL;
+ return E_NOINTERFACE;
+ }
+ return S_OK;
+}
+
+HRESULT Browser::GetTravelLog(ifc_travelloghelper **travelLog)
+{
+ if (NULL == travelLog) return E_POINTER;
+
+ IWebBrowser2 *pWeb2 = NULL;
+ HRESULT hr = GetIWebBrowser2(&pWeb2);
+ if (FAILED(hr))
+ {
+ *travelLog = NULL;
+ return hr;
+ }
+
+ hr = TravelLogHelper::CreateInstance(pWeb2, (TravelLogHelper**)travelLog);
+ pWeb2->Release();
+
+ return hr;
+}
+
+BOOL Browser::InputLangChangeRequest(HWND hwnd, UINT flags, HKL hkl)
+{
+ HWND hTarget = GetParent(hwnd);
+ if (NULL != hTarget)
+ {
+ SendMessage(hTarget, WM_INPUTLANGCHANGEREQUEST, (WPARAM)flags, (LPARAM)hkl);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void Browser::InputLangChange(UINT charset, HKL hkl)
+{
+ ActivateKeyboardLayout(hkl, KLF_SETFORPROCESS);
+}
+
+void Browser::OnClosePopupInternal()
+{
+ if(NULL != EventClosePopup)
+ EventClosePopup(this);
+}
+
+#ifdef _DEBUG
+void BrowserDebug_PrintRefs(Browser *browser)
+{
+ if (NULL == browser)
+ {
+ aTRACE_LINE("browser object is NULL");
+ return;
+ }
+
+ browser->AddRef();
+ ULONG refBrowser, refUnknown, refWeb;
+
+ IUnknown *pUnk = NULL;
+ if (SUCCEEDED(browser->GetIUnknown(&pUnk)) && pUnk != NULL)
+ {
+ refUnknown = pUnk->Release();
+ }
+ else
+ {
+ refUnknown = ((ULONG)(0 - 2));
+ }
+
+ IWebBrowser2 *pWeb2 = NULL;
+ if (SUCCEEDED(browser->GetIWebBrowser2(&pWeb2)) && pWeb2 != NULL)
+ {
+ refWeb = pWeb2->Release();
+ }
+ else
+ {
+ refWeb = ((ULONG)(0 - 2));
+ }
+ refBrowser = browser->Release();
+
+ aTRACE_FMT("Browser Stats: Instance=%d, IUnknown=%d, IWebBrowser2=%d\r\n", refBrowser, refUnknown, refWeb);
+}
+#endif // _DEBUG \ No newline at end of file