AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Autocomplete (Combobox)

Ein Thema von VkPenguin · begonnen am 22. Nov 2014 · letzter Beitrag vom 26. Nov 2014
Antwort Antwort
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#1

Autocomplete (Combobox)

  Alt 22. Nov 2014, 22:20
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!
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.323 Beiträge
 
Delphi XE2 Professional
 
#2

AW: Autocomplete (Combobox)

  Alt 22. Nov 2014, 23:25
vielleicht hilft dir das hier weiter: http://www.s170867368.online.de/delphi/combo.php
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#3

AW: Autocomplete (Combobox)

  Alt 23. Nov 2014, 00:34
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.
Angehängte Dateien
Dateityp: zip AutoComplete_Example.zip (546,6 KB, 55x aufgerufen)

Geändert von hathor (23. Nov 2014 um 01:21 Uhr)
  Mit Zitat antworten Zitat
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#4

AW: Autocomplete (Combobox)

  Alt 25. Nov 2014, 08:55
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!
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#5

AW: Autocomplete (Combobox)

  Alt 25. Nov 2014, 09:56
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.
Angehängte Dateien
Dateityp: zip AUTOCOMPLETE-1.zip (556,7 KB, 62x aufgerufen)

Geändert von hathor (25. Nov 2014 um 19:16 Uhr)
  Mit Zitat antworten Zitat
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#6

AW: Autocomplete (Combobox)

  Alt 25. Nov 2014, 18:12
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.
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#7

AW: Autocomplete (Combobox)

  Alt 25. Nov 2014, 18:51
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?
  Mit Zitat antworten Zitat
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#8

AW: Autocomplete (Combobox)

  Alt 26. Nov 2014, 09:07
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!
  Mit Zitat antworten Zitat
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#9

AW: Autocomplete (Combobox)

  Alt 26. Nov 2014, 16:01
...ich musste zwar eine ganze Weile basteln, aber jetzt hab ichs dann deinem Link hinbekommen, vielen Dank!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:22 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