基于CFromView嵌入Chromium浏览器后OnMouseMove等鼠标事件不触发如何解决?
问题根因
你嵌入的Chrome内核(通常为Chromium Embedded Framework,即CEF)是独立的顶层子窗口控件,所有用户输入事件会优先被该子窗口捕获并自行处理,默认不会路由到作为父窗口的CFormView,因此CFormView中声明的OnMouseMove、OnLButtonUp等消息处理函数无法触发。
解决方案
通过CEF事件回调转发消息
重写CEF的CefRenderProcessHandler对应鼠标事件回调方法,在回调内主动将事件转发给父CFormView窗口,示例代码如下:bool MyRenderHandler::OnLButtonDown(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefMouseEvent event, int modifiers) { HWND hCefWnd = browser->GetHost()->GetWindowHandle(); HWND hParentWnd = ::GetParent(hCefWnd); // 坐标转换:将CEF客户区坐标转为父窗口客户区坐标 POINT pt = {event.x, event.y}; ::MapWindowPoints(hCefWnd, hParentWnd, &pt, 1); // 转发消息到CFormView ::SendMessage(hParentWnd, WM_LBUTTONDOWN, modifiers, MAKELPARAM(pt.x, pt.y)); // 返回false表示CEF继续处理本次事件,返回true则拦截事件不再交给CEF处理 return false; }其余
OnMouseMove、OnLButtonUp等事件参考以上逻辑实现即可。子类化CEF窗口捕获消息
拿到CEF控件的窗口句柄后,调用SetWindowSubclass接口子类化该窗口,在自定义的窗口过程中拦截所需的鼠标、键盘消息,先转发给CFormView处理后再调用CEF的默认窗口过程。使用MFC消息反射机制
在CFormView的消息映射表中添加对应事件的反射消息映射项,调整消息处理函数的参数规则适配MFC反射消息要求,即可接收到子控件上传的反射消息。
注意事项
- 如果不需要CEF响应当前事件,转发完成后可直接返回true拦截事件,避免重复处理
- 事件转发前务必做坐标转换,否则会出现CFormView中获取的鼠标坐标和实际点击位置不一致的问题
内容的提问来源于stack exchange,提问作者madhu sudhan
相关产品推荐
相关产品推荐

