IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants VCL Delphi Discussion :

Parcours des DATAs d'un treeview


Sujet :

Composants VCL Delphi

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 23
    Points : 11
    Points
    11
    Par défaut Parcours des DATAs d'un treeview
    Bonjour,
    j'essaye d'afficher les données incluses dans les data (Awindows dans mon cas) lors du click sur un noeud mais sans succès.
    Le compilateur me dit : "opérateur ou point virgule manquant" sur le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    showmessage (awindows(treeview1.selected.Data)^.windowtext);
    le remplissage du Treeview est ok.

    Merci.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
     
    unit Unit1;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
      System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.StdCtrls;
    Type
      Pwindows = ^Twindows;
      Twindows = record
        windowhandle : hwnd;
        windowtext : string;
        windowclass : string;
       end;
    type
      TForm1 = class(TForm)
        Button1: TButton;
        TreeView1: TTreeView;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
      private
     
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
    var
      Form1: TForm1;
      Pnode, Cnode : TTreeNode;
      AWindows : PWindows;
     
    implementation
     
    {$R *.dfm}
     
    // recherche des objets ENFANT de la fenetre
    function enumchildwindowsproc(wnd : hwnd;form : Tform1): bool; export;
      {$ifdef win32} stdcall; {$endif}
    var
      buffer : array[0..99] of char;
      nomclass : array[0..255] of char;
    begin
    result := true;
    getclassname(wnd,nomclass,256);
    getwindowtext(wnd,buffer,100);
    new(awindows);
    awindows^.windowhandle := wnd;
    awindows^.windowtext := strpas(buffer);
    awindows^.windowclass := strpas(nomclass);
     
    Cnode := Form1.treeview1.items.AddChildObject(pnode, awindows^.windowtext ,awindows);
    //relance des enfants suivant
    if getwindow(wnd,GW_CHILD) = 0 then
      begin
      pnode := cnode;
      enumchildwindows(wnd,@enumchildwindowsproc,0);
    end;
    end;
     
    // recherche des objects PARENT
    function enumwindowsproc(wnd : hwnd;form : Tform1): bool; export;
      {$ifdef win32} stdcall; {$endif}
    var
      buffer : array[0..99] of char;
      nomclass : array[0..255] of char;
    begin
    result := true;
    getclassname(wnd,nomclass,256);
    getwindowtext(wnd,buffer,100);
    new(awindows);
    awindows^.windowhandle := wnd;
    awindows^.windowtext := strpas(buffer);
    awindows^.windowclass := strpas(nomclass);
     
    Pnode := Form1.treeview1.items.AddChildObject(nil, awindows^.windowtext ,awindows);
    //relance des enfants suivant
    enumchildwindows(wnd,@enumchildwindowsproc,0);
    end;
    //lancement du remplissage du Treeview
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    enumwindows(@enumwindowsproc,longint(self));
    end;
     
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    dispose(awindows);
    end;
    //evenement lors du click sur un noeud
    //je veux juste afficher le texte dans un showmessage
    procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
    begin
    showmessage (awindows(treeview1.selected.Data)^.windowtext);
     
    end;
     
    end.

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 126
    Points
    13 126
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    showmessage (Pwindows(treeview1.selected.Data)^.windowtext);
    C'est le type qui t'intéresse ici, pas la variable awindows

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 23
    Points : 11
    Points
    11
    Par défaut
    Mais bien sur ! C'est de l'enregistrement que j'ai besoin ! Pas de la variable qui m'a permis de lier les datas.
    Merci beaucoup !😊

  4. #4
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    ceci dit, je te conseillerais de ne pas utiliser le membre Data mais de créer un dérivé de TTreeNode

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    type
      TWindowTreeNode = class(TTreeNode)
        windowhandle : hwnd;
        windowtext : string;
        windowclass : string;
      end;
     
    var
      Node, pnode: TWindowTreeNode;
    begin
      // au lieu de faire Form1.treeview1.items.AddChildObject(pnode, awindows^.windowtext ,awindows);
      Node := TWindowTreeNode.Create(Form1.TreeView1.Items);
      Node.windowhandle := ...
      Node.windowtext := ...
      Node.windowclass := ...
      Form1.TreeView1.Items.AddNode(Node, pnode, Node.windowtext, nil, naAddChild);
    end;
     
    begin
      ShowMessage(TWindowTreeNode(TreeView1.Selected).windowtext);
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Après quelques années en C++Builder

    Lors que je manipule le Data d'un TListView ou TTreeView j'utilise des assistants pour le transptypage car j'utilise souvent un TObject dedans qui permet de gérer des données différentes selon le level du nœud

    Voici un code pour un TListView mais c'est très similaire au TTreeView

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    //------------------------------------------------------------------------------
    procedure TModulexxxForm.lvDetailxxxClick(Sender: TObject);
    var
      Detail: TModulexxxBusiness.TxxxDetail;
    begin
      if Sender is TListView then
      begin
        Detail := GetViewSelectedDetail(TListView(Sender));
        if Assigned(Detail) then
        begin
          .... Detail.Property ....
     
     
    //------------------------------------------------------------------------------
    function TModulexxxForm.GetViewSelected(AView: TListView): TListItem;
    begin
      if AView.ItemIndex >= 0 then
        Result := AView.Items[AView.ItemIndex]
      else
        Result := nil;
    end;  
     
    //------------------------------------------------------------------------------
    function TModulexxxForm.GetViewSelectedDetail(AView: TListView): TModulexxxBusiness.TxxxDetail;
    var
      ItemSelected: TListItem;
    begin
      ItemSelected := GetViewSelected(AView);
     
      if Assigned(ItemSelected) then
      begin
        if not TThomPointerTool.Dynamic_Cast(ItemSelected.Data, TModulexxxBusiness.TxxxDetail, Result) then
          Result := nil;
      end
      else
      Result := nil;
    end;
    et pour la libération

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //------------------------------------------------------------------------------
    procedure Txx.tvxxxDeletion(Sender: TObject; Node: TTreeNode);
    var
      Obj: TObject;
    begin
      if Assigned(Node) then
      begin
        if TSlitePointerTool.Dynamic_Cast(Node.Data, TObject, Obj) then
          Obj.Free();
        Node.Data := nil;
      end;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    type
      TSlitePointerTool = record
        /// <summary>IsObject permet de savoir si un Pointer contient un TObject</summary>
        class function IsObject(APointer: Pointer): Boolean; static;
        /// <summary>TObject.InheritsFrom ne permet de déterminer si un pointeur contient un objet, cet assistant permet de savoir si un pointeur est un objet et en plus de type AClass</summary>
        class function InheritsFrom(APointer: Pointer; AClass: TClass): Boolean; static;
        /// <summary>dynamic_cast est un opérateur de transtypage C++, en voici son équivalent Delphi.</summary>
        /// <remarks>En C++, la différence entre une référence et un pointeur est quasi-inexistante, c'est la même chose en Delphi même si c'est moins visible (la référence est un pointeur masqué) et comme il n'existe pas d'opérateur pour transformer un pointeur en référence, la méthode Dynamic_Cast jouera ce rôle comme on le ferait naturellement en C++Builder.</remarks>
        /// <example><para>if Dynamic_Cast(ptr, AClass, Obj) then ...</para>
        /// <para>s'écrirait en C++ :</para>
        /// <para>Obj = dynamic_cast&lt;AClass&gt;(ptr);</para>
        /// <para>if (Obj) { ... }</para></example>
        class function Dynamic_Cast(APointer: Pointer; AClass: TClass; var Obj): Boolean; static;
      end;
     
    { TSlitePointerTool }
     
    //------------------------------------------------------------------------------
    class function TSlitePointerTool.Dynamic_Cast(APointer: Pointer; AClass: TClass; var Obj): Boolean;
    begin
      Result := InheritsFrom(APointer, AClass);
      if Result then
        TObject(Obj) := APointer;
    end;
     
    //------------------------------------------------------------------------------
    class function TSlitePointerTool.InheritsFrom(APointer: Pointer; AClass: TClass): Boolean;
    begin
      Result := False;
      if Assigned(APointer) then
      begin
        try
          Result := TObject(APointer).InheritsFrom(AClass);
        except
          on E: Exception do
            Result := False;
        end;
      end;
    end;
     
    //------------------------------------------------------------------------------
    class function TSlitePointerTool.IsObject(APointer: Pointer): Boolean;
    begin
      Result := InheritsFrom(APointer, TObject);
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 126
    Points
    13 126
    Par défaut
    On peut aussi conserver les appels "standards" en renseignant la classe avant création dans l'événement OnCreateNodeClass :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      with TWindowTreeNode(TreeView1.Items.Add(nil, 'Test')) do
      begin
        windowhandle := ...
        windowtext := ...
        windowclass := ...
      end;
    end;
     
    procedure TForm1.TreeView1CreateNodeClass(Sender: TCustomTreeView; var NodeClass: TTreeNodeClass);
    begin
      NodeClass := TWindowTreeNode;
    end;

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Bonne remarque qu'il existe OnCreateNodeClass, je l'ai aussi utilisé en C++Builder mais lorsque j'ai du gérer des classes différentes selon la nature du nœud, je suis revenu au Data
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 126
    Points
    13 126
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    mais lorsque j'ai du gérer des classes différentes selon la nature du nœud, je suis revenu au Data
    C'est un choix. Perso je passe par une variable de classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    type
      TBaseTreeNode = class(TTreeNode)
      private
        class var NodeClass :TTreeNodeClass;
      end;
     
      TTreeNode1 = class(TBaseTreeNode);
      TTreeNode2 = class(TBaseTreeNode);
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      TBaseTreeNode.NodeClass := TTreeNode1;
      TreeView1.Items.Add(nil, 'Test 1');
     
      TBaseTreeNode.NodeClass := TTreeNode2;
      TreeView1.Items.Add(nil, 'Test 2');
    end;
     
    procedure TForm1.TreeView1CreateNodeClass(Sender: TCustomTreeView; var NodeClass: TTreeNodeClass);
    begin
      NodeClass := TBaseTreeNode.NodeClass;
    end;

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Je n'avais pas du tout penser à le faire en deux temps, assigner la classe puis créer le nœud !
    Je le note, ça pourrait m'inspirer !
    Avantage, cela évite de gérer la libération (même si c'est pas grand chose dans OnDeletion), c'est toujours un truc de moins à penser
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #10
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 23
    Points : 11
    Points
    11
    Par défaut
    Un grand merci pour toutes ces propositions !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 08/08/2005, 13h54
  2. Ordonnée des données dans un TreeView
    Par LoicH dans le forum C++Builder
    Réponses: 3
    Dernier message: 17/04/2005, 18h08
  3. Empêcher le parcours des répertoires
    Par Tankian dans le forum Sécurité
    Réponses: 5
    Dernier message: 04/03/2005, 15h10
  4. Pbs pour Glisser-Deplacer des noeuds dans un TreeView.
    Par psau dans le forum C++Builder
    Réponses: 3
    Dernier message: 08/09/2004, 21h02
  5. Des colonnes dans un Treeview
    Par mr_langelot dans le forum Composants VCL
    Réponses: 6
    Dernier message: 28/07/2004, 09h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo