嵌入式 Web 控件(IWebBrowser2),嵌入式 javascript 的 onkeydown 和 onkeyup 未触发
我正在我的 C++ 程序中嵌入一个网页。我遇到的问题是,在嵌入页面的 javascript 中,我可以捕获 onkeypress,但 onkeydown 和 onkeyup 不会触发。
如果我在非嵌入式 IE(或 Chrome)窗口中查看测试 HTML,那么它可以正常工作。只有在将其嵌入 IE 控件中使用时才会出现问题。
如果我挂钩 IE 窗口的 WndProc(或使用 Spy++),WM_KEYDOWN、WM_CHAR 和 WM_KEYUP 消息肯定会到达该窗口。
我试图使示例代码尽可能少 - 删除了很多错误检查、清理等。
在准备 IE 控件时是否缺少一些设置?或者这就是使用嵌入式 IE 时的情况?我认为如果缺少设置我将不会得到任何输入。
这是 HTML 测试文件:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script type="text/javascript" language="javascript">
var n = 0;
document.onkeydown = function()
{
var output=document.getElementById("output");
output.innerHTML = n++ + " onkeydown<br>" + output.innerHTML;
return true;
};
document.onkeypress = function()
{
var output=document.getElementById("output");
output.innerHTML = n++ + " onkeypress<br>" + output.innerHTML;
return true;
};
document.onkeyup = function()
{
var output=document.getElementById("output");
output.innerHTML = n++ + " onkeyup<br>" + output.innerHTML;
return true;
};
</script>
</head>
<body>
This is some testing text.
<input/>
<br>
<div id="output" style="border-style:solid; border-width:1; "></div>
</body>
</html>
以及嵌入该文件的 C++ 代码:
#include <stdio.h>
#include <Windows.h>
#include <string>
#include <atlbase.h> // for CComPtr<>
#include <Exdisp.h>
#include <comdef.h> // for variant_t
namespace
{
const int MAIN_WINDOW_WIDTH = 800;
const int MAIN_WINDOW_HEIGHT = 600;
const int HTML_WINDOW_WIDTH = 640;
const int HTML_WINDOW_HEIGHT = 480;
}
//------------------------------------------------------------------------------
void FatalError(std::string _report)
{
::MessageBox(nullptr, _report.c_str(), "Error", MB_OK);
::ExitProcess(1);
}
//------------------------------------------------------------------------------
class EmbeddedBrowser :
public IOleClientSite,
public IOleInPlaceSite,
public IStorage
{
public:
EmbeddedBrowser(HWND _mainWindow)
{
m_comRefCount = 0;
::SetRect(&m_objectRect, -300, -300, 300, 300);
m_mainWindow = _mainWindow;
CreateBrowserObject();
::ShowWindow(GetControlWindow(), SW_SHOW);
variant_t flags((UINT)0);
m_webBrowser->Navigate(L"about:blank",
&flags, nullptr, nullptr, nullptr);
}
void CreateBrowserObject()
{
HRESULT hr = ::OleCreate(CLSID_WebBrowser,
IID_IOleObject, OLERENDER_DRAW, 0, this, this, (void**)&m_oleObject);
if(FAILED(hr))
FatalError("OleCreate() failed");
hr = m_oleObject->SetClientSite(this);
hr = OleSetContainedObject(m_oleObject, TRUE);
RECT posRect;
::SetRect(&posRect, -300, -300, 300, 300);
hr = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE,
NULL, this, -1, m_mainWindow, &posRect);
if(FAILED(hr))
FatalError("DoVerb(OLEIVERB_INPLACEACTIVATE) failed");
hr = m_oleObject.QueryInterface(&m_webBrowser);
if(FAILED(hr))
FatalError("QueryInterface(IWebBrowser) failed");
}
virtual void Navigate(std::wstring _url)
{
bstr_t url(_url.c_str());
variant_t flags(0x02u); // navNoHistory;
HRESULT hr = m_webBrowser->Navigate(url,
&flags, nullptr, nullptr, nullptr);
}
RECT PixelToHiMetric(const RECT& _rc)
{
static bool s_initialized = false;
static int s_pixelsPerInchX, s_pixelsPerInchY;
if(!s_initialized)
{
HDC hdc = ::GetDC(nullptr);
s_pixelsPerInchX = ::GetDeviceCaps(hdc, LOGPIXELSX);
s_pixelsPerInchY = ::GetDeviceCaps(hdc, LOGPIXELSY);
::ReleaseDC(nullptr, hdc);
s_initialized = true;
}
RECT rc;
rc.left = MulDiv(2540, _rc.left, s_pixelsPerInchX);
rc.top = MulDiv(2540, _rc.top, s_pixelsPerInchY);
rc.right = MulDiv(2540, _rc.right, s_pixelsPerInchX);
rc.bottom = MulDiv(2540, _rc.bottom, s_pixelsPerInchY);
return rc;
}
virtual void SetRect(const RECT& _rc)
{
m_objectRect = _rc;
{
RECT hiMetricRect = PixelToHiMetric(m_objectRect);
SIZEL sz;
sz.cx = hiMetricRect.right - hiMetricRect.left;
sz.cy = hiMetricRect.bottom - hiMetricRect.top;
m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
}
if(m_oleInPlaceObject != nullptr)
{
m_oleInPlaceObject->SetObjectRects(&m_objectRect, &m_objectRect);
}
}
// ----- IUnknown -----
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void**ppvObject) override
{
if(riid == __uuidof(IUnknown))
{ (*ppvObject) = static_cast<IOleClientSite*>(this); }
else if(riid == __uuidof(IOleInPlaceSite))
{ (*ppvObject) = static_cast<IOleInPlaceSite*>(this); }
else
{
return E_NOINTERFACE;
}
AddRef(); // implicit AddRef()
return S_OK;
}
virtual ULONG STDMETHODCALLTYPE AddRef( void) override
{
m_comRefCount++;
return m_comRefCount;
}
virtual ULONG STDMETHODCALLTYPE Release( void) override
{
m_comRefCount--;
return m_comRefCount;
}
// ---------- IOleWindow ----------
virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE GetWindow(
/* [out] */ __RPC__deref_out_opt HWND *phwnd) override
{
(*phwnd) = m_mainWindow;
return S_OK;
}
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
{
OleLockRunning(m_oleObject, TRUE, FALSE);
m_oleObject.QueryInterface(&m_oleInPlaceObject);
m_oleInPlaceObject->SetObjectRects(&m_objectRect, &m_objectRect);
return S_OK;
}
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
{
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;
}
virtual HRESULT STDMETHODCALLTYPE Scroll(
/* [in] */ SIZE scrollExtant) override
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnUIDeactivate(
/* [in] */ BOOL fUndoable) override
{
return S_OK;
}
virtual HWND GetControlWindow()
{
if(m_controlWindow != nullptr)
return m_controlWindow;
if(m_oleInPlaceObject == nullptr)
return nullptr;
m_oleInPlaceObject->GetWindow(&m_controlWindow);
return m_controlWindow;
}
virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate( void) override
{
m_controlWindow = nullptr;
m_oleInPlaceObject = nullptr;
return S_OK;
}
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;
//return E_NOTIMPL;
}
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;
}
private:
protected:
CComPtr<IOleObject> m_oleObject;
LONG m_comRefCount;
HWND m_mainWindow;
RECT m_objectRect;
CComPtr<IWebBrowser2> m_webBrowser;
CComPtr<IOleInPlaceObject> m_oleInPlaceObject;
HWND m_controlWindow;
};
//------------------------------------------------------------------------------
void EventLoop(HWND _mainWindow)
{
while(IsWindow(_mainWindow))
{
MSG msg;
if(GetMessage(&msg, nullptr, 0, 0) <= 0)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
int main(int argc, char* argv[])
{
OleInitialize(nullptr);
WNDCLASS wc;
memset(&wc, 0, sizeof(wc));
wc.lpszClassName = "MyWindowClass";
wc.lpfnWndProc = DefWindowProc;
wc.hCursor = ::LoadCursor(nullptr, IDC_ARROW);
RegisterClass(&wc);
HWND mainWindow = CreateWindow("MyWindowClass",
"My Window", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT,
CW_USEDEFAULT, MAIN_WINDOW_WIDTH, MAIN_WINDOW_HEIGHT, nullptr,
nullptr, nullptr, nullptr);
RECT rc;
rc.left = (MAIN_WINDOW_WIDTH - HTML_WINDOW_WIDTH) / 2;
rc.top = (MAIN_WINDOW_HEIGHT - HTML_WINDOW_HEIGHT) / 2;
rc.right = rc.left + HTML_WINDOW_WIDTH;
rc.bottom = rc.top + HTML_WINDOW_HEIGHT;
wchar_t navUrl[MAX_PATH];
::GetCurrentDirectoryW(MAX_PATH, navUrl);
wcscat_s(navUrl, L"\\test.html");
EmbeddedBrowser* browser = new EmbeddedBrowser(mainWindow);
browser->SetRect(rc);
browser->Navigate(navUrl);
EventLoop(mainWindow);
ExitProcess(0);
return 0;
}
I'm embedding a web page within my C++ program. The problem that I'm running into is that within javascript of the embedded page I can capture onkeypress, but onkeydown and onkeyup don't fire.
If I view the test HTML in a non-embedded IE (or Chrome) window then it works perfectly. It's only a problem when using it embedded in an IE control.
If I hook the WndProc for the IE window (or use Spy++) the WM_KEYDOWN, WM_CHAR and WM_KEYUP messages are definately making it to the window.
I tried to make the example code as minimal as possible - removed a lot of error checking, clean up, etc.
Is there some setup that I'm missing when preparing the IE control? Or is this just the way it is when using IE embedded? I would think that if it was missing setup I wouldn't get ANY input.
Here's the HTML test file:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script type="text/javascript" language="javascript">
var n = 0;
document.onkeydown = function()
{
var output=document.getElementById("output");
output.innerHTML = n++ + " onkeydown<br>" + output.innerHTML;
return true;
};
document.onkeypress = function()
{
var output=document.getElementById("output");
output.innerHTML = n++ + " onkeypress<br>" + output.innerHTML;
return true;
};
document.onkeyup = function()
{
var output=document.getElementById("output");
output.innerHTML = n++ + " onkeyup<br>" + output.innerHTML;
return true;
};
</script>
</head>
<body>
This is some testing text.
<input/>
<br>
<div id="output" style="border-style:solid; border-width:1; "></div>
</body>
</html>
And the C++ code to embed the file:
#include <stdio.h>
#include <Windows.h>
#include <string>
#include <atlbase.h> // for CComPtr<>
#include <Exdisp.h>
#include <comdef.h> // for variant_t
namespace
{
const int MAIN_WINDOW_WIDTH = 800;
const int MAIN_WINDOW_HEIGHT = 600;
const int HTML_WINDOW_WIDTH = 640;
const int HTML_WINDOW_HEIGHT = 480;
}
//------------------------------------------------------------------------------
void FatalError(std::string _report)
{
::MessageBox(nullptr, _report.c_str(), "Error", MB_OK);
::ExitProcess(1);
}
//------------------------------------------------------------------------------
class EmbeddedBrowser :
public IOleClientSite,
public IOleInPlaceSite,
public IStorage
{
public:
EmbeddedBrowser(HWND _mainWindow)
{
m_comRefCount = 0;
::SetRect(&m_objectRect, -300, -300, 300, 300);
m_mainWindow = _mainWindow;
CreateBrowserObject();
::ShowWindow(GetControlWindow(), SW_SHOW);
variant_t flags((UINT)0);
m_webBrowser->Navigate(L"about:blank",
&flags, nullptr, nullptr, nullptr);
}
void CreateBrowserObject()
{
HRESULT hr = ::OleCreate(CLSID_WebBrowser,
IID_IOleObject, OLERENDER_DRAW, 0, this, this, (void**)&m_oleObject);
if(FAILED(hr))
FatalError("OleCreate() failed");
hr = m_oleObject->SetClientSite(this);
hr = OleSetContainedObject(m_oleObject, TRUE);
RECT posRect;
::SetRect(&posRect, -300, -300, 300, 300);
hr = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE,
NULL, this, -1, m_mainWindow, &posRect);
if(FAILED(hr))
FatalError("DoVerb(OLEIVERB_INPLACEACTIVATE) failed");
hr = m_oleObject.QueryInterface(&m_webBrowser);
if(FAILED(hr))
FatalError("QueryInterface(IWebBrowser) failed");
}
virtual void Navigate(std::wstring _url)
{
bstr_t url(_url.c_str());
variant_t flags(0x02u); // navNoHistory;
HRESULT hr = m_webBrowser->Navigate(url,
&flags, nullptr, nullptr, nullptr);
}
RECT PixelToHiMetric(const RECT& _rc)
{
static bool s_initialized = false;
static int s_pixelsPerInchX, s_pixelsPerInchY;
if(!s_initialized)
{
HDC hdc = ::GetDC(nullptr);
s_pixelsPerInchX = ::GetDeviceCaps(hdc, LOGPIXELSX);
s_pixelsPerInchY = ::GetDeviceCaps(hdc, LOGPIXELSY);
::ReleaseDC(nullptr, hdc);
s_initialized = true;
}
RECT rc;
rc.left = MulDiv(2540, _rc.left, s_pixelsPerInchX);
rc.top = MulDiv(2540, _rc.top, s_pixelsPerInchY);
rc.right = MulDiv(2540, _rc.right, s_pixelsPerInchX);
rc.bottom = MulDiv(2540, _rc.bottom, s_pixelsPerInchY);
return rc;
}
virtual void SetRect(const RECT& _rc)
{
m_objectRect = _rc;
{
RECT hiMetricRect = PixelToHiMetric(m_objectRect);
SIZEL sz;
sz.cx = hiMetricRect.right - hiMetricRect.left;
sz.cy = hiMetricRect.bottom - hiMetricRect.top;
m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
}
if(m_oleInPlaceObject != nullptr)
{
m_oleInPlaceObject->SetObjectRects(&m_objectRect, &m_objectRect);
}
}
// ----- IUnknown -----
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void**ppvObject) override
{
if(riid == __uuidof(IUnknown))
{ (*ppvObject) = static_cast<IOleClientSite*>(this); }
else if(riid == __uuidof(IOleInPlaceSite))
{ (*ppvObject) = static_cast<IOleInPlaceSite*>(this); }
else
{
return E_NOINTERFACE;
}
AddRef(); // implicit AddRef()
return S_OK;
}
virtual ULONG STDMETHODCALLTYPE AddRef( void) override
{
m_comRefCount++;
return m_comRefCount;
}
virtual ULONG STDMETHODCALLTYPE Release( void) override
{
m_comRefCount--;
return m_comRefCount;
}
// ---------- IOleWindow ----------
virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE GetWindow(
/* [out] */ __RPC__deref_out_opt HWND *phwnd) override
{
(*phwnd) = m_mainWindow;
return S_OK;
}
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
{
OleLockRunning(m_oleObject, TRUE, FALSE);
m_oleObject.QueryInterface(&m_oleInPlaceObject);
m_oleInPlaceObject->SetObjectRects(&m_objectRect, &m_objectRect);
return S_OK;
}
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
{
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;
}
virtual HRESULT STDMETHODCALLTYPE Scroll(
/* [in] */ SIZE scrollExtant) override
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnUIDeactivate(
/* [in] */ BOOL fUndoable) override
{
return S_OK;
}
virtual HWND GetControlWindow()
{
if(m_controlWindow != nullptr)
return m_controlWindow;
if(m_oleInPlaceObject == nullptr)
return nullptr;
m_oleInPlaceObject->GetWindow(&m_controlWindow);
return m_controlWindow;
}
virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate( void) override
{
m_controlWindow = nullptr;
m_oleInPlaceObject = nullptr;
return S_OK;
}
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;
//return E_NOTIMPL;
}
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;
}
private:
protected:
CComPtr<IOleObject> m_oleObject;
LONG m_comRefCount;
HWND m_mainWindow;
RECT m_objectRect;
CComPtr<IWebBrowser2> m_webBrowser;
CComPtr<IOleInPlaceObject> m_oleInPlaceObject;
HWND m_controlWindow;
};
//------------------------------------------------------------------------------
void EventLoop(HWND _mainWindow)
{
while(IsWindow(_mainWindow))
{
MSG msg;
if(GetMessage(&msg, nullptr, 0, 0) <= 0)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
int main(int argc, char* argv[])
{
OleInitialize(nullptr);
WNDCLASS wc;
memset(&wc, 0, sizeof(wc));
wc.lpszClassName = "MyWindowClass";
wc.lpfnWndProc = DefWindowProc;
wc.hCursor = ::LoadCursor(nullptr, IDC_ARROW);
RegisterClass(&wc);
HWND mainWindow = CreateWindow("MyWindowClass",
"My Window", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT,
CW_USEDEFAULT, MAIN_WINDOW_WIDTH, MAIN_WINDOW_HEIGHT, nullptr,
nullptr, nullptr, nullptr);
RECT rc;
rc.left = (MAIN_WINDOW_WIDTH - HTML_WINDOW_WIDTH) / 2;
rc.top = (MAIN_WINDOW_HEIGHT - HTML_WINDOW_HEIGHT) / 2;
rc.right = rc.left + HTML_WINDOW_WIDTH;
rc.bottom = rc.top + HTML_WINDOW_HEIGHT;
wchar_t navUrl[MAX_PATH];
::GetCurrentDirectoryW(MAX_PATH, navUrl);
wcscat_s(navUrl, L"\\test.html");
EmbeddedBrowser* browser = new EmbeddedBrowser(mainWindow);
browser->SetRect(rc);
browser->Navigate(navUrl);
EventLoop(mainWindow);
ExitProcess(0);
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我知道这是一个相当老的线程,但我遇到了完全相同的问题。
就我而言,错误是我在 Dialog 类中覆盖了 PreTranslateMessage(),但我没有调用 CDialog::PretranslateMessage(),而是从那里调用了 CWnd::PretranslateMessage()。
I know this is a rather old thread, but I had the exactly same Problem.
In my case the error was, that I overwrote PreTranslateMessage() in my Dialog class, but instead of calling CDialog::PretranslateMessage() I called CWnd::PretranslateMessage() from there.