santiago14,
Cita:
Empezado por santiago14
...estoy buscando la forma de hacer el autocompletado...Si hay una solución mas simple, mejor...
|
Revisa este código basado en la solución sugerida en el
Msg #4 y en el
comportamiento de la función SHAutoComplete (Windows API):
Código Delphi
[-]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, StrUtils, ExtCtrls;
type
TComboBox = class(StdCtrls.TComboBox)
private
VK : Boolean;
AuxText : String;
History : String;
FStoredItems : TStringList;
procedure FilterItems;
procedure StoredItemsChange(Sender: TObject);
procedure SetStoredItems(const Value: TStringList);
procedure ComboExit(Sender: TObject);
procedure ComboCloseUp(Sender: TObject);
procedure ComboKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure CNCommand(var Message: TWMCommand); Message CN_COMMAND;
protected
public
constructor Create(Owner: TComponent); override;
destructor Destroy; override;
property StoredItems : TStringList read FStoredItems write SetStoredItems;
end;
type
TForm1 = class(TForm)
ComboBox1 : TComboBox;
Button1 : TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
constructor TComboBox.Create(Owner: TComponent);
var
FS : TFileStream;
begin
inherited;
AutoComplete := False;
FStoredItems := TStringList.Create;
FStoredItems.OnChange := StoredItemsChange;
History := 'History.txt';
Self.OnExit := ComboExit;
Self.OnCloseUp := ComboCloseUp;
Self.OnKeyDown := ComboKeyDown;
Self.Sorted := True;
Self.DropDownCount := 30;
if not FileExists(History) then
begin
FS := TFileStream.Create(History, fmCreate);
FS.Free;
end;
Self.StoredItems.LoadFromFile(History);
end;
destructor TComboBox.Destroy;
begin
FStoredItems.Free;
inherited;
end;
procedure TComboBox.CNCommand(var Message: TWMCommand);
begin
inherited;
if Message.NotifyCode = CBN_EDITUPDATE then
FilterItems;
end;
procedure TComboBox.FilterItems;
var
i : Integer;
StartPos, EndPos : Integer;
begin
SendMessage(Handle, CB_GETEDITSEL, WPARAM(@StartPos), LPARAM(@EndPos));
AuxText := Text;
if Text <> '' then
begin
Items.Clear;
for i := 0 to FStoredItems.Count - 1 do
begin
if PosEx(LowerCase(Text), LowerCase(FStoredItems[i])) > 0 then
Items.Add(FStoredItems[i]);
end;
end
else
Items.Assign(FStoredItems);
SendMessage(Handle, CB_SHOWDROPDOWN, Integer(True), 0);
Text := AuxText;
SendMessage(Handle, CB_SETEDITSEL, 0, MakeLParam(StartPos, EndPos));
end;
procedure TComboBox.StoredItemsChange(Sender: TObject);
begin
if Assigned(FStoredItems) then
FilterItems;
end;
procedure TComboBox.SetStoredItems(const Value: TStringList);
begin
if Assigned(FStoredItems) then
FStoredItems.Assign(Value)
end;
procedure TComboBox.ComboExit(Sender: TObject);
begin
if (Items.IndexOf(Text) = -1) and (Text <> EmptyStr) then
begin
FStoredItems.Add(Text);
FStoredItems.SaveToFile(History);
end;
end;
procedure TComboBox.ComboCloseUp(Sender: TObject);
begin
If (AuxText <> EmptyStr) and (VK = False) then
begin
Text := AuxText;
end;
VK := False;
end;
procedure TComboBox.ComboKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if (Key = VK_UP) or (Key = VK_DOWN) then
VK := True;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(ComboBox1.Text);
end;
end.
El código anterior
simula de forma básica la función SHAutoComplete en un componente TComboBox modificado, como se muestra en la siguiente imagen:
El ejemplo esta disponible en el link:
http://terawiki.clubdelphi.com/Delph...e_ComboBox.rar
Espero sea útil
Nelson.