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

Lazarus Pascal Discussion :

Héritage de TDBNavigator [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Membre habitué Avatar de Patrick25300
    Homme Profil pro
    Retraité en technicien de maintenance et méthodes
    Inscrit en
    Février 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Retraité en technicien de maintenance et méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 153
    Points : 134
    Points
    134
    Par défaut Héritage de TDBNavigator
    Bonjour
    Je cherche le moyen de modifier le comportement du DBNavigator sans pour autant recréer un composant, sans doute que je n'ai rien compris à la POO.
    Le but c'est de ne pas avoir de "post" lors de nouvelle insertion, car je souhaite utiliser une procédure stockée.
    Mais pour l'instant, c'est simplement pourvoir modifier le comportement de la procedure "BtnClick" de la classe "TDBCustomNavigator" de l'unité "DbCtrls"
    Il y a sûrement d'autres moyens, mais j'aimerais bien comprendre comment faire avec un héritage.

    Voici ci-dessous une partie de mon code.
    Le navigateur "DBNavigatorEntrees" fonctionne normalement, mais pas comme je le souhaite.
    La procedure "BtnClick" et un copié/collé de l'originale, mis à part le message coucou afin de faire des essais.

    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
     
    unit Principale;
    interface
    uses
     
    type
     
    { TMyDBNav }
     TMyDBNav = class(TDBNavigator)
      public
       procedure BtnClick(Index: TNavigateBtn); override;
     end;   
     
    type
      { TFormStk }
      TFormStk = class(TForm)
       DBNavigatorEntrees:TMyDBNav; 
      end;
     
    implementation   
     
     
    procedure TMyDBNav.BtnClick(Index: TNavigateBtn);
    begin
      //inherited BtnClick(Index);
       if (DataSource<>nil) and (DataSource.State<>dsInactive) then begin
           if not (csDesigning in ComponentState) and Assigned(BeforeAction) then
             BeforeAction(Self,Index);
           with DataSource.DataSet do begin
             case Index of
             nbPrior:  begin Prior; showmessage'coucou');end;   // pour essai
             nbNext:   Next;
             nbFirst:  begin First; showmessage'coucou'); end;  // pour essai 
             nbLast:   Last;
             nbInsert: Insert;
             nbEdit:   Edit;
             nbCancel: Cancel;
             nbPost:   Post;     // ici j'enleverais "Post" que je gérerais moi même
             nbRefresh: Refresh;
             nbDelete:
               if (not ConfirmDelete)
               or (MessageDlg(rsDeleteRecord, mtConfirmation, mbOKCancel, 0 )<>
                 mrCancel)
               then
                 Delete;
             end;
           end;
         end;
         if not (csDesigning in ComponentState) and Assigned(OnClick) then
           OnClick(Self,Index);
    end;
    Voici une partie de ce qu'il y a dans l'unité "DbCtrls" de Lazarus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    unit DbCtrls; 
     
      { TDBCustomNavigator }
     
      TDBCustomNavigator = class(TCustomPanel) 
      public
        procedure BtnClick(Index: TNavigateBtn); virtual; 
      end;
     
      TDBNavigator = class(TDBCustomNavigator)
    Merci de vos réponses, dans mon idée, il ne doit pas manquer grand chose ou alors c'est complétement faux, il faut faire vraiement différemment, ce n'est pas si simple.

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 301
    Points
    11 301
    Billets dans le blog
    6
    Par défaut
    Le navigateur "DBNavigatorEntrees" fonctionne normalement, mais pas comme je le souhaite.
    Normalement : est-ce à dire qu'il n'affiche pas tes coucous ?
    Ton approche est pourtant la bonne : redéfinir une méthode dynamique d'un ancêtre. Mais ce que tu redéfinis est le OnClick du TDBNavigator, dont tu hérites. Si tu héritais du TDBCustomNavigator, tu n'aurais qu'à définir la méthode virtuelle (et toutes les autres utiles définies dans le TDBNavigator mais qui te conviennent).
    Par contre, on lit ici que le OnClick intervient après l'action normale du bouton => plutôt changer cette action, sur ce modèle.
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Membre habitué Avatar de Patrick25300
    Homme Profil pro
    Retraité en technicien de maintenance et méthodes
    Inscrit en
    Février 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Retraité en technicien de maintenance et méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 153
    Points : 134
    Points
    134
    Par défaut
    Si je peux afficher mes "coucou" je sais que j'utilise la bonne methode.

    En utilisant les points d'arrêt je passe dans l'ordre suivant:
    1. procedure TDBCustomNavigator.BtnClick(Index: TNavigateBtn);
    2. procedure TFormStk.DBNavigatorEntreesBeforeAction(Sender: TObject; Button: TNavigateBtn);
    3. procedure TFormStk.DBNavigatorEntreesClick(Sender: TObject; Button: TNavigateBtn);



    C'est aussi pour ça, que ça me pose problème, car j'ai un "post" avant que je puisse faire quoi que ce soit.

    Merci pour la solution proposée, qui pourrait très bien m'aller.

    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
     
    type
      THackDBNavigator = class(TDBNavigator);
     
    procedure TForm1.DBNavigatorInsertClick(Sender: TObject);
    var
      DBNavigator: TDBNavigator;
    begin
      DBNavigator := ((Sender as TControl).Parent as TDBNavigator);
      if Assigned(DBNavigator.DataSource) and (DBNavigator.DataSource.State <> dsInactive) then
      begin
        if Assigned(DBNavigator.BeforeAction) then
          DBNavigator.BeforeAction(DBNavigator, nbInsert);
     
        DBNavigator.DataSource.DataSet.Append;
     
        if Assigned(DBNavigator.OnClick) then
          DBNavigator.OnClick(DBNavigator, nbInsert);
      end;
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      THackDBNavigator(DBNavigator1).Buttons[nbInsert].OnClick := DBNavigatorInsertClick;
    end;

    Dommage, cette solution ne fonctionne pas, je l'ai un peu modifiée par ceci, afin d'avoir le même paramètre que la procédure.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      THackDBNavigator(DBNavigator1).Buttons[nbInsert].OnClick := DBNavigatorInsertClick(sender);
    end;
    Mais sans succès, j'ai ce message d'erreur:

    Erreur: Incompatible types: got "untyped" expected "<procedure variable type of procedure(TObject) of object;Register>"

    Je ne réussis pas à la faire fonctionner.

  4. #4
    Membre habitué Avatar de Patrick25300
    Homme Profil pro
    Retraité en technicien de maintenance et méthodes
    Inscrit en
    Février 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Retraité en technicien de maintenance et méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 153
    Points : 134
    Points
    134
    Par défaut
    Bonjour

    A mon premier message j'ai donnée ce code

    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
     
    unit Principale;
    interface
    uses
     
    type
     
    { TMyDBNav }
     TMyDBNav = class(TDBNavigator)
      public
       procedure BtnClick(Index: TNavigateBtn); override;
     end;   
     
    type
      { TFormStk }
      TFormStk = class(TForm)
       DBNavigatorEntrees:TMyDBNav; 
      end;
     
    implementation   
     
     
    procedure TMyDBNav.BtnClick(Index: TNavigateBtn);
    begin
      //inherited BtnClick(Index);
       if (DataSource<>nil) and (DataSource.State<>dsInactive) then begin
           if not (csDesigning in ComponentState) and Assigned(BeforeAction) then
             BeforeAction(Self,Index);
           with DataSource.DataSet do begin
             case Index of
             nbPrior:  begin Prior; showmessage'coucou');end;   // pour essai
             nbNext:   Next;
             nbFirst:  begin First; showmessage'coucou'); end;  // pour essai 
             nbLast:   Last;
             nbInsert: Insert;
             nbEdit:   Edit;
             nbCancel: Cancel;
             nbPost:   Post;     // ici j'enleverais "Post" que je gérerais moi même
             nbRefresh: Refresh;
             nbDelete:
               if (not ConfirmDelete)
               or (MessageDlg(rsDeleteRecord, mtConfirmation, mbOKCancel, 0 )<>
                 mrCancel)
               then
                 Delete;
             end;
           end;
         end;
         if not (csDesigning in ComponentState) and Assigned(OnClick) then
           OnClick(Self,Index);
    end;
    Ceci fonctionne à condition que dans la fiche à ouvrir en mode texte "clique droit sur la forme et "afficher le code source ("*lfm")" et mettre TMyDBNav à la place de TDBNavigator à celui à modifier. Par contre ensuite il n'est plus possible de revoir la forme en mode graphique car Lazarus ne connait pas la classe.
    Du coup, j'ai créé une classe, c'est cool.

    1. Fichier/Nouveau et dans la liste choisir paquet, puis OK.
    2. Donner un nom de paquet de votre choix et l'enregistrer (je l'ai mis dans le dossier de mon projet, c'est mon choix).
    3. A partir de la fenêtre "Paquet NomDuPaquet" j'ai cliqué sur "Ajouter/Nouveau composant".
    4. De cette fenêtre j'ai choisi comme type d'ancêtre "TDBNavigator".
    5. J'ai choisi un icône de mon choix dans le dossier "d:\lazarus\images\components\" que j'ai modifié un petit peu pour le reconnaitre de suite.
    6. Cliquer sur le bouton "Créer le nouveau composant".
    7. L’éditeur de source s'ouvre et à partir de là, j'ai simplement copier la procédure ci-dessus "procedure TMyDBNav.BtnClick(Index: TNavigateBtn);" et aussi dans la déclaration de type.
    8. Ensuite il faut compiler à partir de la fenêtre "Paquet NomDuPaquet" et ajouter les unités dans "uses" qui manque pour la compilation dans mon cas "db,LCLStrConsts"
    9. Une fois la compilation réussite.
    10. Bouton "Utiliser/Installer"
    11. Lazarus se recompile et vous avez dans l'onglet "Data Controls" votre nouveau icône.


    Pour l'utiliser dans mon application, j'ai sélectionné mon nouveau Icône de mon nouveau navigateur et glissé sur ma forme, n'importe où.
    Pour ne pas avoir à tous régler, j'ai sélectionné le navigateur qui ne me convient pas, dans l'arborescence des objets de l'application, j'ai fait clique droit sur la sélection dans le menu "Changer la classe" dans nouvelle classe j'ai mis le nom de la classe du nouveau navigateur, que j'ai effacé ensuite.
    Et voila comme ça roule avec Lazarus.

    Voici le code que je vais modifier à ma sauce, je vais enlever les "coucou".

    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
     
     
    unit MyDBNavigator;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, DbCtrls,db,LCLStrConsts;
     
    type
      TMyDBNavigator = class(TDBNavigator)
      private
        { Private declarations }
      protected
        { Protected declarations }
      public
        { Public declarations }
        procedure BtnClick(Index: TNavigateBtn); override;
      published
        { Published declarations }
      end;
     
    procedure Register;
     
    implementation
     
    procedure TMyDBNavigator.BtnClick(Index: TNavigateBtn);
    begin
      //inherited BtnClick(Index);
        if (DataSource<>nil) and (DataSource.State<>dsInactive) then begin
           if not (csDesigning in ComponentState) and Assigned(BeforeAction) then
             BeforeAction(Self,Index);
           with DataSource.DataSet do begin
             case Index of
             nbPrior:  begin Prior; showmessage('coucou'); end;
             nbNext:   Next;
             nbFirst:  begin First; showmessage('coucou'); end;
             nbLast:   Last;
             nbInsert: Insert;
             nbEdit:   Edit;
             nbCancel: Cancel;
             nbPost:   Post;
             nbRefresh: Refresh;
             nbDelete:
               if (not ConfirmDelete)
               or (MessageDlg(rsDeleteRecord, mtConfirmation, mbOKCancel, 0 )<>
                 mrCancel)
               then
                 Delete;
             end;
           end;
         end;
         if not (csDesigning in ComponentState) and Assigned(OnClick) then
           OnClick(Self,Index);
    end;
     
    procedure Register;
    begin
      {$I mydbnavigator_icon.lrs}
      RegisterComponents('Data Controls',[TMyDBNavigator]);
    end;
     
    end.
    Sûrement qu'il y a d'autres méthodes pour ne pas passer par cette ligne "nbPost: Post;" que je ne souhaite pas avoir. Je pense à cette ligne là "BeforeAction(Self,Index);" pouvoir modifie l'index.

  5. #5
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    comment se compliquer la vie

    lazarus et delphi ont pour philosophie de bien distinguer les données des actions
    1°) pour n'afficher que les bouton qui nous interesse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          DBNavigator1.VisibleButtons := [nbFirst, nbPrior, nbNext, nbLast]
    ensuite les action sont au niveaux de ton dataset
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    beforePost 
    AfterPost
    BeforeDelete
    AfterDelete
    beforeScroll
    ....
    pour abandonner une action tu as la commande le dbnavigator ne fait que donner des ordres au dataset attaché
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

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

Discussions similaires

  1. [Postgresql]Héritage
    Par lheureuxaurelie dans le forum PostgreSQL
    Réponses: 13
    Dernier message: 02/10/2008, 09h18
  2. [Héritage] Vos commentaires....
    Par Fyna dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 03/05/2005, 22h10
  3. [XML Schemas]héritage multiple
    Par nicolas_jf dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 10/06/2003, 12h55
  4. [Postgres] Héritage + Clés
    Par k-reen dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 21/05/2003, 16h37
  5. Héritage entre Forms
    Par BarBal dans le forum Composants VCL
    Réponses: 7
    Dernier message: 29/08/2002, 17h44

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