Probleme de Violation d'accès [Résolu]

Mr7Bungle 17 Messages postés vendredi 1 octobre 2004Date d'inscription 30 octobre 2007 Dernière intervention - 10 oct. 2006 à 14:33 - Dernière réponse : cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention
- 11 oct. 2006 à 21:22
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 !
Afficher la suite 

16 réponses

Répondre au sujet
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 11 oct. 2006 à 21:22
+3
Utile
eh oui,
Mr7Bungle, voilà le type même d'exemple où la violation d'accès n'était pas ce que l'on croyait au départ d'où ma prudence..




foxi
t'a glissé un petit inventaire bien fait pour les violations d'accès mais hélas il y en a d'autres...
chacun a ses petits trucs pour les repérer..
dès que tu manipules des composants que tu n'as pas l'habitude d'utiliser, il faut penser à faire beaucoup de sauvegarde permettant ainsi de revenir sur une version stable du source.

bon courage !

cantador
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_cantador
Cirec 4217 Messages postés vendredi 23 juillet 2004Date d'inscription 3 avril 2018 Dernière intervention - 10 oct. 2006 à 16:14
0
Utile
Salut,
essaye déjà de fermer ton application par un simple :
Form1.Close;

 
@+
Cirec

Commenter la réponse de Cirec
Mr7Bungle 17 Messages postés vendredi 1 octobre 2004Date d'inscription 30 octobre 2007 Dernière intervention - 10 oct. 2006 à 16:36
0
Utile
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 =)
Commenter la réponse de Mr7Bungle
Emandhal 199 Messages postés dimanche 2 mars 2003Date d'inscription 10 octobre 2006 Dernière intervention - 10 oct. 2006 à 19:19
0
Utile
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...
Commenter la réponse de Emandhal
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 10 oct. 2006 à 19:42
0
Utile
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
Commenter la réponse de cs_cantador
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 10 oct. 2006 à 21:06
0
Utile
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.
Commenter la réponse de cs_Delphiprog
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 10 oct. 2006 à 21:52
0
Utile
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é.

Commenter la réponse de f0xi
Mr7Bungle 17 Messages postés vendredi 1 octobre 2004Date d'inscription 30 octobre 2007 Dernière intervention - 10 oct. 2006 à 22:16
0
Utile
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.
Commenter la réponse de Mr7Bungle
Mr7Bungle 17 Messages postés vendredi 1 octobre 2004Date d'inscription 30 octobre 2007 Dernière intervention - 11 oct. 2006 à 08:54
0
Utile
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.
Commenter la réponse de Mr7Bungle
sp40 1293 Messages postés mardi 28 octobre 2003Date d'inscriptionContributeurStatut 3 juillet 2015 Dernière intervention - 11 oct. 2006 à 09:25
0
Utile
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
Commenter la réponse de sp40
Mr7Bungle 17 Messages postés vendredi 1 octobre 2004Date d'inscription 30 octobre 2007 Dernière intervention - 11 oct. 2006 à 09:31
0
Utile
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
Commenter la réponse de Mr7Bungle
sp40 1293 Messages postés mardi 28 octobre 2003Date d'inscriptionContributeurStatut 3 juillet 2015 Dernière intervention - 11 oct. 2006 à 10:50
0
Utile
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
Commenter la réponse de sp40
Mr7Bungle 17 Messages postés vendredi 1 octobre 2004Date d'inscription 30 octobre 2007 Dernière intervention - 11 oct. 2006 à 11:23
0
Utile
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
Commenter la réponse de Mr7Bungle
sp40 1293 Messages postés mardi 28 octobre 2003Date d'inscriptionContributeurStatut 3 juillet 2015 Dernière intervention - 11 oct. 2006 à 14:17
0
Utile
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
Commenter la réponse de sp40
Mr7Bungle 17 Messages postés vendredi 1 octobre 2004Date d'inscription 30 octobre 2007 Dernière intervention - 11 oct. 2006 à 14:43
0
Utile
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 !
Commenter la réponse de Mr7Bungle
sp40 1293 Messages postés mardi 28 octobre 2003Date d'inscriptionContributeurStatut 3 juillet 2015 Dernière intervention - 11 oct. 2006 à 15:00
0
Utile
Euuuhhh C'est pas sur ta réponse qu'il faut cliquer...

Simon
Commenter la réponse de sp40

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.