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

Delphi Discussion :

XE7 : Form - Création et passage de variables


Sujet :

Delphi

  1. #1
    Invité
    Invité(e)
    Par défaut XE7 : Form - Création et passage de variables
    Bonjour,

    Pour transmettre une variable d'une Form à une autre, j'utilise une méthode assez classique.
    Exemple sur 3 Forms : Unit1 -> showmodal -> Unit2 -> showmodal -> Unit3
    Code du projet et des 3 Forms
    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
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    program Project1;
     
    uses
      Vcl.Forms,
      Unit1 in 'Unit1.pas' {Form1},
      Unit2 in 'Unit2.pas' {Form2},
      Unit3 in 'Unit3.pas' {Form3};
     
    {$R *.res}
     
    begin
      Application.Initialize;
      Application.MainFormOnTaskbar := True;
      Application.CreateForm(TForm1, Form1);
      Application.CreateForm(TForm2, Form2);
      Application.CreateForm(TForm3, Form3);
     
      Application.Run;
    end.
     
    unit Unit1;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, unit2;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
        FString : string;
      public
        { Déclarations publiques }
        Property prString : string read FString;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      FString := 'Test';
      with Form2 do
         try
           ShowModal;
          finally
            Free;
          end;
    end;
     
    unit Unit2;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, unit3;
     
    type
      TForm2 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
     
      private
        { Déclarations privées }
        FString : string;
      public
        { Déclarations publiques }
        Property prString : string read FString;
      end;
     
    var
      Form2: TForm2;
     
    implementation
     
    {$R *.dfm}
    uses Unit1;
     
     
    procedure TForm2.Button1Click(Sender: TObject);
    begin
      FString := Form1.prString;
      with Form3 do
        try
          ShowModal;
        finally
          Free;
        end;
    end;
     
    end.
     
    unit Unit3;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
     
    type
      TForm3 = class(TForm)
        procedure FormShow(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form3: TForm3;
     
    implementation
     
    {$R *.dfm}
    uses Unit2;
     
    procedure TForm3.FormShow(Sender: TObject);
    begin
      showmessage(Form2.prString);
    end;
     
    end.
    Le code ci-dessus est tout à fait fonctionnel.


    Maintenant, je modifie le code de l'Unit1 ainsi
    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.Button1Click(Sender: TObject);
    begin
      FString := 'Test';
     
      if Assigned(Form2) then FreeAndNil(Form2);
      if not Assigned(Form2) then begin
        with TForm2.Create(Application) do
          try
            ShowModal;
          finally
            Free;
          end;
       end;
    end;
    La Form2 apparaît bien (i.e. sans erreur) et je peux obtenir Form1.prString (par un showmessage par exemple).
    Mais l'appel de Form3 à partir de Form2 entraîne une violation d'accès... au moment de lire Form2.prString.

    Dans Form1, c'est visiblement la création avec with TForm2.Create(nil) qui pose problème... lors du passage de la variable de Form2 vers Form3. Pourquoi ? Le nil ? Qu'est-ce qui est rompu et pas recréé (un pointeur ?).

    Je crois que je vais essayer une autre méthode de gestion des Forms. La désassignation me semble très périlleuse et visiblement je n'en comprends pas son mécanisme... ou ma perception (ce à quoi elle sert exactement) en est très erronée. Si un spécialiste passe par là...
    Merci.
    Dernière modification par Invité ; 30/11/2014 à 20h20.

  2. #2
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    C'est normal Form2 est libéré et est mis à nil...

  3. #3
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    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
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      FString := 'Test';
     
      if Assigned(Form2) then FreeAndNil(Form2);
      if not Assigned(Form2) then begin
        Form2 := TForm2.Create(Application);
      with Form2 do
        try
          ShowModal;
        finally
          Free;
        end;
      end;
    end;
    Je ne comprend pas la logique de vos passage de parametre. Ce que vous faites ne fonctionne pas, Form3 ne recoit pas de parametre (un oubli dans l'exemple ?) mais vous devriez faire autrement.

    Personnellement je préfère envoyer les paramètres lors de l'initialisation de ma fenetre. Ainsi, la fenêtre créée est autonome (ca va fonctionner même si on est pas en showmodal).

    Soit en redéfinissant le constructeur de la form pour passer tous les éléments necessaire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Form2 := TForm2.Create(Application,MonParam);
    soit apres le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Form2 := TForm2.Create(Application);
    j'affecte les propriétés de Form2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Form2.Param1 := monParam;
    Form2.Showmodal;
    Ainsi Form2 'vie sa vie' sans avoir besoin de form1.

  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 430
    Points
    28 430
    Par défaut
    tout à fait, d'ailleurs il n'est pas nécessaire de le vérifier dans ton code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if Assigned(Form2) then FreeAndNil(Form2);
      if not Assigned(Form2) then begin // c'est toujours vrai !
    c'est là que tu dois considérer si Form1 2 et 3 sont des singletons, et donc une seule variable globale peut permettre des les identifier, ou si tu préfères un code "plus propre" du type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
          with TForm2.Create(Application) do
          try
            prString := Self.FString; // passage de Form1.FString à Form2.FSting sans passer par des variables globales (prString doit avoir un setter)
            ShowModal;
          finally
            Free;
          end;
    ou si Form2 a besoin de plus d'infos dans Form1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
          with TForm2.Create(Application) do
          try
            SetForm1(Self); // passage de l'instance de TForm1 à l'instance de TForm2 sans passer par des variables globales
            ShowModal;
          finally
            Free;
          end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Alors je reprends : Une TForm (une classe) me permet d'afficher les bulletins scolaires. Je veux pouvoir afficher simultanément plusieurs instances de la classe autrement dit visualer plusieurs bulletins à l'écran. Chaque TForm d'ailleurs permet d'ouvrir d'autres Forms... Pour l'instant, j'ai un code fonctionnel mais trop peu rigoureux à mon goût. Je sais que les programmeurs professionnels assujettis à la contrainte de productivité seraient pour la plupart tentés de me dire : "pourquoi se casser la tête puisque cela fonctionne ?". Mais ce n'est pas mon attitude... car pas ma contrainte.

    Donc j'utilise un code de modélisation du problème que j'ai précisé ci-dessus.

    Dans l'ordre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if Assigned(Form2) then FreeAndNil(Form2);
      if not Assigned(Form2) then begin // c'est toujours vrai !
    ... Oui, enfin cela ne l'était pas au départ chez moi car je "désassignais" mal [Close + Destroy] donc je vérifiais.Il s'agit donc d'une redondance mais sans aucun impact sur le problème. C'est curieux. Je me suis penché sur pas mal d'objets mais jamais sur les TForms. Je crois que c'est un des rares objets que j'utilise que je n'ai pas dérivé.

    Je ne comprend pas la logique de vos passage de parametre. Ce que vous faites ne fonctionne pas, Form3 ne recoit pas de parametre (un oubli dans l'exemple ?) mais vous devriez faire autrement.
    ... Si, si... le code initial (le premier code fourni) est fait pour cela.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //TForm3
    implementation
    uses Form2;
    procedure TForm3.FormShow(Sender: TObject);
    begin
      showmessage(Form2.prString);
    end;
    TForm3 ne reçoit pas de paramètre mais en appelle un... Il va se "servir" et pour cela, il faut que le paramètre soit correctement référencé... Or, il ne l'est pas. Et d'ailleurs comme je l'ai écrit, il est totalement fonctionnel si je ne désassigne pas Form2. Le problème est le même si je remplace (nil) par (Application) lors de la création de la Form. Normalement, "Form2" est instanciée par défaut avec l'écriture utilisée.

    Donc, je cherche à comprendre pourquoi cela ne fonctionne pas. Une gestion plus fine des exceptions ne me fournit rien... en réalité n'est jamais déclenchée. A priori (et testé de multiples façons), le code avec désassignation est fonctionnel sans l'échange de données. L'écriture me semble correcte et en fait elle ne l'est pas. Mais je ne sais pas pourquoi. J'ai compris : il faut faire autrement. On pratiquera le mimétisme comme approche. Maiscela n'empêche pas de comprendre pourquoi le code est erroné ?

    Finalement la question semble se résumer à cela : "Pourquoi la propriété publique d'une Form2 ouverte avec (nil) n'est pas appelable avec une Form3 dans laquelle est référencée correctement (sur le papier mais pas dans la réalité du fonctionnement de Delphi) Form2 ? Qu'est-ce qui justifie cette impossibilité ?"

    Merci.
    Dernière modification par Invité ; 01/12/2014 à 09h50.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 677
    Points : 13 082
    Points
    13 082
    Par défaut
    Ton erreur vient du fait que tu penses que l'instance de TForm2 créée va automatiquement être assignée à la variable Form2, ce qui n'est pas le cas. Delphi (le RAD) crée automatiquement une structure de base ET un variable de ce type mais il n'y a pas d'autre automatisme. Il faut obligatoirement que les deux soient liés par code, soit par Application.CreateForm(TForm2, Form2), soit par Form2 := TForm2.Create.

  7. #7
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Et bien si le but c'est d'avoir plusieurs instance de Form il ne faut pas utiliser la variable Formx définie par défaut....


    Form1 n'est définie qu'une fois et est unique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Form1 := TForm1.create(Application);
    Form1 := TForm1.create(Application);
    Form1 := TForm1.create(Application);
    Va bien créer 3 fenêtres.

    Mais Form1 ne pointera que vers la dernière....

    Maintenant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Form1 := TForm1.create(Application);
    Form1 := TForm1.create(Application);
    Form1 := TForm1.create(Application);
    Form1 := nil;
    Crée 3 fenêtres également mais Form1 pointe vers ... rien :p

  8. #8
    Invité
    Invité(e)
    Par défaut
    Bonjour Andnotor,

    Oui, oui... En effet !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if Assigned(Form2) then FreeAndNil(Form2);
      if not Assigned(Form2) then begin
       with TForm2.Create(nil) do
          if Assigned(Form2) then showmessage('Assignée') else showmessage('Non assignée');
      [...]
    ... renvoie "Non assignée"....
    Je pourrais peut-être profiter de cet "inconvénient"... Est-il possible de récupérer le nom de l'instanciation, l'appellation remplaçant Form2 ?

    Bonjour Barbibulle,

    Non, non, on ne complique pas les choses . Créer un pool de TForm, c'est OK... Enfin, non... La programmation n'est pas encore dynamique et c'est ce à quoi je m'attelle. Mais pour faire cela, je dois comprendre plus finement le comportement des TForm... Et j'avais la réponse sous les yeux... Form2 n'existe pas... Voilà l'erreur. J'ai pensé que de manière implicite Form2 était affectée lors de la création. sinon, ma nouvelle approche devrait être 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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    interface
     
    uses
      [...], unit2;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
        FString : string;
      public
        { Déclarations publiques }
        Forms2Array : array of TForm2;
     
        Property prString : string read FString;
     
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
       i : integer;
    begin
      SetLength(Forms2Array, Length(Forms2Array)+1);
      i := Length(Forms2Array)-1;
      FString := IntToStr(i);
      Forms2Array[i] := TForm2.Create(Self);
      Forms2Array[i].Show;[...]
    end;
    Pour ne pas allonger le tableau de manière idiote, je compte désassigner les Form2x qui ne servent plus... et réassigner les "trous". Donc de toute façon, le problème évoqué ne sera pas rencontré puisque le nom de l'instanciation est explicite. Et finalement ma simulation dans le cas précis est inutile... sauf que je ne comprenais pas le problème. La réponse d'Andnotor est finalement la mise au point nécessaire.

    Donc résolu... Merci à tous.

    ADD : Version avec récupération des trous
    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
    procedure TForm1.Button1Click(Sender: TObject);
    var
       arrayCount, i, iFree : integer;
    begin
      iFree := -1;
      arrayCount := Length(Forms2Array);
      if arrayCount > 0 then
        for i:= 0 to arrayCount -1 do
         if not Assigned(Forms2Array[i]) then begin
           iFree := i;
           break;
         end;
      if iFree = -1 then begin
        SetLength(Forms2Array, Length(Forms2Array)+1);
        iFree := Length(Forms2Array)-1;
      end;
     
    {Simulation d'une fenêtre détruite}
      if IFree = 2 then  begin
        //Forms2Array[1].Close;          //<- Tjs en suspens : OK mais ????
          FreeandNil(Forms2Array[1]);
       end;
     
      FString := IntToStr(iFree);
      Forms2Array[iFree] := TForm2.Create(Self);
      Forms2Array[iFree].Show;
     
    end;
    J'ai encore quelques doutes dans la partie {Simulation d'une fenêtre détruite}. La gestion des Forms ne peut souffrir d'aucune approximation... Mais je vais utiliser le FreeOrReleaseAndNil proposé dans une réponse.
    Dernière modification par Invité ; 01/12/2014 à 11h06.

  9. #9
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Paul Toth a donné une solution.

    Quand on veut instancier plusieurs form d'une même classe on ne peut plus utiliser le pointeur défini par défaut (ou du moins au mieux il pointera vers une seule des instances).

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 677
    Points : 13 082
    Points
    13 082
    Par défaut
    Citation Envoyé par selzig Voir le message
    Est-il possible de récupérer le nom de l'instanciation, l'appellation remplaçant Form2 ?
    Mais il n'y en a pas ! Create ne fait qu'allouer de la mémoire, à toi de faire pointer une variable dessus. Il n'y a rien de textuel.
    Seule l'instance sait où elle se trouve par l'intermédiaire de Self. Elle apparaît aussi dans la liste Components de son propriétaire s'il a été défini, mais sans plus.

  11. #11
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Ce qui me dérange également c'est le principe de passage du paramètre :

    Vous affectez votre paramètre à une variable dans Form1 pour que Form2 puis la lire, vous affectez une variable dans form2 pour que Form3 puisse la lire... Alors oui cela fonctionne à partir du moment où Form2 à accès à form1.

    Il me parait plus simple d'affecter directement la variable de Form2 avant le showmodal et form2 utilise sa variable sans se soucier si Form1 existe encore.

  12. #12
    Invité
    Invité(e)
    Par défaut
    Andnotor
    Question bête de ma part ... Et confusion avec un autre langage.

    Barbibulle
    Oui, mais c'est un démonstrateur pour mettre en évidence un problème. Il a évolué au fur et à mesure de mes tests. Et donc à l'arrivée c'est un "méandre". La première Form est créée par Application.CreateForm donc le problème ne peut pas être mis en évidence dans Form2. Il faut créer Form2 avec nil pour le faire apparaître dans Form3... Pour le passage des paramètres, j'utilise mes procédés habituels sur les composants... C'est peut-être plus lourd que de passer un paramètre dans le Create de la Form. Mais attendons, le prochain problème pour remettre en question cette méthode

    Encore merci. J'y vois nettement plus clair. Je transpose dans le projet "réel".
    Dernière modification par Invité ; 01/12/2014 à 11h07.

  13. #13
    Invité
    Invité(e)
    Par défaut
    Désolé, je relance la discussion. Le portage en VCL s'effectue correctement, en FMX plus difficilementi.
    Je cherche une petite explication complémentaire.

    • Code 1 :
    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
    unit Unit1;
     
    interface
     
    uses
      [...]
      unit2;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
         wForm2 : TForm2;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      if Assigned(wForm2)
        then showmessage('wForm2 assignée.')
        else showmessage('wForm2 non assignée.');
    end;
    [wForm2 :TForm2 est déclaré en Public]
    Le clic sur le bouton1 renvoie wForm2 non assignée. C'est ce que j'attendais.

    • Code 2 :
    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
    unit Unit1;
     
    interface
     
    uses
      [...]
      unit2;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    var  
      wForm2 : TForm2;
    begin
      if Assigned(wForm2)
        then showmessage('wForm2 assignée.')
        else showmessage('wForm2 non assignée.');
    end;
    [wForm2 :TForm2 est déclaré en local dans le code du TButton]
    Le clic renvoie wForm2 assignée ? Le simple fait de déclarer wForm2 : TForm2 en local l'assigne alors que la Form n'est pas créée ? Pourquoi ?

    • Pour info:
      • Code de l'unit2
        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
        unit Unit2;
         
        interface
         
        uses
          Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
          Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
         
        type
          TForm2 = class(TForm)
          private
            { Déclarations privées }
          public
            { Déclarations publiques }
          end;
         
        var
          Form2: TForm2;
         
        implementation
         
        {$R *.dfm}
         
         
        end.
      • Comportement à peu près identique en VCL et FMX -> Form2Array[iFree] := TForm2.Create(nil); {FMX que nil - VCL admet en plus Application et Self} Mais aucune critique à formuler, je passe de l'un à l'autre sans difficulté majeure. Un gain de temps et de fatigue inappréciable
      • Aucunement dommageable dans mon code... mais comme d'habitude... la curiosité... Pourquoi cette différence de comportement ?
    Dernière modification par Invité ; 01/12/2014 à 16h03.

  14. #14
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Citation Envoyé par selzig Voir le message
    Créer un pool de TForm, c'est OK... Enfin, non... La programmation n'est pas encore dynamique et c'est ce à quoi je m'attelle. Mais pour faire cela, je dois comprendre plus finement le comportement des TForm... Et j'avais la réponse sous les yeux... Form2 n'existe pas... Voilà l'erreur. J'ai pensé que de manière implicite Form2 était affectée lors de la création. sinon, ma nouvelle approche devrait être de ce type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        Forms2Array : array of TForm2;
    Pour ne pas allonger le tableau de manière idiote, je compte désassigner les Form2x qui ne servent plus... et réassigner les "trous". Donc de toute façon, le problème évoqué ne sera pas rencontré puisque le nom de l'instanciation est explicite. Et finalement ma simulation dans le cas précis est inutile... sauf que je ne comprenais pas le problème. La réponse d'Andnotor est finalement la mise au point nécessaire.
    Pourquoi ne pas utiliser un TList à la place de votre tableau ?

  15. #15
    Invité
    Invité(e)
    Par défaut
    Oui pourquoi pas mais qu'est ce que cela changerait ? Les tableaux présenteraient-ils dans ce cas-là une infériorité ?

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    392
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 392
    Points : 635
    Points
    635
    Par défaut
    par défaut les variables globales sont initialisées à 0, les variables locales sont elles dans un état indéterminées tant que tu ne leur assignes pas une valeur

    assigned teste juste si c'est différent de nil pas si l'objet est bien créé

  17. #17
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Citation Envoyé par selzig Voir le message
    Oui pourquoi pas mais qu'est ce que cela changerait ? Les tableaux présenteraient-ils dans ce cas-là une infériorité ?
    Et bien avec un TList vous n'avez pas à gérer les trous

  18. #18
    Invité
    Invité(e)
    Par défaut
    Bonjour Exoseven,

    Les variables locales sont elles dans un état indéterminé
    Désolé, je n'imagine pas : C'est quoi un état indéterminé ?

  19. #19
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Ca veut dire du caca

    La valeur n'est pas assignée par le compilateur donc la valeur que tu vas trouvé c'est ce qu'il y aura en mémoire à cet instant... Donc c'est aléatoire...

    Et le compilateur doit même donner un avertissement comme quoi votre variable wform2 n'est pas initialisée.

  20. #20
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2012
    Messages : 92
    Points : 159
    Points
    159
    Par défaut
    Citation Envoyé par selzig Voir le message
    Bonjour Exoseven,


    Désolé, je n'imagine pas : C'est quoi un état indéterminé ?
    les variables locales vont pointer sur une zone mémoire.
    tant que tu n'auras pas initialisé ta variable, elle peut contenir tout et n'importe quoi et surement pas ce que tu attends.

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

Discussions similaires

  1. passage de variable via form
    Par emilek dans le forum Langage
    Réponses: 2
    Dernier message: 21/11/2007, 14h12
  2. [vb net]passage de variable entre form !
    Par ChristopheOce dans le forum Windows Forms
    Réponses: 5
    Dernier message: 12/09/2006, 13h06
  3. [VB.Net][debutant]passage de variable entre windows form
    Par ChristopheOce dans le forum Windows Forms
    Réponses: 1
    Dernier message: 26/07/2006, 14h18
  4. Réponses: 2
    Dernier message: 29/06/2006, 01h36
  5. [C#] Passage de variables entre 2 forms
    Par Tips dans le forum C#
    Réponses: 6
    Dernier message: 06/12/2005, 16h48

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