基于WebView2的ActiveX控件和拦截WM_LBUTTONDBLCLK
WebView2 based ActiveX control and intercepting WM_LBUTTONDBLCLK
我有一个旧的 VS2008 应用程序需要 WebView2 集成,旧的 IE 实现不再可行。为此,我在 VS2019 中创建了包含 WebView2 API 的 ActiveX 控件。父 VS2008 CDialog 通过 CreateControl() 在网格中支持此 ActiveX 控件的多个实例。 InvokeHelper() 用于简单的 URL 和可见性命令。
所有工作和功能都符合预期。但是,我需要拦截鼠标双击消息以切换执行它的 ActiveX 控件的全屏。
问题是我似乎无法拦截此消息。 ActiveX 控件似乎首先拦截了 WM_LBUTTONDBLCLK 消息,然后简单地将其关闭。
如有任何关于如何拦截此消息的建议,我们将不胜感激。
基于 Poul 的建议,以下内容构成了可接受的解决方案的基础。
来自您的 OnCreateCoreWebView2ControllerCompleted(...) 处理程序
添加 ICoreWebView2::AddSCriptToExecuteOnDocumentCreated(lpszJavacode,...)
以下javascript对我有用
// Individually 'click' and 'dblclick' handlers work, but together the
// 'click' handler pre-dominates. For this reason some timer based
// processing needs to be introduced.
// https://simplernerd.com/js-double-click/
LPCTSTR lpszJavacode =
L"let numClicks = 0;"
L"const handleClick = () => {"
L" numClicks++;"
L" if (numClicks === 1) {"
L" singleClickTimer = setTimeout(() => {"
L" numClicks = 0;"
L" window.chrome.webview.postMessage('click');"
L" }, 400);"
L" } else if (numClicks === 2) {"
L" clearTimeout(singleClickTimer);"
L" numClicks = 0;"
L" window.chrome.webview.postMessage('dblclick');"
L" }"
L"};"
L"document.addEventListener('click', handleClick);";
设置一个接收器,当上面的javascript产生结果时
ICoreWebView2::add_WebMessageReceived ( ... )
在上面收到的回调中获取Json消息
LPWSTR pwStr;
args -> get_WebMessageAsJson( &pwStr );
CString receivedMessage = pwStr
然后在收到的网络消息中搜索'dblclick'和'click'
receivedMessage.Find(L"dblclick") 和 (L"click")
Post适当WM_LBUTTONDBLCLK或WM_LBUTTONUP留言回
COleControl 派生的父级。这被假定为充当容器
WebView2 对象
收到 WM_LBUTTONDBLCLK 或 WM_LBUTTONUP 消息后触发
使用 COleControl::FireDblClick() 返回 ActiveX 容器并
FireClick() 分别。
在ActiveX控件容器中创建一个EVENTSINK_MAP并添加处理程序
DISPID_CLICK 和 DISPIB_DBLCLK。
从那些容器 post WM_LBUTTONDBLCLK 回到消息循环。
WM__LBUTTONDOWN 和 WM_LBUTTONUP 被 post 编辑为单击按钮。
解决方案对于传统 MFC 程序员来说有些出乎意料,但有效
很好,并打开了将 WebView2 集成到 VS2015 之前的大门
应用程序。
我有一个旧的 VS2008 应用程序需要 WebView2 集成,旧的 IE 实现不再可行。为此,我在 VS2019 中创建了包含 WebView2 API 的 ActiveX 控件。父 VS2008 CDialog 通过 CreateControl() 在网格中支持此 ActiveX 控件的多个实例。 InvokeHelper() 用于简单的 URL 和可见性命令。
所有工作和功能都符合预期。但是,我需要拦截鼠标双击消息以切换执行它的 ActiveX 控件的全屏。
问题是我似乎无法拦截此消息。 ActiveX 控件似乎首先拦截了 WM_LBUTTONDBLCLK 消息,然后简单地将其关闭。
如有任何关于如何拦截此消息的建议,我们将不胜感激。
基于 Poul 的建议,以下内容构成了可接受的解决方案的基础。
来自您的 OnCreateCoreWebView2ControllerCompleted(...) 处理程序 添加 ICoreWebView2::AddSCriptToExecuteOnDocumentCreated(lpszJavacode,...)
以下javascript对我有用
// Individually 'click' and 'dblclick' handlers work, but together the // 'click' handler pre-dominates. For this reason some timer based // processing needs to be introduced. // https://simplernerd.com/js-double-click/ LPCTSTR lpszJavacode = L"let numClicks = 0;" L"const handleClick = () => {" L" numClicks++;" L" if (numClicks === 1) {" L" singleClickTimer = setTimeout(() => {" L" numClicks = 0;" L" window.chrome.webview.postMessage('click');" L" }, 400);" L" } else if (numClicks === 2) {" L" clearTimeout(singleClickTimer);" L" numClicks = 0;" L" window.chrome.webview.postMessage('dblclick');" L" }" L"};" L"document.addEventListener('click', handleClick);";
设置一个接收器,当上面的javascript产生结果时 ICoreWebView2::add_WebMessageReceived ( ... )
在上面收到的回调中获取Json消息
LPWSTR pwStr; args -> get_WebMessageAsJson( &pwStr ); CString receivedMessage = pwStr
然后在收到的网络消息中搜索'dblclick'和'click' receivedMessage.Find(L"dblclick") 和 (L"click")
Post适当WM_LBUTTONDBLCLK或WM_LBUTTONUP留言回 COleControl 派生的父级。这被假定为充当容器 WebView2 对象
收到 WM_LBUTTONDBLCLK 或 WM_LBUTTONUP 消息后触发 使用 COleControl::FireDblClick() 返回 ActiveX 容器并 FireClick() 分别。
在ActiveX控件容器中创建一个EVENTSINK_MAP并添加处理程序 DISPID_CLICK 和 DISPIB_DBLCLK。 从那些容器 post WM_LBUTTONDBLCLK 回到消息循环。 WM__LBUTTONDOWN 和 WM_LBUTTONUP 被 post 编辑为单击按钮。
解决方案对于传统 MFC 程序员来说有些出乎意料,但有效 很好,并打开了将 WebView2 集成到 VS2015 之前的大门 应用程序。