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 :

Utilisation d'une fenêtre TDialog sous windows


Sujet :

C++Builder

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 33
    Points : 29
    Points
    29
    Par défaut Utilisation d'une fenêtre TDialog sous windows
    bonjour,
    J'utilise Borland C++ 4.2,qui est un peu ancien,mais satisfaisant.
    J'ai une application avec fenêtrages sous windows,dans laquelle j'ai un problème,parce que je ne maîtrise pas tout à fait la programmation en fenêtrages.C'est l'utilisation des objets (ou dérivés de) TDialog (type Borland C++ prédéfini).
    J'ai utilisé une méthode 1 qui consiste à :créer un nouvel objet du type TApplication (autre type Borland C++),ayant pour fenêtre principale la fenêtre TDialog qu'on veut créer,et exécuter cette TApplication par Run().Cette méthode marche bien.
    J'ai utilisé une méthode 2 qui consiste à:créer un objet TDialog (ou dérivé),avec les fenêtres "child" voulues,et exécuter ce TDialog par Execute().Cette méthode pose problème.D'abord un "child" TListBox (type Borland C++) ne marche pas,mais surtout après fermeture du TDialog,un peu plus tard dans le programme,il y a un plantage par une exception (General Protection) (qui semble se produire quand on manipule la fenêtre de l'application principale).
    Je voudrais comprendre pouquoi cette méthode ne marche pas.Quelqu'un un peu avancé en fenêtrage a-t-il une réponse ? Merci.

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 74
    Points : 62
    Points
    62
    Par défaut
    bonjour,

    Je crois que ton pb est un pb de gestion de la mémoire, assez indépendant du pb de fenêtrage. Les fenêtres enfants sont des objets que tu manipules par des pointeurs.
    Peux-tu montrer le code que tu utilises pour créer/lancer une fenêtre ?

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 33
    Points : 29
    Points
    29
    Par défaut
    Voilà le code correspondant
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    /*On a en variable commune*/
    const int nbx=10;
    // les ressources sont définies dans un fichier .rc :
    // ID_DIALOG la fenêtre de dialogue
    // ID une fenêtre fille (le TEdit)
    // 301 une fenêtre fille PUSHBUTTON
     
    class TMyDial : public TDialog {
    	public:
    		TMyDial (TWindow* pt,int ResId):TDialog (pt,ResId,0)
    		{
    		  BOOL st2=-1;
    		  int ResId2 = ID;
    		  st2 =this->Create();
    		  li = new TEdit ( (TWindow*)this, ResId2,
    		  11*nbx+4, (TModule*)0);
    		  display();
    		};
    		TEdit* li;
    		char tedit[114];     
    		void display();
    		void display2();
    		DECLARE_RESPONSE_TABLE (TMyDial)
    ;
    };
    DEFINE_RESPONSE_TABLE1 (TMyDial,TWindow)
    	EV_COMMAND (WM_CLOSE, EvClose),  //peut-être inutile
    	EV_COMMAND (WM_PAINT, display2),  //peut-être inutile
    	EV_COMMAND ( 301, display2),
    END_RESPONSE_TABLE;
    		void TMyDial::display()
    		//fonction créée car je voulais remplir la fenêtre TEdit à la création du TMyDial
    		{
    			BOOL st2;
    			int ResId2;
    			st2 =li->Create();
    			li->Clear(); 
    			char *lpc = tedit;
    			for (unsigned i=0;i<nbx;i++)
    			{
    			sprintf(lpc,"fi%03d.mtf\r\n",i);
    			lpc += 11;
    			}
    			lpc = tedit;
    			ResId2 = ID;
    			SetDlgItemText (ResId2,lpc);
    			st2 = li->ShowWindow(SW_SHOW);
    			st2 =st2;
    			return;
    		};
    		void TMyDial::display2()
    		//fonction créée car display() ne marchait pas
    		{
    			BOOL st2;
    			int ResId2 =ID;
    			li->Clear(); 
    			char *lpc = tedit;
    			for (unsigned i=0;i<nbx;i++)
    			{
    			sprintf(lpc,"fi%03d.mtf\r\n",i);
    			lpc += 11;
    			}
    			lpc = tedit;
    			SetDlgItemText (ResId2,lpc);
    			st2 = li->ShowWindow(SW_SHOW);
    			st2=st2;
    			return;
    		};
     
     
    	// on est dans une fonction membre de la fenêtre de l'application principale 
    	TMyDial* pt = new TMyDial(this,ID_DIALOG);
    	pt->Execute();
    	if (pt->CanClose())  // instruction rajoutée pour bien vérifier
                                               //la fermeture de pt
    	 {
    	 pt->CloseWindow();
    	 }
    	pt->li->~TEdit(); 
    	pt->~TMyDial();
    	Invalidate();

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 74
    Points : 62
    Points
    62
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    pt->li->~TEdit(); 
    pt->~TMyDial();

    essaye ceci :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // pt->li->~TEdit(); // pourquoi faire ça ? Ce serait mieux de le mettre dans le destructeur de TMyDialog, appelé la ligne d'après. Un test de nullité sur li ne peut pas faire de mal.
    delete pt; // exactemenet pareil mais plus conventionnel

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 33
    Points : 29
    Points
    29
    Par défaut
    J'ai remplacé les destructeurs par deux delete.Ca ne marche pas.
    Apparement,le plantage se produit quand on veut manipuler la fenêtre principale de l'application (réduire,agrandir,déplacer,),après que la fenêtre TMyDial a été fermée et donc n'existe plus.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 33
    Points : 29
    Points
    29
    Par défaut
    Je crois que j'ai trouvé la cause possible de l'exception.En effet,si je supprime les delete de pt->li et de pt,l'exception n'est plus levée.
    Je pense qu'il y a un problème sur la procédure de la fenêtre de dialogue (le WindProc) et la procédure de la fenêtre principale.Il semble que la procédure de la fenêtre principale soit supprimée,ou modifiée quand on fait un delete de pt->li et pt.La procédure de fenêtre est une procédure par défaut,car je ne donne pas une définition utilisateur.Je suppose que la procédure est la même pour les fenêtres dialogue et principale,et qu'elle n'existe qu'à un exemplaire en mémoire.Si on supprime *pt,la procédure est supprimée ou modifiée,ce qui explique l'exception ultérieure.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 74
    Points : 62
    Points
    62
    Par défaut
    pour ce que je connais de fenêtres enfants, il s'agit de fenêtres dérivées . C'est bien ce que vous avez avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class TMyDial : public TDialog
    Et une fenêtre enfant de votre application est une instance de cette classe dérivée.
    Je ne vois pas pourquoi le delete d'une instance entraînerait le delete d'une autre instance d'une autre classe.
    Ce serait bien que le destructeur de TMyDial soit virtual et que ce soit lui qui delete le TEdit * li.
    Peut-être aussi que le constructeur de TMyDialog n'est pas le bon endroit pour faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    st2 =this->Create();
    li = new TEdit ( (TWindow*)this, ResId2,...
    Essayez de déplacer ces instructions dans un autre évènement après la construction.
    Par ailleurs, cet appel dans le constructeur est un peu suspect...bon courage

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 33
    Points : 29
    Points
    29
    Par défaut
    J'ai supposé que la fenêtre principale de l'application et la fenêtre de
    dialogue TMyDial ont la même procédure,ce qui est exact je pense.C'est la
    même procédure par défaut.
    J'ai constaté que,si on ne fait plus les delete,il n'y a plus de plantage,
    et après la fenêtre principale semble se comporter normalement.d'où mon
    hypothèse que le delete altère la procédure de la fenêtre principale.Il y
    a un problème d'instanciation de la procédure,quoi exactement (?)je ne peux pas dire.Je suis
    persuadé que c'est là qu'est la cause du plantage suite aux delete.
    Il y a donc déjà une première solution,je pense,pour éviter le plantage.
    C'est de créer les objets TWindow (ou TDialog) dont on a besoin au début de
    l'application,et d'attendre la fin pour les détruire (ou de laisser
    l'application les détruire elle-même!).

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 33
    Points : 29
    Points
    29
    Par défaut
    Le problème est résolu en pratique.Il faut créer une seule fois les objets TMyDial,TEdit et ne les détruire qu'en fin d'application.Par contre,on peut utiliser les fonctions de manipulation des fenêtres (Create,Close,etc) autant de fois que l'on veut.Je ne connais pas tout à fait la raison théorique exacte de cela.J'ai supposé qu'un delete d'un objet TMyDial supprime ou modifie la procédure de la fenêtre principale.Si ce n'est pas exactement la procédure,en tout cas une ressource qui est commune aux deux fenêtres est supprimée ou modifiée.
    Je ne marque pas le problème comme résolu,car je n'ai pas l'explication rationnelle de l'erreur qui se produisait,avant de trouver la solution pratique.

Discussions similaires

  1. Utiliser une commande UNIX sous Windows XP
    Par issueTracker dans le forum Windows XP
    Réponses: 2
    Dernier message: 16/10/2007, 18h26
  2. Centrer une fenêtre ouverte avec window.open et statusbar
    Par Michaël dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 02/01/2006, 13h07
  3. Réponses: 5
    Dernier message: 06/07/2005, 14h51
  4. Portage d'une librairie linux sous windows
    Par sleg dans le forum C++
    Réponses: 22
    Dernier message: 31/05/2005, 22h21
  5. Utiliser Borland C++ avec Emacs sous Windows
    Par Eikichi dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 02/03/2003, 08h40

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