为了处理字符消息实现自动完成的功能,这是怎么样实现的呢?其实是先记录字符消息响应前的字符串以及选中状态,接着再处理消息,最后才查询可能的输入,做出智能提示。
          
                        
    
      
        
          #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
          
          地址,如果有就重点显示出来。
          
            
    
      
    
      
        
          其实这里最关键的问题就是智能菜单的数据从那里来的呢?怎么样根据用户的输入查找到最合适的提示呢?下一次我们再来分析这方面的问题。
          
            


 
					 
					