Probleme de Violation d'accès

Résolu
Mr7Bungle Messages postés 17 Date d'inscription vendredi 1 octobre 2004 Statut Membre Dernière intervention 30 octobre 2007 - 10 oct. 2006 à 14:33
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 - 11 oct. 2006 à 15:00
Bonjour et merci de bien vouloir preter attention à mon petit soucis =)

Voila, j'ai créer un programme utilisant plusieurs fenetres différentes deja créées à l'aide de l'interface graphique de Delphi7.

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2},
  Unit3 in 'Unit3.pas' {Form3};

{$R *.res}

begin
  Application.Initialize;
  Application.Title := 'ProcessTest';
  Application.CreateForm(TForm1, Form1);
  //Application.CreateForm(TForm2, Form2);
  //Application.CreateForm(TForm3, Form3);
  Application.Run;
end.

Les form2 et 3 ne sont pas créer au lancement du programmes, et je désire pouvoir les créer en fonction d'un quelquonc événement (clic sur boutton ou autre...).

Je m'y prend ainsi :

application.CreateForm(Tform2,form2);
form2.show;

et pour quitter la form2 : form2.destroywindowhandle.

Je reviens sur la form1 et lorsque je veut quitter le programme ainsi :

 form1.DestroyWindowHandle;
application.terminate;

Et bien j'ai le droit à une belle erreur de violation d'accès.....

Merci d'avance pour votre aide !

15 réponses

Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
10 oct. 2006 à 16:14
Salut,
essaye déjà de fermer ton application par un simple :
Form1.Close;

 
@+
Cirec

0
Mr7Bungle Messages postés 17 Date d'inscription vendredi 1 octobre 2004 Statut Membre Dernière intervention 30 octobre 2007
10 oct. 2006 à 16:36
Merci de ta reponse ! mais malheureusement, ça ne fonctionne pas,
j'ai remplacé

form1.destroywindowhandle;
application.terminate;

par :

form1.close;

et donc oui ça ferme l'application mais l'erreur de violation d'accès est toujours présente....

Mais merci tout de même =)
0
Emandhal Messages postés 194 Date d'inscription dimanche 2 mars 2003 Statut Membre Dernière intervention 10 octobre 2006 3
10 oct. 2006 à 19:19
u,

Et en pas à pas ca donne quoi?

Tout problème a sa solution... Mais en général, celle que l'on trouve n'est jamais la bonne...
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
10 oct. 2006 à 19:42
création de forme non automatique :


  Screen.Cursor := crHourGlass;
  if not Assigned(form2) then
    Application.CreateForm(Tform2, form2);
  Screen.Cursor := crDefault;
  form2.ShowModal (ou Show)


Pour la violation d'accès, il faut être prudent, quelquefois on croît que cela vient de là et en fait..


peut-être vaudrait t-il mieux joindre le code complet ?

cantador
0

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

Posez votre question
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
10 oct. 2006 à 21:06
Quand tu écris :
Application.CreateForm(Tform2, form2);
L'objet Application devient propriétaire de form2 et est donc responsable de sa destruction.

Or, avant la fin de d'application, tu détruis le handle de la fenêtre form2 (form2.destroywindowhandle).
Donc, quand l'application se termine, elle transmet à Windows un handle complètement farfelu.

Voilà ce que c'est que de vouloir utiliser des méthodes dont on ne maîtrise pas la portée.Comme l'a écrit Cirec, ferme simplement tes fenêtres par un appel à Close ou Release et tout ira mieux.

May Delphi be with you !


<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
10 oct. 2006 à 21:52
premierement, pourquoi ne pas laisser les fiches etre créées puis les appelées avec Show.
elle ne seront pas visible de toute façons.

deuxiement, on ne ferme pas une fenetre en appelant DestroyWindowHandle mais Free comme pour tout les objets, a condition bien sur qu'on gere la creation et destruction.
le mieux etant d'appeler Form.Close qui genere toute une suite d'evenement qui sont utile pour la procedure de destruction de la fiche.

troisiement, on ne quitte jamais une application en appelant Application.Terminate ou encore Halt(0) directement mais bien en appelant la methode "Close" de la fiche principale, encore une fois, dans un soucis de declancher la suite d'evenement necessaire a la destruction de l'application (OnClose, OnDestroy).
Application.Terminate reviens a tuer le processus via le gestionnaire des taches, ce n'est pas une methode propre et adaptée pour quitter d'une façon normale une application. Les evenements OnClose et OnDestroy etant necessaire pour detruire les instances d'objets ou de pointeurs créés dynamiquement et non géré par l'une des fiches.
en somme en appelant Form1.Close on declanche ceci :

Form1.Close ->
Form1.OnCloseQuery ->
si CloseQuery : Form1.DoClose ->
Form1.OnClose ->

liberations/evenement de fermeture gérées par le developeur -> si Form1 fiche modal : Modalresult mrCancel -<si Form1 fiche MDIChild : action Minimize -<
si Form1 = fiche principale : Application.Terminate ->
si CallTerminateProcs : PostQuitMessage(0);
Liberation gérées par le systeme ->

Form1.Destroy ->

Form1.OnDestroy ->

liberations gérées par le developeur

si on appel directement Application.Terminate on saute donc toutes ces etapes importantes de verification et de liberation, du moins de preparation a une fermeture du programme.
ce qui peu empecher la liberation de ressources, la remise a zero de parametres, la sauvegarde de travail ect...
vus qu'on gere ces problemes dans le gestionnaire OnCloseQuery/OnClose et non dans OnDestroy qui ne sert qu'a liberer des objets dynamique ou des ressources bien qu'ils puissent figurer aussi dans OnClose.

en gros :

tu laisse ton projet tel quel (creation de fiche a la creation de la principale)
pour fermer une fiche tu appel FormX.Close, pour l'ouvrir FormX.Show (ou ShowModal)
pour quitter le programme tu appel FormP.Close (fiche principale)

pour ce qui est des violations d'accés, c'est en general un probleme d'allocation de ressources par exemple a la creation d'un objet ou d'un transtypage ou encore de la lecture/ecriture sur un pointeur/instance non alloué ou erroné.

0
Mr7Bungle Messages postés 17 Date d'inscription vendredi 1 octobre 2004 Statut Membre Dernière intervention 30 octobre 2007
10 oct. 2006 à 22:16
Et bien merci à vous pour vos reponses complètes et la leçon de gestion de fenêtres, j'en avais besoin !!

Effectivement je m'y suis pris un peu brutalement...
je test ça demain dans la matinée mais je pense que ça devrait aller mieux =)

Merci encore.
0
Mr7Bungle Messages postés 17 Date d'inscription vendredi 1 octobre 2004 Statut Membre Dernière intervention 30 octobre 2007
11 oct. 2006 à 08:54
Le fait de créer toutes les fenêtres au debut de l'application ne risquerai pas de surcharger le systeme ?
c'est pour ça que je voulais créer les pages au fur et à mesure suivant le besoin car j'ai 35fenêtres dans mon appli .....

Merci de bien vouloir m'apporter quelques précisions à ce sujet

merci encore.
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
11 oct. 2006 à 09:25
Mr7Bungle,

Partant de la même réflexion que toi, il m'arrive pour économiser la machine de créer les forms à la volée :

Application.Createform(...);

Try

    MaForm.Show; (ou ShowModal)

Finally

    MaForm.Release;

end;

Maitenant, est-ce que l'économie est vraiment conséquente ??? En tout
cas, à chaque fois que la form est appelée, tu n'as pas à réinitialiser
tous les contrôles de la fiches...

Simon
0
Mr7Bungle Messages postés 17 Date d'inscription vendredi 1 octobre 2004 Statut Membre Dernière intervention 30 octobre 2007
11 oct. 2006 à 09:31
Après quelques essai voila ce que ça donne :

program processtest;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2},
  Unit3 in 'Unit3.pas' {Form3};

{$R *.res}

begin
  Application.Initialize;
  Application.Title := 'ProcessTest';
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Application.CreateForm(TForm3, Form3);
  Application.Run;
end.

Donc je créé mes pages au démarrage de l'application, je créé les fiches en même temps que la fiches principale

Pour ouvrir form2 :
  
procedure TForm1.Button3Click(Sender: TObject);
begin
form2.show;
end;

Pour la fermer :

procedure TForm2.Button1Click(Sender: TObject);
begin
form2.close;
end;

et pour quitter l'application :

procedure TForm1.Button1Click(Sender: TObject);
begin
form1.release;
end;

cette méthode fonctionne mais ne stop pas l'application

procedure TForm1.Button1Click(Sender: TObject);
begin
form1.close;
end;

Et celle ci me renvoie toujours une violation d'accès.

Et deuxième essai, en créant les form 2  et 3 dans la propriété formload de ma form1 (principale), et là, au lancement c'est la form2 qui se lance (alors que je ne fais que l'a crée, pas l'afficher) et la form1 qui aurai du apparaitre n'apparait pas.....

J'éspère avoir été clair , à mon avis il y a quelques points que j'ai mal compris, merci de m'apporter vos lumières =)

Bonne prog
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
11 oct. 2006 à 10:50
Euuhhh....


Il semblerait donc que ta form principale soit la form1. Donc, pour
fermer l'application, tu as juste besoin de faire un close sur la
form1... normalement le release sur les autres forms est fait tout
seul... (enfin il me semble)


Pour ouvrir form2 :

  

procedure TForm1.Button3Click(Sender: TObject);

begin

    form2.show;   (Le "Showmodal" est pas mal
aussi dans la mesure où il interdit l'accès à la form1 tant que la
form2 n'est pas fermée)

end;


Pour la fermer :


procedure TForm2.Button1Click(Sender: TObject);

begin

form2.close;

end;


et pour quitter l'application :


procedure TForm1.Button1Click(Sender: TObject);

begin
<strike>form1.release;
</strike>Close; (tout simplement... ou bien "Application.Terminate" si la form2 est toujours ouverte)

end;

Simon
0
Mr7Bungle Messages postés 17 Date d'inscription vendredi 1 octobre 2004 Statut Membre Dernière intervention 30 octobre 2007
11 oct. 2006 à 11:23
Et bien j'ai toujours cette violation d'accès, je vous donne le code complet :

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

begin
  Application.Initialize;
  Application.Title := 'ProcessTest';
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Label2: TLabel;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Image1: TImage;
    SkinData1: TSkinData;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
    close;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
    form2.show;
end;
end.

unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    SkinData1: TSkinData;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  Form2: TForm2;

implementation

uses Unit3;

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
form2.close;
end;

end.

je pense avoir fait comme l'on m'a dis mais la violation d'accès est toujours là ....

Merci à vous
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
11 oct. 2006 à 14:17
Je n'y comprends pas grand chose...


-Est-ce que tu as un événement Form1.OnFormClose ? Si oui, peut-on en disposer ?

-As-tu essayé avec Application.Terminate ?


Sinon, est-ce que c'est pas ton ordi ou ta version de delphi qui pose
problème (parce que des "form.Close" j'en fais tous les jours sans
problème...) ?


Je sais pas si tu as mis en ligne l'intégralité de ton code, mais à mon
avis, ça vient d'autre chose que le form.close... peut être un truc en
cours d'utilisation et qui n'a pas été fermé ou libéré...

Simon
0
Mr7Bungle Messages postés 17 Date d'inscription vendredi 1 octobre 2004 Statut Membre Dernière intervention 30 octobre 2007
11 oct. 2006 à 14:43
Merci encore pour vos reponses !!!

Finalement l'erreur n'avez rien à voir avec la création et la fermeture des fenêtres, mais avec  un composant mal configuré : SkinData .

Effectivement se genre d'erreur (violation d'accès) est tres tres vague....
N'existe-t-il pas d'outils permettant de débugger ce genre d'erreur plus rapidement? , un outils qui apporterai des précisions lors d'une violation d'accès? car se serai tout de même pas de temps de gagné.

Merci encore & bonne prog à vous !
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
11 oct. 2006 à 15:00
Euuuhhh C'est pas sur ta réponse qu'il faut cliquer...

Simon
0
Rejoignez-nous