unit TComboBoxSelLength;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    procedure ComboBox1KeyPress(Sender: TObject; var Key: Char);
    procedure FormCreate(Sender: TObject);
    procedure AddCharacterSet(const S: string);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// BeginExample: TComboBoxSelLength
// Property: StdCtrls.TCustomCombo.SelLength
// Property: StdCtrls.TCustomCombo.SelStart
// Routine: Graphics.GetCharsetValues
// Routine: System.Chr
// Routine: System.Copy
// Routine: System.Break

// BeginCode
{
The following example shows how to complete partial strings
typed into a combo box. The code represents the OnKeyPress
event handler of the combo box, which performs most of the
default keystroke handling before finding a matching list
item and updating the text.
Note:	This OnKeyPress event handler does not deal with the
case when the user types the Delete key. That case must be
caught in the OnKeyDown event handler instead.
Note: Set the TComboBox AutoComplete to false to turn off
default auto completion.
}
procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char);
var
  Found: boolean;
  i, ct, SelSt: Integer;
  TmpStr: string;
begin
  { first, process the keystroke to obtain the current string }
  { This code requires all items in list to be uppercase}
  if Key in ['a'..'z'] then Dec(Key,32); {Force Uppercase only!}
  ct := (Sender as TComboBox).Items.Count;
  with (Sender as TComboBox) do
  begin
    SelSt := SelStart;
    if (Key = Chr(vk_Back)) and (SelLength <> 0) then
     TmpStr := Copy(Text, 1, SelStart) + Copy(Text, SelLength + SelStart + 1, 255)
    else if Key = Chr(vk_Back) then {SelLength = 0}
     TmpStr := Copy(Text, 1, SelStart-1) + Copy(Text, SelStart + 1,255)
    else {Key in ['A'..'Z', etc]}
     TmpStr := Copy(Text, 1, SelStart) + Key + Copy(Text, SelLength + SelStart + 1, 255);
    if TmpStr = '' then Exit;
    { update SelSt to the current insertion point }
    if (Key = Chr(vk_Back)) and (SelSt > 0) then Dec(SelSt)
    else if Key <> Chr(vk_Back) then Inc(SelSt);
    Key := #0; { indicate that key was handled }
    if SelSt = 0 then
    begin
      Text:= '';
      Exit;
    end;
   {Now that TmpStr is the currently typed string, see if we can locate a match }
    Found := False;
    for i := 1 to ct do
    begin
      if Copy(Items[i - 1], 1, Length(TmpStr)) = TmpStr then
      begin
        Text := Items[i-1]; { update to the match that was found }
        ItemIndex := i-1;
        Found := True;
        Break;
      end;
    end;
    if Found then { select the untyped end of the string }
    begin
      SelStart := SelSt;
      SelLength := Length(Text) - SelSt;
    end
    else Beep;
  end;
end;

var
  CharSetList : TStringList;

procedure TForm1.AddCharacterSet(const S: string);
begin
  CharSetList.Add(S);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  CharSetList := TStringList.Create;
  Graphics.GetCharsetValues(AddCharacterSet);
  ComboBox1.Items := CharSetList;
end;
// EndCode
// EndExample: TComboBoxSelLength
end.
