谷歌浏览器的源码分析 9

为了处理字符消息实现自动完成的功能,这是怎么样实现的呢?其实是先记录字符消息响应前的字符串以及选中状态,接着再处理消息,最后才查询可能的输入,做出智能提示。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

#001  void AutocompleteEdit::OnBeforePossibleChange() {

#002    // Record our state.

记录当前已经输入的字符串。

#003    text_before_change_ = GetText();

记录当前选中的字符位置。

#004    GetSelection(sel_before_change_);

#005    select_all_before_change_ = IsSelectAll(sel_before_change_);

#006  }

上面就保存字符消息响应前的状态,接着下来就是消息响应后的处理了,如下:

#001  bool AutocompleteEdit::OnAfterPossibleChange() {

#002    // Prevent the user from selecting the "phantom newline" at the end of the

#003    // edit.  If they try, we just silently move the end of the selection back to

#004    // the end of the real text.

判断用户新选中状态。

#005    CHARRANGE new_sel;

#006    GetSelection(new_sel);

#007    const int length = GetTextLength();

#008    if ((new_sel.cpMin > length) || (new_sel.cpMax > length)) {

#009      if (new_sel.cpMin > length)

#010        new_sel.cpMin = length;

#011      if (new_sel.cpMax > length)

#012        new_sel.cpMax = length;

#013      SetSelectionRange(new_sel);

#014    }

判断用户是否输入字符有变化。

#015    const bool selection_differs = (new_sel.cpMin != sel_before_change_.cpMin) ||

#016        (new_sel.cpMax != sel_before_change_.cpMax);

#017

#018    // See if the text or selection have changed since OnBeforePossibleChange().

#019    const std::wstring new_text(GetText());

#020    const bool text_differs = (new_text != text_before_change_);

#021

#022    // Update the paste state as appropriate: if we‘re just finishing a paste

#023    // that replaced all the text, preserve that information; otherwise, if we‘ve

#024    // made some other edit, clear paste tracking.

#025    if (paste_state_ == REPLACING_ALL)

#026      paste_state_ = REPLACED_ALL;

#027    else if (text_differs)

#028      paste_state_ = NONE;

#029

如果输入没有任何变化,就返回去。

#030    // If something has changed while the control key is down, prevent

#031    // "ctrl-enter" until the control key is released.  When we do this, we need

#032    // to update the popup if it‘s open, since the desired_tld will have changed.

#033    if ((text_differs || selection_differs) &&

#034        (control_key_state_ == DOWN_WITHOUT_CHANGE)) {

#035      control_key_state_ = DOWN_WITH_CHANGE;

#036      if (!text_differs && !popup_->is_open())

#037        return false;  // Don‘t open the popup for no reason.

#038    } else if (!text_differs &&

#039        (inline_autocomplete_text_.empty() || !selection_differs)) {

#040      return false;

#041    }

#042

#043    const bool had_keyword = !is_keyword_hint_ && !keyword_.empty();

#044

下面开始设置新的显示字符串。

#045    // Modifying the selection counts as accepting the autocompleted text.

#046    InternalSetUserText(UserTextFromDisplayText(new_text));

#047    has_temporary_text_ = false;

#048

#049    if (text_differs) {

#050      // When the user has deleted text, don‘t allow inline autocomplete.  Make

#051      // sure to not flag cases like selecting part of the text and then pasting

#052      // (or typing) the prefix of that selection.  (We detect these by making

#053      // sure the caret, which should be after any insertion, hasn‘t moved

#054      // forward of the old selection start.)

#055      just_deleted_text_ = (text_before_change_.length() > new_text.length()) &&

#056        (new_sel.cpMin <= std::min(sel_before_change_.cpMin,

#057                                   sel_before_change_.cpMax));

#058

#059      // When the user doesn‘t have a selected keyword, deleting text or replacing

#060      // all of it with something else should reset the provider affinity.  The

#061      // typical use case for deleting is that the user starts typing, sees that

#062      // some entry is close to what he wants, arrows to it, and then deletes some

#063      // unnecessary bit from the end of the string.  In this case the user didn‘t

#064      // actually want "provider X", he wanted the string from that entry for

#065      // editing purposes, and he‘s no longer looking at the popup to notice that,

#066      // despite deleting some text, the action we‘ll take on enter hasn‘t changed

#067      // at all.

这里删除已经选择的提示。

#068      if (!had_keyword && (just_deleted_text_ || select_all_before_change_)) {

#069        popup_->manually_selected_match_.Clear();

#070      }

#071    }

#072

#073    // Disable the fancy keyword UI if the user didn‘t already have a visible

#074    // keyword and is not at the end of the edit.  This prevents us from showing

#075    // the fancy UI (and interrupting the user‘s editing) if the user happens to

#076    // have a keyword for ‘a‘, types ‘ab‘ then puts a space between the ‘a‘ and

#077    // the ‘b‘.

#078    disable_keyword_ui_ = (is_keyword_hint_ || keyword_.empty()) &&

#079        ((new_sel.cpMax != length) || (new_sel.cpMin != length));

#080

更新智能提示菜单。

#081    UpdatePopup();

#082

#083    if (!had_keyword && !is_keyword_hint_ && !keyword_.empty()) {

#084      // Went from no selected keyword to a selected keyword. Set the affinity to

#085      // the keyword provider.  This forces the selected keyword to persist even

#086      // if the user deletes all the text.

#087      popup_->manually_selected_match_.Clear();

#088      popup_->manually_selected_match_.provider_affinity =

#089          popup_->autocomplete_controller()->keyword_provider();

#090    }

#091

当自动完成框字符串发生变化,就需要更新URL重点显示。

#092    if (text_differs)

#093      TextChanged();

#094

#095    return true;

#096  }

在这个函数里,先判断字符串是否发生变化,然后根据变化来决定是否更新编辑框的显示,同时还需要UpdatePopup更新智能提示菜单,最后判断是否有一个URL地址,如果有就重点显示出来。

其实这里最关键的问题就是智能菜单的数据从那里来的呢?怎么样根据用户的输入查找到最合适的提示呢?下一次我们再来分析这方面的问题。

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

原文地址:https://www.cnblogs.com/skiwnchh/p/10347047.html

时间: 2024-10-02 20:45:30

谷歌浏览器的源码分析 9的相关文章

谷歌浏览器的源码分析 21

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 上一次说到类RenderThread和类RenderView把消息处理,那么这两个类是怎么样处理消息的呢?又是怎么样处理浏览的消息呢?现在就带着这两个问题去分析它的源码,理解它处理消息的方法.类RenderThread处理消息的代码如下:<?xml:namespace prefix = o ns = "urn:schemas-

谷歌浏览器的源码分析 4

关于对话框,主要实现了让用户查看当前软件的版本.软件信息和检查升级的功能.因此这个类主要继续ChromeViews::View类.ChromeViews::DialogDelegate和GoogleUpdateStatusListener.其中ChromeViews::View实现窗口的布局和显示问题,ChromeViews::DialogDelegate实现了事件响应,或者窗口某时是否可以显示按钮的问题,GoogleUpdateStatusListener是用来实现接收更新程序状态信息. 这个

谷歌浏览器的源码分析 6

前面已经介绍了这么引人的输入自动完成功能,并且可以在输入超级连接框里直接通过GOOGLE搜索所有的内容,这是比较大的创新,不但可以节省界面的占用面积,还很方便大家查询的需要,比如记不住的连接,根本不需要去记了,只要你记住需要的内容就行了.这样既不需要到什么门户网站去找连接,也不需要去记住众多的网站,这个功能是非常方便的. 这个输入框的自动完成的功能,是比较智能化的.因为它会根据以往的输入自动完成,或者智能提示所需要的连接或者内容. 下面就来先看这个类的定义: #001  // Provides

谷歌浏览器的源码分析 34

通过上一次的分析,我们看到所有网页数据经过HTML分析器之后,都会变成一个一个RenderObject对象,那么这些RenderObject对象又是怎么样显示到界面上面的呢?现在就带着这个疑问来分析下面的代码,这样肯定会找到解决方法的.怎么样找到入口呢?其实可以先从界面显示的类开始,可以看到显示界面的窗口类名称叫做Chrome_RenderWidgetHostHWND,有了这个类名称,就可以到代码里查看它在那里了. #001  class RenderWidgetHost; #002  clas

谷歌浏览器的源码分析 7

当我们键入字母或者文字开始时,那么类AutocompleteEdit就会从窗口消息里获取到相应的字母或者文字,然后根据输入的信息到本地或者网络上保存的信息库里查找相应的输入提示,这就是自动完成的实现.下面就来先分析输入的函数:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> #001  void AutocompleteEdit::OnChar(TCHAR ch, UIN

谷歌浏览器的源码分析 13

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 上一次说到调用函数OpenURL来打开网络连接,这仅是网络浏览的开始,现在再来分析它怎么样去下载网页数据,然后再显示出来.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> #001  void Autocom

谷歌浏览器的源码分析 29

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 上一次说到通过WinHTTP来接收网络数据,但没有具体介绍怎么样接收,现在就来分析这方面的代码.首先是通过函数WinHttpQueryHeaders来查询HTTP协议头的大小,接着还是通过函数WinHttpQueryHeaders把数据接收到缓冲区里.下面这段代码,就是做这样的事情:<?xml:namespace prefix =

TeamTalk源码分析之login_server

login_server是TeamTalk的登录服务器,负责分配一个负载较小的MsgServer给客户端使用,按照新版TeamTalk完整部署教程来配置的话,login_server的服务端口就是8080,客户端登录服务器地址配置如下(这里是win版本客户端): 1.login_server启动流程 login_server的启动是从login_server.cpp中的main函数开始的,login_server.cpp所在工程路径为server\src\login_server.下表是logi

Android触摸屏事件派发机制详解与源码分析二(ViewGroup篇)

1 背景 还记得前一篇<Android触摸屏事件派发机制详解与源码分析一(View篇)>中关于透过源码继续进阶实例验证模块中存在的点击Button却触发了LinearLayout的事件疑惑吗?当时说了,在那一篇咱们只讨论View的触摸事件派发机制,这个疑惑留在了这一篇解释,也就是ViewGroup的事件派发机制. PS:阅读本篇前建议先查看前一篇<Android触摸屏事件派发机制详解与源码分析一(View篇)>,这一篇承接上一篇. 关于View与ViewGroup的区别在前一篇的A