c++ - 嵌入式 web 控件 (IWebBrowser2),嵌入式 javascript 的 onkeydown 和 onkeyup 不触发-6ren
c++ - Điều khiển web nhúng (IWebBrowser2), onkeydown và onkeyup của javascript được nhúng không được kích hoạt
In lại
Tác giả: Hồ Xil
更新时间:2023-11-01 09:35:34
27
4
我正在我的 C++ 程序中嵌入一个网页。我遇到的问题是,在嵌入式页面的 javascript 中,我可以捕获 onkeypress,但不会触发 onkeydown 和 onkeyup。
如果我在非嵌入式 IE(或 Chrome)窗口中查看测试 HTML,那么它可以完美运行。只有在将它嵌入到 IE 控件中使用时才会出现问题。
如果我为 IE 窗口挂接 WndProc(或使用 Spy++),WM_KEYDOWN、WM_CHAR 和 WM_KEYUP 消息肯定会进入窗口。
我试图使示例代码尽可能少——删除了很多错误检查、清理等。
在准备 IE 控件时是否缺少某些设置?或者这只是使用 IE 嵌入式时的方式?我会认为,如果缺少设置,我将无法获得任何输入。
这是 HTML 测试文件:
<đầu> This is some testing text.
đầu>
Xem sitemap của VNExpress
以及嵌入文件的 C++ 代码:
#include #include #include #include // for CComPtr<> #include #include // 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(this); } else if(riid == __uuidof(IOleInPlaceSite)) { (*ppvObject) = static_cast(this); } khác { 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 m_oleObject; LONG m_comRefCount; HWND m_mainWindow; RECT m_objectRect; CComPtr m_webBrowser; CComPtr m_oleInPlaceObject; HWND m_controlWindow; }; //------------------------------------------------------------------------------ void EventLoop(HWND _mainWindow) { while(IsWindow(_mainWindow)) { MSG msg; if(GetMessage(&msg, nullptr, 0, 0) <= 0) phá vỡ; 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; }
我知道这是一个相当古老的话题,但我遇到了完全相同的问题。
在我的例子中,错误是我在我的 Dialog 类中覆盖了 PreTranslateMessage(),但我没有调用 CDialog::PretranslateMessage(),而是从那里调用了 CWnd::PretranslateMessage()。
c++ - C c;之间有什么区别吗?和 C c = C();?
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
c++ - C 风格字符串差异 : C/C++
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
c++ - c\c++ 转换为 C#
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
c# - C、C++、C# 的功能测试工具
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
c# - C/C++/C# 在监视器上设置窗口位置
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
c# - C/C++/C#中的DES实现
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
c# - 在条件中使用赋值是否安全? C/C++、C#
Thật khó để nói những gì để hỏi ở đây. Câu hỏi không rõ ràng, mơ hồ, không đầy đủ, quá rộng hoặc hùng biện và không thể trả lời hợp lý ở dạng hiện tại. Để được trợ giúp làm rõ vấn đề này để có thể mở lại, hãy truy cập trung tâm trợ giúp Đóng 1.
c++ - C/C++/C# 强制窗口在最上面
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
c# - 套接字服务器应用程序的选择 : C/C++ or C#
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
c++ - C/C++ 运行时库和 C/C++ 标准库的区别
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
c++ - &C::c 和 &(C::c) 有什么区别?
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
c++ - 什么 C++(通用 (c/c++) 与 (通用 c)/c++ )
Thật khó để nói những gì đang được hỏi ở đây. Câu hỏi mơ hồ, mơ hồ, không đầy đủ, quá rộng hoặc hùng biện và không thể trả lời hợp lý ở dạng hiện tại. Để được trợ giúp làm rõ vấn đề này để bạn có thể mở lại, hãy truy cập trung tâm trợ giúp. Đã đóng
c# - 通过网络在 C/C++ 服务器、C/C++ 和 C# 客户端之间发送数据结构
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
c# - C/C++ - 如何将 Buffer.BlockCopy (C#) 转换为 C/C++
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
c++ - C/C++ - 对其他人隐藏 C 或 C++ 函数代码
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
c# - 在托管代码(C++、C、C++/CLI、C#)中使用非托管代码时处理错误
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
c# - C#、C/C++ 或 Objective-C 中的眼动追踪库
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
c++ - C/C++/Objective-C 文本识别库
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
c# - 将 C/C++ 函数导入 C#
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
c - C语言中 "c -= --c - c++;"的结果应该是什么?
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
Tôi là một lập trình viên xuất sắc, rất giỏi!