c++ winapi com webbrowser-control mshtml

c++ - Evento DocumentComplete en Embedded IWebBrowser2 utilizando el método write()



winapi webbrowser-control (1)

Gracias a Remy, intenté nuevamente cargar con IPersistStreamInit y ahora parece estar funcionando. Aquí está la nueva pantallaHTMLStr ():

HRESULT STDMETHODCALLTYPE EmbBrowser::displayHTMLStr(LPCTSTR htmlSource) { HRESULT hr; IDispatch *pDispatch = 0; IHTMLDocument2 *pHtmlDoc2 = 0; IPersistStreamInit *pPSI = 0; IStream *pStream = 0; HGLOBAL hHTMLContent; hr = m_webBrowser->get_Document(&pDispatch); if (FAILED(hr) || !pDispatch) { goto displayHTMLStr_clean; } hr = pDispatch->QueryInterface(IID_IHTMLDocument2, (void **) &pHtmlDoc2); if (FAILED(hr) || !pHtmlDoc2) { goto displayHTMLStr_clean; } hr = pHtmlDoc2->QueryInterface(IID_IPersistStreamInit, (void **) &pPSI); if (FAILED(hr) || !pPSI) { goto displayHTMLStr_clean; } // allocate global memory to copy the HTML content to hHTMLContent = ::GlobalAlloc(GPTR, (::_tcslen(htmlSource) + 1) * sizeof(TCHAR)); if (!hHTMLContent) { hr = E_OUTOFMEMORY; goto displayHTMLStr_clean; } ::_tcscpy((TCHAR *) hHTMLContent, htmlSource); // create a stream object based on the HTML content hr = ::CreateStreamOnHGlobal(hHTMLContent, TRUE, &pStream); if (FAILED(hr) || !pStream) { goto displayHTMLStr_clean; } hr = pPSI->InitNew(); if (FAILED(hr)) { goto displayHTMLStr_clean; } // Connect HTMLDocumentEvents2 to get onDocumentComplete and onClick events this->connectEvents(); hr = pPSI->Load(pStream); _tprintf(_T("Written: /n%s/n/n"), htmlSource); displayHTMLStr_clean: if (pStream) { pStream->Release(); } if (hHTMLContent) { GlobalFree(hHTMLContent); } if (pPSI) { pPSI->Release(); } if (pHtmlDoc2) { pHtmlDoc2->Release(); } if (pDispatch) { pDispatch->Release(); } return hr; }

He estado buscando esto pero todavía no he encontrado ninguna solución. Estoy usando win32 c ++ nativo (sin MFC, ATL o .NET)

Estoy cargando un documento html con IHTMLDocument2-> write (). Me gustaría obtener el evento cuando la página esté lista para mostrarse, lo que significa que todas las imágenes y elementos se descargan y se procesan.

Siguiendo el objeto del navegador incorporado desde el control web incorporado (IWebBrowser2), javascript incrustado onkeydown y onkeyup no se activan y desde aquí http://www.codeproject.com/Articles/3365/Embed-an-HTML-control-in-your- own-window-using-pla Me las arreglé para obtener un navegador web integrado que funcione bien y cargar un html bstr.

Modifiqué el control como se muestra a continuación. Ahora puedo obtener los eventos del documento pero nunca obtengo DISPID_DOCUMENTCOMPLETE. La única solución para obtener este evento es cuando en el html hay un iframe con el atributo src:

<html> ... <body> <iframe src="...">...</iframe> </body> </html>

Entonces, la ventana creada por <iframe src="..."> inicia el DISPID_DOCUMENTCOMPLETE cuando el src está listo para mostrarse. (Requiere actualizar el navegador después de escribir el contenido)

Si el <iframe> no tiene "src", el evento se activa pero el contenido del iframe nunca se procesa.

En http://msdn.microsoft.com/en-us/library/aa768282.aspx dice que se disparará un evento documentComplete para cada ventana en el documento, pero como no estoy usando "Navegar" para cargar el contenido html y DocumentComplete nunca se dispara, sospecho que DocumentComplete solo se activa después de "Navegar", no cuando se usa "write ()" ni cuando se usa "write () + close ()" para cargar html.

También traté de anular "su" protocolo de Internet, por lo que al navegar a "its: // ..." logré cargar el documento (idea desde aquí: http://sumatrapdf.googlecode.com/svn/trunk /src/utils/HtmlWindow.cpp ). Luego obtuve DISPID_DOCUMENTCOMPLETE para cada navegación, pero después de 10-12 navegaciones, el programa se bloquea (lanzó el objeto EventSink más veces que las referidas ... raro). Después de varios días de intentos, llegué a la conclusión de que no tenía tanta experiencia para hacer que esto funcionara, y como no era una solución realmente buena, simplemente una solución fea, decidí volver a IHTMLDocument2-> write ().

También intenté adjuntar a DIID_HTMLDocumentEvents2 el get DISPID_HTMLELEMENTEVENTS2_ONREADYSTATECHANGE pero no tuve éxito en absoluto.

Por favor, ¿alguna solución?

EmbBrowser.h:

(EmbBrowserEventSink es una implementación simple de IDIspatch e IBrowserEventListener es una interfaz con métodos onDocumentComplete y onClick)

#pragma once #include <stdio.h> #include <Windows.h> #include <string> #include <Exdisp.h> #include <comdef.h> // for variant_t #include <exception> #include <mshtml.h> // Defines of stuff like IHTMLDocument2. This is an include file with Visual C 6 and above #include "EmbBrowserEventSink.h" //------------------------------------------------------------------------------ class EmbBrowser : public IUnknown, public IOleClientSite, public IOleInPlaceSite, public IStorage{ public: EmbBrowser(HWND _mainWindow, IBrowserEventListener *browserEventListener = NULL); ~EmbBrowser(); HRESULT STDMETHODCALLTYPE setEventListener(IBrowserEventListener *browserEventListener) { this->mBrowserEventListener = browserEventListener; return S_OK; }; HRESULT STDMETHODCALLTYPE hideScrollBars(); HRESULT STDMETHODCALLTYPE displayHTMLStr(LPCTSTR htmlSource); HRESULT STDMETHODCALLTYPE pixelToHiMetric(const RECT& _rc, RECT *_metricRc); virtual HRESULT STDMETHODCALLTYPE setRect(const RECT &_rc); virtual HRESULT STDMETHODCALLTYPE adjustSize(HWND hWnd); virtual HRESULT STDMETHODCALLTYPE navigate(LPCTSTR _url); // ----- IUnknown ----- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void**ppvObject) override; virtual ULONG STDMETHODCALLTYPE AddRef(void) override { return ++m_comRefCount; }; virtual ULONG STDMETHODCALLTYPE Release( void) override { if (!--m_comRefCount) { delete this; } return m_comRefCount; }; // ---------- IOleWindow ---------- virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE GetWindow(/* [out] */ __RPC__deref_out_opt HWND *phwnd) override; virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp( /* [in] */ BOOL fEnterMode) override { return E_NOTIMPL; }; // ---------- IOleInPlaceSite ---------- virtual HRESULT STDMETHODCALLTYPE CanInPlaceActivate(void) override { return S_OK; }; virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivate(void) override; virtual HRESULT STDMETHODCALLTYPE OnUIActivate(void) override { return S_OK; }; virtual HRESULT STDMETHODCALLTYPE GetWindowContext( /* [out] */ __RPC__deref_out_opt IOleInPlaceFrame **ppFrame, /* [out] */ __RPC__deref_out_opt IOleInPlaceUIWindow **ppDoc, /* [out] */ __RPC__out LPRECT lprcPosRect, /* [out] */ __RPC__out LPRECT lprcClipRect, /* [out][in] */ __RPC__inout LPOLEINPLACEFRAMEINFO lpFrameInfo) override; virtual HRESULT STDMETHODCALLTYPE Scroll(/* [in] */ SIZE scrollExtant) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE OnUIDeactivate(/* [in] */ BOOL fUndoable) override { return S_OK; }; virtual HWND STDMETHODCALLTYPE GetControlWindow(); virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate(void) override; virtual HRESULT STDMETHODCALLTYPE DiscardUndoState(void) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE DeactivateAndUndo(void) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE OnPosRectChange(/* [in] */ __RPC__in LPCRECT lprcPosRect) override { return E_NOTIMPL; }; // ---------- IOleClientSite ---------- virtual HRESULT STDMETHODCALLTYPE SaveObject(void) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE GetMoniker( /* [in] */ DWORD dwAssign, /* [in] */ DWORD dwWhichMoniker, /* [out] */ __RPC__deref_out_opt IMoniker **ppmk) override { if((dwAssign == OLEGETMONIKER_ONLYIFTHERE) && (dwWhichMoniker == OLEWHICHMK_CONTAINER)) { return E_FAIL; } return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE GetContainer(/* [out] */ __RPC__deref_out_opt IOleContainer **ppContainer) override { return E_NOINTERFACE; }; virtual HRESULT STDMETHODCALLTYPE ShowObject( void) override { return S_OK; }; virtual HRESULT STDMETHODCALLTYPE OnShowWindow( /* [in] */ BOOL fShow) override { return S_OK; };; virtual HRESULT STDMETHODCALLTYPE RequestNewObjectLayout( void) override { return E_NOTIMPL; }; // ----- IStorage ----- virtual HRESULT STDMETHODCALLTYPE CreateStream( /* [string][in] */ __RPC__in_string const OLECHAR *pwcsName, /* [in] */ DWORD grfMode, /* [in] */ DWORD reserved1, /* [in] */ DWORD reserved2, /* [out] */ __RPC__deref_out_opt IStream **ppstm) override { return E_NOTIMPL; }; virtual /* [local] */ HRESULT STDMETHODCALLTYPE OpenStream( /* [string][in] */ const OLECHAR *pwcsName, /* [unique][in] */ void *reserved1, /* [in] */ DWORD grfMode, /* [in] */ DWORD reserved2, /* [out] */ IStream **ppstm) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE CreateStorage( /* [string][in] */ __RPC__in_string const OLECHAR *pwcsName, /* [in] */ DWORD grfMode, /* [in] */ DWORD reserved1, /* [in] */ DWORD reserved2, /* [out] */ __RPC__deref_out_opt IStorage **ppstg) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE OpenStorage( /* [string][unique][in] */ __RPC__in_opt_string const OLECHAR *pwcsName, /* [unique][in] */ __RPC__in_opt IStorage *pstgPriority, /* [in] */ DWORD grfMode, /* [unique][in] */ __RPC__deref_opt_in_opt SNB snbExclude, /* [in] */ DWORD reserved, /* [out] */ __RPC__deref_out_opt IStorage **ppstg) override { return E_NOTIMPL; }; virtual /* [local] */ HRESULT STDMETHODCALLTYPE CopyTo( /* [in] */ DWORD ciidExclude, /* [size_is][unique][in] */ const IID *rgiidExclude, /* [annotation][unique][in] */ __RPC__in_opt SNB snbExclude, /* [unique][in] */ IStorage *pstgDest) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE MoveElementTo( /* [string][in] */ __RPC__in_string const OLECHAR *pwcsName, /* [unique][in] */ __RPC__in_opt IStorage *pstgDest, /* [string][in] */ __RPC__in_string const OLECHAR *pwcsNewName, /* [in] */ DWORD grfFlags) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE Commit(/* [in] */ DWORD grfCommitFlags) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE Revert(void) override { return E_NOTIMPL; }; virtual /* [local] */ HRESULT STDMETHODCALLTYPE EnumElements( /* [in] */ DWORD reserved1, /* [size_is][unique][in] */ void *reserved2, /* [in] */ DWORD reserved3, /* [out] */ IEnumSTATSTG **ppenum) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE DestroyElement(/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE RenameElement( /* [string][in] */ __RPC__in_string const OLECHAR *pwcsOldName, /* [string][in] */ __RPC__in_string const OLECHAR *pwcsNewName) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE SetElementTimes( /* [string][unique][in] */ __RPC__in_opt_string const OLECHAR *pwcsName, /* [unique][in] */ __RPC__in_opt const FILETIME *pctime, /* [unique][in] */ __RPC__in_opt const FILETIME *patime, /* [unique][in] */ __RPC__in_opt const FILETIME *pmtime) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE SetClass(/* [in] */ __RPC__in REFCLSID clsid) override { return S_OK; }; virtual HRESULT STDMETHODCALLTYPE SetStateBits( /* [in] */ DWORD grfStateBits, /* [in] */ DWORD grfMask) override { return E_NOTIMPL; }; virtual HRESULT STDMETHODCALLTYPE Stat( /* [out] */ __RPC__out STATSTG *pstatstg, /* [in] */ DWORD grfStatFlag) override { return E_NOTIMPL; }; protected: private: IOleObject *m_oleObject; LONG m_comRefCount; HWND m_mainWindow; RECT m_objectRect; IWebBrowser2 *m_webBrowser; IOleInPlaceObject *m_oleInPlaceObject; HWND m_controlWindow; DWORD mAdviseBrowserEventsCookie; IBrowserEventListener *mBrowserEventListener; EmbBrowserEventSink *mEmbBrowserEventSink; HRESULT STDMETHODCALLTYPE connectEvents(); HRESULT STDMETHODCALLTYPE disconnectEvents(); };

EmbBrowser.cpp

#include "StdAfx.h" #include "EmbBrowser.h" EmbBrowser::EmbBrowser(HWND _mainWindow, IBrowserEventListener *browserEventListener) : m_mainWindow(_mainWindow), mBrowserEventListener(browserEventListener), m_comRefCount(0), mEmbBrowserEventSink(NULL), mAdviseBrowserEventsCookie(0) { ::SetRect(&m_objectRect, -300, -300, 300, 300); HRESULT hr = ::OleCreate(CLSID_WebBrowser, IID_IOleObject, OLERENDER_DRAW, 0, this, this, (void**)&m_oleObject); if (FAILED(hr)) { throw new exception("OleCreate() failed"); } hr = m_oleObject->SetClientSite(this); hr = OleSetContainedObject(m_oleObject, TRUE); if (FAILED(m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, this, -1, m_mainWindow, &m_objectRect))) { throw new exception("DoVerb(OLEIVERB_INPLACEACTIVATE) failed"); } hr = m_oleObject->QueryInterface(&m_webBrowser); if (FAILED(hr)) { throw new exception("QueryInterface(IWebBrowser) failed"); } this->navigate(L"about:blank"); } EmbBrowser::~EmbBrowser() { this->m_webBrowser->Release(); this->m_oleObject->Close(OLECLOSE_NOSAVE); this->m_oleObject->Release(); } HRESULT STDMETHODCALLTYPE EmbBrowser::navigate(LPCTSTR _url) { BSTR url; url = SysAllocString(_url); variant_t flags(0x02u); // navNoHistory; HRESULT hr = m_webBrowser->Navigate(url, &flags, NULL, NULL, NULL); SysFreeString(url); return hr; } HRESULT STDMETHODCALLTYPE EmbBrowser::hideScrollBars() { HRESULT hr; IDispatch *pDocDispatch = 0; IHTMLDocument2 *pHtmlDocument = 0; IHTMLElement *pBodyElm = 0; IHTMLBodyElement *pBody = 0; VARIANT v; hr = m_webBrowser->get_Document(&pDocDispatch); if (FAILED(hr) || !pDocDispatch) { goto hideScrollBar_clean; } hr = pDocDispatch->QueryInterface(IID_IHTMLDocument2, (void **) &pHtmlDocument); if (FAILED(hr) && !pHtmlDocument) { goto hideScrollBar_clean; } hr = pHtmlDocument->get_body(&pBodyElm); if (FAILED(hr) && !pBodyElm) { goto hideScrollBar_clean; } hr = pBodyElm->QueryInterface(IID_IHTMLBodyElement, (void **) &pBody); if (FAILED(hr) && !pBody) { goto hideScrollBar_clean; } v.vt = VT_INT; v.intVal = 0; pBody->put_scroll(L"no"); pBody->put_leftMargin(v); pBody->put_topMargin(v); hideScrollBar_clean: if (pBody) { pBody->Release(); } if (pBodyElm) { pBodyElm->Release(); } if (pHtmlDocument) { pHtmlDocument->Release(); } if (pDocDispatch) { pDocDispatch->Release(); } return hr; } HRESULT STDMETHODCALLTYPE EmbBrowser::displayHTMLStr(LPCTSTR htmlSource) { // This is used by DisplayHTMLStr(). It can be global because we never change it. static const SAFEARRAYBOUND ArrayBound = {1, 0}; HRESULT hr; IDispatch *pDispatch = 0; IHTMLDocument2 *pHtmlDoc2 = 0; SAFEARRAY *sfArray = 0; VARIANT *pVar = 0; BSTR bstr = 0; hr = m_webBrowser->get_Document(&pDispatch); if (FAILED(hr) || !pDispatch) { goto displayHTMLStr_clean; } hr = pDispatch->QueryInterface(IID_IHTMLDocument2, (void **) &pHtmlDoc2); if (FAILED(hr) || !pHtmlDoc2) { goto displayHTMLStr_clean; } // Our HTML must be in the form of a BSTR. And it must be passed to write() in an // array of "VARIENT" structs. So let''s create all that. sfArray = SafeArrayCreate(VT_VARIANT, 1, (SAFEARRAYBOUND *) &ArrayBound); if (!sfArray) { goto displayHTMLStr_clean; } hr = SafeArrayAccessData(sfArray, (void**) &pVar); if (FAILED(hr)) { goto displayHTMLStr_clean; } pVar->vt = VT_BSTR; #ifndef UNICODE { wchar_t *buffer; DWORD size; size = MultiByteToWideChar(CP_ACP, 0, htmlSource, -1, 0, 0); if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))) { goto displayHTMLStr_clean; } MultiByteToWideChar(CP_ACP, 0, htmlSource, -1, buffer, size); bstr = SysAllocString(buffer); GlobalFree(buffer); } #else bstr = SysAllocString(htmlSource); #endif if (!bstr) { hr = E_OUTOFMEMORY; goto displayHTMLStr_clean; } // Connect HTMLDocumentEvents2 to get onDocumentComplete and onClick events this->connectEvents(); //mEmbBrowserEventSink->setFinishedWriting(false); hr = pHtmlDoc2->clear(); if (FAILED(hr)) { goto displayHTMLStr_clean; } hr = pHtmlDoc2->write(sfArray); if (FAILED(hr)) { goto displayHTMLStr_clean; } hr = pHtmlDoc2->close(); if (FAILED(hr)) { goto displayHTMLStr_clean; } //mEmbBrowserEventSink->setFinishedWriting(true); //hr = m_webBrowser->Refresh(); //if (FAILED(hr)) { // goto displayHTMLStr_clean; //} //this->mBrowserEventListener->onDocumentComplete(true); displayHTMLStr_clean: // Normally, we''d need to free our BSTR, but SafeArrayDestroy() does it for us // SysFreeString(bstr); if (bstr) { SysFreeString(bstr); } if (sfArray) { // SafeArrayDestroy(sfArray); SafeArrayUnaccessData(sfArray); } if (pHtmlDoc2) { pHtmlDoc2->Release(); } if (pDispatch) { pDispatch->Release(); } return hr; } HRESULT STDMETHODCALLTYPE EmbBrowser::connectEvents() { HRESULT hr; IConnectionPointContainer *pCPC = 0; IConnectionPoint *pCP = 0; IUnknown *pUnkEventSink = 0; this->disconnectEvents(); this->mEmbBrowserEventSink = new EmbBrowserEventSink(m_webBrowser, this->mBrowserEventListener); hr = this->mEmbBrowserEventSink->QueryInterface(IID_IUnknown, (void **) &pUnkEventSink); if (FAILED(hr) || !pUnkEventSink) { goto connectEvents_clean; } hr = /*pHtmlDoc2*/m_webBrowser->QueryInterface(IID_IConnectionPointContainer, (void **) &pCPC); if (FAILED(hr) || !pCPC) { goto connectEvents_clean; } hr = pCPC->FindConnectionPoint(/*DIID_HTMLDocumentEvents2*/ DIID_DWebBrowserEvents2, &pCP); if (FAILED(hr) || !pCP) { goto connectEvents_clean; } hr = pCP->Advise(pUnkEventSink, &mAdviseBrowserEventsCookie); if (FAILED(hr)) { goto connectEvents_clean; } connectEvents_clean: if (pCP) { pCP->Release(); } if (pCPC) { pCPC->Release(); } if (pUnkEventSink) { pUnkEventSink->Release(); } return hr; } HRESULT STDMETHODCALLTYPE EmbBrowser::disconnectEvents() { HRESULT hr; IDispatch *pDispatch = 0; IHTMLDocument2 *pHtmlDoc2 = 0; IConnectionPointContainer *pCPC = 0; IConnectionPoint *pCP = 0; if (!mAdviseHTMLEventsCookie) { hr = S_OK; goto disconnectHtmlEvents_clean; } //hr = m_webBrowser->get_Document(&pDispatch); //if (FAILED(hr) || !pDispatch) { // goto disconnectHtmlEvents_clean; //} //hr = pDispatch->QueryInterface(IID_IHTMLDocument2, (void **) &pHtmlDoc2); //if (FAILED(hr) || !pHtmlDoc2) { // goto disconnectHtmlEvents_clean; //} hr = /*pHtmlDoc2*/this->m_webBrowser->QueryInterface(IID_IConnectionPointContainer, (void **) &pCPC); if (FAILED(hr) || !pCPC) { goto disconnectHtmlEvents_clean; } hr = pCPC->FindConnectionPoint(/*DIID_HTMLDocumentEvents2*/ DIID_DWebBrowserEvents2, &pCP); if (FAILED(hr) || !pCP) { goto disconnectHtmlEvents_clean; } hr = pCP->Unadvise(mAdviseBrowserEventsCookie); if (FAILED(hr)) { goto disconnectHtmlEvents_clean; } mAdviseBrowserEventsCookie= 0; disconnectHtmlEvents_clean: if (pCP) { pCP->Release(); } if (pCPC) { pCPC->Release(); } if (pHtmlDoc2) { pHtmlDoc2->Release(); } if (pDispatch) { pDispatch->Release(); } return hr; } HRESULT STDMETHODCALLTYPE EmbBrowser::pixelToHiMetric(const RECT& _rc, RECT *_metricRc) { static bool s_initialized = false; static int s_pixelsPerInchX, s_pixelsPerInchY; if (!_metricRc) { return E_INVALIDARG; } if (!s_initialized) { HDC hdc = ::GetDC(NULL); s_pixelsPerInchX = ::GetDeviceCaps(hdc, LOGPIXELSX); s_pixelsPerInchY = ::GetDeviceCaps(hdc, LOGPIXELSY); ::ReleaseDC(NULL, hdc); s_initialized = true; } RECT rc; _metricRc->left = MulDiv(2540, _rc.left, s_pixelsPerInchX); _metricRc->top = MulDiv(2540, _rc.top, s_pixelsPerInchY); _metricRc->right = MulDiv(2540, _rc.right, s_pixelsPerInchX); _metricRc->bottom = MulDiv(2540, _rc.bottom, s_pixelsPerInchY); return S_OK; } HRESULT STDMETHODCALLTYPE EmbBrowser::setRect(const RECT &_rc) { HRESULT hr = E_FAIL; m_objectRect = _rc; { RECT hiMetricRect; hr = pixelToHiMetric(m_objectRect, &hiMetricRect); SIZEL sz; sz.cx = hiMetricRect.right - hiMetricRect.left; sz.cy = hiMetricRect.bottom - hiMetricRect.top; m_oleObject->SetExtent(DVASPECT_CONTENT, &sz); } if (m_oleInPlaceObject != NULL) { hr = m_oleInPlaceObject->SetObjectRects(&m_objectRect, &m_objectRect); } return S_OK; } HRESULT STDMETHODCALLTYPE EmbBrowser::adjustSize(HWND hWnd) { RECT rc; GetWindowRect(hWnd, &rc); rc.bottom -= rc.top; rc.top -= rc.top; rc.right -= rc.left; rc.left -= rc.left; return setRect(rc); } // -----== IUnknown ==-----> HRESULT STDMETHODCALLTYPE EmbBrowser::QueryInterface(REFIID riid, void **ppvObject) { if (riid == __uuidof(IUnknown)) { (*ppvObject) = static_cast<IUnknown *> (this); } else if (riid == __uuidof(IOleClientSite)) { (*ppvObject) = static_cast<IOleClientSite *> (this); } else if (riid == __uuidof(IOleInPlaceSite)) { (*ppvObject) = static_cast<IOleInPlaceSite *> (this); } else if(riid == __uuidof(IStorage)) { (*ppvObject) = static_cast<IStorage *> (this); } else if (riid == __uuidof(IOleWindow)) { (*ppvObject) = static_cast<IOleWindow *> (this); } else { (*ppvObject) = 0; return E_NOINTERFACE; } AddRef(); // implicit AddRef() return S_OK; } // ----------== IOleWindow ==----------> HRESULT STDMETHODCALLTYPE EmbBrowser::GetWindow(__RPC__deref_out_opt HWND *phwnd) { (*phwnd) = m_mainWindow; return S_OK; } // ----------== IOleInPlaceSite ==----------> HRESULT STDMETHODCALLTYPE EmbBrowser::OnInPlaceActivate(void) { OleLockRunning(m_oleObject, TRUE, FALSE); m_oleObject->QueryInterface(&m_oleInPlaceObject); m_oleInPlaceObject->SetObjectRects(&m_objectRect, &m_objectRect); return S_OK; } HRESULT STDMETHODCALLTYPE EmbBrowser::GetWindowContext(__RPC__deref_out_opt IOleInPlaceFrame **ppFrame, __RPC__deref_out_opt IOleInPlaceUIWindow **ppDoc, __RPC__out LPRECT lprcPosRect,__RPC__out LPRECT lprcClipRect, __RPC__inout LPOLEINPLACEFRAMEINFO lpFrameInfo) { HWND hwnd = m_mainWindow; (*ppFrame) = NULL; (*ppDoc) = NULL; (*lprcPosRect).left = m_objectRect.left; (*lprcPosRect).top = m_objectRect.top; (*lprcPosRect).right = m_objectRect.right; (*lprcPosRect).bottom = m_objectRect.bottom; *lprcClipRect = *lprcPosRect; lpFrameInfo->fMDIApp = false; lpFrameInfo->hwndFrame = hwnd; lpFrameInfo->haccel = NULL; lpFrameInfo->cAccelEntries = 0; return S_OK; } HWND STDMETHODCALLTYPE EmbBrowser::GetControlWindow() { if(m_controlWindow != NULL) { return m_controlWindow; } if(m_oleInPlaceObject == NULL) { return NULL; } m_oleInPlaceObject->GetWindow(&m_controlWindow); return m_controlWindow; } HRESULT STDMETHODCALLTYPE EmbBrowser::OnInPlaceDeactivate(void) { m_controlWindow = NULL; m_oleInPlaceObject = NULL; return S_OK; }