Besoin d'explication : Pourquoi ca marche ?

Résolu
bradlemon Messages postés 7 Date d'inscription vendredi 17 octobre 2003 Statut Membre Dernière intervention 10 juin 2008 - 27 janv. 2007 à 15:59
bradlemon Messages postés 7 Date d'inscription vendredi 17 octobre 2003 Statut Membre Dernière intervention 10 juin 2008 - 29 janv. 2007 à 04:10
Tout d'abord bonjour à tous et bonne année !!!

Je débute en delphi et histoire de comprendre comment ca marche je fais quelques petits "essais" et je suis tombé sur un problème de compréhension du langage.

Voici ma question :
mon projet contient un programme principal (essai) 2 forms (main et client) . Sur la première Form, j'ai 2 boutons : 'Consulter' et 'Modifier' qui comme vous l'aurez compris vont ouvrir la seconde Form soit en consultation soit en modification.
le code ci-joint fonctionne (pour tester, je modifie simplement le titre de la seconde fenêtre).

Ma question est la suivante : pourquoi suis-je obligé de mettre Application.CreateForm(TForm_client, Form_client); dans mon programme principal (ligne en rouge) alors que j'ai déjà Form_client.FormCreate(Form_client,mode_choisi); dans les fonctions évenementielles des boutons (lignes en bleu) ?

D'avance merci pour vos réponses.

voici le codes des trois Unit :
********************************************
le programe
********************************************
program essai;

uses
  Forms,
  main in 'main.pas' {Form_main},
  client in 'client.pas' {Form_client};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm_main, Form_main);
  Application.CreateForm(TForm_client, Form_client);
  Application.Run;
end.

******************************************
Unit main : contient les deux boutons
******************************************
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, client;

type
  TForm_main = class(TForm)
    Btn_consulter: TButton;
    Btn_modifier: TButton;
    procedure Btn_consulterClick(Sender: TObject);
    procedure Btn_modifierClick(Sender: TObject);
  private
  public

  end;

var
  Form_main: TForm_main;
  mode_choisi:string;

implementation

{$R *.dfm}

procedure TForm_main.Btn_consulterClick(Sender: TObject);
begin

mode_choisi:='consulter';
Form_client.FormCreate(Form_client,mode_choisi);
Form_client.ShowModal;
end;

procedure TForm_main.Btn_modifierClick(Sender: TObject);
begin
mode_choisi: ='modifier';
Form_client.FormCreate(Form_client,mode_choisi);
Form_client.ShowModal;
end;
end.

************************************************
Unit client : une fenetre vierge où seul le Caption est mis à jour
************************************************
unit client;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm_client = class(TForm)
    procedure FormCreate(Sender :TObject; var mode:string);
  private
    { Private declarations }
  public
  end;

var
  Form_client: TForm_client;

implementation

{$R *.dfm}
procedure TForm_client.FormCreate(Sender :TObject; var mode: string);
begin

if mode='consulter' then
  Form_client.Caption:='Consultation'
else
  Form_client.Caption:='Modification'
end;

end.

8 réponses

f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
27 janv. 2007 à 16:44
mon dieu ... faut pas faire comme ça mon ami!

bon deja, bon point pour toi, tu utilise ShowModal ce qui est bien pour ce type d'application.

mais c'est mieux de faire comme cela :

<hr size="2" width="100%" />
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm_main = class(TForm)
    Btn_consulter: TButton;
    Btn_modifier: TButton;
    procedure Btn_consulterClick(Sender: TObject);
    procedure Btn_modifierClick(Sender: TObject);
  private
  public

  end;

var
  Form_main: TForm_main;

implementation

{$R *.dfm}

uses Client;

procedure TForm_main.Btn_consulterClick(Sender: TObject);
begin
  Form_Client.Execute(FCL_SHOW);

  { // variante d'utilisation :

  if Form_Client.Execute(FCL_SHOW) then

     ShowMessage('La fiche viens d''être consultée.');

  }
end;

procedure TForm_main.Btn_modifierClick(Sender: TObject);
begin
  Form_Client.Execute(FCL_EDIT);
 
  { // variante  d'utilisation :

  if Form_Client.Execute(FCL_SHOW) then

     ShowMessage('La fiche viens d''être modifiée.')
  else

     ShowMessage('Modification de la fiche annulée.')

  }
end;

end.

<hr size="2" width="100%" />
unit client;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm_client = class(TForm)
    Btn_Ok     : TButton; { propriété ModalResult sur mrOK }
    Btn_Cancel : TButton; { propriété ModalResult sur mrCancel }
  private
  public
    function Execute(const Mode : word) : boolean;
  end;

var
  Form_client: TForm_client;

const
  FCL_SHOW = word($0001);
  FCL_EDIT = word($0002);

implementation

{$R *.dfm}

function TForm_client.Execute(const Mode : word) : boolean;
begin
  case Mode of
    FCL_SHOW : Caption := 'Consultation';
    FCL_EDIT : Caption := 'Modification';
  end;

  // en mode consultation pas de boutton "annuler"
  Btn_Cancel.Enabled := Mode <> FCL_SHOW;

  // Execute ne renvois True que si le boutton Ok est préssé  Result :ShowModal mrOK;
end;

end.

<hr size="2" width="100%" />Croc (click me)
3
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
28 janv. 2007 à 13:13
Dans delphi, tu as deux possibilités pour les formes :



Soit tu laisses Delphi les créer automatiquement (voir Projet/Options/fiches)
et dans ce cas pour les afficher tu peux utiliser :
Form1.show ou Form1.ShowModal ou utiliser l'astuce de foxi pour changer le caption.
Cette technique est à priviligier lorsque les formes servent très souvent ou sont petites.

lorsque les formes sont plus imposantes ou sont utilisées moins fréquemment, on aura intérêt à ne pas les créer au démarrage (voir Projet/Options/fiches)
mais à différer leurs créations, en utilisant par exemple :

  If not Assigned(Form_client) then
  Application.CreateForm(TForm_client, Form_client);
  Form_client.Show;

cantador
3
jace1975 Messages postés 81 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 12 octobre 2007 1
28 janv. 2007 à 13:24
c'est tout bete,

va dans le menu projet/options/fiche. Là tu vois deux listbox, une indiquant les fiches créées dès le début d'execution de ton programme et à droite celles qui ne le sont pas mais que tu peux appeler en cours.

donc si toutes tes fiches sont dans la listbox de gauche, c'est normal que tu es Application.CreateForm(TForm_client, Form_client) dans la partie program et le Form_client.FormCreate(Form_client,mode_choisi); n'est pas nécessaire.

par contre si une fiche est dans la listbox de droite, tu dois la créer avant son appel, donc faire appel à tes Form_client.FormCreate(Form_client,mode_choisi); et ne pas oublier aussi de tous bien libérer si tu as vraiment un probleme de mémoire .

pour plus d'info regarde dans l'aide à tapplication; tu auras la réponse à tes questions

j'espère avoir été clair
3
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
28 janv. 2007 à 17:48
1. dans la déclaration des constantes FCL_SHOW et FCL_EDIT que signifient ($0001) et ($0002) ?



$ signifie que le chiffre qui suis vas etre en hexadecimal, $0001 et $0002 sont equivalant a 1 et 2, mais
dans le cas de constante qu'on utilise comme des "flags" (switch de mode etc) on prefere souvent les ecrires
en hexa avec parfois un transtypage inclus dans l'affectation : word($0001) pour signifier que FCL_? ne vas prendre
que deux octets (registre 16 bits) et non dans un integer (registre 32bits).
ici on aurait meme pus signifier : byte($01) et byte($02) pour les stocker dans un registre 8 bits.

2. Je suis donc obligé de garder Application.CreateForm(TForm_client, Form_client); dans la partie program.
Cela signifie-t-il que la Form est créée dès le démarrage du programme
? si oui, la mémoire nécessaire pour la création de la Form_client est
également allouée dès le démarrage du programme ?

en effet, avec cette methode c'est l'appli qui gere la creation de la fiche Form_Client, elle alloue egalement la memoire
necessaire pour cette fiche dés le demarrage.
la ou Cantador a tort et a la fois raison, c'est qu'il faut reflechir a 2 choses, en effet des petites fiches ne prendrons pas
beaucoup de ressources memoire mais, une grosse fiche pourrait etre plus longue a etre crée.
il faut donc reflechir au confort d'utilisation, soit on economise les ressources, soit on prefere la rapiditée d'utilisation.
sincerement je prefere toujours laisser l'appli gerer les fiches consequentes ou petites, de toute façon, les ressources
devront etre allouée tot ou tard, au moins, en allouant dés le debut, on est sur de la disponibilitée de ces dernieres quand
on appeleras nos fiches enfants.

3. Dois-je mettre une Application.CreateForm(...) dans la partie program
pour toutes les Form qui vont exister dans mon logiciel ? Je veux dire
que si j'ai une trentaine de Form dans l'ensemble du logiciel, cela
fait beaucoup de Form crées dès le démarrage alors que seules
quelques-unes ne seront peut-être utilisées par l'utilisateur, non ?

voir ma reponse au dessus, a toi de gerrer correctement l'equilibre ressource/performance. voir TOpenDialog, TSaveDialog
et surtout TCustomDialog, cela peut etre une bonne idée quand on a besoin de plusieurs fenetre "outils".
on les appel directement par leur fonction Execute qui se charge de la creation et de la liberation.

<hr size="2" width="100%" />Croc (click me)
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
28 janv. 2007 à 19:53
Oui foxi, ce qui également intéressant afin de compléter ton explication, est qu'une fois la fiche créée, il n'est pas nécessaire de la re-contruire une deuxième fois, ainsi l'utilisateur verra le sablier (en cas de grosse fiche) au premier click mais lors du 2e la fiche s'ouvrira instantément...

@+

cantador
3
bradlemon Messages postés 7 Date d'inscription vendredi 17 octobre 2003 Statut Membre Dernière intervention 10 juin 2008
28 janv. 2007 à 07:52
merci FOxi pour ton aide.
J'aurai trois questions supplémentaires : 

   1. dans la déclaration des constantes FCL_SHOW et FCL_EDIT que signifient ($0001) et ($0002) ?

   2. Je suis donc obligé de garder Application.CreateForm(TForm_client, Form_client); dans la partie program. Cela signifie-t-il que la Form est créée dès le démarrage du programme ? si oui, la mémoire nécessaire pour la création de la Form_client est également allouée dès le démarrage du programme ?

   3. Dois-je mettre une Application.CreateForm(...) dans la partie program pour toutes les Form qui vont exister dans mon logiciel ? Je veux dire que si j'ai une trentaine de Form dans l'ensemble du logiciel, cela fait beaucoup de Form crées dès le démarrage alors que seules quelques-unes ne seront peut-être utilisées par l'utilisateur, non ?

D'avance merci.
0
bradlemon Messages postés 7 Date d'inscription vendredi 17 octobre 2003 Statut Membre Dernière intervention 10 juin 2008
28 janv. 2007 à 17:22
merci à tous pour votre aide.
@bientôt.
0
bradlemon Messages postés 7 Date d'inscription vendredi 17 octobre 2003 Statut Membre Dernière intervention 10 juin 2008
29 janv. 2007 à 04:10
En fait dans le code que j'ai envoyé au début du post, je faisais une confusion à cause du nom de la fonction utilisé dans Form_main ( à savoir FormCreate) du coup j'avais l'impression de créer la Form_client 2 fois, d'où mon incompréhension. J'aurai très bien pu appeler ma fonction MajForm_Client(mode_choisi) par exemple et garder FormCreate(...) dans program.
Ton exemple de code m'a beaucoup aidé Foxi.

Je vais en effet étudier les fonctions TOpenDialog, TSaveDialog et TCustomDialog.

 Merci encore pour votre aide et la rapidité de vos réponses.
@bientôt,
Brad.
0
Rejoignez-nous