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 :

Comment passer deux objets différents (mais similaires) à une seule procédure ? [Lazarus]


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 135
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 135
    Par défaut Comment passer deux objets différents (mais similaires) à une seule procédure ?
    Bonjour,

    Soit une procédure procedure TMainForm.ShowDirectory(ListDir: string; var Liste: TCheckListBox); qui fonctionne bien, je peux lui passer l'une ou l'autre des TCheckListBox de ma fiche, et ça affiche bien les fichiers en liste, tutti va bene.

    Mais voilà-t-y pas que j'ai maintenant aussi besoin d'une TListBox pour récupérer tout pareil la liste des fichiers d'un dossier.

    L'idée serait donc d'aller chercher le parent commun des deux objets cible, à savoir TCustomListBox, de déclarer
    procedure ShowDirectory(ListDir: string; var Liste: TCustomListBox); et d'appeler ShowDirectory(chemin, MyCheckListBox); ou MyListBox); mais vous pensez bien que ça serait trop simple !

    Je ne compile pas (Error: Call by var for arg no. 2 has to match exactly: Got "TCheckListBox" expected "TCustomListBox"), normal, j'ai essayé de ruser avec du as, avec du ClassName, mais je patauge et je n'avance pas...
    Je viens donc quémander un peu d'aide, une idée, quelque chose pour m'éviter de bêtement dupliquer cette procédure ShowDirectory juste à cause de la cible, qui est pratiquement la même dans les deux cas.

    Il existerait une méthode bourrin consistant en l'utilisation d'une TListBox cachée qui serait recopiée après l'appel, mais est-ce bien honnête ? Genre
    procedure ShowDirectory(ListDir: string; var ListBoxCachée: TListBox); et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ShowDirectory(chemin, ListBoxCachée);
    MyCheckListBox := ListBoxCachée;
    // ou
    MyListBox := ListBoxCachée;
    .
    Comment vous feriez, vous ?
    (Google n'est pas d'une grande aide, ou je ne sais pas formuler la bonne question)

  2. #2
    Membre émérite

    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2012
    Messages
    1 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Retraité
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 035
    Par défaut
    Pour autant que j'aie compris la question ( Pourquoi var liste ? Il me semble que liste suffirait ) une méthode primaire serait un truc du genre ou on envoie NIL pour celui dont on à pas besoin:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure ShowDirectory(ListDir: string; Tmp_Liste_1: TCustomListBox, Tmp_Liste_2: TListBox);
    Begin
      if Tmp_Liste_1:=NIL then ShowDirectory(chemin, Tmp_Liste_2) else
      ShowDirectory(chemin, Tmp_Liste_1)
    End;
    Il me semble que ça devrait marcher. Sinon il y-a longtemps j'avais fait un test ( Que je ne retrouve plus ) pour un truc du genre.
    Avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure ShowDirectory(ListDir: string; Liste: Tobject);
    Tu peux envoyer n'importe quoi dans liste.
    Ensuite je crois que la formule magique est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if Liste is TcustomListBox then ... else
    if Liste is TListBox then ..
    .
    Mais pas certain, pour les détails attendre un expert. Ma seule certitude c'est que sur le principe ça marche.

    Edit:

    https://www.developpez.net/forums/d1...r-d-evenement/

    En cherchant "if sender" lazarus dans gogol tu en auras une brouette.

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 934
    Billets dans le blog
    6
    Par défaut
    Hello !
    Ne serait-il pas possible (et plus simple) d'avoir un paramètre TStrings et de passer à la procédure celui de la liste voulue, c'est-à-dire TListBox.Items ou TCheckListBox.Items ?
    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 !

  4. #4
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 135
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 135
    Par défaut
    Yop !
    Citation Envoyé par tourlourou Voir le message
    Hello !
    Ne serait-il pas possible (et plus simple) d'avoir un paramètre TStrings et de passer à la procédure celui de la liste voulue, c'est-à-dire TListBox.Items ou TCheckListBox.Items ?
    Oui, ça fait penser à ma liste cachée,


    Citation Envoyé par mm_71 Voir le message
    Sinon il y a longtemps j'avais fait un test (que je ne retrouve plus) pour un truc du genre.
    ...
    Ma seule certitude c'est que sur le principe ça marche.
    C'était en Delphi ?

    L'idée était belle, mais dans ShowDirectory la 1re ligne c'est Liste.Items.Clear; et bien sûr je gagne Error: identifier idents no member "Items".
    Idem en rajoutant if Liste is TCustomListBox do ou if Liste is TCheckListBox do ou with Liste as TCheckListBox do...

    Citation Envoyé par mm_71 Voir le message
    Edit:
    https://www.developpez.net/forums/d1...r-d-evenement/

    En cherchant "if sender" lazarus dans gogol tu en auras une brouette.
    Tout ça utilise Sender, que je n'ai pas...

    Citation Envoyé par mm_71 Voir le message
    ( Pourquoi var liste ? Il me semble que liste suffirait )
    Pour aller plus vite.

    Citation Envoyé par mm_71 Voir le message
    une méthode primaire serait un truc du genre où on envoie NIL pour celui dont on n'a pas besoin:
    --snip--
    Il me semble que ça devrait marcher.
    Oui, l'idée du test sur nil pourrait être une bidouille intéressante, un peu comme ma liste cachée.

  5. #5
    Membre émérite

    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2012
    Messages
    1 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Retraité
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 035
    Par défaut
    Tout ça utilise Sender, que je n'ai pas...
    Euh ? Sender c'est juste un nom de variable, tu peux le remplacer par n'importe quoi y compris var liste.

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 934
    Billets dans le blog
    6
    Par défaut
    Le code le plus générique est à mon avis de ce type :
    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
    procedure TForm1.Button1Click(Sender: TObject);
     
    procedure ShowDirectory(ListDir: string; FileList: TStrings);
    var
     ListeLocale: TStringList;
     i: integer;
    begin
      ListeLocale := TStringList.Create;
      try
        ListeLocale.Add(ListDir);
        for i:=1 to 10 do
          ListeLocale.Add(IntToStr(i));
        FileList.Assign(ListeLocale);
      finally
        ListeLocale.Free;
      end;
    end;
     
    begin
      ShowDirectory('ListBox', ListBox1.Items);
      ShowDirectory('ComboBox', ComboBox1.Items);
    end;
    Essayé à l'instant sous CT6.15/W7, il peuple les listes des 2 composants.
    Pour ton problème, c'est avant l'appel qu'il faut faire un Clear, pour effacer les coches d'une CheckBox.
    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 !

  7. #7
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 135
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 135
    Par défaut
    Citation Envoyé par mm_71 Voir le message
    Euh ? Sender c'est juste un nom de variable, tu peux le remplacer par n'importe quoi y compris var liste.
    Oui mais une recherche gogol avec "if toto" je suis pas sûr que je vais gagner beaucoup,

    Citation Envoyé par tourlourou Voir le message
    Hello !
    Ne serait-il pas possible (et plus simple) d'avoir un paramètre TStrings et de passer à la procédure celui de la liste voulue, c'est-à-dire TListBox.Items ou TCheckListBox.Items ?
    Ben non...
    Et c'est un truc qui me dépasse complètement : ShowDirectory(chemin, clbFiles. );... la complétion m'indique qu'il faut Items: TStrings, ce que j'accepte (= ShowDirectory(chemin, clbFiles.Items);), et je gagne Error: Can''t take the address of constant expressions avec le curseur qui clignote après Items...

    En gros, va te rouler avec ce machin que je te propose et que je te refuse...

  8. #8
    Membre émérite

    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2012
    Messages
    1 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Retraité
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 035
    Par défaut
    Error: identifier idents no member "Items"
    Oui, en effet. J'avais oublié qq. chose... Test complet ci-dessous qui marche chez moi.

    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
    unit Unit1;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
      CheckLst, Buttons;
     
    type
     
      { TForm1 }
     
      TForm1 = class(TForm)
        BitBtn1: TBitBtn;
        BitBtn2: TBitBtn;
        CheckListBox1: TCheckListBox;
        ListBox1: TListBox;
        procedure BitBtn1Click(Sender: TObject);
        procedure BitBtn2Click(Sender: TObject);
        procedure Test ( liste:TObject );
      private
     
      public
     
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.lfm}
     
    { TForm1 }
     
    procedure TForm1.BitBtn1Click(Sender: TObject);
    begin
    test (ListBox1);
    end;
     
    procedure TForm1.BitBtn2Click(Sender: TObject);
    begin
     test ( CheckListBox1);
    end;
     
    Procedure TForm1.Test ( Liste:Tobject );
    Begin
      if liste is TListBox then (Liste as TListBox).Items.Clear;
      if liste is TCheckListBox then (Liste as TCheckListBox).Items.Clear;
    end;
     
    end.

  9. #9
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 135
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 135
    Par défaut
    Bonsoir à tous,

    Citation Envoyé par mm_71 Voir le message
    Oui, en effet. J'avais oublié qq. chose...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      if liste is TListBox then (Liste as TListBox).Items.Clear;
    qq chose à quoi je n'ai pas du tout pensé pour la bonne et simple raison que je trouve ça redondant.
    Je m'explique : on a un premier test if liste is TListBox then et si c'est le cas on veut effacer ses Items donc pour moi l'association suivante Liste as TListBox n'est pas nécessaire.

    C'est un peu comme si on disait Si l''objet_devant_toi est une porte alors ouvre-la et sors : c'est parfaitement fonctionnel, et je ne vois pas pourquoi j'aurais dû écrire Si l''objet_devant_toi est une porte alors ouvre la porte et sors : c'est moche et peu français, donc mon cerveau n'a pas pu concevoir ce truc...

    Je me doutais que ça tournait autour de ça, mais mon ange gardien n'en a pas voulu, et au final, je n'ai même plus besoin de TListBox cachée, en repensant très fort à tout ça, ben je peux m'en sortir uniquement avec des TCheckListBox, d'après les tests de fin d'après-midi,

    Désolé de vous avoir fait perdre votre temps.

    @Yves : je trouve ta solution un peu tarabiscotée, surtout avec le Create et le Free à chaque appel, tout ça est peu lisible, surtout qu'au bout du compte, que ça soit des TStrings, une TStringList ou une TLisBox, une fois tout ça compilé je pense qu'on doit se retrouver, au niveau binaire, avec plus ou moins la même chose. Non ?

    @BM : tu nous fais un mélange des réponses d'Yves et de mm_71, on dirait, alors relis ce qui précède en commençant par le bas,

    Merci à tous,

  10. #10
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 135
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 135
    Par défaut
    Bon, ne vous prenez plus la tête, ça fonctionne très bien avec la TListBox cachée, et d'autant plus qu'elle ne sert que pour passer les infos aux TCheckListBox :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      ShowDirectory(Chemin, lbHidden);
      clbFiles.Items := lbHidden.Items;
    Si je dois remplir une TListBox normale, je la passe directement et voilou !

    Bon aprème,

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 28/03/2016, 15h51
  2. [RCP][débutant] Comment passer un objet d'une vue à une autre
    Par jycronier dans le forum Eclipse Java
    Réponses: 4
    Dernier message: 20/07/2006, 15h13
  3. Réponses: 4
    Dernier message: 20/04/2006, 11h07
  4. [JACOB] Comment passer un objet par référence à une méthode
    Par zlavock dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 21/03/2005, 18h28

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