CEF3 获取(失去)焦点focus 并通知C++界面

这次遇到的问题是这样的,我们使用C++(QT) 做的客户端,里面是嵌入CEF的界面(web页面)。也就是外层是C++界面,里面是cef界面。在外层有使用C++做的搜索框,输入搜索内容,会自动将搜索结果实时的以类似弹窗的方式展示出来。类似下面的功能:
CEF3 获取(失去)焦点focus 并通知C++界面_第1张图片
关于这个弹出的结果框,如何消失出现了问题。就是鼠标点击了一下其他C++界面,这个弹窗失去了焦点,就会自动收回。
========================================================================
如果鼠标点击了cef界面,这时候cef的web页面获取了焦点,但是这时候C++并不知道自己已经失去了焦点,在搜索框内的鼠标还在闪烁,同时,搜索结果框也并没有消失。
造成这个问题的原因就是C++不知道cef界面已经获取了焦点,所以自己并没有释放焦点,弹窗也并没有消失。

那么解决方法就是当cef的web页面获取了焦点,就要通知c++界面,让c++知道自己已经失去了焦点,并且做失去焦点之后该做的事(比如收起弹窗,清除搜索框的焦点等)。

知道了我们应该去做什么,但是怎么去做呢?还得从cef的handler入手,仔细查找cef常用的handler,发现了cef关于焦点处理的handler: CefFocusHandler 我们查看一些他们提供的API,其中都是关于焦点的接口,一共三个:

  ///
  // Called when the browser component is about to loose focus. For instance, if
  // focus was on the last HTML element and the user pressed the TAB key. |next|
  // will be true if the browser is giving focus to the next component and false
  // if the browser is giving focus to the previous component.
  ///
  /*--cef()--*/
  virtual void OnTakeFocus(CefRefPtr browser, bool next) {}

  ///
  // Called when the browser component is requesting focus. |source| indicates
  // where the focus request is originating from. Return false to allow the
  // focus to be set or true to cancel setting the focus.
  ///
  /*--cef()--*/
  virtual bool OnSetFocus(CefRefPtr browser, FocusSource source) {
    return false;
  }

  ///
  // Called when the browser component has received focus.
  ///
  /*--cef()--*/
  virtual void OnGotFocus(CefRefPtr browser) {}

其中 我们来逐个分析一下

  1. OnTaskeFocus : 在浏览器组件将要失去焦点的时候调用。
  2. OnSetFocus : 在浏览器组件请求焦点的时候调用。
  3. OnGotFocus : 在浏览器组件得到了焦点的时候调用。

CEF提供的这三个关于焦点的处理函数,分别是失去焦点的时候、请求焦点与得到了焦点时候调用。那么很显然,我们是需要使用最后一个函数OnGotFocus的时候需要通知C++,而不是使用OnsetFocus的时候,为什么呢?因为万一浏览器请求焦点的时候失败了呢(虽然这种概率很小)?这时候焦点还是不在浏览器上。

那么具体做法是:

  1. 我们自己的handler继承CefFocusHandler
	class SimpleHandler : public CefClient,
    	public CefFocusHandler
  1. 重写OnGotFocus方法
    //CefFocusHandler
    /**
     * @brief OnGotFocus                CEF界面得到焦点后执行
     * @param browser
     */
    virtual void OnGotFocus(CefRefPtr browser) OVERRIDE;

  1. 在OnGotFocus方法中,将浏览器得到了焦点的消息通知出去。
    将浏览器得到焦点的消息通知给C++的 方法有很多种比如使用PostMessage/SendMessage/回调函数/信号槽等。

在C++界面的接收函数里进行失去焦点的处理:比如收起搜索结果框体,收起其他的弹出框,清除搜索框的焦点等等。

你可能感兴趣的:(QT,CEF3,C++)