Click here to Skip to main content
15,881,715 members
Articles / Desktop Programming / MFC
Article

Autocomplection in RichEdit Control

Rate me:
Please Sign up or sign in to vote.
4.96/5 (22 votes)
11 Jul 2002Public Domain3 min read 200.9K   6.7K   89   29
A control that allows to use an autocomplection feature in RichEdit controls as the one in Visual Studio

Sample Image - AutocomplectionCtrl.gif

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

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication


Written By
Software Developer (Senior) Ermit
Italy Italy
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWhat Licenses in this under? Pin
Matt1 Anderson15-Oct-14 12:16
Matt1 Anderson15-Oct-14 12:16 
AnswerRe: What Licenses in this under? Pin
Paolo Vernazza24-Dec-15 0:59
Paolo Vernazza24-Dec-15 0:59 
QuestionAutocomplection in RichEdit Control - License Pin
Member 1086227328-Jul-14 11:41
Member 1086227328-Jul-14 11:41 
GeneralThis is not working for Japanese text Pin
Member 9328194-Jun-10 1:56
Member 9328194-Jun-10 1:56 
GeneralIncorrect twips conversion Pin
Dan East14-Dec-07 18:46
Dan East14-Dec-07 18:46 
GeneralVC8 compilation issues : error C2065: 'i' : undeclared identifier [modified] Pin
carlosrt27-Sep-06 2:27
carlosrt27-Sep-06 2:27 
Generalpb with download Pin
hiko-seijuro26-Jun-05 21:41
hiko-seijuro26-Jun-05 21:41 
Questionhow to add image Pin
nevis9-Jul-04 3:29
nevis9-Jul-04 3:29 
GeneralSelect list item with mouse Pin
Adrian Gibbons3-Feb-04 4:03
Adrian Gibbons3-Feb-04 4:03 
GeneralRe: Select list item with mouse Pin
S.Cartwright3-Jun-04 19:33
S.Cartwright3-Jun-04 19:33 
GeneralRe: Select list item with mouse Pin
Adrian Gibbons3-Jun-04 23:32
Adrian Gibbons3-Jun-04 23:32 
Hey Sam, I sure did manage to solve the problem. I think you've posted a similar solution in your next post but this is my code from PreTranslateMessage():

if(pMsg->hwnd == m_lbListBox.m_hWnd && pMsg->message == WM_LBUTTONDBLCLK)
{
PostMessage(WM_CHAR, VK_RETURN);

return TRUE; // Don't dispatch message.
}

if(pMsg->message == WM_MOUSEWHEEL && m_lbListBox.GetSafeHwnd())
{
CPoint pt = (CPoint)pMsg->lParam;
CRect rcLB;
m_lbListBox.GetWindowRect(&rcLB);

// If mouse pointer over listbox forward message.
if(rcLB.PtInRect(pt))
{
m_lbListBox.SendMessage(WM_MOUSEWHEEL, pMsg->wParam, pMsg->lParam);
}
else
{
RemoveListbox();
}

return TRUE; // Don't dispatch message.
}

Double clicking an item with the mouse cursor stimulates a enter key press. The list will scroll with the mouse wheel if the cursor is over it, otherwise the view will be scrolled and the list box removed.

Hope this helps,

Adrian.
GeneralRe: Select list item with mouse Pin
S.Cartwright3-Jun-04 22:06
S.Cartwright3-Jun-04 22:06 
GeneralProblem with scrolling Pin
arikgreen6-Sep-03 14:15
arikgreen6-Sep-03 14:15 
Generaldo not appear inside a text Pin
mmueller22-May-03 8:14
mmueller22-May-03 8:14 
Generalbug with tabs Pin
mmueller22-May-03 7:41
mmueller22-May-03 7:41 
GeneralRe: bug with tabs Pin
Ganesan Subramaniam15-Jan-04 3:44
sussGanesan Subramaniam15-Jan-04 3:44 
GeneralListbox disapears Pin
Skipla20-Feb-03 12:14
Skipla20-Feb-03 12:14 
GeneralRe: Listbox disapears Pin
S.Cartwright3-Jun-04 19:36
S.Cartwright3-Jun-04 19:36 
Generalbug: list box leaves artifacts Pin
hector80111-Feb-03 20:18
hector80111-Feb-03 20:18 
QuestionHow to implement in CRichEditView? Pin
RickGavin5-Aug-02 20:42
RickGavin5-Aug-02 20:42 
AnswerRe: How to implement in CRichEditView? Pin
Paolo Vernazza7-Aug-02 1:30
Paolo Vernazza7-Aug-02 1:30 
GeneralRe: How to implement in CRichEditView? Pin
allelimo18-Nov-02 3:23
allelimo18-Nov-02 3:23 
GeneralRe: How to implement in CRichEditView? Pin
Adrian Gibbons11-Dec-03 2:05
Adrian Gibbons11-Dec-03 2:05 
AnswerRe: How to implement in CRichEditView? Pin
worldtree113-Apr-06 18:26
worldtree113-Apr-06 18:26 
GeneralThis is Great Pin
ColinDavies14-Jul-02 19:32
ColinDavies14-Jul-02 19:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.