為了處理字符消息實(shí)現(xiàn)自動(dòng)完成的功能,這是怎么樣實(shí)現(xiàn)的呢?其實(shí)是先記錄字符消息響應(yīng)前的字符串以及選中狀態(tài),接著再處理消息,最后才查詢可能的輸入,做出智能提示。
#001
?
void AutocompleteEdit::OnBeforePossibleChange() {
#002
???
// Record our state.
記錄當(dāng)前已經(jīng)輸入的字符串。
#003
???
text_before_change_ = GetText();
記錄當(dāng)前選中的字符位置。
#004
???
GetSelection(sel_before_change_);
#005
???
select_all_before_change_ = IsSelectAll(sel_before_change_);
#006
?
}
上面就保存字符消息響應(yīng)前的狀態(tài),接著下來就是消息響應(yīng)后的處理了,如下:
#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.
判斷用戶新選中狀態(tài)。
#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
?
下面開始設(shè)置新的顯示字符串。
#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.
這里刪除已經(jīng)選擇的提示。
#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
?
當(dāng)自動(dòng)完成框字符串發(fā)生變化,就需要更新
URL
重點(diǎn)顯示。
#092
???
if (text_differs)
#093
?????
TextChanged();
#094
?
#095
???
return true;
#096
?
}
在這個(gè)函數(shù)里,先判斷字符串是否發(fā)生變化,然后根據(jù)變化來決定是否更新編輯框的顯示,同時(shí)還需要
UpdatePopup
更新智能提示菜單,最后判斷是否有一個(gè)
URL
地址,如果有就重點(diǎn)顯示出來。
其實(shí)這里最關(guān)鍵的問題就是智能菜單的數(shù)據(jù)從那里來的呢?怎么樣根據(jù)用戶的輸入查找到最合適的提示呢?下一次我們?cè)賮矸治鲞@方面的問題。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

