#001
void AutocompleteEdit::UpdatePopup() {
冻结输入。
#002
ScopedFreeze freeze(this, GetTextObjectModel());
设置正在输入过程中。
#003
SetInputInProgress(true);
#004
如果输入的
EDIT
框没有焦点,就直接返回。
#005
if (!has_focus_) {
#006
// When we're in the midst of losing focus, don't rerun autocomplete.
This
#007
// can happen when losing focus causes the IME to cancel/finalize a
#008
// composition.
We still want to note that user input is in progress, we
#009
// just don't want to do anything else.
#010
//
#011
// Note that in this case the ScopedFreeze above was unnecessary; however,
#012
// we're inside the callstack of OnKillFocus(), which has already frozen the
#013
// edit, so this will never result in an unnecessary UpdateWindow() call.
#014
return;
#015
}
#016
#017
// Figure out whether the user is trying to compose something in an IME.
判断是否从输入法打开,如果是就从输入法窗口里获取字符串。
#018
bool ime_composing = false;
#019
HIMC context = ImmGetContext(m_hWnd);
#020
if (context) {
#021
ime_composing = !!ImmGetCompositionString(context, GCS_COMPSTR, NULL, 0);
#022
ImmReleaseContext(m_hWnd, context);
#023
}
#024
#025
// Don't inline autocomplete when:
#026
//
* The user is deleting text
#027
//
* The caret/selection isn't at the end of the text
#028
//
* The user has just pasted in something that replaced all the text
#029
//
* The user is trying to compose something in an IME
获取当前选择的字符串。
#030
CHARRANGE sel;
#031
GetSel(sel);
根据用户输入的字符串来查找智能提示菜单的内容。
#032
popup_->StartAutocomplete(user_text_, GetDesiredTLD(),
#033
just_deleted_text_ || (sel.cpMax < GetTextLength()) ||
#034
(paste_state_ != NONE) || ime_composing);
#035
}
在这个函数里主要调用类
AutocompletePopupModel
的函数
StartAutocomplete
来完成智能提示。而类
AutocompletePopupModel
的声明如下:
class AutocompletePopupModel : public ACControllerListener, public Task {
public:
AutocompletePopupModel(const ChromeFont& font,
AutocompleteEdit* editor,
Profile* profile);
~AutocompletePopupModel();
从这个类里可以看到它是继承类
ACControllerListener
,说明它是响应一个返回结果的监听器;继承类
Task
说明它是一个任务线程类。由这两个类可以看出,它是把关键字给一个线程,然后让这个线程去查询结果,当结果返回时,就再更新到显示窗口里。
虽然上面理解它的查询过程了,但是向谁查询呢?这是一个一定需要了解的问题。现在就来分析类
AutocompleteController
,它在构造函数时,就会创建三个查询的对象:
#001
AutocompleteController::AutocompleteController(ACControllerListener* listener,
#002
Profile* profile)
#003
: listener_(listener) {
#004
providers_.push_back(new
SearchProvider
(this, profile));
#005
providers_.push_back(new
HistoryURLProvider
(this, profile));
#006
keyword_provider_ = new
KeywordProvider
(this, profile);
#007
providers_.push_back(keyword_provider_);
#008
if (listener) {
#009
// These providers are async-only, so there's no need to create them when
#010
// we'll only be doing synchronous queries.
#011
history_contents_provider_ = new
HistoryContentsProvider
(this, profile);
#012
providers_.push_back(history_contents_provider_);
#013
} else {
#014
history_contents_provider_ = NULL;
#015
}
#016
for (ACProviders::iterator i(providers_.begin()); i != providers_.end(); ++i)
#017
(*i)->AddRef();
#018
}
从上面的代码,可以看到它是向
SearchProvider
、
HistoryURLProvider
、
KeywordProvider
和
HistoryContentsProvider
来查找到合适的智能提示。类
SearchProvider
是从搜索引擎里查找合适的内容;类
HistoryURLProvider
是从历史的
URL
里查找合适的内容;类
KeywordProvider
是从关键字搜索引擎里查找合适的内容;类
HistoryContentsProvider
是从历史内容里查找合适内容。从上面四种智能提示里,在以前的浏览器里一般只能做到从历史的
URL
里提示,现在“可多米”可以做到从搜索引擎和关键字引擎里查找到相应的结果回来,可见它是智能提示完美的体现,智能的水平可想而知了。这就是强大的云计算典型应用,如果没有强大的服务器群是做不到几亿人输入关键字时,还能快速返回结果的。
分析到这里,也许知道为什么
GOOGLE
开发浏览器的原因了吧,如果其它浏览是不可能采用这样的技术来分析用户的输入的,顶多是到历史记录里查找一下就算了。
虽然提供这么强大的搜索,它们又是怎么样实现的呢?下一次再来分析它们。