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

C++Builder Discussion :

DLL et MainForm je suis perdu !


Sujet :

C++Builder

  1. #1
    Candidat au Club
    Inscrit en
    Août 2003
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 17
    Points : 4
    Points
    4
    Par défaut DLL et MainForm je suis perdu !
    Bonjour,

    Voilà j'ai un petit problème, j'ai fait une application pour un client qui se compose de plusieurs modules (Fiches), je voudrais mettre tout ca en DLL, afin d'avoir que peux de maintenance a faire sur l'ensemble du programme, mais aussi me faciliter la tâche pour les maj !

    J'ai donc créer deux projet vierge, l'un est une dll qui posséde une form classique avec un bouton, l'autre est un exe qui posséde également une form classique mais avec trois boutons.

    Le 1er bouton de l'exe, fait apparaître la form de la dll(MDIChild), le second bouton ne fait que la faire disparaître et la décharger avec FreeLibrary et le dernier me sert juste a initialiser le caption de la form de la DLL.

    Jusque là rien de trés compliqué (surtout quand on a le tut des DLL de LFE sous les yeux, d'ailleurs merci ), le problème est que j'aimerais bien faire en sorte qu'a partir du bouton de ma dll je puisse changer une variable quelconque de ma mainform, disons int var=0; au départ et que j'aimerais qu'elle soit à 1.

    Déjà est-ce possible et si oui comment ?

    Car a chaque fois que je fait Form1->var = 1;, le compilateur me jette, ce qui est évident puisque Form1 n'est pas connu et même si j'inclue le Unit1.h, au moment de faire le link, il me dit "unresolved external "_Form1" ..." !

    Cela devient trés énervant a force

    Si quelqu'un a une idée, elle est la bienvenue.

    Rudy.

  2. #2
    Membre habitué Avatar de ken_le_videur
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 129
    Points : 145
    Points
    145
    Par défaut
    Il faut passer à ta dll un pointeur sur ta form1 ou à ta variable var.

  3. #3
    Candidat au Club
    Inscrit en
    Août 2003
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 17
    Points : 4
    Points
    4
    Par défaut
    Ok, mais comment fait tu pour lui passer un pointeur de la Form1, car quand j'essaie, et que j'utilise var qui dépend de Form1, il me met une erreur comme quoi var n'est pas un membre de Form1 !

    Merci.

  4. #4
    Membre expérimenté Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    886
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 886
    Points : 1 526
    Points
    1 526
    Par défaut
    Qu'est-ce que c'est, "Form1" ? La fiche de l'EXE, de la DLL ... ou les deux ?

  5. #5
    Candidat au Club
    Inscrit en
    Août 2003
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 17
    Points : 4
    Points
    4
    Par défaut
    Effectivement, c'est pas trés claire, la form1 est la form de l'EXE et la form2 celle de la DLL.

    Mais je crois avoir trouvé une solution, peux être pas trés "propre", mais faut voir, j'essaie et je vous dit ce qu'il en est !

  6. #6
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Il doit y avoir au moins deux possibilités utilisant à la base la GetProcAddress de l'API :

    - soit pour récupérer l'adresse d'une fonction qui à l'aide d'un paramètre va modifier
    la variable
    - soit pour récupérer l'adresse de la variable pour la modifier directement

    Celà sous entend que ces éléments (fonction et/ou variable) soient déclarés comme exportables dans leur dll
    afin qu'un autre module puisse en récupérer l'adresse avec GetProcAddress.

    A plus !

  7. #7
    Candidat au Club
    Inscrit en
    Août 2003
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 17
    Points : 4
    Points
    4
    Par défaut
    Salut,

    Alors j'ai pas tout compris, mais le principe est ok, seulement je cherchais a directement modifier les variables sans passer par des fonctions spécifiques ayant chacune cinq paramètres voir plus (c'est le minimum) !

    En fait j'ai trouvé une solution, surement pas trés "propre", mais si vous avez mieux ...

    Dans mon Unit2.h, j'ai tout simplement mis :

    #ifdef dll
    TForm1 *res;
    #else
    TForm *res;
    #endif

    et dans Unit2.cpp, j'ai :

    #ifndef dll
    #define dll
    #endif

    Pourquoi me direz-vous ? Tout simplement parceque La form2 correspond a ma DLL, et que pour accéder a la form1, il faut inclure Unit1.h, je définis donc dans la form2 la variable dll, ainsi lors de la compilation, lorsqu'il s'agit de compiler la dll, il utilisera TForm1 * res, et par conséquent il connaitra tout les membre de la form1 !

    Et lorsque je compile l'EXE, il utilisera TForm *res, ce qui évitera des erreurs de compilation vue que j'inclue Unit2.h dans la form1 (pour pouvoir accéder a ces membres également).

    Résultat, lorsque je clique sur le bouton qui se trouve dans la form2 de ma dll, avec le code suivant :

    res->Edit1->Text = Form2->Caption;

    ca marche

    Au chargement de ma dll dans la form1, j'ai le code suivant:

    Form2->res = Form1;

    Ce qui permet de renseigner la ressource res de la dll, ainsi j'accède a la form1 de ma dll.

    Quant a la communication de la form1 vers la form2, c'est une instruction classique du type :

    Form2->Caption = Edit1->Text;

    et voilà

    Bien sûre je suis persuadé qu'on peux faire mieux mais qu'en pensez-vous ?

  8. #8
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    En supposant que tu développes tout dans le même dossier,
    est-ce que tu ne pourrais pas inclure les lignes suivante dans la dll
    qui se chargerait de créer une Form2 ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    include "Unit2.h";
    USEFORM("Unit2.cpp", Form2);
    C'est juste une idée... je vais tester ça de mon coté !

    A plus !

  9. #9
    Candidat au Club
    Inscrit en
    Août 2003
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 17
    Points : 4
    Points
    4
    Par défaut
    En fait c'est déjà ce qui se passe, la form2 est bien dans la DLL.

    Par contre j'ai un petit souci, tout fonctionne nikel, du moins dans le programme que j'ai fait juste pour tester, j'attaquerais la transformation du logiciel dés que j'aurais tout compris

    J'ai tout compilé, DLL et EXE et ca fonctionne nikel, l'EXE(form1) appel la form qui se trouve dans la DLL (form2), sachant que la form1 est une MDIForm et form2 une MDIChild, par contre dés que je passe en version finale, dés que je clique sur le bouton qui est censé chargé la DLL et afficher la form2, plantage !

    Il me dit : "Cannot create form. No MDI Forms are currently active."

    c'est un comble car la fenêtre est forcément active vue que je clique sur le bouton !

    Enfin, le problème n'a pas l'air de venir de là, j'ai cherché sur le forum et apparemment c'est déjà arrivé, il faudrait inclure les paquets a la compilation, mais le problème c'est qu'une fois compilé, si je le mets sur une machine "vierge", donc qui n'a pas bcb6, il me dit qu'il lui manque vcl.bpi pour s'éxécuter !

    Hors j'aimerais bien que mon appli soit la plus légère possible, cad qu'il n'y ait qu'un minimum de dll, en autres les miennes et c'est tout !!!

    Si quelqu'un a une idée :

  10. #10
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    C'est sans doute un problème au niveau du Owner de la MDIChild qui devrait être la MDIForm,
    il me semble (à cause des propriétés et méthodes liées aux Children).

    A plus et bon réveillon !

  11. #11
    Candidat au Club
    Inscrit en
    Août 2003
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 17
    Points : 4
    Points
    4
    Par défaut
    c'est a dire ?

    un petit exemple ?

    Question subsidiaire pourquoi ca fonctionne en debug et pas en release ?

    MErci.

  12. #12
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Citation Envoyé par rudy2
    c'est a dire ?

    un petit exemple ?

    Question subsidiaire pourquoi ca fonctionne en debug et pas en release ?

    MErci.
    Car tu as sans doute des problèmes d'initialisation de variables.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  13. #13
    Candidat au Club
    Inscrit en
    Août 2003
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 17
    Points : 4
    Points
    4
    Par défaut
    Bonjour,

    c'est ce dont je pensais hier soir, en fait voilà le code qui est exécuté dans la DLL juste aprés le chargement de la DLL:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int __stdcall LoadForm(HWND hwnd)
    {
            Form2 = NULL;
            oldhandle = Application->Handle;
            Application->Handle = hwnd;
            Form2 = new TForm2(Application);
            ShowWindow (Form2->Handle , SW_SHOW);
            return (0);
    }
    Et pourtant toujours la même erreur, en fait j'ai remarqué que lorsque je compile en debug, le hwnd a pour valeur 'NULL' et application->Handle également, mais pas lorsque je compile en release

    Bizarre quand même, j'ai donc essayé de mettre ces valeurs a 'NULL', mais rien n'y fait, en fait les valeur ne sont pas mise a NULL, comment cela se fait-il ???

    Je n'y comprend plus rien !!

    Balises [Code] rajoutées par Ricky81
    Pensez y à l'avenir

  14. #14
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Form2 = new TForm2(Application);
    Normalement le propriétaire d'une MDIChild n'est pas Application mais la MDIForm.

    Par contre... chez moi ça fonctionne jusqu'à la libération de la dll où je
    me paie une violation d'accès ! Je ne sais plus où mettre la FreeLibrary ?
    C'est pas important... je trouverai ça l'an prochain !

    D'ici là bon réveillon !

    A plus !

  15. #15
    Candidat au Club
    Inscrit en
    Août 2003
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 17
    Points : 4
    Points
    4
    Par défaut
    Désolé pour la balise code, je n'y avais pas fait attention

    Oui en fait dans l'appel de la fonction j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    iRet = ImpFuncDLL(Form1->Handle);
    Mais ca ne fonctionne pas mieux

  16. #16
    Candidat au Club
    Inscrit en
    Août 2003
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 17
    Points : 4
    Points
    4
    Par défaut
    Bon aprés plusieurs essais, je constate que lorsqu'on compile en debug avec les paquets, cela fonctionne trés bien, mais dés lors que l'on ne construit plus avec les paquets, le code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application->Handle = hwnd;
    ne fonctionne plus

    En effet, le Handle ne prend pas la valeur qu'on essaie de lui attribuer !

    J'abandonne pour l'instant, ca va me reposer un peu, merci en tout cas a vous tous, et passez une bonne année

  17. #17
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Il semblerait que tu aies modifié ton programme...

    J'ai réussi à trouver une bidouille... (parce que à ce stade j'ai du mal à bien comprendre,
    et qu'à mon grand étonnement ça marche !)

    Pour ce qui concerne les MDIChild, en fait l'appel au constructeur peut se faire ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new TForm2(Application->MainForm); //puisque la MainForm n'est autre que la MDIForm
    Par ailleurs et au cas où tu aurais des problèmes lors de la fermeture du programme,
    (ayant voulu tester la génération d'autant de MDIChild dont on a besoin) voici ce que
    j'ai fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
    DestroyComponents(); //Solution au bug qui me donnait une violation d'accès (???)
    if(ChildFormDll != NULL)
        {
        FreeLibrary(ChildFormDll);
        }
    }
    Dans la form2 où l'on est censé avoir un bouton pour fermer la fenêtre enfant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void __fastcall TForm2::SpeedButton1Click(TObject *Sender)
    {
    TForm *MdiForm = Application->MainForm;
    MdiForm->RemoveComponent(this); //la retirer des MDIChildren de la MDIForm
    Free(); //libérer la mémoire    
    }
    Toutefois on trouve dans l'aide :

    N'appelez pas la méthode Free d'un objet. Utilisez à la place le mot-clé delete qui appelle Free
    pour détruire un objet. Free appelle automatiquement le destructeur de l'objet si l'instance de
    l'objet n'est pas NULL. Tout objet instancié à l'exécution qui n'a pas de possesseur doit être détruit
    en utilisant delete qui appelle Free, afin que l'objet soit correctement détruit et la mémoire libérée.
    pourtant ça marche... je n'ai pas voulu faire delete(this) !

    A plus !

  18. #18
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Pour la méthode du bouton... (GAG !!)
    J'ai rajouté deux ou trois trucs dans la Form2 et ça m'a donné d'autres bugs au niveau VCL...
    Maintenant j'ai donc bien au plus simple (pourquoi ne pas faire ce qui est déconseillé alors
    que ça marche) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void __fastcall TForm2::SpeedButton1Click(TObject *Sender)
    {
    delete this; // aucun problème alors qu'il m'avait semblé jusqu'à present que "delete this" ???
    }
    Bon... il faut que j'aille ouvrir les huitres... parce que ici... la fête va reprendre !

    A plus !

  19. #19
    Candidat au Club
    Inscrit en
    Août 2003
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 17
    Points : 4
    Points
    4
    Par défaut
    Salut Henderson,

    Non ca ne fonctionne toujours pas, en fait ca fonctionne lorsque dans les options de compilation de mon projet la case "construire avec les paquets" est coché, autrement ca ne fonctionne pas !

    Le problème c'est qu'a ce moment là il faut obligatoirement inclure le fichier vcl.bpl lorsqu'on distribue l'appli, hors je n'en ai jamais eu besoin depuis que je programme avec bcb6 !

    Je continue de chercher, mais a mon avis c'est voué a l'echec cette fois !

    Bonne fête a toi

    Rudy.

  20. #20
    Expert éminent sénior


    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    7 856
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 7 856
    Points : 34 380
    Points
    34 380
    Par défaut
    Citation Envoyé par rudy2
    Salut Henderson,

    Non ca ne fonctionne toujours pas, en fait ca fonctionne lorsque dans les options de compilation de mon projet la case "construire avec les paquets" est coché, autrement ca ne fonctionne pas !

    Le problème c'est qu'a ce moment là il faut obligatoirement inclure le fichier vcl.bpl lorsqu'on distribue l'appli, hors je n'en ai jamais eu besoin depuis que je programme avec bcb6 !

    Je continue de chercher, mais a mon avis c'est voué a l'echec cette fois !

    Bonne fête a toi

    Rudy.
    Il me semble qu'n a déjà eu un cas similaire où l'application ne fonctionnait pas comme elle devait lorsque "construire avec les paquets" était décoché. Il s'est avéré que des variables qui n'avaient pas été initialisées ne prenaient pas les mêmes valeurs dans les 2 configurations.

    En espérant que ca puisse te mettre sur une piste ... (Trap D l'a déjà évoqué précédement)

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

Discussions similaires

  1. Je suis perdu avec le type *wstring d'une DLL C++
    Par alain8550 dans le forum C++/CLI
    Réponses: 1
    Dernier message: 14/04/2010, 21h48
  2. [ODBC] Je suis perdu avec ODBC
    Par Nowhere dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 19/05/2006, 08h50
  3. [Tableaux] aide je suis perdu
    Par covin85 dans le forum Langage
    Réponses: 12
    Dernier message: 14/04/2006, 17h56
  4. [Architecture] EJB ou pas EJB ? Je suis perdu ...
    Par n!co dans le forum Java EE
    Réponses: 18
    Dernier message: 26/01/2006, 18h21
  5. RAM DDR, PC3200, 333Mhz , 400Mhz je suis perdu
    Par ahage4x4 dans le forum Composants
    Réponses: 2
    Dernier message: 08/12/2005, 17h52

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