Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

TEdit с возможностью автоматического выбора

01.01.2007
...маленький компонент THintEdit, порожденный от TCustomEdit, который представляет собой с виду обычный TEdit элемент с возможностью автоматического выбора стринговых значений из скрытого списка (так, как это реализовано в Netscape Navigator'е). Описание особенно не нужно, так как выполнено все достаточно элементарно: значения для выбора заносятся в свойство HintList, тип свойства TStrings. При нажатии клавиш вверх/вниз выбираются значения, соответствующие набранным начальным символам.

unit HintEdit;
 
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;
 
type
  THintEdit = class(TCustomEdit)
  private
    { Private declarations }
    FHintList: TStrings;
    Searching,
      CanSearch: boolean;
    CurSPos: integer;
  protected
    { Protected declarations }
    procedure Change; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    property HintList: TStrings read FHintList write FHintList;
    destructor Destroy; override;
  published
    { Published declarations }
    property Anchors;
    property AutoSelect;
    property AutoSize;
    property BiDiMode;
    property BorderStyle;
    property CharCase;
    property Color;
    property Constraints;
    property Ctl3D;
    property DragCursor;
    property DragKind;
    property DragMode;
    property Enabled;
    property Font;
    property HideSelection;
    property ImeMode;
    property ImeName;
    property MaxLength;
    property OEMConvert;
    property ParentBiDiMode;
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PasswordChar;
    property PopupMenu;
    property ReadOnly;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Text;
    property Visible;
    property OnChange;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDock;
    property OnStartDrag;
  end;
 
procedure Register;
 
implementation
 
{$R *.DCR}
 
procedure Register;
begin
  RegisterComponents('Netscape', [THintEdit]);
end;
 
constructor THintEdit.Create;
begin
  inherited;
  FHintList := TStringList.Create;
  Searching := false;
  CanSearch := true;
  CurSPos := -1;
end;
 
procedure THintEdit.Change;
var
  i, l: integer;
begin
  if Searching then
    Exit;
  if not CanSearch then
    Exit;
  if Text = '' then
    exit;
  l := Length(Text);
  for i := 0 to FHintList.Count - 1 do
    if Copy(FHintList[i], 1, l) = Text then
    begin
      Searching := true;
      CurSPos := i;
      Text := FHintList[i];
      Searching := false;
      SelStart := Length(Text);
      SelLength := -(Length(Text) - l);
      break;
    end;
  inherited;
end;
 
procedure THintEdit.KeyDown;
var
  l: integer;
begin
  if Chr(Key) in ['A'..'z', 'А'..'Я', 'а'..'я'] then
    CanSearch := true
  else
    CanSearch := false;
  case Key of
    VK_DOWN:
      begin
        if (CurSPos < HintList.Count - 1) and (SelLength > 0) then
          if Copy(FHintList[CurSPos + 1], 1, SelStart) = Copy(Text, 1, SelStart)
            then
          begin
            l := SelStart;
            Inc(CurSPos);
            Text := FHintList[CurSPos];
            SelStart := Length(Text);
            SelLength := -(Length(Text) - l);
          end;
        Key := VK_RETURN;
      end;
    VK_UP:
      begin
        if (CurSPos > 0) and (SelLength > 0) then
          if Copy(FHintList[CurSPos - 1], 1, SelStart) = Copy(Text, 1, SelStart)
            then
          begin
            l := SelStart;
            Dec(CurSPos);
            Text := FHintList[CurSPos];
            SelStart := Length(Text);
            SelLength := -(Length(Text) - l);
          end;
        Key := VK_RETURN;
      end;
    VK_RETURN:
      begin
        SelStart := 0;
        SelLength := Length(Text);
      end;
  end;
  inherited;
end;
 
destructor THintEdit.Destroy;
begin
  FHintList.Free;
  inherited;
end;
 
 

https://delphiworld.narod.ru/

DelphiWorld 6.0

 

Подстановка в TEdit

var
  words: TStringList;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  words := TStringList.Create;
  words.Sorted := true;
  words.Add('one');
  words.Add('two');
  words.Add('four');
  words.Add('five');
  words.Add('six');
  words.Add('seven');
  words.Add('eight');
  words.Add('nine');
  words.Add('ten');
end;
 
procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
const
  chars: set of char = ['A'..'Z', 'a'..'z', 'А'..'Я', 'а'..'я'];
var
  w: string;
  i: integer;
  s: string;
  full: string;
  SelSt: integer;
begin
  case Key of
    VK_RETURN, VK_TAB:
    begin
      Edit1.SelStart := Edit1.SelStart + Edit1.SelLength;
      Edit1.SelLength := 0;
      Exit;
    end;
    VK_DELETE, VK_BACK:
    begin
      Edit1.ClearSelection;
      Exit;
    end;
  end;
  s := Edit1.Text;
  SelSt := Edit1.SelStart;
  i := SelSt;
  if (length(s) > i) and (s[i+1] in chars) then
    Exit;
  w := '';
  while (i >= 1) and (s[i] in chars) do
  begin
    w := s[i] + w;
    dec(i);
  end;
  if length(w) <= 0 then
    Exit;
  words.Find(w, i);
  if (i >= 0) and (UpperCase(copy(words[i], 1,
  length(w))) = UpperCase(w)) then
  begin
    full := words[i];
    insert(copy(full, length(w) + 1, length(full)), s, SelSt + 1);
    Edit1.Text := s;
    Edit1.SelStart := SelSt;
    Edit1.SelLength := length(full) - length(w);
  end;
end;

https://delphiworld.narod.ru/

DelphiWorld 6.0