mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-12-01 00:07:16 +01:00
2108 lines
52 KiB
C++
2108 lines
52 KiB
C++
#include "./HTMLContainer2.h"
|
|
#include "../winamp/wa_ipc.h"
|
|
#include "CGlobalAtom.h"
|
|
|
|
#include <exdisp.h>
|
|
#include <mshtmdid.h>
|
|
#include <mshtml.h>
|
|
#include <exdispid.h>
|
|
#include <urlmon.h>
|
|
#include <Wininet.h>
|
|
#include <shlwapi.h>
|
|
#include <strsafe.h>
|
|
|
|
#ifndef GetWindowStyle
|
|
#define GetWindowStyle(__hwnd) ((UINT)GetWindowLongPtrW((__hwnd), GWL_STYLE))
|
|
#endif //GetWindowStyle
|
|
|
|
#ifndef GetWindowStyleEx
|
|
#define GetWindowStyleEx(__hwnd) ((UINT)GetWindowLongPtrW((__hwnd), GWL_EXSTYLE))
|
|
#endif // GetWindowStyleEx
|
|
|
|
static UINT WM_REDIRECTNAVIGATE = 0;
|
|
|
|
#ifndef DISPID_NEWWINDOW3
|
|
#define DISPID_NEWWINDOW3 273
|
|
#endif
|
|
|
|
static CGlobalAtom WNDPROP_SCCTRLW(L"SCCTRL");
|
|
|
|
static UINT WINAMP_WM_DIRECT_MOUSE_WHEEL = WM_NULL;
|
|
|
|
#define REGISTRY_FEATURE_CONTROL L"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl"
|
|
#define REGISTRY_FEATURE_USE_LEGACY_JSCRIPT (REGISTRY_FEATURE_CONTROL L"\\FEATURE_USE_LEGACY_JSCRIPT")
|
|
|
|
#ifndef LONGX86
|
|
#ifdef _WIN64
|
|
#define LONGX86 LONG_PTR
|
|
#else /*_WIN64*/
|
|
#define LONGX86 LONG
|
|
#endif /*_WIN64*/
|
|
#endif // LONGX86
|
|
|
|
#ifndef CSTR_INVARIANT
|
|
#define CSTR_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
|
|
#endif //CSTR_INVARIANT
|
|
|
|
#define IS_EQUALCLASS(__class1, __class2)\
|
|
(CSTR_EQUAL == CompareStringW(CSTR_INVARIANT, NORM_IGNORECASE, __class1, -1, __class2, -1))
|
|
|
|
#define DEFAULT_HOSTBKCOLOR 0x00FFFFFF
|
|
#define DEFAULT_DOCHOSTUIFLAGS (DOCHOSTUIFLAG_NO3DOUTERBORDER | \
|
|
DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION | \
|
|
DOCHOSTUIFLAG_NO3DBORDER | \
|
|
DOCHOSTUIDBLCLK_DEFAULT | \
|
|
0)
|
|
|
|
#define DEFAULT_DOWNLOADFLAGS (DLCTL_DLIMAGES | \
|
|
DLCTL_VIDEOS | \
|
|
DLCTL_PRAGMA_NO_CACHE | \
|
|
0)
|
|
|
|
#define CF_DISABLEBEFORENAVFILTER 0x00000002
|
|
|
|
typedef struct __RMNAVIGATE2
|
|
{
|
|
VARIANT URL;
|
|
VARIANT Flags;
|
|
VARIANT TargetFrameName;
|
|
VARIANT PostData;
|
|
VARIANT Headers;
|
|
}RMNAVIGATE2;
|
|
|
|
typedef struct __RMNAVIGATETONAME
|
|
{
|
|
BSTR url;
|
|
UINT flags;
|
|
} RMNAVIGATETONAME;
|
|
|
|
typedef struct _IECURSOR
|
|
{
|
|
INT nSysId;
|
|
HCURSOR hSys;
|
|
HCURSOR hUser;
|
|
} IECURSOR;
|
|
|
|
static INT bIsVistaOrHigher = -1;
|
|
|
|
typedef struct __LIBHDR LIBHDR;
|
|
|
|
typedef BOOL (WINAPI *LIBRARYLOADER)(LIBHDR* /*header*/);
|
|
|
|
typedef struct __LIBHDR
|
|
{
|
|
HMODULE hMod;
|
|
LPCWSTR name;
|
|
LIBRARYLOADER loader;
|
|
size_t size;
|
|
} LIBHDR;
|
|
|
|
typedef struct __LIBWININET
|
|
{
|
|
LIBHDR hdr;
|
|
|
|
typedef BOOL (WINAPI *INTERNETCRACKURL)(LPCWSTR /*lpszUrl*/, DWORD /*dwUrlLength*/, DWORD /*dwFlags*/, URL_COMPONENTSW* /*lpUrlComponents*/);
|
|
|
|
INTERNETCRACKURL InternetCrackUrl;
|
|
|
|
static BOOL CALLBACK Loader(LIBHDR *pHdr)
|
|
{
|
|
LIBWININET *lib = (LIBWININET*)pHdr;
|
|
lib->InternetCrackUrl = (LIBWININET::INTERNETCRACKURL)GetProcAddress(pHdr->hMod, "InternetCrackUrlW");
|
|
return TRUE;
|
|
}
|
|
} LIBWININET;
|
|
|
|
typedef struct __LIBURLMON
|
|
{
|
|
LIBHDR hdr;
|
|
|
|
typedef HRESULT (WINAPI *COINTERNETSETFEATUREENABLED)(INTERNETFEATURELIST /*FeatureEntry*/, DWORD /*dwFlags*/, BOOL /*fEnable*/);
|
|
typedef HRESULT (WINAPI *COINTERNETISFEATUREENABLED)(INTERNETFEATURELIST /*FeatureEntry*/, DWORD /*dwFlags*/);
|
|
|
|
COINTERNETSETFEATUREENABLED CoInternetSetFeatureEnabled;
|
|
COINTERNETISFEATUREENABLED CoInternetIsFeatureEnabled;
|
|
|
|
static BOOL CALLBACK Loader(LIBHDR *pHdr)
|
|
{
|
|
LIBURLMON *lib = (LIBURLMON*)pHdr;
|
|
lib->CoInternetSetFeatureEnabled = (LIBURLMON::COINTERNETSETFEATUREENABLED)GetProcAddress(pHdr->hMod, "CoInternetSetFeatureEnabled");
|
|
lib->CoInternetIsFeatureEnabled = (LIBURLMON::COINTERNETISFEATUREENABLED)GetProcAddress(pHdr->hMod, "CoInternetIsFeatureEnabled");
|
|
return TRUE;
|
|
}
|
|
} LIBURLMON;
|
|
|
|
static LIBWININET libWininet = { { NULL, L"WinInet.dll", LIBWININET::Loader, sizeof(LIBWININET)}, NULL, };
|
|
static LIBURLMON libUrlmon = { { NULL, L"UrlMon.dll", LIBURLMON::Loader, sizeof(LIBURLMON)}, NULL, };
|
|
static LIBHDR* szLibrary[] = { (LIBHDR*)&libWininet, (LIBHDR*)&libUrlmon };
|
|
|
|
BOOL HTMLContainer2_Initialize()
|
|
{
|
|
for(size_t i = 0; i < ARRAYSIZE(szLibrary); i++)
|
|
{
|
|
if (NULL == szLibrary[i]->hMod)
|
|
{
|
|
size_t size = szLibrary[i]->size - sizeof(LIBHDR);
|
|
ZeroMemory((BYTE*)szLibrary[i] + sizeof(LIBHDR), size);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL HTMLContainer2_Uninitialize()
|
|
{
|
|
for(size_t i = 0; i < ARRAYSIZE(szLibrary); i++)
|
|
{
|
|
if (NULL != szLibrary[i]->hMod)
|
|
{
|
|
FreeLibrary(szLibrary[i]->hMod);
|
|
szLibrary[i]->hMod = NULL;
|
|
}
|
|
size_t size = szLibrary[i]->size - sizeof(LIBHDR);
|
|
ZeroMemory((BYTE*)szLibrary[i] + sizeof(LIBHDR), size);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL HTMLContainer2_LoadLibray(LIBHDR *libraryHeader)
|
|
{
|
|
if (NULL == libraryHeader)
|
|
return FALSE;
|
|
|
|
if (NULL != libraryHeader->hMod)
|
|
return TRUE;
|
|
|
|
libraryHeader->hMod = LoadLibraryW(libraryHeader->name);
|
|
if (NULL == libraryHeader->hMod)
|
|
return FALSE;
|
|
|
|
return (NULL != libraryHeader->loader) ?
|
|
libraryHeader->loader(libraryHeader) :
|
|
TRUE;
|
|
}
|
|
|
|
static BOOL SublassControl_IsAttached(HWND hwnd);
|
|
static BOOL SubclassControl_Attach(HWND hControl, HTMLContainer2 *pContainer);
|
|
|
|
// uncomment if you ever want to use mozilla instead of IE
|
|
// change the CLSID_WebBrowser in the constructor below to CLSID_MozillaBrowser
|
|
// but window.external from javascript doesn't work :(
|
|
|
|
static const CLSID CLSID_MozillaBrowser=
|
|
{ 0x1339B54C, 0x3453, 0x11D2, { 0x93, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
|
|
|
|
HTMLContainer2::HTMLContainer2(HWND waWindow, HWND hwndParent) :
|
|
ref(1), pUnk(NULL), hParent(hwndParent), dwCookie(0),
|
|
dwFlags(0), fnBrwoserCB(NULL) ,userData(NULL),
|
|
bNavigating(FALSE), hCursors(NULL), nCursors(0),
|
|
ensureChakraLoaded(TRUE), winampWindow(waWindow)
|
|
{
|
|
if (NULL == hParent || FALSE == GetClientRect(hParent, &rect))
|
|
SetRectEmpty(&rect);
|
|
|
|
if (-1 == bIsVistaOrHigher)
|
|
{
|
|
OSVERSIONINFO os;
|
|
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
bIsVistaOrHigher = (GetVersionEx(&os) && os.dwMajorVersion >= 6);
|
|
}
|
|
}
|
|
|
|
HTMLContainer2::~HTMLContainer2(void)
|
|
{
|
|
if (NULL != fnBrwoserCB)
|
|
fnBrwoserCB(this, DISPID_DESTRUCTOR, NULL, userData);
|
|
|
|
if (hCursors)
|
|
{
|
|
HCURSOR hc;
|
|
for(int i = 0; i < nCursors; i++)
|
|
{
|
|
hc = ((IECURSOR*)hCursors)[i].hUser;
|
|
if (hc) DestroyCursor(hc);
|
|
}
|
|
free(hCursors);
|
|
}
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::Initialize(void)
|
|
{
|
|
IOleObject *pioo = NULL;
|
|
IConnectionPoint *pcp = NULL;
|
|
IConnectionPointContainer *pcpc = NULL;
|
|
|
|
HRESULT hr = CoCreateInstance(CLSID_WebBrowser, NULL, CLSCTX_INPROC, IID_IUnknown, (PVOID*)&pUnk);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
hr = pUnk->QueryInterface(IID_IOleObject, (PVOID*)&pioo);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DWORD dwFlags = 0;
|
|
if (FAILED(pioo->GetMiscStatus(DVASPECT_CONTENT, &dwFlags)))
|
|
dwFlags = 0;
|
|
|
|
if (0 != (OLEMISC_SETCLIENTSITEFIRST & dwFlags))
|
|
{
|
|
IOleClientSite *pClientSite = NULL;
|
|
hr = QueryInterface(IID_IOleClientSite, (void**)&pClientSite);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pioo->SetClientSite(pClientSite);
|
|
pioo->SetHostNames(L"NullsoftHtmlContainer2", NULL);
|
|
|
|
if(NULL == hParent || FALSE == GetClientRect(hParent, &rect))
|
|
SetRectEmpty(&rect);
|
|
|
|
pioo->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, pClientSite, 0, hParent, &rect);
|
|
|
|
pClientSite->Release();
|
|
}
|
|
}
|
|
pioo->Release();
|
|
|
|
HWND hHost = GetHostHWND();
|
|
if (IsWindow(hHost))
|
|
{
|
|
SubclassControl_Attach(hHost, this);
|
|
}
|
|
}
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
hr = pUnk->QueryInterface(IID_IConnectionPointContainer, (PVOID*)&pcpc);
|
|
if (SUCCEEDED (hr))
|
|
{
|
|
hr = pcpc->FindConnectionPoint(DIID_DWebBrowserEvents2, &pcp);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pcp->Advise(static_cast<IDispatch*>(this), &dwCookie);
|
|
if (FAILED(hr)) dwCookie = 0;
|
|
pcp->Release();
|
|
}
|
|
pcpc->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::Finish(void)
|
|
{
|
|
if (!pUnk) return S_OK;
|
|
|
|
AddRef();
|
|
|
|
UnadviseBrowserEvents();
|
|
|
|
IOleObject *pioo = NULL;
|
|
IOleInPlaceObject *pipo = NULL;
|
|
HRESULT hr = pUnk->QueryInterface(IID_IOleInPlaceObject, (PVOID*)&pipo);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pipo->InPlaceDeactivate();
|
|
pipo->UIDeactivate();
|
|
pipo->Release();
|
|
}
|
|
|
|
hr = pUnk->QueryInterface(IID_IOleObject, (PVOID*)&pioo);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pioo->Close(OLECLOSE_NOSAVE);
|
|
pioo->SetClientSite(NULL);
|
|
pioo->Release();
|
|
}
|
|
|
|
ULONG r = pUnk->Release();
|
|
pUnk = NULL;
|
|
|
|
Release();
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::QueryInterface(REFIID riid, PVOID *ppvObject)
|
|
{
|
|
if (!ppvObject)
|
|
return E_POINTER;
|
|
|
|
if (IsEqualIID(riid, IID_IOleClientSite))
|
|
*ppvObject = (IOleClientSite*)this;
|
|
else if (IsEqualIID(riid, IID_IOleInPlaceSite))
|
|
*ppvObject = (IOleInPlaceSite*)this;
|
|
else if (IsEqualIID(riid, IID_IOleInPlaceFrame))
|
|
*ppvObject = (IOleInPlaceFrame*)this;
|
|
else if (IsEqualIID(riid, IID_IOleInPlaceUIWindow))
|
|
*ppvObject = (IOleInPlaceUIWindow*)this;
|
|
else if (IsEqualIID(riid, IID_IOleControlSite))
|
|
*ppvObject = (IOleControlSite*)this;
|
|
else if (IsEqualIID(riid, IID_IOleWindow))
|
|
*ppvObject = reinterpret_cast<IOleWindow*>(this);
|
|
else if (IsEqualIID(riid, IID_IDispatch))
|
|
*ppvObject = (IDispatch*)this;
|
|
else if (IsEqualIID(riid, IID_IUnknown))
|
|
*ppvObject = reinterpret_cast<IUnknown*>(this);
|
|
else if (IsEqualIID(riid, IID_IDocHostUIHandler))
|
|
*ppvObject = (IDocHostUIHandler*)this;
|
|
else if (IsEqualIID(riid, IID_IDocHostUIHandler2))
|
|
*ppvObject = (IDocHostUIHandler2*)this;
|
|
else if (IsEqualIID(riid, IID_IDocHostShowUI))
|
|
*ppvObject = (IDocHostShowUI*)this;
|
|
else if (IsEqualIID(riid, IID_IOleCommandTarget))
|
|
*ppvObject = (IOleCommandTarget*)this;
|
|
else if (IsEqualIID(riid, IID_IServiceProvider))
|
|
*ppvObject = (IServiceProvider*)this;
|
|
else
|
|
{
|
|
*ppvObject = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
ULONG HTMLContainer2::AddRef(void)
|
|
{
|
|
return InterlockedIncrement(&ref);
|
|
}
|
|
|
|
ULONG HTMLContainer2::Release(void)
|
|
{
|
|
if (0 == ref)
|
|
return ref;
|
|
|
|
LONG r = InterlockedDecrement(&ref);
|
|
if (0 == r)
|
|
delete(this);
|
|
|
|
return r;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::SaveObject()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER * ppMk)
|
|
{
|
|
*ppMk = NULL;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetContainer(LPOLECONTAINER * ppContainer)
|
|
{
|
|
*ppContainer = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::ShowObject()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::OnShowWindow(BOOL fShow)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::RequestNewObjectLayout()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetWindow(HWND * lphwnd)
|
|
{
|
|
if (NULL != hParent && IsWindow(hParent))
|
|
{
|
|
*lphwnd = hParent;
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
*lphwnd = NULL;
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::ContextSensitiveHelp(BOOL fEnterMode)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::CanInPlaceActivate(void)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::OnInPlaceActivate(void)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::OnUIActivate(void)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetWindowContext(IOleInPlaceFrame ** ppFrame, IOleInPlaceUIWindow ** ppIIPUIWin,
|
|
LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
|
|
{
|
|
if (FAILED(QueryInterface(IID_IOleInPlaceFrame, (void**)ppFrame)))
|
|
*ppFrame = NULL;
|
|
|
|
*ppIIPUIWin = NULL;
|
|
|
|
CopyRect(lprcPosRect, &rect);
|
|
CopyRect(lprcClipRect, &rect);
|
|
|
|
lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
|
|
lpFrameInfo->fMDIApp = FALSE;
|
|
lpFrameInfo->hwndFrame = hParent;
|
|
lpFrameInfo->haccel = NULL;
|
|
lpFrameInfo->cAccelEntries = 0;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::Scroll(SIZE scrollExtent)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::OnUIDeactivate(BOOL fUndoable)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::OnInPlaceDeactivate(void)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::DiscardUndoState(void)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::DeactivateAndUndo(void)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::OnPosRectChange(LPCRECT lprcPosRect)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::RemoveMenus(HMENU hmenuShared)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::SetStatusText(LPCOLESTR pszStatusText)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::TranslateAccelerator(LPMSG lpmsg, WORD wID)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::EnableModeless(BOOL fEnable)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::OnControlInfoChanged()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::LockInPlaceActive(BOOL fLock)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetExtendedControl(IDispatch **ppDisp)
|
|
{
|
|
if (ppDisp == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
*ppDisp = (IDispatch *)this;
|
|
(*ppDisp)->AddRef();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::TransformCoords(POINTL *pptlHimetric, POINTF *pptfContainer, DWORD dwFlags)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::TranslateAccelerator(LPMSG pMsg, DWORD grfModifiers)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::OnFocus(BOOL fGotFocus)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::ShowPropertyFrame(void)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
|
|
{
|
|
*rgdispid = DISPID_UNKNOWN;
|
|
return DISP_E_UNKNOWNNAME;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetTypeInfoCount(unsigned int FAR * pctinfo)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT HTMLContainer2_OnShowUiElementHelper(HTMLContainer2 *instance, UINT elementId, DISPPARAMS *pDispParams)
|
|
{
|
|
if (NULL == pDispParams) return E_UNEXPECTED;
|
|
if (1 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_BOOL != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
|
|
instance->OnShowUiElement(elementId, pDispParams->rgvarg[0].boolVal);
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::Invoke(DISPID dispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pDispParams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
|
|
{
|
|
if (fnBrwoserCB && fnBrwoserCB(this, dispId, pDispParams, userData))
|
|
{
|
|
return DISP_E_MEMBERNOTFOUND;
|
|
}
|
|
|
|
switch (dispId)
|
|
{
|
|
case DISPID_BEFORENAVIGATE2:
|
|
if(7 == pDispParams->cArgs)
|
|
{
|
|
OnBeforeNavigate(pDispParams->rgvarg[6].pdispVal, pDispParams->rgvarg[5].pvarVal,
|
|
pDispParams->rgvarg[4].pvarVal, pDispParams->rgvarg[3].pvarVal,
|
|
pDispParams->rgvarg[2].pvarVal, pDispParams->rgvarg[1].pvarVal,
|
|
pDispParams->rgvarg[0].pboolVal);
|
|
return S_OK;
|
|
}
|
|
break;
|
|
|
|
case DISPID_NAVIGATEERROR:
|
|
if (200 == pDispParams->rgvarg[1].pvarVal->lVal)
|
|
{
|
|
*pDispParams->rgvarg[0].pboolVal = VARIANT_TRUE;
|
|
}
|
|
if (5 == pDispParams->cArgs)
|
|
{
|
|
OnNavigateError(pDispParams->rgvarg[4].pdispVal, pDispParams->rgvarg[3].pvarVal,
|
|
pDispParams->rgvarg[2].pvarVal, pDispParams->rgvarg[1].pvarVal,
|
|
pDispParams->rgvarg[0].pboolVal);
|
|
return S_OK;
|
|
}
|
|
break;
|
|
|
|
case DISPID_NAVIGATECOMPLETE2:
|
|
if (2 == pDispParams->cArgs)
|
|
{
|
|
OnNavigateComplete(pDispParams->rgvarg[1].pdispVal, pDispParams->rgvarg[0].pvarVal);
|
|
return S_OK;
|
|
}
|
|
break;
|
|
|
|
case DISPID_DOCUMENTCOMPLETE:
|
|
if (2 == pDispParams->cArgs)
|
|
{
|
|
OnDocumentComplete(pDispParams->rgvarg[1].pdispVal, pDispParams->rgvarg[0].pvarVal);
|
|
}
|
|
|
|
if (NULL != pUnk)
|
|
{
|
|
IWebBrowser2 *pWeb1 = NULL, *pWeb2 = NULL;
|
|
|
|
if (FAILED(GetIWebBrowser2(&pWeb1)))
|
|
pWeb1 = NULL;
|
|
|
|
if (pDispParams->cArgs < 2 ||
|
|
NULL == pDispParams->rgvarg[1].pdispVal ||
|
|
FAILED(pDispParams->rgvarg[1].pdispVal->QueryInterface(IID_IWebBrowser2, (void**)&pWeb2)))
|
|
{
|
|
pWeb2 = NULL;
|
|
}
|
|
|
|
if (NULL != pWeb1) pWeb1->Release();
|
|
if (NULL != pWeb2) pWeb2->Release();
|
|
|
|
if (NULL != pWeb1 && pWeb1 == pWeb2)
|
|
OnDocumentReady(pDispParams->rgvarg[1].pdispVal, pDispParams->rgvarg[0].pvarVal);
|
|
}
|
|
return S_OK;
|
|
|
|
case DISPID_DOWNLOADBEGIN:
|
|
OnDownloadBegin();
|
|
return S_OK;
|
|
|
|
case DISPID_DOWNLOADCOMPLETE:
|
|
OnDownloadComplete();
|
|
return S_OK;
|
|
|
|
case DISPID_FILEDOWNLOAD:
|
|
if (2 == pDispParams->cArgs)
|
|
{
|
|
OnFileDownload(pDispParams->rgvarg[1].pboolVal, pDispParams->rgvarg[0].pboolVal);
|
|
return S_OK;
|
|
}
|
|
break;
|
|
|
|
case DISPID_NEWWINDOW2:
|
|
if (2 == pDispParams->cArgs)
|
|
{
|
|
OnNewWindow2(pDispParams->rgvarg[1].ppdispVal, pDispParams->rgvarg[0].pboolVal);
|
|
return S_OK;
|
|
}
|
|
break;
|
|
|
|
case DISPID_NEWWINDOW3:
|
|
if (5 != pDispParams->cArgs)
|
|
return DISP_E_BADPARAMCOUNT;
|
|
|
|
if ((VT_DISPATCH | VT_BYREF) != pDispParams->rgvarg[4].vt ||
|
|
(VT_BOOL | VT_BYREF) != pDispParams->rgvarg[3].vt ||
|
|
VT_I4 != pDispParams->rgvarg[2].vt ||
|
|
VT_BSTR != pDispParams->rgvarg[1].vt ||
|
|
VT_BSTR != pDispParams->rgvarg[0].vt)
|
|
{
|
|
return DISP_E_BADVARTYPE;
|
|
}
|
|
|
|
OnNewWindow3(pDispParams->rgvarg[4].ppdispVal, pDispParams->rgvarg[3].pboolVal,
|
|
pDispParams->rgvarg[2].intVal, pDispParams->rgvarg[1].bstrVal, pDispParams->rgvarg[0].bstrVal);
|
|
return S_OK;
|
|
|
|
case DISPID_PROGRESSCHANGE:
|
|
if (2 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_I4 != pDispParams->rgvarg[1].vt ||
|
|
VT_I4 != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
OnProgressChange(pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0].lVal);
|
|
return S_OK;
|
|
|
|
case DISPID_STATUSTEXTCHANGE:
|
|
if (1 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_BSTR != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
OnStatusTextChange(pDispParams->rgvarg[0].bstrVal);
|
|
return S_OK;
|
|
|
|
case DISPID_AMBIENT_USERAGENT:
|
|
pvarResult->vt = VT_BSTR;
|
|
pvarResult->bstrVal = SysAllocString(OnGetUserAgent());
|
|
if (NULL != pvarResult->bstrVal)
|
|
return S_OK;
|
|
break;
|
|
|
|
case DISPID_AMBIENT_DLCONTROL:
|
|
pvarResult->vt = VT_I4;
|
|
pvarResult->lVal = OnGetDownlodFlags();
|
|
return S_OK;
|
|
|
|
case DISPID_COMMANDSTATECHANGE:
|
|
if (2 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_I4 != pDispParams->rgvarg[1].vt ||
|
|
VT_BOOL != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
OnCommandStateChange(pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0].boolVal);
|
|
return S_OK;
|
|
|
|
case DISPID_SETSECURELOCKICON:
|
|
if (1 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_I4 != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
OnSetSecureLockIcon(pDispParams->rgvarg[0].lVal);
|
|
return S_OK;
|
|
|
|
case DISPID_TITLECHANGE:
|
|
if (1 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_BSTR != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
OnTitleChange(pDispParams->rgvarg[0].bstrVal);
|
|
return S_OK;
|
|
|
|
case DISPID_ONVISIBLE:
|
|
if(1 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_BOOL != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
OnVisibleChange(pDispParams->rgvarg[0].boolVal);
|
|
return S_OK;
|
|
|
|
case DISPID_WINDOWCLOSING:
|
|
if (2 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_BOOL != pDispParams->rgvarg[1].vt ||
|
|
(VT_BOOL|VT_BYREF) != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
OnWindowClosing(pDispParams->rgvarg[1].boolVal, pDispParams->rgvarg[0].pboolVal);
|
|
return S_OK;
|
|
|
|
case DISPID_ONTOOLBAR: return HTMLContainer2_OnShowUiElementHelper(this, uiToolbar, pDispParams);
|
|
case DISPID_ONMENUBAR: return HTMLContainer2_OnShowUiElementHelper(this, uiMenubar, pDispParams);
|
|
case DISPID_ONSTATUSBAR: return HTMLContainer2_OnShowUiElementHelper(this, uiStatusbar, pDispParams);
|
|
case DISPID_ONADDRESSBAR: return HTMLContainer2_OnShowUiElementHelper(this, uiAddressbar, pDispParams);
|
|
|
|
case DISPID_ONFULLSCREEN:
|
|
if (1 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_BOOL != pDispParams->rgvarg[0].vt) DISP_E_BADVARTYPE;
|
|
OnEnableFullscreen(pDispParams->rgvarg[0].boolVal);
|
|
return S_OK;
|
|
|
|
case DISPID_WINDOWSETRESIZABLE:
|
|
if (1 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_BOOL != pDispParams->rgvarg[0].vt) DISP_E_BADVARTYPE;
|
|
OnWindowSetResizable(pDispParams->rgvarg[0].boolVal);
|
|
return S_OK;
|
|
|
|
case DISPID_CLIENTTOHOSTWINDOW:
|
|
if (2 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if ((VT_BYREF|VT_I4) != pDispParams->rgvarg[1].vt ||
|
|
(VT_BYREF|VT_I4) != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
OnClientToHostWindow(pDispParams->rgvarg[1].plVal, pDispParams->rgvarg[0].plVal);
|
|
return S_OK;
|
|
|
|
case DISPID_WINDOWSETLEFT:
|
|
if (1 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_I4 != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
OnSetWindowPos(wndLeft, pDispParams->rgvarg[0].lVal, 0, 0, 0);
|
|
return S_OK;
|
|
|
|
case DISPID_WINDOWSETTOP:
|
|
if (1 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_I4 != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
OnSetWindowPos(wndTop, 0, pDispParams->rgvarg[0].lVal, 0, 0);
|
|
return S_OK;
|
|
|
|
case DISPID_WINDOWSETWIDTH:
|
|
if (1 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_I4 != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
OnSetWindowPos(wndWidth, 0, 0, pDispParams->rgvarg[0].lVal, 0);
|
|
return S_OK;
|
|
|
|
case DISPID_WINDOWSETHEIGHT:
|
|
if (1 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
|
|
if (VT_I4 != pDispParams->rgvarg[0].vt) return DISP_E_BADVARTYPE;
|
|
OnSetWindowPos(wndHeight, 0, 0, 0, pDispParams->rgvarg[0].lVal);
|
|
return S_OK;
|
|
}
|
|
|
|
return DISP_E_MEMBERNOTFOUND;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::SetLocation(int x, int y, int width, int height)
|
|
{
|
|
if (!pUnk) return E_NOINTERFACE;
|
|
|
|
SetRect(&rect, x, y, x + width, y + height);
|
|
|
|
IOleInPlaceObject *pipo = NULL;
|
|
HRESULT hr = pUnk->QueryInterface(IID_IOleInPlaceObject, (PVOID*)&pipo);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pipo->SetObjectRects(&rect, &rect);
|
|
pipo->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetBorder(LPRECT lprectBorder)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::RequestBorderSpace(LPCBORDERWIDTHS lpborderwidths)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::SetBorderSpace(LPCBORDERWIDTHS lpborderwidths)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::SetActiveObject(IOleInPlaceActiveObject * pActiveObject, LPCOLESTR lpszObjName)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::SetFocus(BOOL fFocused)
|
|
{
|
|
if (NULL == pUnk)
|
|
return E_NOINTERFACE;
|
|
|
|
if (FALSE != fFocused)
|
|
{
|
|
IOleObject *pioo = NULL;
|
|
if (SUCCEEDED(pUnk->QueryInterface(IID_IOleObject, (PVOID*)&pioo)))
|
|
{
|
|
pioo->DoVerb(OLEIVERB_UIACTIVATE, NULL, this, 0, hParent, &rect);
|
|
pioo->Release();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
IOleInPlaceObject *pipo = NULL;
|
|
if (SUCCEEDED(pUnk->QueryInterface(IID_IOleInPlaceObject, (void**)&pipo)))
|
|
{
|
|
pipo->UIDeactivate();
|
|
pipo->Release();
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
BOOL HTMLContainer2::TranslateKey(LPMSG pMsg)
|
|
{
|
|
if (!pUnk) return FALSE;
|
|
|
|
IOleInPlaceActiveObject *pao = NULL;
|
|
HRESULT hr = pUnk->QueryInterface(IID_IOleInPlaceActiveObject, (PVOID*)&pao);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pao->TranslateAccelerator(pMsg);
|
|
pao->Release();
|
|
}
|
|
|
|
return (S_OK == hr);
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::ShowHelp(HWND hwnd, LPOLESTR pszHelpFile, UINT uCommand, DWORD dwData, POINT ptMouse, IDispatch *pDispatchObjectHit)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::ShowMessage(HWND hwnd, LPOLESTR lpstrText, LPOLESTR lpstrCaption, DWORD dwType, LPOLESTR lpstrHelpFile, DWORD dwHelpContext, LRESULT *plResult)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
// ***********************************************************************
|
|
// IDocHostUIHandler
|
|
// ***********************************************************************
|
|
|
|
STDMETHODIMP HTMLContainer2::ShowContextMenu(DWORD dwID, POINT __RPC_FAR *ppt, IUnknown __RPC_FAR *pcmdtReserved, IDispatch __RPC_FAR *pdispReserved)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetHostInfo(DOCHOSTUIINFO __RPC_FAR *pInfo)
|
|
{
|
|
pInfo->cbSize = sizeof(DOCHOSTUIINFO);
|
|
pInfo->dwFlags = OnGetHostInfoFlags();
|
|
|
|
pInfo->pchHostCss = OnGetHostCSS();
|
|
pInfo->pchHostNS = OnGetHostNamespace();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::ShowUI(DWORD dwID, IOleInPlaceActiveObject __RPC_FAR *pActiveObject, IOleCommandTarget __RPC_FAR *pCommandTarget, IOleInPlaceFrame __RPC_FAR *pFrame, IOleInPlaceUIWindow __RPC_FAR *pDoc)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::HideUI(void)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::UpdateUI(void)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::OnDocWindowActivate(BOOL fActivate)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::OnFrameWindowActivate(BOOL fActivate)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow __RPC_FAR *pUIWindow, BOOL fRameWindow)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::TranslateAccelerator(LPMSG lpMsg, const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID)
|
|
{
|
|
if ((0x8000 & GetAsyncKeyState(VK_MENU)) || (0x8000 & GetAsyncKeyState(VK_CONTROL)))
|
|
{
|
|
if (NULL != hParent && IsWindow(hParent) &&
|
|
PostMessageW(hParent, lpMsg->message, lpMsg->wParam, lpMsg->lParam))
|
|
{
|
|
return S_OK;
|
|
}
|
|
}
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetOptionKeyPath(LPOLESTR __RPC_FAR *pchKey, DWORD dw)
|
|
{
|
|
*pchKey = NULL;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetDropTarget(IDropTarget __RPC_FAR *pDropTarget, IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetExternal(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch)
|
|
{
|
|
*ppDispatch = NULL;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::TranslateUrl(DWORD dwTranslate, OLECHAR __RPC_FAR *pchURLIn, OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut)
|
|
{
|
|
*ppchURLOut = NULL;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::FilterDataObject(IDataObject __RPC_FAR *pDO, IDataObject __RPC_FAR *__RPC_FAR *ppDORet)
|
|
{
|
|
*ppDORet = NULL;
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::GetOverrideKeyPath(LPOLESTR __RPC_FAR *pchKey, DWORD dw)
|
|
{
|
|
*pchKey = NULL;
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText)
|
|
{
|
|
return OLECMDERR_E_NOTSUPPORTED;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut)
|
|
{
|
|
return OLECMDERR_E_UNKNOWNGROUP;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::QueryService(REFGUID guidService, REFIID riid, void **ppv)
|
|
{
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::GetIUnknown(IUnknown **ppUnk)
|
|
{
|
|
if (!pUnk)
|
|
{
|
|
*ppUnk = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
pUnk->AddRef();
|
|
*ppUnk = pUnk;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::GetIDispatch(IDispatch **ppDisp)
|
|
{
|
|
*ppDisp = NULL;
|
|
return (pUnk) ? pUnk->QueryInterface(IID_IDispatch, (PVOID*)ppDisp) : E_NOINTERFACE;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::GetIWebBrowser2(IWebBrowser2 **ppWeb2)
|
|
{
|
|
*ppWeb2 = NULL;
|
|
return (pUnk) ? pUnk->QueryInterface(IID_IWebBrowser2, (PVOID*)ppWeb2) : E_NOINTERFACE;
|
|
}
|
|
|
|
HWND HTMLContainer2::GetHostHWND(void)
|
|
{
|
|
if (NULL == pUnk) return NULL;
|
|
|
|
HWND hwndHost = NULL;
|
|
IOleInPlaceObject *pipo = NULL;
|
|
HRESULT hr = pUnk->QueryInterface(IID_IOleInPlaceObject, (PVOID *)&pipo);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pipo->GetWindow(&hwndHost);
|
|
if (FAILED(hr)) hwndHost = NULL;
|
|
pipo->Release();
|
|
}
|
|
|
|
return hwndHost;
|
|
}
|
|
|
|
HWND HTMLContainer2::GetParentHWND(void)
|
|
{
|
|
return hParent;
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::UnadviseBrowserEvents()
|
|
{
|
|
if (0 == dwCookie)
|
|
return S_OK;
|
|
|
|
IConnectionPoint *pcp = NULL;
|
|
IConnectionPointContainer *pcpc = NULL;
|
|
HRESULT hr = pUnk->QueryInterface(IID_IConnectionPointContainer, (PVOID*)&pcpc);
|
|
if (SUCCEEDED (hr))
|
|
{
|
|
hr = pcpc->FindConnectionPoint(DIID_DWebBrowserEvents2, &pcp);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pcp->Unadvise(dwCookie);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
dwCookie = 0;
|
|
}
|
|
pcp->Release();
|
|
}
|
|
pcpc->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::PostRedirectMessage(UINT messageId, LPARAM param)
|
|
{
|
|
HWND hHost = GetHostHWND();
|
|
if (NULL == hHost) return E_HANDLE;
|
|
if (FALSE == SublassControl_IsAttached(hHost)) return E_NOTIMPL;
|
|
|
|
if (0 == WM_REDIRECTNAVIGATE)
|
|
{
|
|
WM_REDIRECTNAVIGATE = RegisterWindowMessageW(L"htmlContainterRedirectNavigate");
|
|
if (0 == WM_REDIRECTNAVIGATE) return E_UNEXPECTED;
|
|
}
|
|
|
|
if (FALSE == PostMessageW(hHost, WM_REDIRECTNAVIGATE, (WPARAM)messageId, param))
|
|
{
|
|
DWORD errorCode = GetLastError();
|
|
return HRESULT_FROM_WIN32(errorCode);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::NavigateEx(IWebBrowser2 *pWeb2, VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
|
|
{
|
|
HRESULT hr;
|
|
if (NULL == pWeb2)
|
|
return E_NOINTERFACE;
|
|
|
|
pWeb2->AddRef();
|
|
|
|
VARIANT vtHeader;
|
|
BOOL performNavigate = TRUE;
|
|
|
|
VariantInit(&vtHeader);
|
|
|
|
LPCWSTR pszUserAgent = OnGetUserAgent();
|
|
if (!Headers && NULL != pszUserAgent && L'\0' != *pszUserAgent)
|
|
{
|
|
wchar_t szBuffer[256] = {0};
|
|
if (SUCCEEDED(StringCchPrintfW(szBuffer, ARRAYSIZE(szBuffer), L"User-Agent: %s", pszUserAgent)))
|
|
{
|
|
V_VT(&vtHeader) = VT_BSTR;
|
|
vtHeader.bstrVal = SysAllocString(szBuffer);
|
|
Headers = &vtHeader;
|
|
}
|
|
}
|
|
|
|
if (FALSE != ensureChakraLoaded)
|
|
{
|
|
if (NULL == GetModuleHandleW(L"mshtml.dll"))
|
|
{
|
|
HKEY hKey = NULL;
|
|
unsigned long disposition = 0;
|
|
long createResult = 0;
|
|
wchar_t processName[2*MAX_PATH] = {0};
|
|
HANDLE lock = CreateMutexW(NULL, FALSE, L"HTMLContainer2::ChakraEnabler");
|
|
if (NULL != lock)
|
|
WaitForSingleObject(lock, INFINITE);
|
|
|
|
createResult = RegCreateKeyExW(HKEY_CURRENT_USER, REGISTRY_FEATURE_USE_LEGACY_JSCRIPT,
|
|
NULL, NULL, REG_OPTION_VOLATILE, KEY_SET_VALUE,
|
|
NULL, &hKey, &disposition);
|
|
|
|
if (ERROR_SUCCESS == createResult)
|
|
{
|
|
unsigned long featureEnabled = 0;
|
|
if (0 != GetModuleFileNameW(NULL, processName, ARRAYSIZE(processName)))
|
|
{
|
|
featureEnabled = 0;
|
|
PathStripPathW(processName);
|
|
|
|
RegSetValueExW(hKey, processName, 0, REG_DWORD, (const BYTE*)&featureEnabled, sizeof(unsigned long));
|
|
|
|
hr = pWeb2->Navigate2(URL, Flags, TargetFrameName, PostData, Headers);
|
|
performNavigate = FALSE;
|
|
|
|
RegDeleteValueW(hKey, processName);
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
if (NULL != lock)
|
|
{
|
|
ReleaseMutex(lock);
|
|
CloseHandle(lock);
|
|
}
|
|
}
|
|
ensureChakraLoaded = FALSE;
|
|
}
|
|
|
|
if (FALSE != performNavigate)
|
|
hr = pWeb2->Navigate2(URL, Flags, TargetFrameName, PostData, Headers);
|
|
|
|
VariantClear(&vtHeader);
|
|
pWeb2->Release();
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::Navigate2(VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
|
|
{
|
|
if (NULL == pUnk)
|
|
return E_NOINTERFACE;
|
|
|
|
IWebBrowser2 *pWeb2 = NULL;
|
|
HRESULT hr = pUnk->QueryInterface(IID_IWebBrowser2, (LPVOID*)&pWeb2);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = NavigateEx(pWeb2, URL, Flags, TargetFrameName, PostData, Headers);
|
|
pWeb2->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::PostNavigate2(VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
|
|
{
|
|
RMNAVIGATE2 *param = (RMNAVIGATE2*)calloc(1, sizeof(RMNAVIGATE2));
|
|
if (NULL == param) return E_OUTOFMEMORY;
|
|
|
|
VariantInit(¶m->URL);
|
|
VariantInit(¶m->Flags);
|
|
VariantInit(¶m->TargetFrameName);
|
|
VariantInit(¶m->PostData);
|
|
VariantInit(¶m->Headers);
|
|
|
|
if (NULL != URL) VariantCopyInd(¶m->URL, URL);
|
|
if (NULL != Flags) VariantCopyInd(¶m->Flags, Flags);
|
|
if (NULL != TargetFrameName) VariantCopyInd(¶m->TargetFrameName, TargetFrameName);
|
|
if (NULL != PostData) VariantCopyInd(¶m->PostData, PostData);
|
|
if (NULL != Headers) VariantCopyInd(¶m->Headers, Headers);
|
|
|
|
HRESULT hr = PostRedirectMessage(HTMLContainer2::msgNavigate2, (LPARAM)param);
|
|
if (FAILED(hr))
|
|
{
|
|
VariantClear(¶m->URL);
|
|
VariantClear(¶m->Flags);
|
|
VariantClear(¶m->TargetFrameName);
|
|
VariantClear(¶m->PostData);
|
|
VariantClear(¶m->Headers);
|
|
free(param);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::NavigateToNameEx(IWebBrowser2 *pWeb2, LPCWSTR pszUrl, UINT fFlags)
|
|
{
|
|
VARIANT Flags;
|
|
VARIANT URL;
|
|
|
|
if (NULL == pszUrl || L'\0' == *pszUrl)
|
|
{
|
|
pszUrl = L"about:blank";
|
|
}
|
|
|
|
VariantInit(&Flags);
|
|
V_VT(&Flags) = VT_I4;
|
|
V_I4(&Flags) = fFlags;
|
|
|
|
VariantInit(&URL);
|
|
V_VT(&URL) = VT_BSTR;
|
|
URL.bstrVal = SysAllocString(pszUrl);
|
|
|
|
HRESULT hr = (NULL != URL.bstrVal) ? NavigateEx(pWeb2, &URL, &Flags, NULL, NULL, NULL) : E_FAIL;
|
|
|
|
VariantClear(&URL);
|
|
VariantClear(&Flags);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::NavigateToName(LPCWSTR pszUrl, UINT fFlags)
|
|
{
|
|
if (NULL == pUnk)
|
|
return E_NOINTERFACE;
|
|
|
|
IWebBrowser2 *pWeb2 = NULL;
|
|
HRESULT hr = pUnk->QueryInterface(IID_IWebBrowser2, (LPVOID*)&pWeb2);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = NavigateToNameEx(pWeb2, pszUrl, fFlags);
|
|
pWeb2->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::PostNavigateToName(LPCWSTR pszUrl, UINT fFlags)
|
|
{
|
|
RMNAVIGATETONAME *param = (RMNAVIGATETONAME*)calloc(1, sizeof(RMNAVIGATETONAME));
|
|
if (NULL == param) return E_OUTOFMEMORY;
|
|
|
|
param->url = SysAllocString(pszUrl);
|
|
param->flags = fFlags;
|
|
|
|
HRESULT hr = PostRedirectMessage(HTMLContainer2::msgNavigateToName, (LPARAM)param);
|
|
if (FAILED(hr))
|
|
{
|
|
SysFreeString(param->url);
|
|
free(param);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::WriteHTML(LPCWSTR pszHTML)
|
|
{
|
|
BSTR data = SysAllocString(pszHTML);
|
|
if (NULL == data && NULL != pszHTML)
|
|
return E_OUTOFMEMORY;
|
|
|
|
HRESULT hr = WriteDocument(data);
|
|
if (FAILED(hr))
|
|
{
|
|
SysFreeString(data);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::WriteDocument(BSTR data)
|
|
{
|
|
IWebBrowser2 *pWeb2 = NULL;
|
|
HRESULT hr = GetIWebBrowser2(&pWeb2);
|
|
if (FAILED(hr)) return hr;
|
|
|
|
IDispatch *pDisp = NULL;
|
|
hr = pWeb2->get_Document(&pDisp);
|
|
if (S_OK == hr)
|
|
{
|
|
IHTMLDocument2 *pDoc = NULL;
|
|
hr = pDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
SAFEARRAY *array = SafeArrayCreateVector(VT_VARIANT, 0, 1);
|
|
if (NULL != array)
|
|
{
|
|
VARIANT *item = NULL;
|
|
hr = SafeArrayAccessData(array, (void**)&item);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
VariantInit(item);
|
|
V_VT(item) = VT_BSTR;
|
|
V_BSTR(item) = data;
|
|
|
|
hr = pDoc->write(array);
|
|
pDoc->close();
|
|
|
|
if (FAILED(hr))
|
|
V_BSTR(item) = NULL;
|
|
|
|
SafeArrayUnaccessData(array);
|
|
}
|
|
SafeArrayDestroy(array);
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
pDoc->Release();
|
|
}
|
|
pDisp->Release();
|
|
}
|
|
pWeb2->Release();
|
|
return hr;
|
|
}
|
|
|
|
COLORREF HTMLContainer2::OnGetHostBkColor(void)
|
|
{
|
|
return DEFAULT_HOSTBKCOLOR;
|
|
}
|
|
|
|
DWORD HTMLContainer2::OnGetHostInfoFlags(void)
|
|
{
|
|
return DEFAULT_DOCHOSTUIFLAGS;
|
|
}
|
|
|
|
OLECHAR *HTMLContainer2::OnGetHostCSS(void)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
OLECHAR *HTMLContainer2::OnGetHostNamespace(void)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
DWORD HTMLContainer2::OnGetDownlodFlags(void)
|
|
{
|
|
return DEFAULT_DOWNLOADFLAGS;
|
|
}
|
|
|
|
LPCWSTR HTMLContainer2::OnGetUserAgent(void)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::InvokeScriptFunction(LPCWSTR pszFuncName, LCID lcid, DISPPARAMS FAR *pDispParams, VARIANT FAR *pVarResult, EXCEPINFO FAR *pExcepInfo, UINT FAR *puArgErr)
|
|
{
|
|
IWebBrowser2 *pWeb2 = NULL;
|
|
IDispatch *pDisp = NULL;
|
|
IDispatch *pDispScript = NULL;
|
|
IHTMLDocument2 *pDoc = NULL;
|
|
DISPID dispid;
|
|
|
|
HRESULT hr = GetIWebBrowser2(&pWeb2);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pWeb2->get_Document(&pDisp);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pDoc->get_Script(&pDispScript);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pDispScript->GetIDsOfNames(IID_NULL, (LPWSTR*)&pszFuncName, 1, lcid, &dispid);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pDispScript->Invoke(dispid, IID_NULL, lcid, DISPATCH_METHOD, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
|
}
|
|
pDispScript->Release();
|
|
}
|
|
pDoc->Release();
|
|
}
|
|
pDisp->Release();
|
|
}
|
|
pWeb2->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
BROWSERCB HTMLContainer2::RegisterBrowserEventCB(BROWSERCB fnBrowserCB, LPVOID pUserData)
|
|
{
|
|
BROWSERCB fnTemp = this->fnBrwoserCB;
|
|
this->fnBrwoserCB = fnBrowserCB;
|
|
this->userData = pUserData;
|
|
return fnTemp;
|
|
}
|
|
|
|
DWORD HTMLContainer2::GetContainerStyle(void)
|
|
{
|
|
return CSTYLE_NORMAL;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::IsFrameset(IWebBrowser2 *pWeb2)
|
|
{
|
|
if (NULL == pWeb2)
|
|
return E_INVALIDARG;
|
|
|
|
IDispatch *pDocDisp = NULL;
|
|
HRESULT hr = pWeb2->get_Document(&pDocDisp);
|
|
if (SUCCEEDED(hr) && NULL != pDocDisp)
|
|
{
|
|
IHTMLDocument2 *pDoc = NULL;
|
|
hr = pDocDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc);
|
|
if (SUCCEEDED(hr) && NULL != pDoc)
|
|
{
|
|
IHTMLElement *pElement = NULL;
|
|
if (SUCCEEDED(pDoc->get_body(&pElement)) && NULL != pElement)
|
|
{
|
|
IHTMLBodyElement* pBodyElement = NULL;
|
|
if (SUCCEEDED(pElement->QueryInterface(IID_IHTMLBodyElement, (void**)&pBodyElement)))
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
pElement->Release();
|
|
}
|
|
pDoc->Release();
|
|
}
|
|
pDocDisp->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::GetFramesCount(IWebBrowser2 *pWeb2, INT *frameCount)
|
|
{
|
|
if (NULL == frameCount)
|
|
return E_POINTER;
|
|
|
|
*frameCount = 0;
|
|
|
|
if(NULL == pWeb2)
|
|
return E_INVALIDARG;
|
|
|
|
IDispatch *pDocDisp = NULL;
|
|
HRESULT hr = pWeb2->get_Document(&pDocDisp);
|
|
if (SUCCEEDED(hr) && NULL != pDocDisp)
|
|
{
|
|
IOleContainer *pContainer = NULL;
|
|
hr = pDocDisp->QueryInterface(IID_IOleContainer, (void**)&pContainer);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IEnumUnknown* pEnumerator = NULL;
|
|
hr = pContainer->EnumObjects(OLECONTF_EMBEDDINGS, &pEnumerator);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IUnknown* pUnknown = NULL;
|
|
ULONG uFetched = 0;
|
|
for (UINT i = 0; S_OK == pEnumerator->Next(1, &pUnknown, &uFetched); i++)
|
|
{
|
|
IWebBrowser2* pBrowser = NULL;
|
|
if (SUCCEEDED(pUnknown->QueryInterface(IID_IWebBrowser2, (void**)&pBrowser)))
|
|
{
|
|
if (S_OK == IsFrameset(pBrowser))
|
|
{
|
|
INT f = 0;
|
|
if (SUCCEEDED(GetFramesCount(pBrowser, &f)))
|
|
*frameCount += f;
|
|
}
|
|
else
|
|
{
|
|
(*frameCount)++;
|
|
}
|
|
pBrowser->Release();
|
|
}
|
|
pUnknown->Release();
|
|
}
|
|
pEnumerator->Release();
|
|
}
|
|
pContainer->Release();
|
|
}
|
|
pDocDisp->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
BOOL HTMLContainer2::ValidateURLHost(LPCWSTR pszUrl)
|
|
{
|
|
if (NULL == libWininet.InternetCrackUrl)
|
|
{
|
|
HTMLContainer2_LoadLibray((LIBHDR*)&libWininet);
|
|
if (NULL == libWininet.InternetCrackUrl)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if (NULL == pszUrl || L'\0' == *pszUrl)
|
|
return FALSE;
|
|
|
|
URL_COMPONENTSW uc;
|
|
WCHAR szHost[2048] = {0};
|
|
|
|
ZeroMemory(&uc, sizeof(URL_COMPONENTSW));
|
|
uc.dwStructSize = sizeof(URL_COMPONENTSW);
|
|
uc.lpszHostName = szHost;
|
|
uc.dwHostNameLength = ARRAYSIZE(szHost);
|
|
|
|
if (FALSE == libWininet.InternetCrackUrl(pszUrl, 0, NULL, &uc))
|
|
{
|
|
// ERROR_INTERNET_INVALID_URL
|
|
DWORD error = GetLastError();
|
|
|
|
BSTR version = NULL;
|
|
if (SUCCEEDED(GetAppVersion(&version)) && NULL != version)
|
|
{
|
|
if (NULL != StrStrIW(version, L"MSIE 6.0"))
|
|
{
|
|
LPCWSTR c = pszUrl;
|
|
while(c && L'\0' != *c)
|
|
{
|
|
if (L'?' == *c)
|
|
{
|
|
WCHAR szTemp[2048] = {0};
|
|
if (SUCCEEDED(StringCchCopyNW(szTemp, ARRAYSIZE(szTemp), pszUrl, (c - pszUrl))) &&
|
|
FALSE != libWininet.InternetCrackUrl(szTemp, 0, NULL, &uc))
|
|
{
|
|
error = ERROR_SUCCESS;
|
|
}
|
|
break;
|
|
}
|
|
c++;
|
|
}
|
|
}
|
|
|
|
SysFreeString(version);
|
|
}
|
|
if (ERROR_SUCCESS != error)
|
|
return FALSE;
|
|
}
|
|
|
|
if (0 == uc.dwHostNameLength)
|
|
return TRUE;
|
|
|
|
switch(uc.nScheme)
|
|
{
|
|
case INTERNET_SCHEME_PARTIAL:
|
|
case INTERNET_SCHEME_DEFAULT:
|
|
case INTERNET_SCHEME_FTP:
|
|
case INTERNET_SCHEME_GOPHER:
|
|
case INTERNET_SCHEME_HTTP:
|
|
case INTERNET_SCHEME_HTTPS:
|
|
{
|
|
LPCWSTR block = uc.lpszHostName;
|
|
LPCWSTR end = block + uc.dwHostNameLength;
|
|
LPCWSTR cursor = block;
|
|
|
|
for(;;)
|
|
{
|
|
if (cursor == end || L'.' == *cursor)
|
|
{
|
|
if (block == cursor && end != cursor)
|
|
return FALSE;
|
|
|
|
if (end == cursor)
|
|
return TRUE;
|
|
}
|
|
cursor++;
|
|
}
|
|
}
|
|
break;
|
|
case INTERNET_SCHEME_RES:
|
|
case INTERNET_SCHEME_FILE:
|
|
if (CSTR_EQUAL == CompareStringW(CSTR_INVARIANT, 0, L"shdoclc", -1, uc.lpszHostName, -1))
|
|
{
|
|
if (NULL != StrStrIW(pszUrl, L"syntax.htm"))
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::GetAppVersion(BSTR *p)
|
|
{
|
|
if (NULL == p)
|
|
return E_POINTER;
|
|
|
|
IWebBrowser2 *pWeb2 = NULL;
|
|
HRESULT hr = GetIWebBrowser2(&pWeb2);
|
|
if (FAILED(hr)) return hr;
|
|
|
|
IDispatch *pDispatch = NULL;
|
|
hr = pWeb2->get_Document(&pDispatch);
|
|
if (NULL == pDispatch) hr = E_FAIL;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IHTMLDocument2 *pDoc = NULL;
|
|
hr = pDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IHTMLWindow2 *pWnd = NULL;
|
|
hr = pDoc->get_parentWindow(&pWnd);
|
|
if (NULL == pWnd) hr = E_FAIL;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IOmNavigator *pNavigator = NULL;
|
|
hr = pWnd->get_navigator(&pNavigator);
|
|
if (NULL == pNavigator) hr = E_FAIL;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pNavigator->get_appVersion(p);
|
|
pNavigator->Release();
|
|
}
|
|
pWnd->Release();
|
|
}
|
|
pDoc->Release();
|
|
}
|
|
pDispatch->Release();
|
|
}
|
|
|
|
pWeb2->Release();
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::GetUserAgent(BSTR *p)
|
|
{
|
|
if (NULL == p)
|
|
return E_POINTER;
|
|
|
|
IWebBrowser2 *pWeb2 = NULL;
|
|
HRESULT hr = GetIWebBrowser2(&pWeb2);
|
|
if (FAILED(hr)) return hr;
|
|
|
|
IDispatch *pDispatch = NULL;
|
|
hr = pWeb2->get_Document(&pDispatch);
|
|
if (NULL == pDispatch) hr = E_FAIL;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IHTMLDocument2 *pDoc = NULL;
|
|
hr = pDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IHTMLWindow2 *pWnd = NULL;
|
|
hr = pDoc->get_parentWindow(&pWnd);
|
|
if (NULL == pWnd) hr = E_FAIL;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IOmNavigator *pNavigator = NULL;
|
|
hr = pWnd->get_navigator(&pNavigator);
|
|
if (NULL == pNavigator) hr = E_FAIL;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pNavigator->get_userAgent(p);
|
|
pNavigator->Release();
|
|
}
|
|
pWnd->Release();
|
|
}
|
|
pDoc->Release();
|
|
}
|
|
pDispatch->Release();
|
|
}
|
|
|
|
pWeb2->Release();
|
|
return hr;
|
|
}
|
|
|
|
void HTMLContainer2::OnBeforeNavigate(IDispatch *pDispatch, VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers, VARIANT_BOOL *Cancel)
|
|
{
|
|
if (0 == (CF_DISABLEBEFORENAVFILTER & dwFlags))
|
|
{
|
|
// follow the Winamp internet preferences options
|
|
if (!SendMessageW(winampWindow, WM_WA_IPC, 0, IPC_INETAVAILABLE))
|
|
{
|
|
LPCWSTR pszTemplate = L"res://";
|
|
LPCWSTR pszEntry = StrStrIW(URL->bstrVal, pszTemplate);
|
|
if (NULL == pszEntry)
|
|
{
|
|
if (StrCmpNIW(URL->bstrVal, L"about:blank", 11) && StrCmpNIW(URL->bstrVal, L"javascript:", 11))
|
|
{
|
|
*Cancel = ((VARIANT_BOOL)-2);
|
|
dwFlags |= CF_DISABLEBEFORENAVFILTER;
|
|
OnNavigateCancelled(NULL, Cancel);
|
|
dwFlags &= ~CF_DISABLEBEFORENAVFILTER;
|
|
if (NULL != Cancel && VARIANT_TRUE == *Cancel)
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (FALSE == ValidateURLHost(URL->bstrVal))
|
|
{
|
|
VARIANT StatusCode;
|
|
VariantInit(&StatusCode);
|
|
V_VT(&StatusCode) = VT_I4;
|
|
V_I4(&StatusCode) = INET_E_INVALID_URL;
|
|
|
|
dwFlags |= CF_DISABLEBEFORENAVFILTER;
|
|
|
|
*Cancel = VARIANT_TRUE;
|
|
OnNavigateError(pDispatch, URL, TargetFrameName, &StatusCode, Cancel);
|
|
Navigate2(URL, NULL, TargetFrameName, NULL, NULL);
|
|
|
|
dwFlags &= ~CF_DISABLEBEFORENAVFILTER;
|
|
if (NULL != Cancel && VARIANT_TRUE == *Cancel)
|
|
return;
|
|
}
|
|
|
|
IWebBrowser2 *pWebMine = NULL, *pWebFrame = NULL;
|
|
if (FAILED(GetIWebBrowser2(&pWebMine)))
|
|
pWebMine = NULL;
|
|
|
|
if (NULL == pDispatch ||
|
|
FAILED(pDispatch->QueryInterface(IID_IWebBrowser2, (void**)&pWebFrame)))
|
|
{
|
|
pWebFrame = NULL;
|
|
}
|
|
|
|
if (NULL != pWebMine) pWebMine->Release();
|
|
if (NULL != pWebFrame) pWebFrame->Release();
|
|
|
|
if (NULL != pWebMine && pWebMine == pWebFrame && NULL != URL && VT_BSTR == URL->vt && NULL != URL->bstrVal)
|
|
{
|
|
LPCWSTR pszTemplate = L"navcancl.htm#";
|
|
LPCWSTR pszEntry = StrStrIW(URL->bstrVal, pszTemplate);
|
|
if (NULL != pszEntry)
|
|
{
|
|
dwFlags |= CF_DISABLEBEFORENAVFILTER;
|
|
OnNavigateCancelled(pszEntry + lstrlenW(pszTemplate), Cancel);
|
|
dwFlags &= ~CF_DISABLEBEFORENAVFILTER;
|
|
|
|
if (NULL != Cancel && VARIANT_TRUE == *Cancel)
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
STDMETHODIMP HTMLContainer2::RegisterBrowserCursor(INT nSysCurID, HCURSOR hCurToUse)
|
|
{
|
|
IECURSOR *pCursor = (IECURSOR*)hCursors;
|
|
if (pCursor)
|
|
{
|
|
for (int i =0; i < nCursors; i++)
|
|
{
|
|
if (pCursor[i].nSysId == nSysCurID)
|
|
{
|
|
if (pCursor[i].hUser) DestroyCursor(pCursor[i].hUser);
|
|
pCursor[i].hSys = NULL;
|
|
if (hCurToUse) pCursor[i].hUser = hCurToUse;
|
|
else
|
|
{
|
|
MoveMemory(&pCursor[i], &pCursor[i + 1], sizeof(IECURSOR)*(nCursors - i - 1));
|
|
nCursors--;
|
|
if (!nCursors)
|
|
{
|
|
free(hCursors);
|
|
hCursors = NULL;
|
|
}
|
|
|
|
VOID* data = realloc(hCursors, sizeof(IECURSOR)*nCursors);
|
|
if (data) hCursors = data;
|
|
else return E_OUTOFMEMORY;
|
|
}
|
|
return S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hCurToUse)
|
|
{
|
|
VOID *data = realloc(hCursors, sizeof(IECURSOR)*(nCursors + 1));
|
|
if (!data) return E_OUTOFMEMORY;
|
|
hCursors = data;
|
|
pCursor = (IECURSOR*)hCursors;
|
|
pCursor[nCursors].nSysId = nSysCurID;
|
|
pCursor[nCursors].hSys = NULL;
|
|
pCursor[nCursors].hUser = hCurToUse;
|
|
nCursors++;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT HTMLContainer2::InternetSetFeatureEnabled(INTERNETFEATURELIST FeatureEntry, DWORD dwFlags, BOOL fEnable)
|
|
{
|
|
if (NULL == libUrlmon.CoInternetSetFeatureEnabled)
|
|
{
|
|
HTMLContainer2_LoadLibray((LIBHDR*)&libUrlmon);
|
|
if (NULL == libUrlmon.CoInternetSetFeatureEnabled)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
return libUrlmon.CoInternetSetFeatureEnabled(FeatureEntry, dwFlags, fEnable);
|
|
}
|
|
|
|
HRESULT HTMLContainer2::InternetIsFeatureEnabled(INTERNETFEATURELIST FeatureEntry, DWORD dwFlags)
|
|
{
|
|
if (NULL == libUrlmon.CoInternetIsFeatureEnabled)
|
|
{
|
|
HTMLContainer2_LoadLibray((LIBHDR*)&libUrlmon);
|
|
if (NULL == libUrlmon.CoInternetIsFeatureEnabled)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
return libUrlmon.CoInternetIsFeatureEnabled(FeatureEntry, dwFlags);
|
|
}
|
|
|
|
void HTMLContainer2::ProcessRedirectedMessage(HWND hwnd, UINT messageId, LPARAM param)
|
|
{
|
|
switch(messageId)
|
|
{
|
|
case HTMLContainer2::msgNavigate2:
|
|
{
|
|
RMNAVIGATE2 *pnp = (RMNAVIGATE2*)param;
|
|
if (NULL != pnp)
|
|
{
|
|
Navigate2(&pnp->URL, &pnp->Flags, NULL, NULL, &pnp->Headers);
|
|
VariantClear(&pnp->URL);
|
|
VariantClear(&pnp->Flags);
|
|
VariantClear(&pnp->TargetFrameName);
|
|
VariantClear(&pnp->PostData);
|
|
VariantClear(&pnp->Headers);
|
|
free(pnp);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HTMLContainer2::msgNavigateToName:
|
|
{
|
|
RMNAVIGATETONAME *pntn = (RMNAVIGATETONAME*)param;
|
|
if (NULL != pntn)
|
|
{
|
|
NavigateToName(pntn->url, pntn->flags);
|
|
free(pntn);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
#define SUBCLASS_UNKNOWN 0
|
|
#define SUBCLASS_EMBED 1
|
|
#define SUBCLASS_DOCOBJECT 2
|
|
#define SUBCLASS_IESERVER 3
|
|
|
|
typedef struct __SUBCLASSCTRL
|
|
{
|
|
UINT type;
|
|
WNDPROC originalProc;
|
|
HTMLContainer2 *container;
|
|
} SUBCLASSCTRL;
|
|
|
|
static LRESULT SubclassControl_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
SUBCLASSCTRL *psc = (SUBCLASSCTRL*)GetPropW(hwnd, WNDPROP_SCCTRLW);
|
|
if (NULL == psc || NULL == psc->originalProc)
|
|
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_NCDESTROY:
|
|
case WM_DESTROY: // detach
|
|
RemovePropW(hwnd, WNDPROP_SCCTRLW);
|
|
SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)psc->originalProc);
|
|
CallWindowProcW(psc->originalProc, hwnd, uMsg, wParam, lParam);
|
|
free(psc);
|
|
return 0;
|
|
|
|
case WM_ERASEBKGND:
|
|
if( NULL != wParam &&
|
|
NULL != psc->container &&
|
|
(SUBCLASS_EMBED == psc->type || SUBCLASS_DOCOBJECT == psc->type))
|
|
{
|
|
HWND hChild = GetWindow(hwnd, GW_CHILD);
|
|
if (NULL == hChild || 0 == (WS_VISIBLE & GetWindowLongPtrW(hChild, GWL_STYLE)))
|
|
{
|
|
RECT paintRect;
|
|
if (FALSE != GetUpdateRect(hwnd, &paintRect, FALSE) ||
|
|
FALSE != GetClientRect(hwnd, &paintRect))
|
|
{
|
|
SetBkColor((HDC)wParam, psc->container->OnGetHostBkColor());
|
|
ExtTextOutW((HDC)wParam, 0, 0, ETO_OPAQUE, &paintRect, NULL, 0, NULL);
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
|
|
case WM_SETFOCUS:
|
|
if (SUBCLASS_IESERVER == psc->type)
|
|
{
|
|
if (NULL != psc->container)
|
|
psc->container->SetFocus(TRUE);
|
|
}
|
|
else
|
|
{
|
|
HWND hFocus = (HWND)wParam;
|
|
if (NULL != hFocus && IsWindowEnabled(hFocus))
|
|
{
|
|
HWND hRoot = GetAncestor(hwnd, GA_ROOT);
|
|
if (hFocus == hRoot || IsChild(hRoot, hFocus))
|
|
{
|
|
SetFocus(hFocus);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_KILLFOCUS:
|
|
if (SUBCLASS_IESERVER == psc->type && NULL != psc->container)
|
|
{
|
|
psc->container->SetFocus(FALSE);
|
|
}
|
|
break;
|
|
|
|
case WM_PARENTNOTIFY:
|
|
if ((SUBCLASS_EMBED == psc->type || SUBCLASS_DOCOBJECT == psc->type) &&
|
|
WM_CREATE == LOWORD(wParam) && 0L != lParam)
|
|
{
|
|
SubclassControl_Attach((HWND)lParam, psc->container);
|
|
}
|
|
|
|
if (SUBCLASS_EMBED == psc->type && WM_DESTROY == LOWORD(wParam) && NULL != lParam)
|
|
{
|
|
HWND hChild = (HWND)lParam;
|
|
WCHAR szClass[64] = {0};
|
|
if (0 != GetClassNameW(hChild, szClass, ARRAYSIZE(szClass)) &&
|
|
IS_EQUALCLASS(szClass, L"Shell DocObject View"))
|
|
{
|
|
HWND hPrimary = FindWindowExW(hwnd, NULL, L"Shell DocObject View", NULL);
|
|
if (hPrimary != NULL && hPrimary != hChild)
|
|
{
|
|
if(NULL != psc->container)
|
|
psc->container->OnClosePopupInternal();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_SETCURSOR:
|
|
if (SUBCLASS_IESERVER == psc->type && FALSE == bIsVistaOrHigher &&
|
|
NULL != psc->container && psc->container->nCursors)
|
|
{
|
|
ShowCursor(FALSE);
|
|
CallWindowProcW(psc->originalProc, hwnd, uMsg, wParam, lParam);
|
|
|
|
HCURSOR hCur = GetCursor();
|
|
IECURSOR *pCur = (IECURSOR*)(psc->container->hCursors);
|
|
for( int i= psc->container->nCursors -1; i > -1 ; i--)
|
|
{
|
|
if (NULL == pCur[i].hSys)
|
|
pCur[i].hSys = LoadCursor(NULL, MAKEINTRESOURCE(pCur[i].nSysId));
|
|
|
|
if (pCur[i].hSys == hCur)
|
|
{
|
|
if (NULL != pCur[i].hUser)
|
|
SetCursor(pCur[i].hUser);
|
|
break;
|
|
}
|
|
}
|
|
|
|
ShowCursor(TRUE);
|
|
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
if (NULL != psc->container)
|
|
{
|
|
HANDLE hook = psc->container->InitializePopupHook(hwnd, uMsg, wParam, lParam);
|
|
if (NULL != hook)
|
|
{
|
|
LRESULT result = CallWindowProcW(psc->originalProc, hwnd, uMsg, wParam, lParam);
|
|
psc->container->DeletePopupHook(hook);
|
|
return result;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_INITMENUPOPUP:
|
|
if (NULL != psc->container)
|
|
{
|
|
psc->container->InitializeMenuPopup(hwnd, (HMENU)wParam, LOWORD(lParam), HIWORD(lParam));
|
|
}
|
|
break;
|
|
|
|
case WM_INPUTLANGCHANGEREQUEST:
|
|
if (SUBCLASS_IESERVER == psc->type &&
|
|
NULL != psc->container &&
|
|
FALSE != psc->container->InputLangChangeRequest(hwnd, (UINT)wParam, (HKL)lParam))
|
|
{
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case WM_INPUTLANGCHANGE:
|
|
if (SUBCLASS_IESERVER == psc->type && NULL != psc->container)
|
|
psc->container->InputLangChange((UINT)wParam, (HKL)lParam);
|
|
break;
|
|
}
|
|
|
|
if (0 != WM_REDIRECTNAVIGATE && WM_REDIRECTNAVIGATE == uMsg)
|
|
{
|
|
if(SUBCLASS_EMBED == psc->type && NULL != psc->container)
|
|
psc->container->ProcessRedirectedMessage(hwnd, (UINT)wParam, lParam);
|
|
return TRUE;
|
|
}
|
|
|
|
if (WINAMP_WM_DIRECT_MOUSE_WHEEL == uMsg &&
|
|
WM_NULL != WINAMP_WM_DIRECT_MOUSE_WHEEL)
|
|
{
|
|
ReplyMessage(TRUE);
|
|
SendMessageW(hwnd, WM_MOUSEWHEEL, wParam, lParam);
|
|
return TRUE;
|
|
}
|
|
|
|
return CallWindowProcW(psc->originalProc, hwnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
static BOOL SublassControl_IsAttached(HWND hwnd)
|
|
{
|
|
SUBCLASSCTRL *psc = (SUBCLASSCTRL*)GetPropW(hwnd, WNDPROP_SCCTRLW);
|
|
return (NULL != psc);
|
|
}
|
|
|
|
static BOOL SubclassControl_Attach(HWND hControl, HTMLContainer2 *pContainer)
|
|
{
|
|
if (NULL == hControl || FALSE == IsWindow(hControl))
|
|
return FALSE;
|
|
|
|
SUBCLASSCTRL *psc = (SUBCLASSCTRL*)GetPropW(hControl, WNDPROP_SCCTRLW);
|
|
if (NULL != psc) return TRUE;
|
|
|
|
UINT controlType = SUBCLASS_UNKNOWN;
|
|
|
|
if (WM_NULL == WINAMP_WM_DIRECT_MOUSE_WHEEL)
|
|
WINAMP_WM_DIRECT_MOUSE_WHEEL = RegisterWindowMessageW(L"WINAMP_WM_DIRECT_MOUSE_WHEEL");
|
|
|
|
WCHAR szClass[128] = {0};
|
|
if (!GetClassNameW(hControl, szClass, ARRAYSIZE(szClass)))
|
|
return FALSE;
|
|
|
|
if (IS_EQUALCLASS(szClass, L"Shell Embedding")) controlType = SUBCLASS_EMBED;
|
|
else if (IS_EQUALCLASS(szClass, L"Shell DocObject View")) controlType = SUBCLASS_DOCOBJECT;
|
|
else if (IS_EQUALCLASS(szClass, L"Internet Explorer_Server")) controlType = SUBCLASS_IESERVER;
|
|
|
|
if (SUBCLASS_UNKNOWN == controlType)
|
|
return FALSE;
|
|
|
|
if (SUBCLASS_IESERVER != controlType)
|
|
{
|
|
DWORD styleEx = GetWindowStyleEx(hControl);
|
|
SetWindowLongPtrW(hControl, GWL_EXSTYLE, styleEx | WS_EX_CONTROLPARENT);
|
|
}
|
|
else
|
|
{
|
|
DWORD style = GetWindowStyle(hControl);
|
|
SetWindowLongPtrW(hControl, GWL_STYLE, style | WS_TABSTOP);
|
|
}
|
|
|
|
psc = (SUBCLASSCTRL*)calloc(1, sizeof(SUBCLASSCTRL));
|
|
if (NULL == psc) return FALSE;
|
|
|
|
psc->container = pContainer;
|
|
psc->type = controlType;
|
|
psc->originalProc = (WNDPROC)(LONG_PTR)SetWindowLongPtrW(hControl, GWLP_WNDPROC, (LONGX86)(LONG_PTR)SubclassControl_WindowProc);
|
|
|
|
if (NULL == psc->originalProc ||
|
|
FALSE == SetPropW(hControl, WNDPROP_SCCTRLW, psc))
|
|
{
|
|
if (NULL != psc->originalProc)
|
|
SetWindowLongPtrW(hControl, GWLP_WNDPROC, (LONGX86)(LONG_PTR)psc->originalProc);
|
|
free(psc);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
} |