Andnotor
Le code que tu presentes date de 2002.
Il est en accord avec les recommandations données dans Delphi 7.
Je suivais les recommandations Delphi parce que je les connaissais.
Je ne vois pas en quoi l'Exécute te dérange. Peux-tu expliquer s'il te plaît.
Paul Toth
REPONSE et CONCEQUENCES dans le message précèdent.
Excuse je n'avais pas précisé.
J'attends toujours que tu nous explique ce qui, dans le code de ShowModal, libère la mémoire de la fiche d'une part et d'autre part, où il est écrit dans les recommandation Embarcadero qu'on ne peut pas lire les membres d'une fiche affichée par ShowModal. Ton passage "REPONSE et CONSEQUENCES" ne provient pas de la doc Delphi.
Tout cela ressemble fort à la malédiction qu'a prononcée sur le bûcher le Grand Maître du Temple en 1314.
Comme les rois de France maudits sur treize générations, sur combien de générations allons-nous être frappés par le bug du ModalResult ?
Encore une preuve que les Templiers sont toujours parmi nous.
Andnotor
Depuis la version 2 de DELPHI et jusqu'à la version en cours XE2 et suivant l'aide en ligne de Borland et ses conseils....
Tu confirmes mes assertions : tu ne lis pas tu survoles, il n'y a pas de virgule après suivant donc il faut lire ...version en cours XE2. Et suivant l'aide en ligne ...
Je réitère ma question : je ne vois pas en quoi l'Exécute te dérange.
Peux-tu expliquer s'il te plaît ?
Faire des remarques, qui sont peut-être évidentes pour toi, c'est bien, mais il faut les expliquer aux autres, si tu veux être constructif.
Paul Toth
Lire :
ms-help://embarcadero.rs_xe2/rad/Récupération_des_données_des_fiches_modales.html
Nous trouvons au début l'information suivante :
- l'exemple donné ne le fait pas alors qu'il pourrait le faire.Si la fiche B est toujours en mémoire, il est possible de l'interroger via ses propriétés et ses fonctions membres tout comme les fiches non modales....
- l'exemple donné ne le fait pasMais comment faire si la fiche B est retirée de la mémoire une fois fermée....
A la fin de la recommandation on nous dit :
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 procedure GetColor(PColor: Pointer); begin ColorForm := TColorForm.CreateWithColor(PColor, Self); ColorForm.ShowModal; 1) si la phrase précédente est vrai on aurait pu avoir le code du SelectButtonClick ici en testant la valeur du ModalResult ou la valeur de retour du ShowModal... 2) les infos sont récupérées avant que la fiche B ne soit retirée de la mémoire... ColorForm.Free; end;
- Je comprends que le retour du ShowModal n'est pas fiable.N'oubliez jamais qu'il faut laisser à la fiche appelante un moyen de savoir que la fiche modale a été fermée sans modification, ni sélection.... ???
- Je comprends qu'il faut utiliser une référence puisque Addr est obsolète.Il est possible d'utiliser des objets plus complexes...
- L'exemple ne récupère pas les infos après le ShowModal.
Dans le doute je m'abstiens de récupérer les informations après le ShowModal.
l'exemple est donné DANS LE CAS OU LA FICHE EST SUPPRIMEE !! puisque "Si la fiche B est toujours en mémoire, il est possible de l'interroger via ses propriétés et ses fonctions membres tout comme les fiches non modales" c'est pourtant simple à comprendre non ?
je le dis et le répète, si la fiche est détruite "ColorForm.Free" plantera SAUF si ColorForm vaut "nil" ce qui n'est pas précisé dans ce très mauvais exemple !
Ce qui est faux ! ça veux dire que la méthode GetColor ne permet pas de "savoir que la fiche modale a été fermée sans modification, ni sélection".
où as-tu vu que Addr est obsolète ?! "des objets plus complexes" ce sont des Record, des Instances d'objets, des Array of...
l'exemple s'intéresse au cas de figure où la fiche est détruite et ne peut donc pas lire ses infos ! c'est l'objet même de cet exemple mal foutu qui pose en tout premier lieu : "Si la fiche B est toujours en mémoire, il est possible de l'interroger via ses propriétés et ses fonctions membres tout comme les fiches non modales", tout le reste ne s'intéresse qu'aux fiches détruites.
Et tu ne m'a toujours pas indiqué le code à l'origine du "problème [qui] n'est pas dans notre code mais dans le code écrit par Borland au niveau du changement du ModalResult".
Je plussoie Paul Toth.
Ajouterais-je qu'en traçant l'exécution d'un exemple* dans la fenêtre CPU sous D5, il ne m'a pas semblé passer dans une quelconque fonction qui libèrerait quelque mémoire que ce soit ?
*exemple en Action=caHide, bien sûr, et exécution sans souci d'un accès à des champs de la fiche modale après moult créations dynamiques : j'ai voulu jouer à Saint Thomas, mais là, je n'ai rien vu !
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 !
Tu as raison de me reprendre sur Addr dans XE2 il ne le signale pas comme obsolète. Dans une version précédente de Delphi c'est ce que j'avais lu.
Je suis d'accord avec toi l'exemple est soit très mauvais,
et pourtant il est présent depuis plusieurs années,
soit il manque une information pour qu'il soit clair.
Cette information sur le ModalResult qui libère la mémoire,
je l'ai lue dans une revue, il y a plus de dix ans.
Je ne suis pas en mesure de la monter.
Hey ! Je n'ai même pas taper de code dans ce sujet, comment pourrais-je faire une boulette !
Pour la confusion du ModalResult, le plus proche en D6 c'est de combiner deux pages
L'affectation à ModalResult d'une valeur non nulle ferme la fiche.Ce qu'il ne faut surtout pas faire c'est d'accéder à une référence qui à un caFree comme Action du Close comme l'a fait souligné AndNotOr, Paul TOTH et tous les autres !Pour fermer la fiche et la libérer dans un événement OnClose, affectez la valeur caFree à Action.
Personnellement, j'encapsule les ShowModal par des méthodes Execute comme celle du TOpenDialog mais parfois qu'un boolean ou Integer, plus rare un record\objet contenant tout ce qu'il faut !
(voir l'exemple plus bas)
D'ailleurs, il suffit de lire le code d'InputQuery qui va carrément lire parcourir les contrôles de la forme pour trouver TOUS le TEdit (du coup, je viens de découvrir qu'ils ont fait une version multi-champ, cool !)
En fait l'exemple de Borland pour moi est plus approprié à des fenêtres non modales dont on ne maitrise pas la libération (caFree) et qui utilisent un objet ou une zone mémoire externe pour fournir des données
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 if ShowModal = mrOk then begin J := 0; for I := 0 to ControlCount - 1 do if Controls[I] is TEdit then begin Edit := TEdit(Controls[I]); AValues[J] := Edit.Text; Inc(J); end; Result := True; end;
Faut être un peu con pour mettre caFree à une fenêtre modale qui renvoie un résultat !
Je pense par exemple à une fenêtre de patience non bloquante permettant d'annuler le traitement (une boucle), un var Boolean passé en paramètre
Pour moi, l'idéal, en non modal, c'est de créer un évènement, l'appelant en fournissant le gestionnaire, lorsque l'on modifie une valeur, on le notifie par l'évènement
Personnellement, je n'utilise caFree que très rarement (la plupart du temps avec du MDI)
the form automatically closes ... il y a la Version Française :Cela évoque bien la fermeture et non la libération implicite du caFree !elle se ferme automatiquement lorsque l'utilisateur clique sur l'un de ces boutons et renvoie la valeur de ModalResult comme valeur de renvoi de ShowModal.
Il est vrai que l'article Récupération des données des fiches modales (que tu as très mal lu d'ailleurs) insiste beaucoup sur la libération implicite à la fermeture via caFree mais l'important c'estTu as complètement loupé cette phrase !Lors de la fermeture de B, la fiche A a besoin de savoir ce que l'utilisateur a fait dans la fiche B pour décider comment poursuivre les traitements de la fiche A. Si la fiche B est toujours en mémoire, il est possible de l'interroger via ses propriétés et ses fonctions membres tout comme les fiches non modales de l'exemple précédent.
Sinon pour la POO, c'est vrai que si en interne, Borland\Embarcadero la pratique, il ne donne pas le bon exemple à ce sujet !
Leurs exemples sont souvent TRES foireux !
Pense que davidif est débutant, évite de l'embrouiller !
le pauvre vous lui avez pourri son sujet !
Code c++ : 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 //--------------------------------------------------------------------------- /** * Execute show listing */ /*static*/void TFrmListeCamera::Execute() { TFrmListeCamera *Form = new TFrmListeCamera(NULL); try { Form->ShowModal(); } __finally { delete Form; } }En C++Builder, on peut "masquer" les constructeurs, du coup, on peut empêcher une utilisation manuelle de la fenêtre et obliger l'utilisation des wrappers !
Code c++ : 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 //--------------------------------------------------------------------------- /** * Execute show listing with the option of selecting a Camera maybe for add on the supervision map (plan) * @param ModePlan Indique si c'est une selection polyvalente ou une sélection dédiée à l'ajout sur un Plan * @return Camera PrimaryID ( <= 0 - if not select) */ /*static*/int TFrmListeCamera::ExecuteSelect(bool ModePlan/* = false*/) { int Result = -1; TFrmListeCamera *Form = new TFrmListeCamera(NULL); try { Form->BtnSelection->Visible = true; // Enabled dépend de l'Habilité "Chargement" Form->BtnSelection->Default = true; if (ModePlan) Form->BtnSelection->Caption = "Ajouter au Plan"; if (Form->ShowModal() == Controls::mrYes) Result = Form->FObjCamera->PrimaryID; } __finally { delete Form; } return Result; }
En Delphi, pour "guider" les autres développeurs, je n'ai pas hésité à empêcher l'utilisation directement du Create ou CreateNew par des exceptions pour les orienter vers d'autres constructeurs avec des paramètres (souvent des Objets métiers servant d'entrée-sortie)
Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité !
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager