18

Everyone probably knows what I mean, but to clarify the control would need to:

  • Fire an event when user edits the text. The event would provide a SuggestionList: TStrings which you could fill with matches/suggestions.
  • if the SuggestionList is not empty a drop down should appear.
  • Unlike combo, the control should not attempt to automatically select/auto complete or otherwise affect the editing.

So, is there a Delphi edit/combo control that works like that ?

kapa
  • 77,694
  • 21
  • 158
  • 175

5 Answers5

25

Use the autocompletion feature built in to all Windows edit controls.

First, fill your TStrings object however you want. Then use GetOleStrings to create a TStringsAdapter to wrap it. (The adapter does not claim ownership of the TStrings object, so you must make sure you don't destroy it while the adapter is still live.) The adapter gives you an IStrings interface, which you'll need because the autocompletion feature requires an IEnumString interface to provide the completion matches. Call _NewEnum for that.

Next, call CoCreateInstance to create an IAutoComplete object. Call its Init method to associate it with the window handle of your edit control. If you're using a combo box, then send it a cbem_GetEditControl message to find the underlying edit window.

You can stop at that point and autocompletion should work automatically. You can disable autocompletion if you want, or you can set any number of autocompletion options.

You say you don't want autocompletion, but in the OS terminology, I think what you really don't want is called auto append, where the remainder of the string is entered into the edit box automatically as the user types, but selected so that further typing will overwrite it, and the user needs to delete the excess text if the desired value is shorter than one of the matches.

There is also auto suggest, which displays a drop-down list of suggestions.

You can enable either or both options. You don't need to filter the list of suggestions yourself; the autocomplete object filters the IEnumString list by itself.

menjaraz
  • 7,551
  • 4
  • 41
  • 81
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • This is nothing short of perfect, precisely what I want, I wasn't aware of autocompletion options, thanks. –  Jan 12 '10 at 08:45
  • IAutoComplete doesn't seem to support matching of any partial string, but only supports matching from the start. I mean, given two strings, 'bcd' and 'abcd', if I type 'bc', only 'bcd' will be matched, but I also want 'abcd' to be matched also. – Edwin Yip Oct 07 '12 at 03:55
  • Then "autocomplete" isn't the feature you wanted in the first place, @Edwin. It *completes* what you've already typed. – Rob Kennedy Oct 07 '12 at 12:54
  • how it supports multiple entry? like outlook recipient edit box? – FLICKER Nov 19 '13 at 20:03
  • 1
    @Mohammad, the comments of an almost-four-year-old answer are not the place to ask a new question. Please use the "ask question" button at the top of the page. – Rob Kennedy Dec 02 '13 at 22:30
4

You can use standard TComboBox and faststrings library (for stringMatches() function).

procedure TForm1.cbChange(Sender: TObject);
var
  s:Integer;
  tmpstr:string;
begin
  //suggestions: tstringlist
  cb.AutoComplete:=false;
  tmpstr:=cb.Text;
  cb.Items.Clear;
  for s:=0 to suggestions.Count - 1 do
    if StringMatches(suggestions[s],cb.Text+'*') then
      cb.Items.Add(suggestions[s]);
  cb.DroppedDown:=(cb.Items.Count<>0) and (Length(cb.Text)<>0);
  cb.Text:=tmpstr;
  cb.SelStart:=Length(cb.Text)
end;
Wolf
  • 9,679
  • 7
  • 62
  • 108
bmeric
  • 1,124
  • 1
  • 17
  • 27
  • 1
    Yes, this is close, but has few issues. When you enter first character in an empty combo, for a split second it will autocomplete it before you set the cb.text back to what it was. Also if you move the focus to some other control while the dropdown is visible it will again autocomplete. And if you use the up/down keys to navigate the drop down items the text will again get autocompleted. And lastly you set the SelStart to the last character, but it should be set to where it was, so SelStart needs to be stored at the begging of the method and restored at the end. –  Jan 06 '10 at 16:36
3

If you just want to show a file or url list:

SHAutoComplete(GetWindow(eb_MyComboBox->Handle, GW_CHILD), SHACF_AUTOSUGGEST_FORCE_ON | SHACF_FILESYS_DIRS);
RRUZ
  • 134,889
  • 20
  • 356
  • 483
pcunite
  • 1,197
  • 15
  • 23
2

I first implemented this feature like Rob described it in his answer. Later I saw that TComboBoxEx has the property AutoCompleteOptions where I set acoAutoSuggest to True and acoAutoAppend to False. The ComboBox now filters its item list when doing some entry and shows the matching items.

I'm using RAD Studio 10 Seattle and XE2 but don't know if this feature is available in older versions.

Kerem
  • 429
  • 5
  • 20
1

To the last bit of your question: "So, is there a Delphi edit/combo control that works like that ?":

A bit late to the party but yes, I have written a free and open source component that implements the Google Place Autocomplete and Google Place Details API's:

It does inherit from the standard TComboBox but you can modify the code to work with any TEdit

https://carbonsoft.co.za/components/

or

https://github.com/RynoCoetzee/TRCGPlaceAutoCompleteCombo

Ryno Coetzee
  • 516
  • 4
  • 13