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 :

TForm et Interface


Sujet :

Composants VCL Delphi

  1. #1
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut TForm et Interface
    Salut à tous

    J'ai créé un programme qui utilise des plugins. J'avais au départ utilisé des DLL sans interface. Mais d'après beaucoup de monde, c'est mal
    J'ai donc commencé à tester des solutions avec des interfaces. Seulement voila, j'ai des gros pépins.
    J'ai donc créé un projet vierge avec une fiche et un bouton. J'ai aussi un projet de DLL qui exporte une fonction qui renvoie l'interface en question.
    Voici le gabarit de mon interface:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
      IPedroTest = interface
      ['{1665DEEB-3ADB-4185-B21A-BFD75836C3CF}']
      //Getters
      procedure SetAppHandle(const Value: HWND); StdCall;
      //Setters
      function GetAppHandle: HWND; StdCall;
     
      //publié
        function Test1: boolean; StdCall;
        property AppHandle: HWND read GetAppHandle write SetAppHandle;
      end;
    La propriété AppHandle est là pour les tests.
    Voici l'implémentation de Test1 qui ne fait que créer et afficher une fiche de façon modale:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    function TTest.Test1: boolean;
    begin
    //  Application.Handle := AppHandle;
    //  with TDLLForm.Create(Application) do
      with TDLLForm.Create(nil) do
      try
        Result := ShowModal = mrOk;
      finally
        Free;
      end;
    end;
    Je récupère donc ma procédure dans la DLL qui me crée l'interface. Je lance alors la procédure Test1.
    La fiche s'affiche bien mais:

    • Lorsque je ferme cette fiche, tout le projet se ferme. Si je suis en mode Debug (F9), j'ai droit à une AV. Sinon, tout se ferme sans autre forme de procès.
    • La fiche de la DLL a son propre bouton dans la barre des tâches en plus de celle du programme principal ce que je ne veux pas. En passant le Handle de l'application et en initialisant Application.Handle := FAppHandle, le bouton ne s'affiche plus MAIS (il y en a toujours un) le bouton du programme principal n'est pas enfoncé. Si je clique dessus, la fiche principale désactivé repasse devant la fiche de la DLL... Il faut ensuite faire Alt-Tab pour revenir sur la fiche modale.

    Je ne sais pas si je suis bien clair Quoi qu'il en soit, ma question est: Qu'est-ce que j'ai oublié?? Ou alors, plus généralement: Comment utiliser une fiche avec une interface sans qu'il y ait tous ces défauts?

    Merci d'avance

    PS: pour ceux qui veulent tester, voici mon projet de test (Le GUID est certainement à changer (Ctrl+Shift+G)):
    http://pedro.developpez.com/divers/test_interface.zip

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    La fiche de la DLL a son propre bouton dans la barre des tâches en plus de celle du programme principal ce que je ne veux pas. En passant le Handle de l'application et en initialisant Application.Handle := FAppHandle, le bouton ne s'affiche plus MAIS (il y en a toujours un) le bouton du programme principal n'est pas enfoncé.
    Je dirais plutôt le Owner de la fenêtre est à affecter ...

    Pour l'Access Violation, qui viens de l'interface je crois, alors là galère.

    J'ai essayé diverse truc avec les interfaces mais j'ai carrément laissé tout tomber. J'ai remarqué que la gestion des interfaces avec FastMM et le memory manager de borland sont différentes. Où FastMM se plaint d'un memory leak, l'autre roule très bien. En fixant le memory leak rapporté par fastMM, crash avec mm de borland. De plus, très peu de documentation clair.
    Un gros bordèle pour le release et le add. En résumé, sur un gros projet, j'ai trop galéré et j'ai abandonné.

    Bref, je vous souhaite bon voyage.

  3. #3
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par pepi22 Voir le message
    Je dirais plutôt le Owner de la fenêtre est à affecter ...
    Bah c'est ce que l'on pourrait croire mais tous mes tests effectués jusqu'ici donnent systématiquement le Handle de l'application comme solution pour éviter ce bouton disgracieux
    Citation Envoyé par pepi22 Voir le message
    Pour l'Access Violation, qui viens de l'interface je crois, alors là galère.
    Elle vient seulement lorsque tout se ferme, après quelques secondes...
    Citation Envoyé par pepi22 Voir le message
    J'ai essayé diverse truc avec les interfaces mais j'ai carrément laissé tout tomber. J'ai remarqué que la gestion des interfaces avec FastMM et le memory manager de borland sont différentes. Où FastMM se plaint d'un memory leak, l'autre roule très bien. En fixant le memory leak rapporté par fastMM, crash avec mm de borland. De plus, très peu de documentation clair.
    Pour ma part, dans mon gros projet, j'ai utilisé SimpleShareMem qui marche très bien mais qui, comme toi visiblement, me produit des memory leaks. Bon pas beaucoup mais cela se produit à chaque fois que je lance un plugin! C'est pour éviter cela que j'essaie de passer aux interfaces mais je galère pas mal A vrai dire, en faisant "comme il ne faut pas faire", ça a très bien marché jusque là Mis à part la perte de mémoire évidemment
    Citation Envoyé par pepi22 Voir le message
    Un gros bordèle pour le release et le add. En résumé, sur un gros projet, j'ai trop galéré et j'ai abandonné.

    Bref, je vous souhaite bon voyage.
    Merci

    [EDIT]
    Je viens de réessayer en créant avec un Owner (en l'occurence, la fiche du prog principal) mais même problème: 2nd bouton et fermeture totale...

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    Elle vient seulement lorsque tout se ferme, après quelques secondes...
    C'est ce que je dis, cela doit surement provenir de l'interface.

    Est-ce que vous appelez release?

  5. #5
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par pepi22 Voir le message
    C'est ce que je dis, cela doit surement provenir de l'interface.
    Aïe
    Citation Envoyé par pepi22 Voir le message
    Est-ce que vous appelez release?
    J'ai essayé Release, Free et Destroy et même FreeAndNil sans grand résultat

    Merci en tout cas de m'aider

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    Question peut-être curieuse, avez vous essayez de ne rien faire du tout?

  7. #7
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par pepi22 Voir le message
    Question peut-être curieuse, avez vous essayez de ne rien faire du tout?
    ? Comment ça? Dans la procédure Test1 (celle de l'interface) ?
    Je vais essayer.

  8. #8
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    OK j'ai essayé et ça fait comme ça devrait faire:
    Rien Mais ça ne bugge pas: la fiche principale ne bouge pas

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    Non, je voulais dire pas de release!

  10. #10
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par pepi22 Voir le message
    Non, je voulais dire pas de release!
    Ah! ok j'essaie...

  11. #11
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Ca fait pareil... Décidemment je ne comprends pas... Je ne pensais pas bloquer juste à cause de ça
    Bizarrement, aucune perte de mémoire Comprends vraiment plus là...

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    De quelle classe hérite la classe qui utilise l'interface?

  13. #13
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par pepi22 Voir le message
    De quelle classe hérite la classe qui utilise l'interface?
    TInterfacedObject.
    Voici la déclaration de cette classe:
    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
     
      TTest = class(TInterfacedObject, IPedroTest)
      private
        FAppHandle: HWND;
        FOwnerControl: TWinControl;
        procedure SetAppHandle(const Value: HWND); StdCall;
        procedure SetOwnerControl(const Value: TWinControl); StdCall;
     
        function GetAppHandle: HWND; StdCall;
        function GetOwnerControl: TWinControl; StdCall;
      public
        function Test1: boolean; StdCall;
     
        property AppHandle: HWND read GetAppHandle write SetAppHandle;
        property OwnerControl: TWinControl read GetOwnerControl write SetOwnerControl;
      end;
    Note: toutes les méthodes ne servent pas. C'est uniquement pour les tests
    Voici actuellement la méthode Test1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    function TTest.Test1: boolean;
    begin
    //  Application.Handle := AppHandle;
    //  with TDLLForm.Create(Application) do
    //  with TDLLForm.Create(nil) do
      with TDLLForm.Create(FOwnerControl) do
      try
        Result := ShowModal = mrOk;
      finally
    //    Release;
      end;
    end;
    Sachant que FOwnerControl est la form du programme principal.

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    Est-ce que vous libèrez la classe TTest à la fin du programme?

  15. #15
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par pepi22 Voir le message
    Est-ce que vous libèrez la classe TTest à la fin du programme?
    Comme c'est une interface, il suffit de la mettre à nil, ce que je fais:
    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
     
    var
      hnd: HWND;
      GetIntfProc: TPedroTest;
      intf: IPedroTest;
    begin
      Result := false;
      hnd := LoadLibrary(PChar('Project2.dll'));
      if hnd <> 0 then
      begin
        @GetIntfProc := GetProcAddress(hnd, 'GetIntf');
        if @GetIntfProc <> nil then
        begin
          intf := GetIntfProc;
          intf.AppHandle := Application.Handle;
          intf.OwnerControl := Form1;
          Result := intf.Test1;
          intf := nil;
        end;
        FreeLibrary(hnd);
      end;
    PS: pas la peine de me vouvoyer quand même

  16. #16
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    mmmmm? je suis pas certain que d'assigner le pointeur nil à un interface diminuera le count. Je vérifie ...

  17. #17
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078

  18. #18
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    Trouvé

    l'assignation de NIL dans la variable d'interface ne provoque aucune suppression de l'instance de classe car, bien qu'il soit en théorie à zéro, le compteur de référence n'est pas géré. Notez toutefois que l'appel des méthodes _AddRef et _Release est effectif.
    Liens : http://laurent-dardenne.developpez.c...hi/Interfaces/

  19. #19
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par pepi22 Voir le message
    Ah
    Quelle est donc la solution pour libérer correctement une interface?

  20. #20
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    lol je sais c'est de la m****,

    toutefois, essayez de libèrer l'objet vous même ...

Discussions similaires

  1. [Débutant] imprimer une interface TForm
    Par bicha_27 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/09/2012, 10h49
  2. Interface dune Tform
    Par Panaméen dans le forum C++
    Réponses: 0
    Dernier message: 15/05/2008, 17h49
  3. TForm dans une DLL avec utilisation d'Interface
    Par guedelmalin dans le forum Langage
    Réponses: 13
    Dernier message: 17/06/2005, 12h58
  4. interface utilisateur avec OpenGL
    Par demis20 dans le forum OpenGL
    Réponses: 6
    Dernier message: 03/10/2002, 13h27
  5. Probleme d'impression avec la méthode TForm->Print()
    Par Kid Icarus dans le forum C++Builder
    Réponses: 13
    Dernier message: 31/07/2002, 15h26

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