CAutocomplectionCtrl
is a control designed to
add
the auto completion feature in a CRichEditCtrl
. You can easily
modify the code to add the auto completion feature in a CRichEditView
.
You can specify options such as displaying all known words or only the matching ones.
User can start the auto completion feature pressing
Ctrl+space; he can confirm the selected word pressing space, Enter or a non-alpha
char; he can use up, down, pgUp, pgDown, home, end, Ctrl+Space or mouse-wheel
to switch between the
words
in the list; he can use left, right to modify the
matching part of the word.
Using the control
Using ClassWizard add a variable in your dialog class; the
variable must be a CAutocomplectionCtrl
control; if the ClassWizard
displays
only CRichEdit
select it, and change it to CAutocomplectionCtrl
in the .h file.
Remember to include "Autocomplection.h" in your .h file and to
insert the line
AfxInitRichEdit();
in the Initinstance()
function of your
application.
Then you must define your
dictionary using the AddKeyword()
funcion; usually you'll do that
in the OnInitDialog
function. In the
sample application I read the words from a file, so resulting code is:
while (file.ReadString(keyword))
m_edit.AddKeyword(keyword);
Well, your work is done :)
If you
like you can specify some options...
Option functions
void Enable(BOOL);
You can enable or disable the auto completion feature; by
default it's enabled.
void ShowListBox(BOOL);
You can select if to display the listbox or not
void ListAllWords(BOOL);
You can select if to display in the listbox all known words, or only the
matching ones
void TrapEnter(BOOL);
Pressing Enter, the selected word is confirmed.
If TrapEnter
is set to FALSE,
when pressing Enter, the control will add a new line char, if TrapEnter
is set
to TRUE, the new line char will not be displayed
void CaseSensitive(BOOL);
You can select if the matching function must be case
sensitive or not.
void AutoLearn(BOOL);
That feature isn't very useful; if enabled, when the user
types an unknown word, the control will add it to the dictionary; that could be
nice if the user never mistakes typing words...
void LearnOnDblClick(BOOL);
If this feature is enabled, when the user double-clicks
over a word, the control learns it.
Dictionary functions
void GetDictionary(CStringArray& dictionary);
This function fills the given CStringArray
with all known words.
void ResetDictionary();
This function empties the dictionary.
BOOL AddKeyword(const CString& str);
This function adds the specified word in the dictionary.
BOOL IsKeyword(const CString& str);
This function checks if the specified word is in the dictionary.
Developing notes
The code compiles cleanly under the warning level 4.
Search
I chose to insert word in alphabetic order and to find them using
a binary search, so the search
function is O(log(n)).
Case sense
Word matching can be case sensitive or not case sensitive. Instead of checking anytime or duplicate the code I decided to use
function pointers...
Word recognition
Word recognition is done looking for the left-nearest "space" character. You can easily change your word recognition
modifying the line
while (from && buffer[from]!=' ')
with a such line
while (from && buffer[from]!=' ' && buffer[from]!='(' && buffer[from]!='=')
Further improvements (aka TODO)
The learn feature could be improved; anyhow the applicative context
suggests different improvement modalities: e.g., you could want to learn only frequent typed words, or only the # nearest words, or....
You could like to display an icon near the word (yes, like
Visual Studio)... so you should replace the CArrayString
with an array class and
a class containing the string and an ID specifying the icon.
Sometimes (when there are many matching words) filling
CListBox
is slow. It could be useful to replace the CListBox
with a faster one (maybe a owner data listbox...)
History
12 July 2002 - First public release