Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Autocomplete (Combobox) (https://www.delphipraxis.net/182870-autocomplete-combobox.html)

VkPenguin 22. Nov 2014 21:20

Autocomplete (Combobox)
 
Guten Abend zusammen,

ich habe eine Frage zur Combobox. Ich hätte gerne, dass diese ähnlich fungiert wie das Suchfeld in Google, also: Sobald man sie anklickt, erscheint ein dropdownmenü, dass die 5 zuletzt verwendeten Suchbegriffe anzeigt. Bei jeder Änderung des Texts soll die Anzeige dann gefiltert werden.

Ich bin soweit gekommen, dass die Eingaben automatisch gespeichert werden, sodass ich mit einer einfachen funktion die 5 Vorschläge abrufen und diese als Items in der Combobox hinzufügen kann.

Ich hätte nun aber gern, dass der oberste Vorschlag makiert ist, sodass man mit den Pfeiltasten etwas auswählen kann und die mit Enter bestätigt (oder auch anklicken). Gleichzeitig soll es aber auch möglich sein, die Vorschläge zu ignorieren und einfach weiterzuschreiben. Die Combobox makiert aber automatisch den gesamten Text. Wie kann ich das verhindern?

Ich habe zwar schon einige ähnliche Beiträge gefunden, diese haben mir aber leider nicht weitergeholfen. Hier mal meine Onchange-Routine (zunächst nur mit einem Vorschlag):
Delphi-Quellcode:
CB_ADD_Verwendung.Items.Clear;
If (not(FS_Show(CB_ADD_Verwendung.Text)='')) then
 Begin
 CB_ADD_Verwendung.AddItem(FS_Show(CB_ADD_Verwendung.Text),nil);
 SendMessage(CB_ADD_Verwendung.handle, CB_SHOWDROPDOWN, Integer(True), 0);
End
else SendMessage(CB_ADD_Verwendung.handle, CB_SHOWDROPDOWN, Integer(False), 0);
CB_ADD_Verwendung.SelStart := Length(CB_ADD_Verwendung.Text);
Vielen Dank für die Hilfe!

Helmi 22. Nov 2014 22:25

AW: Autocomplete (Combobox)
 
vielleicht hilft dir das hier weiter: http://www.s170867368.online.de/delphi/combo.php

hathor 22. Nov 2014 23:34

AW: Autocomplete (Combobox)
 
Liste der Anhänge anzeigen (Anzahl: 1)
function SHAutoComplete(hwndEdit: HWnd; dwFlags: DWORD): HResult; stdcall; external 'Shlwapi.dll';
ist die Lösung:

http://www.scalabium.com/faq/dct0148.htm

Delphi-Quellcode:
unit AutoCompleteUnit;

interface

uses Windows, StdCtrls, ComObj;

Const
  SHACF_DEFAULT = $0;
  SHACF_FILESYSTEM = $1;
  SHACF_URLHISTORY = $2;
  SHACF_URLMRU = $4;
  SHACF_URLALL = (SHACF_URLHISTORY Or SHACF_URLMRU);
  SHACF_AUTOSUGGEST_FORCE_ON = $10000000;
  SHACF_AUTOSUGGEST_FORCE_OFF = $20000000;
  SHACF_AUTOAPPEND_FORCE_ON = $40000000;
  SHACF_AUTOAPPEND_FORCE_OFF = $80000000;

function AutoComplete(editField: TEdit; dwFlags: DWORD): Boolean;

implementation

type TShAutoCompleteFunc = function(hwndEdit: HWND; dwFlags: dWord): LongInt; stdcall;

var SHAutoComplete: TShAutoCompleteFunc;
     theDLL: THandle;

function AutoComplete(editField: TEdit; dwFlags: DWORD): Boolean;
begin
  if @ShAutoComplete <> nil then
     Result := (SHAutoComplete(editField.Handle, dwFlags) = 0)
  else
    Result := false;
end;

initialization
  theDLL := LoadLibrary('shlwapi.dll');
  if theDLL <> 0 then
    @ShAutoComplete := GetProcAdress(theDLL, 'SHAutoComplete');
finalization
  if theDLL <> 0 then FreeLibrary(theDLL);
end.

VkPenguin 25. Nov 2014 07:55

AW: Autocomplete (Combobox)
 
Hallo,

vielen Dank für Eure Antworten! Ich wollte mal es mal nach der Art von Hathor versuchen, da mir das Testprojekt gut gefällt. Ich habe dazu jedoch ein paar Fragen, komme leider noch nicht von allein damit zurecht.

1. Ich habe ja bereits eine Funktion, welche die Fünf Strings raussucht, die angeboten werden sollen (das muss nach einem bestimmten Prinzip funktionieren, ist hier aber ja egal). An welcher Stelle sollte ich das denn einfügen?
2. Wo/wie rufe ich die Funktion denn auf? Im OnChange-Event des Editfeldes?
3. Wenn ich deinen Code übernehme und Compiliere bekommme ich folgende Fehlermeldung, sobald ich etwas in mein Edit-Feld eintrage:

---------------------------
Rmfproj
---------------------------
Zugriffsverletzung bei Adresse 75A66EB7 in Modul 'shell32.dll'. Lesen von Adresse FEEEFEEE.
---------------------------
OK
---------------------------

Ich habe alles erstmal einfach übernommen, nur aus "GetProcAdress" musste ich "GetProcAddress" machen, da Delphi die Funktion sonst nicht erkennt, aber das wird ja wahrscheinlich nur ein Tippfehler gewesen sein. Danke nochmal für die Hilfe!

hathor 25. Nov 2014 08:56

AW: Autocomplete (Combobox)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Im Anhang Source + EXE.
Hier ist der vollständige Sourcecode:

Delphi-Quellcode:
program AutoComplete_Example;

uses
  Forms,
  Main in 'Main.pas' {MainForm},
  UAutoComplete in 'UAutoComplete.pas';

{$R *.res}
{$R WindowsXP.res}

begin
  Application.Initialize;
  Application.Title := 'Example AutoComplete';
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
end.
//------------------------------------------------
unit Main;

interface

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

type
  TMainForm = class(TForm)
    InfoLbl: TLabel;
    EditControl: TEdit;
    OptionsBox: TGroupBox;
    FileBox: TCheckBox;
    HistoryBox: TCheckBox;
    RecentBox: TCheckBox;
    QuitBtn: TButton;
    SepBevel: TBevel;
    AppendBox: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure QuitBtnClick(Sender: TObject);
    procedure OptionChange(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  MainForm: TMainForm;
  Params: TCompleteParams;

implementation

{$R *.dfm}

procedure TMainForm.FormCreate(Sender: TObject);
begin
 DoubleBuffered := True;
 OptionsBox.DoubleBuffered := True;
 with Params do
  begin
   Options := [coeFileSystem,coeURLHistory,coeRecent];
   Append := True;
  end;
 if not AutoComplete(EditControl.Handle, Params) then raise
 Exception.Create('ERROR: Definition Auto-Complete');
end;

procedure TMainForm.QuitBtnClick(Sender: TObject);
begin
 Close;
end;

function ElementFromTag(Value: Integer): TCompleteOptionsElements;
begin
 case Value of
  1: Result := coeFileSystem;
  2: Result := coeURLHistory;
  3: Result := coeRecent;
  else Result := coeFileSystem;
 end;
end;

procedure TMainForm.OptionChange(Sender: TObject);
begin
 if Sender is TCheckBox then
  with TCheckBox(Sender), Params do
   begin
    if (Tag in [1..3]) then if Checked then
    Include(Options, ElementFromTag(Tag)) else Exclude(Options, ElementFromTag(Tag));
    if Tag = 4 then Append := Checked;
    if not AutoComplete(EditControl.Handle, Params) then raise
    Exception.Create('ERROR: Definition Auto-Complete');
   end;
end;

end.
//------------------------------------------------------
unit UAutoComplete;

interface

uses ComObj;

type
 Longword = Cardinal;

 TCompleteOptionsElements = (coeFileSystem, coeURLHistory, coeRecent);
 TCompleteOptions = set of TCompleteOptionsElements;

 TCompleteParams = record
  Options: TCompleteOptions;
  Append: Boolean;
 end;

function AutoComplete(Handle: Longword; Params: TCompleteParams): Boolean;

implementation

function SHAutoComplete(hwndEdit, dwFlags: Longword): Longword; stdcall; external 'shlwapi.dll';

const
 SHACF_AUTOAPPEND_FORCE_OFF = $80000000;
 SHACF_AUTOAPPEND_FORCE_ON  = $40000000;
 SHACF_FILESYSTEM           = $00000001;
 SHACF_URLHISTORY           = $00000002;
 SHACF_URLMRU               = $00000004;
 SHACF_NOAUTOCOMPLETE       = $00000008;

 AppendConsts: array [Boolean] of Longword = (SHACF_AUTOAPPEND_FORCE_OFF, SHACF_AUTOAPPEND_FORCE_ON);

function CompleteOptionsToFlags(Value: TCompleteOptions): Longword;
begin
 if Value = [] then Result := SHACF_NOAUTOCOMPLETE else
  begin
   Result := 0;
   if coeFileSystem in Value then Result := Result or SHACF_FILESYSTEM;
   if coeURLHistory in Value then Result := Result or SHACF_URLHISTORY;
   if coeRecent in Value then Result := Result or SHACF_URLMRU;
  end;
end;

function AutoComplete(Handle: Longword; Params: TCompleteParams): Boolean;
begin
 with Params do Result := (SHAutoComplete(Handle, CompleteOptionsToFlags(Options) or AppendConsts[Append]) = 0);
end;

end.

VkPenguin 25. Nov 2014 17:12

AW: Autocomplete (Combobox)
 
Vielen lieben Dank!

Jetzt funktioniert es, war eigentlich nur ein Flüchtigkeitsfehler.

Allerdings verstehe ich noch nicht, wie es funktioniert. Also wenn ich es richtig sehe, kann ich zumindest ElementfromTag und Optionchange ja streichen, weil ich das für meine Zwecke nicht benötige. Aber an welcher Stelle müsste ich denn anknüpfen, um meine Ergebnisse anzugeben? URLHistory etc. brauche ich ja gar nicht, ich hab ja schon die Ergebnisse, es geht nur um die Anzeige. Das müsste also im Prinzip so aussehen:

Code:
AutoComplete(EditControl.Handle, E1,..,E5);
Kannst du mir da vielleicht einen Tipp geben? Oder soll ich lieber konkrete Fragen zum Code stellen, wenn ich deinen verstehe kann ich ihn sicher auf modifizieren.

hathor 25. Nov 2014 17:51

AW: Autocomplete (Combobox)
 
Welche Daten liegen WIE und WO vor?
Wie sollen sie präsentiert und ausgewählt werden?
WOFÜR werden sie gebraucht?

Hast Du das hier
http://www.delphipraxis.net/125828-a...hedit-uvm.html
schon gesehen?

VkPenguin 26. Nov 2014 08:07

AW: Autocomplete (Combobox)
 
Ich habe eine
Code:
function FSSearch(Eingabe:String):Array [1..5] of String
,
die mir im Bezug auf den Text, den man in das Edit-Feld schreibt, die besten 5 Treffer raussucht. Diese 5 Treffer sollen genau so angezeigt und behandelt werden wie in Deinem Beispielprogramm. Ich müsste also in deine Autocomletefunktion irgendwie meine 5 Strings einfließen lassen, damit der Nutzer aus diesen wie bei Dir wählen kann. Also Quasi alles genau wie bei dir, nur, dass ich mir die Strings, die präsentiert werden sollen schon selbst raussuche.

Das Thema, welches Du verlinkt hast hab ich bisher noch nicht gesehen, schaue es mir jetzt aber mal an, danke! :)

VkPenguin 26. Nov 2014 15:01

AW: Autocomplete (Combobox)
 
...ich musste zwar eine ganze Weile basteln, aber jetzt hab ichs dann deinem Link hinbekommen, vielen Dank! :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:51 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz