AGB  ·  Datenschutz  ·  Impressum  







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

VST und ADO

Ein Thema von ucor · begonnen am 19. Apr 2005 · letzter Beitrag vom 23. Apr 2005
Antwort Antwort
ucor

Registriert seit: 19. Apr 2005
18 Beiträge
 
#1

VST und ADO

  Alt 19. Apr 2005, 18:27
Hallo,
seit einiger Zeit benutze ich Delphi und beschäftige mich zur Zeit mit dem VirtualStringTree.
Im Internet habe ich ein interresantes Beispiel gefunden, das mit dem ClientDataSet arbeitet.
Ich würde gern eine Accessdatenbankverbindung über AdoConnection und BetterADODataSet herstellen.
Das Problem liegt in der Methode FindKey, die nicht unterstützt wird. Mit Seek habe ich leider keinen
Erfolg gehabt. Ich poste mal den Sourcecode.


Code:
unit VTDBExample;

interface

   uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      VirtualTrees, StdCtrls, ExtCtrls, Provider, DB, DBClient,
      Menus, ImgList, Grids, DBGrids, ADODB, BetterADODataSet;
  type

      TBasicNode =
      class
         protected
         FCaption   : shortstring;
         FID        : longint;
         FImageIndex : longint;
         FHasChanged : boolean;

         public
         constructor Create( const sCaption : shortstring; const iID, iIndex: longint);

         property Caption    : shortstring read FCaption    write FCaption;
         property ID         : longint     read FID         write FID;
         property ImageIndex : longint     read FImageIndex write FImageIndex;
         property HasChanged : boolean     read FHasChanged write FHasChanged;
      end;

      TBasicNodeAdd =
      class(TBasicNode)
         protected
         FJobTitle  : shortstring;
         FAdd1       : shortstring;
         FAdd2       : shortstring;
         FAdd3       : shortstring;
                                                               
         public
         property Add1 : shortstring read FAdd1 write FAdd1;
         property Add2 : shortstring read FAdd2 write FAdd2;
         property Add3 : shortstring read FAdd3 write FAdd3;
         property JobTitle   : shortstring read FJobTitle   write FJobTitle;
      end;            

      PTreeData = ^TTreeData;
      TTreeData = record
      FObject : TBasicNode;
      end;


   type
      TfrmVTDBExample =
      class(TForm)
         Label1: TLabel;
         cds: TClientDataSet;
         Panel1: TPanel;
         VT: TVirtualStringTree;
         imgMaster: TImageList;
         cds3: TBetterADODataSet;
         ADOConnection1: TADOConnection;
         
         procedure FormClose(Sender: TObject; var Action: TCloseAction);
         procedure VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
         var Text: WideString);
         procedure VTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
         procedure VTInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode;
         var InitialStates: TVirtualNodeInitStates);
         procedure FormActivate(Sender: TObject);
         procedure VTGetImageIndex(Sender: TBaseVirtualTree;
         Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
         var Ghosted: Boolean; var ImageIndex: Integer);
         procedure VTCompareNodes(Sender: TBaseVirtualTree; Node1,
         Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
         procedure VTGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
         procedure VTInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode; var ChildCount: Cardinal);


         private
         procedure LoadCDS;

      end;
   
implementation
{$R *.DFM}

constructor TBasicNode.Create( const sCaption : shortstring; const iID, iIndex: longint);
   begin
      inherited Create;
      FCaption   := sCaption;
      FID        := iID;
      FImageIndex := iIndex;
   end;

   const
      FLDN_CustNo            = 0;
      FLDN_Company           = 1;
      FLDN_Addr1              = 2;
      FLDN_Addr2              = 3;
      FLDN_City              = 4;
      FLDN_State             = 5;
      FLDN_Zip               = 6;
      FLDN_Country           = 7;
      FLDN_Phone             = 8;
      FLDN_FAX               = 9;
      FLDN_TaxRate           = 10;
      FLDN_Contact           = 11;
      FLDN_LastInvoiceDate   = 12;

   procedure TfrmVTDBExample.FormActivate(Sender: TObject);
   var
      r : TRect;
   begin
      SystemParametersInfo(SPI_GETWORKAREA, 0, @r, 0);
      Height := r.Bottom-Top;
      Width := r.Right-Left;
      Application.ProcessMessages;
      LoadCDS;
   end;

   procedure TfrmVTDBExample.FormClose(Sender: TObject; var Action: TCloseAction);
   begin
      Action := caFree;
   end;

   procedure TfrmVTDBExample.LoadCDS;
   var
      Node : PVirtualNode;
   begin
      with cds do
      begin
         VT.BeginUpdate;
         try
            FileName := 'customer.cds';
            Active := True;
            IndexFieldNames := 'CustNo';
             while not eof do
                begin
                  Node := VT.AddChild(nil);
                  VT.ValidateNode( Node, False );
                  Next;
                end;
         finally
            VT.EndUpdate;
         end;
      end;
   end;

   procedure TfrmVTDBExample.VTGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
   begin
      NodeDataSize := SizeOf(TTreeData);
   end;

   procedure TfrmVTDBExample.VTInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode;
             var InitialStates: TVirtualNodeInitStates);
   var
      Data    : PTreeData;
      iImage  : integer;
   begin
      Data := Sender.GetNodeData(Node);
      iImage  := -1;
      if Sender.GetNodeLevel( Node ) = 0 then
      begin
         iImage  := 3;
         if (Node.Index < 10) then
         begin
            iImage  := 31;
            InitialStates := InitialStates + [ivsHasChildren];
         end;
      end;  
      Data.FObject := TBasicNodeAdd.Create( cds.Fields[FLDN_Company].AsString, cds.Fields[FLDN_CustNo].AsInteger, iImage );
   end;                                                                          

   procedure TfrmVTDBExample.VTInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode; var ChildCount: Cardinal);
   begin
      ChildCount := 1;
   end;
   
   procedure TfrmVTDBExample.VTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
   var
      Data: PTreeData;
   begin
      Data := Sender.GetNodeData(Node);
      Data.FObject.Free;
      Finalize( Data^ );
   end;
Hier die entscheidende Procedure

Code:
   
   procedure TfrmVTDBExample.VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var Text: WideString);
   var
      Data    : PTreeData;
      FObject : TBasicNodeAdd;
      iLevel  : integer;
   begin
      Text := '';
      Data := Sender.GetNodeData(Node);
      if Assigned(Data) and (Data.FObject <> nil) then with Data.FObject do
      begin
         iLevel := Sender.GetNodeLevel( Node );

         case Column of
         0:
            begin
               case TextType of
                  ttNormal:
                  begin
                     if iLevel = 0 then
                        begin
                           Text:=Caption
                        end
                     else
                       begin
                         if cds.FindKey([ID]) then with cds do
                           Text    := Trim( Fields[ FLDN_Addr1   ].AsString + ' ' +
                                       Fields[ FLDN_Addr2   ].AsString + ' ' +
                                       Fields[ FLDN_City   ].AsString + ' ' +
                                       Fields[ FLDN_State  ].AsString + ' ' +
                                       Fields[ FLDN_Zip    ].AsString + ' ' +
                                       Fields[ FLDN_Country ].AsString );
                       end;
                  end;
                  ttStatic:
                  begin
                     Text := '';
                  end;
               end;
            end;

            1:
            begin
               FObject := TBasicNodeAdd( Data.FObject );
               case TextType of
                  ttNormal:
                  begin
                     if (iLevel = 0)and cds.FindKey([ID])
                      then with cds do
                        Text := Fields[ FLDN_Contact ].AsString;
                  end;
               end;
            end;  

            2:
            begin
               if TextType = ttNormal then
                  Text := ' ';
            end;

         end;  
      end;
   end;
Code:
   procedure TfrmVTDBExample.VTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind;
               Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer);
   var
      Data : PTreeData;
      iLevel: integer;
   begin
      ImageIndex := -1;
      Data := Sender.GetNodeData(Node);
      iLevel:= Sender.GetNodeLevel( Node );

      if (Column = 2 ) then
      begin
         if ( Kind in [ ikNormal, ikSelected ] ) and (iLevel=0) then
            ImageIndex := 20
      end  
      else if Assigned(Data) and (Data.FObject <> nil) and (Column = 0) then
         ImageIndex := Data.FObject.ImageIndex;
   end;



   procedure TfrmVTDBExample.VTCompareNodes(Sender: TBaseVirtualTree; Node1,
     Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
   var
      Data1  : PTreeData;
      Data2  : PTreeData;
   begin
      Data1 := Sender.GetNodeData(Node1);
      Data2 := Sender.GetNodeData(Node2);

      case Column of
         0: Result := CompareText( Data1.FObject.Caption, Data2.FObject.Caption )
      end;
   end;

end.
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.416 Beiträge
 
Delphi XE5 Professional
 
#2

Re: VST und ADO

  Alt 22. Apr 2005, 14:03
du hast die vcl und den vst nicht verstanden...

FormActivate wird immer dann aufgerufen wenn die anwendung bzw. das formular den focus erhält. (dunkelblauber form titel bei w2k)
dort den tree zu initialisieren ist nicht das klügste.
jedesmal wenn wieder in die anwendung geswitcht wird (z.b. mit alt-tab), wird der tree initialisiert.
(es sei den du hast das gewollt, dann nehme ich das mit dervcl zurueck)
besser im onCreate

zum tree:
dieser gekommt gesagt wie gross die daten sind. (nodedatasize)
normal nimmt man dort record weil diese haben eine feste groesse.
in meinen projekte nehme ich objekte -> nodedatasize ist dann die groesse des pointer auf das objekt

jetzt gibt es mehrere möglichkeiten den tree zu füllen.
a)
du laeuft durch eine schleife so oft wie datensätze da sind und kopierst diese in ein passendes record oder in ein objekt und fügst diese dann mit addchild+daten hinzu.

deine load routine (loadcds) ist also irgendwie am ziel vorbei

b)
man baut die struktur zusammen und lässt dann die knoten per initnode füllen.
nur knoten die angezeigt werden werden dann auch initialisiert (geladen aus der datenbank).

methode b) hat einen grossen geschwindigkeitsvorteil.
wenn du rootnodecount angibst wird gleich der noetige speicherplatz (für die records) belegt.
geladen werden nur die die angezeigt werden.

egal welche methode du verwendest - du brauchst nur firecursors (readonly, forwardonly)
langsames cursorspringen mit locate, filter usw braucht man nicht.

im gettext gibt man eigendlich dann nun noch den record bzw obj aus (welches sich dann im speicher befindet).
langsame datenbankoperation führt man dort eigendlich nicht aus.

gruss
  Mit Zitat antworten Zitat
ucor

Registriert seit: 19. Apr 2005
18 Beiträge
 
#3

Re: VST und ADO

  Alt 23. Apr 2005, 16:27
Hallo generic,

zunächst mal Danke, dass du dich mit meinem Problem auseinandersetzt.
Es stimmt, dass ich den VST noch nicht richtig verstanden habe, deshalb versuche ich dieses Beispielprogramm zu analysieren und auf andere Datenbanken umzusetzen.
Der Code stammt nicht von mir, sondern gehört zu der Anwendung VTBasic/Database Example 1, die ich unter folgender Adresse heruntergeladen habe:
Extensive Basic Demo
Mein Problem liegt in der Methode FindKey, die ich mit ADO nicht benutzen kann.

Gruß u.
  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 23:18 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