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

Composants VCL Delphi Discussion :

Problèmes avec une TForm créée dynamiquement


Sujet :

Composants VCL Delphi

  1. #1
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 897
    Points : 1 561
    Points
    1 561
    Par défaut Problèmes avec une TForm créée dynamiquement
    J'ai deux petites questions à partir du simple code qui suit. Je n'arrive hélas pas à règler ces deux problèmes. Si une âme charitable peut éclairer mes lumières.

    1. Comment indiquer la prise de focus à la fiche enfant (barre de titre en surbrillance) ?
    2. Pourquoi est-ce que le second TEdit ne prend pas le focus dès que l'on clique dessus ?

    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
      ...
    TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormCreate(Sender: TObject);
    var f: TForm;
    begin
      f := Tform.Create(Self);
      f.parent := Form1;
      with TEdit.Create(Self) do
        parent := f;
      with TEdit.Create(Self) do
      begin
        top := 30;
        parent := f;
      end;
      f.show;
    end;
    ...
    Pensez à utiliser les tags dans le titre.
    Avant de poser une question reportez-vous à la FAQ Delphi
    Respectez les règles du forum.

  2. #2
    Membre expérimenté
    Avatar de Bloon
    Homme Profil pro
    Consultant Freelance
    Inscrit en
    Avril 2002
    Messages
    467
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant Freelance
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2002
    Messages : 467
    Points : 1 339
    Points
    1 339
    Par défaut
    Effectivement c'est curieux, d'autant plus que l'événement Click est bien déclenché et avec d'autres contrôles ça fonctionne !

    Pourquoi ne pas utiliser une fenêtre MDI sur OnActivate ?

    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.FormActivate(Sender: TObject);
    var f: TForm;
    begin
      f := Tform.Create(Self); // TForm1 étant fsMDIForm 
      f.FormStyle := fsMDIChild;
      with TEdit.Create(f) do
        parent := f;
      with TEdit.Create(f) do
      begin
        top := 30;
        parent := f;
      end;
      f.show;
    end;
    Bloon
    A lire : Les règles du club
    Delphi : La FAQ - Articles

  3. #3
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 897
    Points : 1 561
    Points
    1 561
    Par défaut
    Citation Envoyé par Bloon
    Effectivement c'est curieux, d'autant plus que l'événement Click est bien déclenché et avec d'autres contrôles ça fonctionne !

    Pourquoi ne pas utiliser une fenêtre MDI sur OnActivate ?
    Je ne peux utiliser une fenêtre MDI car la fenêtre parent qui accueille les TForm créées dynamiquement sera une fenêtre MDIChild.
    Pensez à utiliser les tags dans le titre.
    Avant de poser une question reportez-vous à la FAQ Delphi
    Respectez les règles du forum.

  4. #4
    Membre chevronné
    Avatar de Pierre Castelain
    Inscrit en
    Avril 2002
    Messages
    523
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 523
    Points : 1 943
    Points
    1 943
    Par défaut
    Je viens de faire quelques essais car j'étais étonné de ce comportement. Je me sert de ce genre de mécanisme dans de nombreuses applications et ça marche. La seule différence, mais elle semble être de taille, est que mes fenêtres "embarquées" n'ont pas de bordure. Je m'en sert comme des frames. Bizarrement, si tu ajoute :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      f.BorderStyle:= bsNone;
    les TEdit se comportent normalement.

  5. #5
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 897
    Points : 1 561
    Points
    1 561
    Par défaut
    Citation Envoyé par Pierre Castelain
    La seule différence, mais elle semble être de taille, est que mes fenêtres "embarquées" n'ont pas de bordure. Je m'en sert comme des frames. Bizarrement, si tu ajoutes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      f.BorderStyle:= bsNone;
    les TEdit se comportent normalement.
    Effectivement, mais je perds la bordure. Dans une version précédente j'utilisais des TFrame, mais je trouvais ce mécanisme trop lourd. C'est pour cela que je me suis fixé l'objectif d'utiliser des TForm afin d'hériter de leurs comportements.

    La partie qui pose rééllement un problème dans ce code réside dans l'affectation :
    J'ai tenté d'affecter le Handle de la fiche embarquée à la propriété parentWindow de la fiche parent, comme pour un activeX. Mais sans résultat probant.

    Par ailleurs, en explorant un peu la liste des API, j'ai découvert que dans l'unité windows, on dispose d'une API :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function SetParent; external user32 name 'SetParent';
    qui permet de spécifier un parent pour une fiche enfant:
    la syntaxe est la suivante :
    HWND SetParent( HWND hWndChild,
    HWND hWndNewParent
    );
    En poursuivant cette idée j'ai donc modifié le code du premier post afin d'obtenir le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var F: TForm;
    begin
      F := TForm.Create(Form1);
      with TEdit.Create(Self) do
        parent := F;
      with TEdit.Create(Self) do
      begin
        top := 30;
        parent := F;
      end;
      Windows.SetParent(F.Handle, Form1.Handle);
      F.Show;
    end;
    En testant ce code, on peut remarquer que notre fiche embarquée se comporte maintenant réélement comme une fiche enfant MDI. D'autre part les composants TEdit sont à nouveau accessible à l'exécution.
    Pensez à utiliser les tags dans le titre.
    Avant de poser une question reportez-vous à la FAQ Delphi
    Respectez les règles du forum.

  6. #6
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 897
    Points : 1 561
    Points
    1 561
    Par défaut
    [notes supplémentaires]

    En utilisant cette méthode, il faut veiller à ce que la propriété Parent de la fiche embarquée soit toujours égale à NIL, sinon nous retombons sur le problème énoncé ci-dessus.

    Il faut alors redéfinir une propriété équivalente à Parent pour la pseudo fiche enfant de telle façon de manipuler les composants de la fiche qui embarque.

    En dérivant une classe TForm, pour la fiche embarquée, il faudra alors définir une propriété Ancetre de la manière suivante:

    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
    ...type
      TForm2 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
        FAncetre: TWinControl;
        procedure setFAncetre(value: TWinControl);
      public
        { Déclarations publiques }
        property ancetre: TWinControl read FAncetre write setFAncetre default nil;
      end;
     
    var
      Form2: TForm2;
     
    implementation
     
    {$R *.dfm}
     
    uses unit1;
     
    procedure TForm2.setFAncetre(value: TWinControl);
    begin
      FAncetre := value;
    end;...
    Lors de la création de la fiche embarquée, il faut procéder ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ...var F: TForm2;
    begin
      F := TForm2.Create(Form1);
      Windows.SetParent(F.Handle, Form1.Handle);
      // F.parent := Nil; //veiller à ce que cette valeur ne soit jamais modifiée.
      F.ancetre := Self;
      F.Show;
    end;
    Ce qui permet dans la fiche enfant, de manipuler par exemple un composant TEdit de la fiche pricipale de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (ancetre as Tform1).Edit1.Text := self.Name;
    En gérant une TList, avec les fenêtres embarquées créées lors de l'execution, cela simule parfaitement un applicatif MDI et en plus avec n-niveaux de profondeur.
    Pensez à utiliser les tags dans le titre.
    Avant de poser une question reportez-vous à la FAQ Delphi
    Respectez les règles du forum.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 02/01/2014, 20h58
  2. problème avec une DLL créée sous matlab
    Par orang dans le forum C#
    Réponses: 3
    Dernier message: 24/04/2011, 14h29
  3. Réponses: 10
    Dernier message: 09/02/2011, 15h31
  4. Problème avec une requête en SQL dynamique
    Par pascal_T dans le forum PL/SQL
    Réponses: 4
    Dernier message: 26/08/2008, 15h23
  5. Réponses: 5
    Dernier message: 20/09/2007, 17h53

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