mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-26 07:04:12 +08:00
1229 lines
26 KiB
C++
1229 lines
26 KiB
C++
// MWebBrowser.cpp --- simple Win32 Web Browser
|
|
// Copyright (C) 2019 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
|
// This file is public domain software.
|
|
|
|
#include "MWebBrowser.hpp"
|
|
|
|
#include <ExDispid.h>
|
|
/*static*/ MWebBrowser *
|
|
MWebBrowser::Create(HWND hwndParent)
|
|
{
|
|
MWebBrowser *pBrowser = new MWebBrowser(hwndParent);
|
|
if (!pBrowser->IsCreated())
|
|
{
|
|
pBrowser->Release();
|
|
pBrowser = NULL;
|
|
}
|
|
return pBrowser;
|
|
}
|
|
void JSObject::bindfunction(const std::wstring &funcname, functiontype function)
|
|
{
|
|
auto curr = DISPID_VALUE + 1 + funcnames.size();
|
|
funcnames[funcname] = curr;
|
|
funcmap[curr] = function;
|
|
}
|
|
HRESULT STDMETHODCALLTYPE JSObject::QueryInterface(REFIID riid, void **ppv)
|
|
{
|
|
*ppv = NULL;
|
|
|
|
if (riid == IID_IUnknown || riid == IID_IDispatch)
|
|
{
|
|
*ppv = static_cast<IDispatch *>(this);
|
|
}
|
|
|
|
if (*ppv != NULL)
|
|
{
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
ULONG STDMETHODCALLTYPE JSObject::AddRef()
|
|
{
|
|
return InterlockedIncrement(&ref);
|
|
}
|
|
|
|
ULONG STDMETHODCALLTYPE JSObject::Release()
|
|
{
|
|
int tmp = InterlockedDecrement(&ref);
|
|
|
|
if (tmp == 0)
|
|
{
|
|
// OutputDebugString("JSObject::Release(): delete this");
|
|
delete this;
|
|
}
|
|
|
|
return tmp;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE JSObject::GetTypeInfoCount(UINT *pctinfo)
|
|
{
|
|
*pctinfo = 0;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE JSObject::GetTypeInfo(UINT iTInfo, LCID lcid,
|
|
ITypeInfo **ppTInfo)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE JSObject::GetIDsOfNames(REFIID riid,
|
|
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
for (UINT i = 0; i < cNames; i++)
|
|
{
|
|
auto iter = funcnames.find(rgszNames[i]);
|
|
if (iter != funcnames.end())
|
|
{
|
|
rgDispId[i] = iter->second;
|
|
}
|
|
else
|
|
{
|
|
rgDispId[i] = DISPID_UNKNOWN;
|
|
hr = DISP_E_UNKNOWNNAME;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// https://github.com/Tobbe/CppIEEmbed
|
|
HRESULT STDMETHODCALLTYPE JSObject::Invoke(DISPID dispIdMember, REFIID riid,
|
|
LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
|
|
EXCEPINFO *pExcepInfo, UINT *puArgErr)
|
|
{
|
|
if (wFlags & DISPATCH_METHOD)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
std::vector<BSTR> args;
|
|
for (size_t i = 0; i < pDispParams->cArgs; ++i)
|
|
{
|
|
BSTR bstrArg = pDispParams->rgvarg[i].bstrVal;
|
|
args.push_back(bstrArg);
|
|
}
|
|
if (funcmap.find(dispIdMember) == funcmap.end())
|
|
return DISP_E_MEMBERNOTFOUND;
|
|
funcmap[dispIdMember](args.data(), args.size());
|
|
return S_OK;
|
|
}
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
MWebBrowser::MWebBrowser(HWND hwndParent) : m_nRefCount(0),
|
|
m_hwndParent(NULL),
|
|
m_hwndCtrl(NULL),
|
|
m_hwndIEServer(NULL),
|
|
m_web_browser2(NULL),
|
|
m_ole_object(NULL),
|
|
m_ole_inplace_object(NULL),
|
|
m_pDocHostUIHandler(NULL),
|
|
m_hr(S_OK),
|
|
m_bAllowInsecure(FALSE),
|
|
m_nZoomPercents(100)
|
|
{
|
|
::SetRectEmpty(&m_rc);
|
|
|
|
m_hr = CreateBrowser(hwndParent);
|
|
|
|
htmlSource = L"";
|
|
IConnectionPointContainer *container = nullptr;
|
|
m_web_browser2->QueryInterface(IID_IConnectionPointContainer, (void **)&container);
|
|
container->FindConnectionPoint(__uuidof(DWebBrowserEvents2), &callback);
|
|
IUnknown *punk = nullptr;
|
|
QueryInterface(IID_IUnknown, (void **)&punk);
|
|
callback->Advise(punk, &eventCookie);
|
|
punk->Release();
|
|
container->Release();
|
|
jsobj = new JSObject();
|
|
jsobj->AddRef();
|
|
}
|
|
|
|
BOOL MWebBrowser::IsCreated() const
|
|
{
|
|
return m_hr == S_OK;
|
|
}
|
|
|
|
MWebBrowser::~MWebBrowser()
|
|
{
|
|
if (m_pDocHostUIHandler)
|
|
{
|
|
m_pDocHostUIHandler->Release();
|
|
m_pDocHostUIHandler = NULL;
|
|
}
|
|
if (m_ole_object)
|
|
{
|
|
m_ole_object->Release();
|
|
m_ole_object = NULL;
|
|
}
|
|
if (m_ole_inplace_object)
|
|
{
|
|
m_ole_inplace_object->Release();
|
|
m_ole_inplace_object = NULL;
|
|
}
|
|
if (m_web_browser2)
|
|
{
|
|
m_web_browser2->Release();
|
|
m_web_browser2 = NULL;
|
|
}
|
|
if (jsobj)
|
|
{
|
|
jsobj->Release();
|
|
delete jsobj;
|
|
jsobj = NULL;
|
|
}
|
|
}
|
|
|
|
IWebBrowser2 *MWebBrowser::GetIWebBrowser2()
|
|
{
|
|
return m_web_browser2;
|
|
}
|
|
|
|
IHTMLDocument2 *MWebBrowser::GetIHTMLDocument2()
|
|
{
|
|
IDispatch *pDisp;
|
|
m_web_browser2->get_Document(&pDisp);
|
|
if (pDisp)
|
|
{
|
|
return static_cast<IHTMLDocument2 *>(pDisp);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
HWND MWebBrowser::GetControlWindow()
|
|
{
|
|
if (::IsWindow(m_hwndCtrl))
|
|
return m_hwndCtrl;
|
|
|
|
if (!m_ole_inplace_object)
|
|
return NULL;
|
|
|
|
m_ole_inplace_object->GetWindow(&m_hwndCtrl);
|
|
return m_hwndCtrl;
|
|
}
|
|
|
|
HWND MWebBrowser::GetIEServerWindow()
|
|
{
|
|
if (::IsWindow(m_hwndIEServer))
|
|
return m_hwndIEServer;
|
|
|
|
HWND hwnd = ::GetWindow(m_hwndParent, GW_CHILD);
|
|
while (hwnd)
|
|
{
|
|
WCHAR szClass[64];
|
|
::GetClassNameW(hwnd, szClass, 64);
|
|
if (lstrcmpiW(szClass, L"Internet Explorer_Server") == 0)
|
|
{
|
|
m_hwndIEServer = hwnd;
|
|
return hwnd;
|
|
}
|
|
hwnd = ::GetWindow(hwnd, GW_CHILD);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
HRESULT MWebBrowser::CreateBrowser(HWND hwndParent)
|
|
{
|
|
m_hwndParent = hwndParent;
|
|
|
|
HRESULT hr;
|
|
hr = ::OleCreate(CLSID_WebBrowser, IID_IOleObject, OLERENDER_DRAW, NULL,
|
|
this, this, (void **)&m_ole_object);
|
|
if (FAILED(hr))
|
|
{
|
|
assert(0);
|
|
return hr;
|
|
}
|
|
|
|
if (m_pDocHostUIHandler)
|
|
{
|
|
m_pDocHostUIHandler->Release();
|
|
m_pDocHostUIHandler = NULL;
|
|
}
|
|
m_ole_object->QueryInterface(&m_pDocHostUIHandler);
|
|
|
|
hr = m_ole_object->SetClientSite(this);
|
|
if (FAILED(hr))
|
|
{
|
|
assert(0);
|
|
return hr;
|
|
}
|
|
|
|
hr = ::OleSetContainedObject(m_ole_object, TRUE);
|
|
if (FAILED(hr))
|
|
{
|
|
assert(0);
|
|
return hr;
|
|
}
|
|
|
|
RECT rc;
|
|
::SetRectEmpty(&rc);
|
|
hr = m_ole_object->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, this, 0,
|
|
m_hwndParent, &rc);
|
|
if (FAILED(hr))
|
|
{
|
|
assert(0);
|
|
return hr;
|
|
}
|
|
|
|
hr = m_ole_object->QueryInterface(&m_web_browser2);
|
|
if (FAILED(hr))
|
|
{
|
|
assert(0);
|
|
return hr;
|
|
}
|
|
|
|
HWND hwnd = GetControlWindow();
|
|
|
|
DWORD exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
|
|
SetWindowLong(hwnd, GWL_EXSTYLE, exstyle | WS_EX_CLIENTEDGE);
|
|
|
|
ShowWindow(hwnd, SW_SHOWNORMAL);
|
|
|
|
Release();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
void MWebBrowser::Destroy()
|
|
{
|
|
if (m_web_browser2)
|
|
m_web_browser2->Quit();
|
|
|
|
m_hwndParent = NULL;
|
|
m_hwndCtrl = NULL;
|
|
m_hwndIEServer = NULL;
|
|
}
|
|
|
|
RECT MWebBrowser::PixelToHIMETRIC(const RECT &rc)
|
|
{
|
|
HDC hDC = ::GetDC(NULL);
|
|
INT nPixelsPerInchX = ::GetDeviceCaps(hDC, LOGPIXELSX);
|
|
INT nPixelsPerInchY = ::GetDeviceCaps(hDC, LOGPIXELSY);
|
|
RECT ret;
|
|
ret.left = MulDiv(rc.left, 2540, nPixelsPerInchX);
|
|
ret.top = MulDiv(rc.top, 2540, nPixelsPerInchY);
|
|
ret.right = MulDiv(rc.right, 2540, nPixelsPerInchX);
|
|
ret.bottom = MulDiv(rc.bottom, 2540, nPixelsPerInchY);
|
|
::ReleaseDC(NULL, hDC);
|
|
return ret;
|
|
}
|
|
|
|
void MWebBrowser::MoveWindow(const RECT &rc)
|
|
{
|
|
m_rc = rc;
|
|
|
|
SIZEL siz;
|
|
RECT rcHIMETRIC = PixelToHIMETRIC(rc);
|
|
siz.cx = rcHIMETRIC.right - rcHIMETRIC.left;
|
|
siz.cy = rcHIMETRIC.bottom - rcHIMETRIC.top;
|
|
m_ole_object->SetExtent(DVASPECT_CONTENT, &siz);
|
|
|
|
if (m_ole_inplace_object)
|
|
{
|
|
m_ole_inplace_object->SetObjectRects(&m_rc, &m_rc);
|
|
}
|
|
}
|
|
|
|
void MWebBrowser::GoHome()
|
|
{
|
|
if (m_web_browser2)
|
|
m_web_browser2->GoHome();
|
|
}
|
|
|
|
void MWebBrowser::GoBack()
|
|
{
|
|
if (m_web_browser2)
|
|
m_web_browser2->GoBack();
|
|
}
|
|
|
|
void MWebBrowser::GoForward()
|
|
{
|
|
if (m_web_browser2)
|
|
m_web_browser2->GoForward();
|
|
}
|
|
|
|
void MWebBrowser::Stop()
|
|
{
|
|
if (m_web_browser2)
|
|
m_web_browser2->Stop();
|
|
}
|
|
|
|
void MWebBrowser::StopDownload()
|
|
{
|
|
if (!m_web_browser2)
|
|
return;
|
|
|
|
IDispatch *pDisp;
|
|
m_web_browser2->get_Document(&pDisp);
|
|
if (pDisp)
|
|
{
|
|
IOleCommandTarget *pCmdTarget = NULL;
|
|
pDisp->QueryInterface(&pCmdTarget);
|
|
if (pCmdTarget)
|
|
{
|
|
OLECMDEXECOPT option = OLECMDEXECOPT_DONTPROMPTUSER;
|
|
pCmdTarget->Exec(NULL, OLECMDID_STOPDOWNLOAD, option, NULL, NULL);
|
|
pCmdTarget->Release();
|
|
}
|
|
pDisp->Release();
|
|
}
|
|
}
|
|
|
|
void MWebBrowser::Refresh()
|
|
{
|
|
if (m_web_browser2)
|
|
m_web_browser2->Refresh();
|
|
}
|
|
|
|
HRESULT MWebBrowser::Navigate(const WCHAR *url)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
if (m_web_browser2)
|
|
{
|
|
bstr_t bstrURL(url);
|
|
variant_t flags(0);
|
|
hr = m_web_browser2->Navigate(bstrURL, &flags, 0, 0, 0);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT MWebBrowser::Navigate2(const WCHAR *url, DWORD dwFlags)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
if (!m_web_browser2)
|
|
{
|
|
return hr;
|
|
}
|
|
VARIANT var1, var2, varEmpty;
|
|
|
|
VariantInit(&var1);
|
|
VariantInit(&var2);
|
|
VariantInit(&varEmpty);
|
|
|
|
V_VT(&var1) = VT_BSTR;
|
|
V_BSTR(&var1) = SysAllocString(url);
|
|
|
|
V_VT(&var2) = VT_I4;
|
|
V_I4(&var2) = dwFlags;
|
|
|
|
V_VT(&varEmpty) = VT_EMPTY;
|
|
|
|
hr = m_web_browser2->Navigate2(&var1, &var2, &varEmpty, &varEmpty, &varEmpty);
|
|
|
|
VariantClear(&var1);
|
|
VariantClear(&var2);
|
|
VariantClear(&varEmpty);
|
|
|
|
return hr;
|
|
}
|
|
|
|
void MWebBrowser::Print(BOOL bBang)
|
|
{
|
|
if (!m_web_browser2)
|
|
return;
|
|
|
|
IDispatch *pDisp;
|
|
m_web_browser2->get_Document(&pDisp);
|
|
if (pDisp)
|
|
{
|
|
IOleCommandTarget *pCmdTarget = NULL;
|
|
pDisp->QueryInterface(&pCmdTarget);
|
|
if (pCmdTarget)
|
|
{
|
|
OLECMDEXECOPT option;
|
|
if (bBang)
|
|
option = OLECMDEXECOPT_DONTPROMPTUSER;
|
|
else
|
|
option = OLECMDEXECOPT_PROMPTUSER;
|
|
pCmdTarget->Exec(NULL, OLECMDID_PRINT, option, NULL, NULL);
|
|
pCmdTarget->Release();
|
|
}
|
|
pDisp->Release();
|
|
}
|
|
}
|
|
|
|
void MWebBrowser::PrintPreview()
|
|
{
|
|
if (!m_web_browser2)
|
|
return;
|
|
|
|
IDispatch *pDisp;
|
|
m_web_browser2->get_Document(&pDisp);
|
|
if (pDisp)
|
|
{
|
|
IOleCommandTarget *pCmdTarget = NULL;
|
|
pDisp->QueryInterface(&pCmdTarget);
|
|
if (pCmdTarget)
|
|
{
|
|
OLECMDEXECOPT option = OLECMDEXECOPT_DONTPROMPTUSER;
|
|
pCmdTarget->Exec(NULL, OLECMDID_PRINTPREVIEW, option, NULL, NULL);
|
|
pCmdTarget->Release();
|
|
}
|
|
pDisp->Release();
|
|
}
|
|
}
|
|
|
|
void MWebBrowser::PageSetup()
|
|
{
|
|
if (!m_web_browser2)
|
|
return;
|
|
|
|
IDispatch *pDisp;
|
|
m_web_browser2->get_Document(&pDisp);
|
|
if (pDisp)
|
|
{
|
|
IOleCommandTarget *pCmdTarget = NULL;
|
|
pDisp->QueryInterface(&pCmdTarget);
|
|
if (pCmdTarget)
|
|
{
|
|
OLECMDEXECOPT option = OLECMDEXECOPT_DONTPROMPTUSER;
|
|
pCmdTarget->Exec(NULL, OLECMDID_PAGESETUP, option, NULL, NULL);
|
|
pCmdTarget->Release();
|
|
}
|
|
pDisp->Release();
|
|
}
|
|
}
|
|
|
|
BOOL MWebBrowser::TranslateAccelerator(LPMSG pMsg)
|
|
{
|
|
if (!m_web_browser2)
|
|
return FALSE;
|
|
|
|
IOleInPlaceActiveObject *pOIPAO = NULL;
|
|
HRESULT hr = m_web_browser2->QueryInterface(&pOIPAO);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pOIPAO->TranslateAccelerator(pMsg);
|
|
pOIPAO->Release();
|
|
return hr == S_OK;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
HRESULT MWebBrowser::get_LocationURL(BSTR *bstrURL) const
|
|
{
|
|
if (!m_web_browser2)
|
|
{
|
|
*bstrURL = NULL;
|
|
return E_FAIL;
|
|
}
|
|
|
|
return m_web_browser2->get_LocationURL(bstrURL);
|
|
}
|
|
|
|
HRESULT MWebBrowser::get_mimeType(BSTR *bstrMIME) const
|
|
{
|
|
if (!m_web_browser2)
|
|
{
|
|
*bstrMIME = NULL;
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT hr = E_FAIL;
|
|
IDispatch *pDisp;
|
|
m_web_browser2->get_Document(&pDisp);
|
|
if (pDisp)
|
|
{
|
|
IHTMLDocument2 *pDocument = static_cast<IHTMLDocument2 *>(pDisp);
|
|
hr = pDocument->get_mimeType(bstrMIME);
|
|
pDisp->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
BOOL MWebBrowser::is_busy() const
|
|
{
|
|
if (!m_web_browser2)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
VARIANT_BOOL b = FALSE;
|
|
m_web_browser2->get_Busy(&b);
|
|
return b;
|
|
}
|
|
|
|
HRESULT MWebBrowser::get_Application(IDispatch **ppApplication) const
|
|
{
|
|
*ppApplication = NULL;
|
|
if (!m_web_browser2)
|
|
return E_NOINTERFACE;
|
|
|
|
return m_web_browser2->get_Application(ppApplication);
|
|
}
|
|
|
|
void MWebBrowser::AllowInsecure(BOOL bAllow)
|
|
{
|
|
m_bAllowInsecure = bAllow;
|
|
}
|
|
|
|
HRESULT MWebBrowser::put_Silent(VARIANT_BOOL bSilent)
|
|
{
|
|
if (!m_web_browser2)
|
|
return E_NOINTERFACE;
|
|
return m_web_browser2->put_Silent(bSilent);
|
|
}
|
|
|
|
HRESULT MWebBrowser::ZoomUp()
|
|
{
|
|
LONG percents = m_nZoomPercents;
|
|
if (percents >= 300)
|
|
return E_FAIL;
|
|
|
|
if (percents < 100)
|
|
{
|
|
percents += 10;
|
|
}
|
|
else
|
|
{
|
|
percents += 50;
|
|
}
|
|
|
|
return ZoomPercents(percents);
|
|
}
|
|
|
|
HRESULT MWebBrowser::ZoomDown()
|
|
{
|
|
LONG percents = m_nZoomPercents;
|
|
if (percents <= 50)
|
|
return E_FAIL;
|
|
|
|
if (percents > 100)
|
|
{
|
|
percents -= 50;
|
|
}
|
|
else
|
|
{
|
|
percents -= 10;
|
|
}
|
|
|
|
return ZoomPercents(percents);
|
|
}
|
|
|
|
HRESULT MWebBrowser::Zoom100()
|
|
{
|
|
return ZoomPercents(100);
|
|
}
|
|
|
|
HRESULT MWebBrowser::ZoomPercents(LONG percents)
|
|
{
|
|
VARIANT zoom;
|
|
VariantInit(&zoom);
|
|
V_VT(&zoom) = VT_I4;
|
|
V_I4(&zoom) = percents;
|
|
|
|
OLECMDEXECOPT option = OLECMDEXECOPT_DONTPROMPTUSER;
|
|
HRESULT hr = m_web_browser2->ExecWB(OLECMDID_OPTICAL_ZOOM, option, &zoom, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
m_nZoomPercents = percents;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// IUnknown interface
|
|
|
|
STDMETHODIMP MWebBrowser::QueryInterface(REFIID riid, void **ppvObj)
|
|
{
|
|
if (riid == __uuidof(IUnknown))
|
|
{
|
|
*ppvObj = static_cast<IOleClientSite *>(this);
|
|
}
|
|
else if (riid == __uuidof(IOleInPlaceSite))
|
|
{
|
|
*ppvObj = static_cast<IOleInPlaceSite *>(this);
|
|
}
|
|
else if (riid == __uuidof(IServiceProvider))
|
|
{
|
|
*ppvObj = static_cast<IServiceProvider *>(this);
|
|
}
|
|
else if (riid == __uuidof(IDocHostUIHandler))
|
|
{
|
|
*ppvObj = static_cast<IDocHostUIHandler *>(this);
|
|
}
|
|
else if (riid == __uuidof(IDispatch))
|
|
*ppvObj = static_cast<IDispatch *>(this);
|
|
else if (riid == __uuidof(IOleClientSite))
|
|
*ppvObj = static_cast<IOleClientSite *>(this);
|
|
else
|
|
{
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
MWebBrowser::AddRef()
|
|
{
|
|
m_nRefCount++;
|
|
return m_nRefCount;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
MWebBrowser::Release()
|
|
{
|
|
--m_nRefCount;
|
|
if (m_nRefCount != 0)
|
|
return m_nRefCount;
|
|
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
// IOleWindow interface
|
|
|
|
STDMETHODIMP MWebBrowser::GetWindow(HWND *phwnd)
|
|
{
|
|
*phwnd = m_hwndParent;
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::ContextSensitiveHelp(BOOL fEnterMode)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
// IOleInPlaceSite interface
|
|
|
|
STDMETHODIMP MWebBrowser::CanInPlaceActivate()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::OnInPlaceActivate()
|
|
{
|
|
::OleLockRunning(m_ole_object, TRUE, FALSE);
|
|
m_ole_object->QueryInterface(&m_ole_inplace_object);
|
|
m_ole_inplace_object->SetObjectRects(&m_rc, &m_rc);
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::OnUIActivate()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::GetWindowContext(
|
|
IOleInPlaceFrame **ppFrame,
|
|
IOleInPlaceUIWindow **ppDoc,
|
|
LPRECT lprcPosRect,
|
|
LPRECT lprcClipRect,
|
|
LPOLEINPLACEFRAMEINFO lpFrameInfo)
|
|
{
|
|
*ppFrame = NULL;
|
|
*ppDoc = NULL;
|
|
*lprcPosRect = m_rc;
|
|
*lprcClipRect = *lprcPosRect;
|
|
|
|
lpFrameInfo->fMDIApp = FALSE;
|
|
lpFrameInfo->hwndFrame = m_hwndParent;
|
|
lpFrameInfo->haccel = NULL;
|
|
lpFrameInfo->cAccelEntries = 0;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::Scroll(SIZE scrollExtant)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::OnUIDeactivate(BOOL fUndoable)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::OnInPlaceDeactivate()
|
|
{
|
|
m_hwndCtrl = NULL;
|
|
m_ole_inplace_object = NULL;
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::DiscardUndoState()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::DeactivateAndUndo()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::OnPosRectChange(LPCRECT lprcPosRect)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
// IOleClientSite interface
|
|
|
|
STDMETHODIMP MWebBrowser::SaveObject()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::GetMoniker(
|
|
DWORD dwAssign,
|
|
DWORD dwWhichMoniker,
|
|
IMoniker **ppmk)
|
|
{
|
|
if (dwAssign == OLEGETMONIKER_ONLYIFTHERE &&
|
|
dwWhichMoniker == OLEWHICHMK_CONTAINER)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::GetContainer(IOleContainer **ppContainer)
|
|
{
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::ShowObject()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::OnShowWindow(BOOL fShow)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::RequestNewObjectLayout()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
// IStorage interface
|
|
|
|
STDMETHODIMP MWebBrowser::CreateStream(
|
|
const OLECHAR *pwcsName,
|
|
DWORD grfMode,
|
|
DWORD reserved1,
|
|
DWORD reserved2,
|
|
IStream **ppstm)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::OpenStream(
|
|
const OLECHAR *pwcsName,
|
|
void *reserved1,
|
|
DWORD grfMode,
|
|
DWORD reserved2,
|
|
IStream **ppstm)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::CreateStorage(
|
|
const OLECHAR *pwcsName,
|
|
DWORD grfMode,
|
|
DWORD reserved1,
|
|
DWORD reserved2,
|
|
IStorage **ppstg)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::OpenStorage(
|
|
const OLECHAR *pwcsName,
|
|
IStorage *pstgPriority,
|
|
DWORD grfMode,
|
|
SNB snbExclude,
|
|
DWORD reserved,
|
|
IStorage **ppstg)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::CopyTo(
|
|
DWORD ciidExclude,
|
|
const IID *rgiidExclude,
|
|
SNB snbExclude,
|
|
IStorage *pstgDest)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::MoveElementTo(
|
|
const OLECHAR *pwcsName,
|
|
IStorage *pstgDest,
|
|
const OLECHAR *pwcsNewName,
|
|
DWORD grfFlags)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::Commit(DWORD grfCommitFlags)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::Revert()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::EnumElements(
|
|
DWORD reserved1,
|
|
void *reserved2,
|
|
DWORD reserved3,
|
|
IEnumSTATSTG **ppenum)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::DestroyElement(
|
|
const OLECHAR *pwcsName)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::RenameElement(
|
|
const OLECHAR *pwcsOldName,
|
|
const OLECHAR *pwcsNewName)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::SetElementTimes(
|
|
const OLECHAR *pwcsName,
|
|
const FILETIME *pctime,
|
|
const FILETIME *patime,
|
|
const FILETIME *pmtime)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::SetClass(REFCLSID clsid)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::SetStateBits(DWORD grfStateBits, DWORD grfMask)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
// IServiceProvider interface
|
|
|
|
STDMETHODIMP MWebBrowser::QueryService(
|
|
REFGUID guidService,
|
|
REFIID riid,
|
|
void **ppvObject)
|
|
{
|
|
*ppvObject = NULL;
|
|
|
|
if (riid == __uuidof(IWindowForBindingUI) ||
|
|
riid == __uuidof(IHttpSecurity))
|
|
{
|
|
*ppvObject = static_cast<IHttpSecurity *>(this);
|
|
}
|
|
else
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
// IWindowForBindingUI interface
|
|
|
|
STDMETHODIMP MWebBrowser::GetWindow(REFGUID rguidReason, HWND *phwnd)
|
|
{
|
|
*phwnd = m_hwndParent;
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::OnSecurityProblem(DWORD dwProblem)
|
|
{
|
|
printf("MWebBrowser::OnSecurityProblem\n");
|
|
|
|
BSTR url = NULL;
|
|
get_LocationURL(&url);
|
|
if (url)
|
|
{
|
|
SysFreeString(url);
|
|
}
|
|
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
return E_ABORT;
|
|
}
|
|
|
|
// IDocHostUIHandler interface
|
|
|
|
STDMETHODIMP MWebBrowser::ShowContextMenu(
|
|
DWORD dwID,
|
|
POINT *ppt,
|
|
IUnknown *pcmdtReserved,
|
|
IDispatch *pdispReserved)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::GetHostInfo(DOCHOSTUIINFO *pInfo)
|
|
{
|
|
if (m_pDocHostUIHandler)
|
|
return m_pDocHostUIHandler->GetHostInfo(pInfo);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::ShowUI(
|
|
DWORD dwID,
|
|
IOleInPlaceActiveObject *pActiveObject,
|
|
IOleCommandTarget *pCommandTarget,
|
|
IOleInPlaceFrame *pFrame,
|
|
IOleInPlaceUIWindow *pDoc)
|
|
{
|
|
if (m_pDocHostUIHandler)
|
|
return m_pDocHostUIHandler->ShowUI(dwID, pActiveObject, pCommandTarget, pFrame, pDoc);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::HideUI()
|
|
{
|
|
if (m_pDocHostUIHandler)
|
|
return m_pDocHostUIHandler->HideUI();
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::UpdateUI()
|
|
{
|
|
if (m_pDocHostUIHandler)
|
|
return m_pDocHostUIHandler->UpdateUI();
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::EnableModeless(BOOL fEnable)
|
|
{
|
|
if (m_pDocHostUIHandler)
|
|
return m_pDocHostUIHandler->EnableModeless(fEnable);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::OnDocWindowActivate(BOOL fActivate)
|
|
{
|
|
if (m_pDocHostUIHandler)
|
|
return m_pDocHostUIHandler->OnDocWindowActivate(fActivate);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::OnFrameWindowActivate(BOOL fActivate)
|
|
{
|
|
if (m_pDocHostUIHandler)
|
|
return m_pDocHostUIHandler->OnFrameWindowActivate(fActivate);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::ResizeBorder(
|
|
LPCRECT prcBorder,
|
|
IOleInPlaceUIWindow *pUIWindow,
|
|
BOOL fRameWindow)
|
|
{
|
|
if (m_pDocHostUIHandler)
|
|
return m_pDocHostUIHandler->ResizeBorder(prcBorder, pUIWindow, fRameWindow);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::TranslateAccelerator(
|
|
LPMSG lpMsg,
|
|
const GUID *pguidCmdGroup,
|
|
DWORD nCmdID)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::GetOptionKeyPath(LPOLESTR *pchKey, DWORD dw)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::GetDropTarget(
|
|
IDropTarget *pDropTarget,
|
|
IDropTarget **ppDropTarget)
|
|
{
|
|
*ppDropTarget = NULL;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::GetExternal(IDispatch **ppDispatch)
|
|
{
|
|
*ppDispatch = NULL;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::TranslateUrl(
|
|
DWORD dwTranslate,
|
|
OLECHAR *pchURLIn,
|
|
OLECHAR **ppchURLOut)
|
|
{
|
|
*ppchURLOut = NULL;
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP MWebBrowser::FilterDataObject(IDataObject *pDO, IDataObject **ppDORet)
|
|
{
|
|
*ppDORet = NULL;
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT MWebBrowser::Quit()
|
|
{
|
|
if (!m_web_browser2)
|
|
return E_NOINTERFACE;
|
|
|
|
return m_web_browser2->Quit();
|
|
}
|
|
HRESULT MWebBrowser::GetTypeInfoCount(UINT *pctinfo) { return E_FAIL; }
|
|
HRESULT MWebBrowser::GetTypeInfo(UINT, LCID, ITypeInfo **) { return E_FAIL; }
|
|
HRESULT MWebBrowser::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { return E_FAIL; }
|
|
|
|
void AddCustomObject(IHTMLDocument2 *doc, IDispatch *custObj, std::string name)
|
|
{
|
|
|
|
if (doc == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
IHTMLWindow2 *win = NULL;
|
|
doc->get_parentWindow(&win);
|
|
doc->Release();
|
|
|
|
if (win == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
IDispatchEx *winEx;
|
|
win->QueryInterface(&winEx);
|
|
win->Release();
|
|
|
|
if (winEx == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int lenW = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name.c_str(), -1, NULL, 0);
|
|
BSTR objName = SysAllocStringLen(0, lenW);
|
|
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name.c_str(), -1, objName, lenW);
|
|
|
|
DISPID dispid;
|
|
HRESULT hr = winEx->GetDispID(objName, fdexNameEnsure, &dispid);
|
|
|
|
SysFreeString(objName);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return;
|
|
}
|
|
|
|
DISPID namedArgs[] = {DISPID_PROPERTYPUT};
|
|
DISPPARAMS params;
|
|
params.rgvarg = new VARIANT[1];
|
|
params.rgvarg[0].pdispVal = custObj;
|
|
params.rgvarg[0].vt = VT_DISPATCH;
|
|
params.rgdispidNamedArgs = namedArgs;
|
|
params.cArgs = 1;
|
|
params.cNamedArgs = 1;
|
|
|
|
hr = winEx->InvokeEx(dispid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, NULL);
|
|
winEx->Release();
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
HRESULT MWebBrowser::Invoke(DISPID dispIdMember, REFIID, LCID, WORD,
|
|
DISPPARAMS *pDispParams, VARIANT *pVarResult,
|
|
EXCEPINFO *, UINT *)
|
|
{
|
|
if (dispIdMember == DISPID_DOCUMENTCOMPLETE)
|
|
return OnCompleted(pDispParams);
|
|
else if (dispIdMember == DISPID_NAVIGATECOMPLETE2)
|
|
return AddCustomObject(GetIHTMLDocument2(), jsobj, "LUNAJSObject"), S_OK;
|
|
else
|
|
return S_OK;
|
|
}
|
|
HRESULT MWebBrowser::OnCompleted(DISPPARAMS *args)
|
|
{
|
|
HRESULT hr;
|
|
|
|
IDispatch *pDispatch = 0;
|
|
IHTMLDocument2 *pHtmlDoc2 = 0;
|
|
IPersistStreamInit *pPSI = 0;
|
|
IStream *pStream = 0;
|
|
HGLOBAL hHTMLContent;
|
|
|
|
if (htmlSource.empty())
|
|
return S_OK;
|
|
hr = m_web_browser2->get_Document(&pDispatch);
|
|
if (SUCCEEDED(hr) && pDispatch)
|
|
hr = pDispatch->QueryInterface(IID_IHTMLDocument2, (void **)&pHtmlDoc2);
|
|
if (SUCCEEDED(hr) && pHtmlDoc2)
|
|
hr = pHtmlDoc2->QueryInterface(IID_IPersistStreamInit, (void **)&pPSI);
|
|
|
|
// allocate global memory to copy the HTML content to
|
|
hHTMLContent = ::GlobalAlloc(GMEM_MOVEABLE, (htmlSource.size() + 1) * sizeof(TCHAR));
|
|
if (hHTMLContent)
|
|
{
|
|
wchar_t *p_content(static_cast<wchar_t *>(GlobalLock(hHTMLContent)));
|
|
::wcscpy(p_content, htmlSource.c_str());
|
|
GlobalUnlock(hHTMLContent);
|
|
|
|
// create a stream object based on the HTML content
|
|
if (SUCCEEDED(hr) && pPSI)
|
|
hr = ::CreateStreamOnHGlobal(hHTMLContent, TRUE, &pStream);
|
|
|
|
if (SUCCEEDED(hr) && pStream)
|
|
hr = pPSI->InitNew();
|
|
if (SUCCEEDED(hr))
|
|
hr = pPSI->Load(pStream);
|
|
}
|
|
if (pStream)
|
|
pStream->Release();
|
|
if (pPSI)
|
|
pPSI->Release();
|
|
if (pHtmlDoc2)
|
|
pHtmlDoc2->Release();
|
|
if (pDispatch)
|
|
pDispatch->Release();
|
|
htmlSource = L"";
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT MWebBrowser::SetHtml(const wchar_t *html)
|
|
{
|
|
htmlSource = html;
|
|
Navigate(L"about:blank");
|
|
return S_OK;
|
|
}
|