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 Suche im VST - Suche nächster - Suche vorheriger (https://www.delphipraxis.net/61176-suche-im-vst-suche-naechster-suche-vorheriger.html)

ratloser 17. Jan 2006 21:04


Suche im VST - Suche nächster - Suche vorheriger
 
Hallo an Alle!

Hab mal wieder ein kleines Problem :gruebel: :gruebel: :gruebel:

Hab im VirtualStringTree eine Suche eingebaut.
Es gibt dabei vier verschiedene Felder zur Eingabe von Suchbegriffen.

Diese vier Suchbegriffe werden über einen ONExit-Event in die Variable suchobjekttext eingelesen.

Button7 startet die Suche - VST findet dabei den ersten Suchbegriff.

Delphi-Quellcode:
procedure TKalk.Button7Click(Sender: TObject);
var
  f ,run : PVirtualNode;
  suchobjekt: String;
begin
   suchzaehler := 0;
   suchobjekt := suchobjekttext;
   vst.FocusedNode := vst.getfirst;
   vst.FullCollapse;
   vst.SetFocus;
  if assigned(vst.FocusedNode) then begin
    run := vst.FocusedNode;
    while Assigned(run) do begin
      f := vst.IterateSubTree(run,ausfuehren,Pointer(suchobjekt),[],true,false);
      if assigned(f) then begin
        vst.FocusedNode := f;
        vst.Selected[f] := true;
        break;
      end;
      run := run.NextSibling;
    end;
  end;
end;
Nachfolgender Code soll den vorherigen Eintrag suchen

Delphi-Quellcode:
procedure TKalk.vorherigeneintragsuchenClick(Sender: TObject);
var
  f ,run : PVirtualNode;
  suchobjekt: String;
  laufenderzaehler: integer;
begin
   if suchzaehler > 0 then suchzaehler := suchzaehler - 1;
   laufenderzaehler:= suchzaehler;
   suchobjekt := suchobjekttext;
   vst.FocusedNode := vst.getfirst;
   vst.SetFocus;
  if assigned(vst.FocusedNode) then begin
    run := vst.FocusedNode;
    while Assigned(run) do begin
      f := vst.IterateSubTree(run,ausfuehren,Pointer(suchobjekt),[],true,false);
      if assigned(f) then begin
        if laufenderzaehler = suchzaehler then
        begin
           vst.FocusedNode := f;
           vst.Selected[f] := true;
           break;
        end
        else
        laufenderzaehler := laufenderzaehler + 1;
      end;
      run := run.NextSibling;
    end;
  end;
end;
Nachfolgender Code soll den nächsten Eintrag finden:

Delphi-Quellcode:
procedure TKalk.naechsteneintragsuchenClick(Sender: TObject);
var
  f ,run : PVirtualNode;
  suchobjekt: String;
  laufenderzaehler: integer;
begin
   suchzaehler := suchzaehler + 1;
   laufenderzaehler:= 0;
   suchobjekt := suchobjekttext;
   vst.FocusedNode := vst.getfirst;
   vst.SetFocus;
  if assigned(vst.FocusedNode) then begin
    run := vst.FocusedNode;
    while Assigned(run) do begin
      f := vst.IterateSubTree(run,ausfuehren,Pointer(suchobjekt),[],true,false);
      if assigned(f) then begin
        if laufenderzaehler = suchzaehler then
        begin
           vst.FocusedNode := f;
           vst.Selected[f] := true;
           break;
        end
        else
        laufenderzaehler := laufenderzaehler + 1;
      end;
      run := run.NextSibling;
    end;
  end;
end;
Nun zu meinem Problem:

Die Suche funktioniert einwandfrei, die Suche nach dem nächsten oder vorherigen Eintrag funktioniert eigentlich auch - solange ich nicht den letzten Sucheintrag erreiche. Wenn ich den letzten Sucheintrag erreiche und dann nochmals auf NÄCHSTEN FINDEN klicke, dann weiss ich nicht, wie ich die Suche stoppen soll - eigentlich sollte er anzeigen - LETZTEN EINTRAG GEFUNDEN.

Macht er aber nicht, und wenn ich dann auf VORHERIGEN SUCHEN klicke, dann springt er völlig unmotiviert zu irgenwelchem Eintrag.

Hat jemand eine Idee.

LG Ratloser

ratloser 20. Jan 2006 16:16

Re: Suche im VST - Suche nächster - Suche vorheriger
 
Ich kämpfe immer noch am selben Problem, hab leider noch keine Lösung gefunden.

Eigentlich müsste ich ja nur den letzten Eintrag abfragen können.

Vielleicht hat dazu jemand eine Idee.

LG Ratloser

Overclocker 25. Feb 2008 09:07

Re: Suche im VST - Suche nächster - Suche vorheriger
 
Hi,

genau das was du hier programmiert hast suche ich auch, nur irgendwie find ich keine lösung zum TVTGetNodeProc

ausfuehren ist ja vom Typ TVTGetNodeProc doch wie ist das ganze definiert???



Danke für die Hilfe

generic 25. Feb 2008 10:16

Re: Suche im VST - Suche nächster - Suche vorheriger
 
wenn ich es nicht ganz falsch verstanden habe:
Delphi-Quellcode:
  ta = class
    fs: string;
    constructor Create(s:string);
  end;

// musterdaten
procedure TForm1.Button1Click(Sender: TObject);
var
  nodea,nodeb: PVirtualNode;
begin
  VirtualStringTree1.NodeDataSize:=sizeof(ta);

  nodea:=VirtualStringTree1.AddChild(nil, ta.Create('a'));
  nodeb:=VirtualStringTree1.AddChild(nodea, ta.Create('aa'));
  VirtualStringTree1.AddChild(nodeb, ta.Create('aaa'));
  nodeb:=VirtualStringTree1.AddChild(nodea, ta.Create('ab'));
  VirtualStringTree1.AddChild(nodeb, ta.Create('aba'));
  VirtualStringTree1.AddChild(nodeb, ta.Create('abb'));

  nodea:=VirtualStringTree1.AddChild(nil, ta.Create('b'));
  nodeb:=VirtualStringTree1.AddChild(nodea, ta.Create('ba'));
  VirtualStringTree1.AddChild(nodeb, ta.Create('baa'));
  nodeb:=VirtualStringTree1.AddChild(nodea, ta.Create('bb'));
  VirtualStringTree1.AddChild(nodeb, ta.Create('bba'));
  VirtualStringTree1.AddChild(nodeb, ta.Create('bbb'));

  VirtualStringTree1.FullExpand();
end;

// vorwärtssuche

procedure TForm1.Button2Click(Sender: TObject);
var
  node: PVirtualNode;
  a: ta;
begin
  VirtualStringTree1.ClearSelection;
  if VirtualStringTree1.FocusedNode=nil then
    node:=VirtualStringTree1.GetFirst
  else
    node:=VirtualStringTree1.FocusedNode;

  while node<>nil do
  begin
    node:=VirtualStringTree1.GetNext(node);
    if node=nil then
    begin
      MessageDlg('ende', mtWarning, [mbOK], 0);
      break;
    end;

    a:=ta(VirtualStringTree1.GetNodeData(node)^);
    if pos(Edit1.text, a.fs)>0 then
    begin
      VirtualStringTree1.FocusedNode:=node;
      VirtualStringTree1.Selected[node]:=true;
      break;
    end;
  end;

end;

// rückwärtssuche
procedure TForm1.Button3Click(Sender: TObject);
var
  node: PVirtualNode;
  a: ta;
begin
  VirtualStringTree1.ClearSelection;
  if VirtualStringTree1.FocusedNode=nil then
    node:=VirtualStringTree1.GetFirst
  else
    node:=VirtualStringTree1.FocusedNode;

  while node<>nil do
  begin
    node:=VirtualStringTree1.GetPrevious(node);
    if node=nil then
    begin
      MessageDlg('ende', mtWarning, [mbOK], 0);
      break;
    end;

    a:=ta(VirtualStringTree1.GetNodeData(node)^);
    if pos(Edit1.text, a.fs)>0 then
    begin
      VirtualStringTree1.FocusedNode:=node;
      VirtualStringTree1.Selected[node]:=true;
      break;
    end;
  end;

end;

procedure TForm1.VirtualStringTree1GetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: WideString);
var
  a: ta;
begin
  a:=ta(sender.GetNodeData(node)^);
  CellText:=a.fs;
end;

{ ta }

constructor ta.Create(s: string);
begin
  inherited Create;   
  fs:=s;
end;

Overclocker 25. Feb 2008 10:43

Re: Suche im VST - Suche nächster - Suche vorheriger
 
Hey,

danke für deinen ausführlichen Code.

bei mir kommt an der position

if pos(srcsearch.text, a.fs)>0 then

eine Zugrifssverletzung. woran kann das liegen?habe einfach nur deinen code reinkopiert und die bezeichnungen ausgetauscht

generic 25. Feb 2008 14:15

Re: Suche im VST - Suche nächster - Suche vorheriger
 
warscheinlich bei
Delphi-Quellcode:
a:=ta(VirtualStringTree1.GetNodeData(node)^);
das Dach hinten vergessen oder dein Searchobj ist nicht mehr richtig.

Overclocker 25. Feb 2008 14:45

Re: Suche im VST - Suche nächster - Suche vorheriger
 
das dach habe ich nicht vergessen, wie gesagt copy und paste :)

und mein srcsearch.text (ist ein edit feld) stimmt auch.... wenn ich das ganze weglösche ohne If dann kommt kein fehler,allerdings sucht er auch dann nicht sondern wählt einfach immer den nächsten node aus (im endeffekt springt er einfach nur zeile für zeile den baum durch)

Lun 25. Feb 2008 15:28

Re: Suche im VST - Suche nächster - Suche vorheriger
 
Hi @ll,

habe die Fowardsuche gerade mal getestet bei mir funktioniert die, ich benutze wohl als Datentyp Objekte von ner Klasse, aber ich denke das dürfte ja nicht viel ändern. Hier mal der code, wobei er sich nicht großartig unterscheidet von generics.

Delphi-Quellcode:
procedure TForm1.FindDialog1Find(Sender: TObject);
var
  node: PVirtualNode;
  Data: PTreeData;
begin
   VST.ClearSelection;
  if (VST.FocusedNode=nil) then begin
    node:=VST.GetFirst
  end
  else begin
    node:=VST.FocusedNode;
    while node<>nil do
    begin
      node:=VST.GetNext(node);
    if node=nil then
    begin
      MessageDlg('ende', mtWarning, [mbOK], 0);
      break;
    end;

    Data := VST.GetNodeData(Node);

    if pos(FindDialog1.FindText,TTreeDataClass(Data.FObject).Titel) > 0 then
    begin
      VST.FocusedNode := Node;
      VST.Selected[node]:=true;
      break;
    end;
  end;

end;
end;
Mein Datentyp sieht dann so aus wie hier im Tutorial darum hab ich auch kein Dach :wink:

Vielleicht hilfts ja, also irgendwas stimmt bei dir beim Zugriff auf den String nicht deines Datentyps

greetz Lun

Overclocker 26. Feb 2008 08:33

Re: Suche im VST - Suche nächster - Suche vorheriger
 
ich glaub echt ich steh irgendwie aufm schlauch, hier mal mein code:

Delphi-Quellcode:
type TTreeDataClass = class
  private     FTestStr1: String;
               FTestint: Integer;
  published     property TestStr1: String read FTestStr1 write FTestStr1;
                 property TestInt: Integer read FTestInt write FTestInt;
  end;

type PTreeData = ^TTreeData; TTreeData = record   FObject : TObject; end;



procedure TGeoDlg.Button1Click(Sender: TObject);

var
  node: PVirtualNode;
  Data: PTreeData;
begin
   VST.ClearSelection;
  if (VST.FocusedNode=nil) then begin
    node:=VST.GetFirst
  end
  else begin
    node:=VST.FocusedNode;
    while node<>nil do
    begin
      node:=VST.GetNext(node);
    if node=nil then
    begin
      MessageDlg('ende', mtWarning, [mbOK], 0);
      break;
    end;

    Data := VST.GetNodeData(Node);

    if pos(srcsearch.text,TTreeDataClass(Data.FObject).FTestStr1) > 0 then //srcsearch.text = editfeld = suchwort
    begin
      VST.FocusedNode := Node;
      VST.Selected[node]:=true;
      break;
    end;
  end;

end;
end;
Ich nimm den code,geb im edi feld (srcsearch.text) ein wort ein und er macht überhaupt nix. mach ich ein paar Nodes auf und klick ein node an und such nochmal, kommt wieder an der POS stelle eine zugrifssverletzung

generic 26. Feb 2008 09:23

Re: Suche im VST - Suche nächster - Suche vorheriger
 
Ich schlage vor das ihr den Code erstmal verkleinert und er Zeigerprobleme erstmal etwas aus dem weg geht.
Delphi-Quellcode:
type PTreeData = ^TTreeData; TTreeData = record   FObject : TObject; end;
^wenn ihr eh nur Objekte in den Tree hängt könnt ihr das viel leichter haben.

Dazu nochmal dezent die Hinweise auf:
- Entwickler Magazin 02/08 Seite 68 ff.
- Das Stammtischvideo #2 zum VSThttp://www.delphipraxis.net/video.php#Stammtisch_2

Ich würde dann schauen, ob die Schutzverletztung noch auftritt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:33 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