AGB  ·  Datenschutz  ·  Impressum  







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

Komponente ComboBox mit AutoFill-Funktion

Ein Thema von eddy · begonnen am 11. Feb 2003 · letzter Beitrag vom 13. Feb 2003
Antwort Antwort
Benutzerbild von eddy
eddy

Registriert seit: 3. Jan 2003
Ort: Sachsen
573 Beiträge
 
Delphi 5 Professional
 
#1

Komponente ComboBox mit AutoFill-Funktion

  Alt 11. Feb 2003, 22:08
Hallo Leute,

ich nutze seit längerer Zeit eine Funktion, um ComboBoxen automatisch während der Eingabe zu füllen, dh. man tippt ein Zeichen, und über ein in OnChange verankertes Unterprogramm wird in den Items nach dem ersten passenden Eintrag gesucht. Wird einer gefunden, wird der Eintrag in ComboBox.Text aufgefüllt und markiert. Mit dem nächsten Zeichen wiederholt sich das Ganze.

Nachteil: Man muß bei jeder verwendeten ComboBox in KeyDown ein globale Variable LastKey mit key:word belegen, um diese dann in OnChange auszuwerten. Funktioniert, ist aber lästig.

Nun habe ich eine Komponente erzeugt, die das auch macht, ohne daß ich immer die gleichen Prozeduren hinterlegen muß.

Da es sich um meine erste eigene Komponente handelt, stelle ich das Ergebnis hier zur Diskusion zur Verfügung. Vielleicht sind ja noch ein paar Verbesserungen oder/und sinnvolle Erweiterungen möglich.

Delphi-Quellcode:
unit ComboBoxAF; //ComboBox AutoFill

interface

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

type
  TComboBoxAF = class(TComboBox)
  private
    { Private-Deklarationen }
    FAutoFill : Boolean;
    FLastKey : word;
    FOnKeyDown : TKeyEvent;
    function GetLastKey : word;
    procedure SetLastKey(key : word);
    function GetAutoFill : Boolean;
    procedure SetAutoFill(value : Boolean);
  protected
    { Protected-Deklarationen }
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure Change; override;
  public
    { Public-Deklarationen }
    constructor Create(aOwner: TComponent); override;
    Destructor Destroy; override;
    property OnKeyDown : TKeyEvent read FOnKeyDown write FOnKeyDown;
  published
    { Published-Deklarationen }
    property LastKey : word read GetLastKey write SetLastKey;
    property AutoFill : Boolean read GetAutoFill write SetAutoFill;
  end;

procedure Register;

implementation

procedure TComboBoxAF.Change;
var
  srch : string;
  ix : integer;
begin
  if Focused and AutoFill then begin
    srch := Text;
    if LastKey = $08 then begin
      LastKey := 0;
    end
    else begin
      LastKey := 0;
      ix := Perform(CB_FINDSTRING, -1, LongInt(PChar(srch)));
      if ix > CB_ERR then begin
        ItemIndex := ix;
        SelStart := Length(srch);
        SelLength := Length(Text) - length(srch);
      end;
    end;
  end;
  Inherited;
end;

procedure TComboBoxAF.KeyDown(var Key: Word; Shift: TShiftState);
begin
  Inherited; // KeyDown(Key, Shift);
  FLastKey := key;
end;

function TComboBoxAF.GetLastKey : word;
begin
  Result := FLastKey;
end;

procedure TComboBoxAF.SetLastKey(key : word);
begin
  FLastKey := key;
end;

function TComboBoxAF.GetAutoFill : Boolean;
begin
  Result := FAutoFill;
end;

procedure TComboBoxAF.SetAutoFill(value : Boolean);
begin
  FAutoFill := value;
end;

constructor TComboBoxAF.Create(aOwner: TComponent);
begin
  inherited Create(aOwner);
  FLastKey := 0;
  FAutoFill := true;
end;

Destructor TComboBoxAF.Destroy;
Begin
  inherited Destroy;
End;

procedure Register;
begin
  RegisterComponents('Beispiele', [TComboBoxAF]); //
end;

end.
mfg
eddy
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#2
  Alt 11. Feb 2003, 22:27
Hier mal die Lösung, welche ich vor Monaten auf D3K veröffentlicht habe. (Sorry, habe z.Z. gerade keine .pas Version hier rumzuliegen und war zu faul Notepad zu öffnen).

Vollständiger Artikel: http://www.delphi3000.com/articles/article_2743.asp

Delphi-Quellcode:
unit FillComboBox;

interface

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

type
  TFillComboBox = class(TComboBox)
  private
    FAutomaticFillin: Boolean;
    procedure SetAutomaticFillin(const Value: Boolean);
  protected
    procedure ComboWndProc(
      var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer
    ); override;
  public
  published
    constructor Create(AOwner: TComponent); override;
    property AutomaticFillin: Boolean
      read FAutomaticFillin
      write SetAutomaticFillin
      default True;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Standard', [TFillComboBox]);
end;

{ TFillComboBox } 

procedure TFillComboBox.ComboWndProc(
  var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer
);
var
  I: Integer;
  CurrentText: String;
begin
  inherited ComboWndProc(Message, ComboWnd, ComboProc);
  // skip processing, if turned off
  if not FAutomaticFillin then
    Exit;
  // first check whether the backspace key was pressed, we do not fill in
  // in such case!
  if Message.Msg = WM_CHAR then
  begin
    // all characters from 32 (Space) through 127 (Upper ANSI) are matched
    if TWMChar(Message).CharCode in [$20..$7F] then
    begin
      // fill in the rest of the text
      // save the current text, the user has typed
      CurrentText := Text;
      // get the first string, matching the text partially
      I := SendMessage(Handle, CB_FINDSTRING, -1, LongInt(PChar(CurrentText)));
      if I >= 0 then
      begin
        // match found!
        // load matching text, I is the position of the matching string
        Text := Items.Strings[I];
        // select the text beyond the text typed
        SelStart := Length(CurrentText);
        SelLength := Length(Text) - Length(CurrentText);
      end;
    end;
  end;
end;

constructor TFillComboBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FAutomaticFillin := True;
end;

procedure TFillComboBox.SetAutomaticFillin(const Value: Boolean);
begin
  FAutomaticFillin := Value;
end;

end.
......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Benutzerbild von eddy
eddy

Registriert seit: 3. Jan 2003
Ort: Sachsen
573 Beiträge
 
Delphi 5 Professional
 
#3
  Alt 11. Feb 2003, 23:37
Hallo sakura,

habe Deine Version soeben adaptiert, funktioniert auch unter Delphi 5. Kürzerer Quellcode ist immer effektiver.

mfg
eddy
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#4
  Alt 12. Feb 2003, 08:27
Zitat von eddy:
habe Deine Version soeben adaptiert, funktioniert auch unter Delphi 5. Kürzerer Quellcode ist immer effektiver.
Nicht immer, aber danke

Wozu dient eigentlich die Eigenschaft LastKey in Deiner Version?

......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Benutzerbild von eddy
eddy

Registriert seit: 3. Jan 2003
Ort: Sachsen
573 Beiträge
 
Delphi 5 Professional
 
#5
  Alt 12. Feb 2003, 14:36
Hallo sakura,

LastKey ist reine Übernahme aus vorangegangener Version (irgendwo aus dem Internet), die nicht als eigene Komponente definiert war, sondern mit der Standardversion funktioniert. In OnKey wurde da immer LastKey mit Key ersetzt und in OnChange wurde LastKey ausgewertet. Habe das ganze nie ohne LastKey probiert.

Jetzt würde mich nur noch interessieren, wie ich der Komponente eine anderes Icon zuordnen kann. Irgendwo habe ich das schon als Frage gesehen, aber wo nur .... ??

mfg
eddy
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#6
  Alt 12. Feb 2003, 14:48
Ist eigentlich ganz einfach: Du musst eine Resource-Datei (DCR) (z.B. mit Borlands Image Editor, im Tools/Werkzeuge Menü) erstellen, welche genau wie die Unit heisst, welche ein Bitmap (24x24 Pixel) für Deine Komponente enthält. Die Bitmap-Resource muss genauso wie Deine Komponente heissen. Wenn Du jetzt Deine Unit für die Komponente in ein Package einbindest, bindet Delphi die DCR-Datei automatisch mit ein und installiert das Bild in der Palette.

......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Benutzerbild von eddy
eddy

Registriert seit: 3. Jan 2003
Ort: Sachsen
573 Beiträge
 
Delphi 5 Professional
 
#7
  Alt 13. Feb 2003, 00:02
Hallo sakura,

vielen Dank, Du hast mich auf die richtige Spur geführt. Leider bin ich nicht zurechtgekommen.

Unter Komponenten entwickeln habe ich eine detailierte Anleitung gefunden.

mfg
eddy
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#8
  Alt 13. Feb 2003, 08:15
Zitat von eddy:
vielen Dank, Du hast mich auf die richtige Spur geführt. Leider bin ich nicht zurechtgekommen.
Gern geschehen, aber was ist Dein Problem, oder wie hast Du es gemacht?
......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Benutzerbild von eddy
eddy

Registriert seit: 3. Jan 2003
Ort: Sachsen
573 Beiträge
 
Delphi 5 Professional
 
#9
  Alt 13. Feb 2003, 17:15
Hallo sakura,

mein Fehler! Ich glaube, alles so gemacht zu haben, wie Du es beschrieben hast, aber Delphi hat trotzdem nicht mein Icon verwendet, sondern weiterhin das Standard-ComboBox-Icon. Auf der oben angegebenen Seite steht:

"Jetzt wurde das Ressourcenfenster um weitere Einträge erweitert. Unser Bitmap ist "Bitmap1". Dieses müssen wir erst mal in "TBeispielComp" umbenennen, weil unsere Komponente ja die Klasse "TBeispielComp" ist. Per Doppelklick auf den jetzt "TBeispielComp" heißenden Eintrag lässtsich das Symbol bearbeiten."

Und diese Kleinigkeit muß man wissen. Nachdem ich "Bitmap1" umbenannt habe in "TComboBoxAF" (AF = AutoFill) wurde von Delphi beim Compilieren auch das von mir gewünschte Icon verwendet.

Und nachdem ich nun weiß, wie es geht, kann ich Deine bis dato ignorierten Worte:
Zitat:
Die Bitmap-Resource muss genauso wie Deine Komponente heissen.
interpretieren. Du hast es ein wenig kürzer beschrieben, nur ich hab's nicht gleich begriffen!


mfg
eddy
  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 01:11 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