diff options
Diffstat (limited to 'Src/omBrowser/browser.cpp')
-rw-r--r-- | Src/omBrowser/browser.cpp | 1579 |
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(¶m); + V_VT(¶m) = VT_I4; + V_I4(¶m) = REFRESH_COMPLETELY; + hr = pWeb2->Refresh2(¶m); + } + 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(¤tUrl))) + 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(¶ms, sizeof(DISPPARAMS)); + Invoke(DISPID_DOWNLOADCOMPLETE, GUID_NULL, 0, DISPATCH_METHOD, ¶ms, 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 |