1. #1
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 768
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 768
    Points : 7 929
    Points
    7 929

    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)
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #2
    Membre actif
    Inscrit en
    juin 2012
    Messages
    144
    Détails du profil
    Informations forums :
    Inscription : juin 2012
    Messages : 144
    Points : 260
    Points
    260

    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
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : mars 2005
    Messages : 2 898
    Points : 7 835
    Points
    7 835

    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 10.1 Berlin Starter Edition - CodeTyphon 6.15 sous Win 7 et 5.20 sous Ubuntu 14.04
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  4. #4
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 768
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 768
    Points : 7 929
    Points
    7 929

    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.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  5. #5
    Membre actif
    Inscrit en
    juin 2012
    Messages
    144
    Détails du profil
    Informations forums :
    Inscription : juin 2012
    Messages : 144
    Points : 260
    Points
    260

    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
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 768
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 768
    Points : 7 929
    Points
    7 929

    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...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  7. #7
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 768
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 768
    Points : 7 929
    Points
    7 929

    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,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  8. #8
    Membre actif
    Inscrit en
    juin 2012
    Messages
    144
    Détails du profil
    Informations forums :
    Inscription : juin 2012
    Messages : 144
    Points : 260
    Points
    260

    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
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : mars 2005
    Messages : 2 898
    Points : 7 835
    Points
    7 835

    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 10.1 Berlin Starter Edition - CodeTyphon 6.15 sous Win 7 et 5.20 sous Ubuntu 14.04
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  10. #10
    Membre actif
    Inscrit en
    juin 2012
    Messages
    144
    Détails du profil
    Informations forums :
    Inscription : juin 2012
    Messages : 144
    Points : 260
    Points
    260

    Par défaut

    Oui mais une recherche gogol avec "if toto" je suis pas sûr que je vais gagner beaucoup,
    En effet, mais ce que je voulais dire c'est que dans les exemples avec "if sender" tu pouvais remplacer sender par n'importe quoi dans ton programme même si tout le monde utilise "sender".
    ç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 :
    Si elle ne sert qu'a ça la remplacer par une TStringList globale te simplifierait peut-être la vie ?

  11. #11
    Membre confirmé

    Homme Profil pro
    Amateur Passionné
    Inscrit en
    septembre 2015
    Messages
    226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : septembre 2015
    Messages : 226
    Points : 484
    Points
    484

    Par défaut

    Salut bon j'ai survolé vite fait la discussion mais pourquoi pas :

    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
     
    Type
      TMyCustomListboxClass = class of TCustomListBox;
     
    procedure TMainForm.ShowDirectory(ListDir: string; var Liste: TMyCustomListBoxClass);
    begin
      if (Liste is TListBox) then
      begin
        With (Liste As TListBox) Do 
        begin
            .....
        end;
      end
      else if (Liste is TCheckListBox) then
      begin
         ...
      end;
    end;
    en principe cela devrai fonctionner

    A+
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

  12. #12
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 768
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 768
    Points : 7 929
    Points
    7 929

    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,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  13. #13
    Membre expert
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2002
    Messages
    2 423
    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 : 2 423
    Points : 3 805
    Points
    3 805

    Par défaut

    salut

    Tourlourou t'as montré la voie passe par un TStrings ancetre du TStringList les items de tes deux composant sont eux aussi des TStrings
    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

  14. #14
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2002
    Messages
    6 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 6 756
    Points : 21 591
    Points
    21 591

    Par défaut

    je n'ai pas compris si le problème est solutionné, mais deux choses:

    1) si TCustomListBox fait l'affaire, il suffit de supprimer le "var" du paramètre pour que cela fonctionne.
    "var" n'est nécessaire que si on veut modifier la paramètre lui-même, pas son contenu, et c'est lui qui réclame un type identique.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    procedure ShowDirectory(ListDir: string; Liste: TCustomListBox);
    Begin
      Liste.Items.Clear;
    End;
     
    begin
      ShowDirectory('c:\', ListBox1);
      ShowDirectory('c:\', CheckListBox1);
    end;
    2) il est probable que la fonction puisse se contenter d'un TStrings comme paramètre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    procedure ShowDirectory(ListDir: string; Liste: TStrings);
    Begin
      Liste.Clear;
    End;
     
    begin
      ShowDirectory('c:\', ListBox1.Items);
      ShowDirectory('c:\', CheckListBox1.Items);
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Produits : UPnP, RemoteOffice, FlashPascal

  15. #15
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 768
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 768
    Points : 7 929
    Points
    7 929

    Par défaut

    Bonjour Paul,
    Citation Envoyé par Paul TOTH Voir le message
    je n'ai pas compris si le problème est solutionné:
    Oui, à force de compliquer les choses (+ la chaleur...), je m'étais bien embrouillé, en reprenant les choses calmement à la fraîche j'ai pu simplifier un tas de trucs et n'ai plus besoin de tout ça.

    Néanmoins, just in case, une petite précision s'impose, là :
    Citation Envoyé par Paul TOTH Voir le message
    "var" n'est nécessaire que si on veut modifier le paramètre lui-même, pas son contenu,
    C'est quoi, le "paramètre lui-même" ? Ses propriétés ? Genre, pour une T(Check)ListBox, ça serait Enabled ou pas, sa Width, etc ?

    Question subsidiaire : quid de ce tuto, où la notion dont tu parles n'est pas du tout prise en compte ?
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

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

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

    Informations forums :
    Inscription : mars 2005
    Messages : 2 898
    Points : 7 835
    Points
    7 835

    Par défaut

    Bonsoir,

    Une fonction/procédure peut renvoyer une instance différente dans un paramètre var, mais du même type.

    Autrement dit, on peut par exemple recevoir un objet dans une variable qui était initialisée à nil et pointera donc désormais sur l'objet reçu lors de l'appel.

    Pour un paramètre entier passé en var, sa valeur peut changer, mais ça reste un entier. Pour un paramètre objet passé en var, pareil : on peut avoir une instance ou une autre, mais d'un même type d'objet.
    Delphi 5 Pro - Delphi 10.1 Berlin Starter Edition - CodeTyphon 6.15 sous Win 7 et 5.20 sous Ubuntu 14.04
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  17. #17
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2002
    Messages
    6 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 6 756
    Points : 21 591
    Points
    21 591

    Par défaut

    Citation Envoyé par Jipété Voir le message
    Bonjour Paul,

    Oui, à force de compliquer les choses (+ la chaleur...), je m'étais bien embrouillé, en reprenant les choses calmement à la fraîche j'ai pu simplifier un tas de trucs et n'ai plus besoin de tout ça.

    Néanmoins, just in case, une petite précision s'impose, là :

    C'est quoi, le "paramètre lui-même" ? Ses propriétés ? Genre, pour une T(Check)ListBox, ça serait Enabled ou pas, sa Width, etc ?

    Question subsidiaire : quid de ce tuto, où la notion dont tu parles n'est pas du tout prise en compte ?
    un exemple vaut mieux qu'un long discours

    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
     
    procedure test1(var L: TStringList);
    begin
      if L = nil then L := TStringList.Create;
    end;
     
    procedure test2(const L:TStringList);
    begin
      L.Add('Hello'); // ok
      L := nil; // impossible car L est une constante <- erreur de compilation
    end;
     
    procedure test3(L: TStringList);
    begin
      L.Add('Hello'); // ok
      L := nil; // ok mais ça ne change pas la liste ci-dessus, simplement la valeur locale de L
    end;
     
    procedure test4(var L: TStringList);
    begin
      L.Free;
      L := nil; // le paramètre est mis à nil chez l'appelant !
    end;
     
    var
      L: TStringList;
    begin
      L := nil;
      test1(L); // crée un TStringList
      test1(L); // ne fait rien
      test2(L); // ajoute "Hello" à L
      test3(L); // ajoute "Hello" à L
      test3(L); // ajoute "Hello" à L qui n'est pas 'nil'
      test4(L); // la liste est détruire, et L = nil
    end:
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Produits : UPnP, RemoteOffice, FlashPascal

  18. #18
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 768
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 768
    Points : 7 929
    Points
    7 929

    Par défaut

    Bonsoir,
    Citation Envoyé par Paul TOTH Voir le message
    un exemple vaut mieux qu'un long discours
    Merci, c'est gentil mais ça ne m'explique pas concrètement la différence entre le paramètre et le contenu du paramètre.

    Citation Envoyé par Paul TOTH Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    procedure test4(var L: TStringList);
    begin
      L.Free;
      L := nil; // le paramètre est mis à nil chez l'appelant !
    end;
    C'est bien comme ça que je l'entendais, et que je l'ai toujours compris (en gros, c'est un peu le comportement d'une variable globale : tout le monde peut la modifier, et la bonne valeur c'est le dernier qui "parle" qui la définit, jusqu'à ce qu'un autre "parle" à son tour.)


    Citation Envoyé par tourlourou Voir le message
    Pour un paramètre entier passé en var, sa valeur peut changer, mais ça reste un entier. Pour un paramètre objet passé en var, pareil : on peut avoir une instance ou une autre, mais d'un même type d'objet.
    Yves, par pitié, un paramètre entier, pour moi c'est un article puis un nom commun suivi d'un adjectif qualificatif, genre on pourrait avoir un paramètre pas fini, un paramètre diminué, un paramètre réduit, tu vois le truc ? Et on ne découvre la clé que 10 mots plus loin : ça reste un entier. Ah ! Rembobinage, relecture, un paramètre integer passé en var c'est ça que tu as voulu dire ?
    Et si c'est pas ça ?
    Bon, je suppose que c'est ça car j'ai déjà vu des exemples parlant du passage d'objets "simples", le problème pour moi c'est que même les objets les plus compliqués se révèlent au final n'être que des types basiques, des assemblages de 0 et de 1 sur 16, 32, 64 bits de large selon l'architecture hardware de la machine.

    Et donc si on peut passer un integer on doit pouvoir passer de la même manière un truc hyper-sophistiqué puisqu'au final c'est la même chose, la seule différence c'est les messages d'erreur du compilateur qui fait rien que nous embêter à nous mettre des bâtons dans les roues,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  19. #19
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    avril 2002
    Messages
    2 409
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : avril 2002
    Messages : 2 409
    Points : 4 083
    Points
    4 083

    Par défaut

    Pour mieux comprendre, il faut raisonner avec "l'adresse" et "la valeur" d'une variable (peu importe son type). Si le mot-clé var est spécifié, la procédure/fonction appelée reçoit l'adresse de la zone mémoire où est stockée la variable. La procédure/fonction appelée est donc capable de modifier la véritable variable désignée.

    Sans mot-clé var, la valeur de la variable est passée à la procédure/fonction appelée. C'est en fait une copie de la variable à l'instant t lors de l'appel, qui est passée. Impossible donc de modifier la variable en elle-même.

    Tout se complique ensuite quand on insère des pointeurs (qui représentent des adresses), la plupart des cas ont été donnés par Paul.

    Ici, Pascal masque la complexité, mais le C montre clairement la distinction : le mot-clé var n'existe pas et les développeurs manipulent plus librement les adresses lors du passage des paramètres.
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  20. #20
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2002
    Messages
    6 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 6 756
    Points : 21 591
    Points
    21 591

    Par défaut

    Citation Envoyé par Jipété Voir le message
    Bonsoir,

    Merci, c'est gentil mais ça ne m'explique pas concrètement la différence entre le paramètre et le contenu du paramètre.
    hum...ça c'est la notion de pointeur.

    mais soyons plus précis avec le cas qui nous intéresse. ListBox1 est une variable qui pointe sur une instance de la classe TListBox. je peux modifier la liste en utilisant par exemple ListBox1.Items.Clear qui efface le contenu de la liste, mais si j'écris "ListBox1 := nil", je modifie la variable ListBox1 sans affecter la liste elle-même; elle n'est pas détruite ni même altérée. c'est là la différence en le paramètre (ou ici une variable) et son contenu.

    dans la fonction test2(const L: TStringList), je peux modifier la liste avec L.Clear, L.Add....mais pas le paramètre "L", je ne peux donc pas écrire "L := nil" par exemple...autant dire que le mot clé const dans ce cas de figure est rarement utile.

    de même, le mot clé "var" dans test4(var L: TStringList) me permet de modifier la variable qui est passé dans l'appel test4(L), c'est parfois utile comme dans la fonction FreeAndNil() qui non seulement libère l'objet mais s'assure que la variable vaut nil également (paramètre, et contenu)...mais dans la plupart des cas, on n'a besoin ni de "var" ni de "const", et l'objet pointé (le contenu) reste totalement modifiable.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Produits : UPnP, RemoteOffice, FlashPascal

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

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. 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