AutoComplete without IAutoComplete






4.90/5 (44 votes)
An AutoCompletion control that doesn't use IAutoComplete but still retains the same look and feel.
Introduction
There have been already several articles on AutoComplete functions on CodeProject. Many subclass a CEdit
or CComboBox
and complete the input in the control or show a variety in the dropdown list. Another option is to use the IAutoComplete
with IEnumString
and quite a lot of other I functions.
When I saw the WTL-AutoComplete function by Klaus Probst, I thought, "cool, but all that should be working even without Internet Explorer and cryptic calls". And, even more, fairly easily.
How to use
Copy the files (ACEdit.cpp/h + ACListWnd.cpp/h) into the project directory, then add them to the project and insert the header, preferably in stdafx.h.
#include "ACEdit.h"
Declare a CEdit
or a CComboBox
and subclass it to CACEdit
bevorehand: CEdit m_EditCtrl1; afterwards: CACEdit m_EditCtrl1;
Afterwards initialise the control and define the mode, e.g. in OnInitDialog
.
m_EditCtrl1.Init();
m_EditCtrl1.SetMode(); // default = _MODE_STANDARD_
Possible modes could be:
_MODE_STANDARD_
_MODE_SEPARATION_
_MODE_FILESYSTEM_
_MODE_FS_ONLY_FILE_
_MODE_FS_ONLY_DIR_
_MODE_FS_START_DIR_
_MODE_SD_ONLY_FILE_
_MODE_SD_ONLY_DIR_
_MODE_CURSOR_O_LIST_
_MODE_FIND_ALL_
.
See further down for more explanations. If you forget Init()
, the initialisation will be made up later in SetMode()
.
Finally, insert the strings. There are two different methods to do this: AddSearchString
and AddSearchStrings
.
m_EditCtrl1.AddSearchString("Test1"); m_EditCtrl1.AddSearchString("Test2"); m_EditCtrl1.AddSearchString("Tiger"); m_EditCtrl1.AddSearchString("Dog"); or static LPCTSTR STRINGS[] = { _T("Test1"), _T("Test2"), _T("Tiger"), _T("Dog"), NULL }; m_EditCtrl1.AddSearchStrings(STRINGS);
Before the insertion of the strings, the function AddSearchStrings()
calls RemoveSearchAll()
, and clears the internal item list of the type CStringArray
. AddSearchStrings()
can be combined with AddSearchString()
, but this doesn’t work vice versa. A specific deletion of strings is not implemented at present.
This is all we need for a simple AutoComplete. Moreover, there is a possibility to implement separators. A m_EditCtrl1.SetSeparator(_T("\\"));
causes a \ to function as a beginning or end of a line. If you enter XXX\t\YYY, in our example you will see a list including Test1, Test2 and Tiger.
But if the user enters xxTi, however, this fails. If you use constants like <Parameter1> (constants enclosed in brace characters, in our example <>). Then the possibility is given to extend the command SetSeparator()
with a prefix, that is the first sign of your constants. The prefix must not be part of the SearchStrings
. However, it does appear in the list and is part of a result.
... m_EditCtrl1.AddSearchString("PARAMETER1>"); // without prefix! m_EditCtrl1.AddSearchString("PARAMETER2>"); m_EditCtrl1.AddSearchString("PARAMETER3>"); m_EditCtrl1.SetSeparator("<",'<'); ...
This example yields the result as well if entered XXX< or /<.
And AutoComplete for the file system:
... m_DirEdit.SetMode(_MODE_FILESYSTEM_); ...
Now, when you start typing a path, the control will drop down a list with paths that match what you've typed so far - run-command in the start menu (in Win2K or on machines with IE 5.0).
SetMode(_MODE_FS_ONLY_FILE_)
lists files only and SetMode(_MODE_FS_ONLY_DIR_)
only lists directories.
m_DirEdit.SetMode(_MODE_FS_START_DIR_);
m_DirEdit.SetStartDirectory(_T("C:\\Windows\\"));
...
If you use either SetMode() _MODE_FS_START_DIR_, _MODE_SD_ONLY_FILE_
or _MODE_SD_ONLY_DIR_
, a directory can be indicated by SetStartDirectory()
.
In the example above, the control lists all files in C:\Windows, but in contrast to _MODE_FILESYSTEM_
without showing the path (C:\Windows).
Version 1.2
-Fix: _MODE_SD_ONLY_DIR_
-Fix: OnActivateApp()
VC6/VC7 compiler adaptation
-Fix: OnGetMinMaxInfo()
following the suggestions of "yogurt" (cp. comments)
-_MODE_FIND_ALL_
for SetMode()
if you enter on, the function finds One, One1, Melon, Lemon, ...
Version 1.1
ComboBox-Support:
-int AddString( LPCTSTR lpszString);
-int GetLBText( int nIndex, LPTSTR lpszText );
-void GetLBText( int nIndex, CString& rString );
-int SetDroppedWidth(UINT nWidth);
-int FindString( int nStartAfter, LPCTSTR lpszString );
-int SelectString( int nStartAfter, LPCTSTR lpszString );
-void ShowDropDown(BOOL bShowIt = TRUE );
-void ResetContent();
-int GetCurSel();
and
_MODE_CURSOR_O_LIST_
(Open the List with Corsorkeys)
If this flag is set with SetMode()
, it is already possible to indicate the list of the search strings with the cursor keys (UP/DOWN) in an empty input field. This works only with a CEdit control, however, as the cursor keys in a ComboBox have different functions.
Conclusion
The control looks like the function in Windows (which triggered the project), but it works entirely withoutIAutoComplete
. There are definitely various ways to extend it, but as it works the way it should, I’m fine with it. Hopefully, the control will be of use to you – I had fun writing it.
Sources:
- IAutoComplete and custom IEnumString implementation for WTL dialogs
(Klaus Probst)
my stirring inspiration - Autocompletion and the ACTest Demo App
(Paul DiLascia)
the recognition trick for ComboBox/Edit Control - An Enhanced CCheckComboBox
(Magerusan Grigore Cosmin)
shows how to keep a window inactive when selected (Create)