Gestion des fenetre mdi

Résolu
Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 - 14 avril 2011 à 19:35
Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 - 15 avril 2011 à 11:04
Bonjour à tous,

je fais appel à vous car j'ai un gros soucis avec la gestion dynamique de fenêtre.
Je suis en train de construire une application de diagnostique automobile avec des fenêtres qui sont construites en dynamique.
J'ai une fiche FMesSetup qui lorsque l'utilisateur appui sur un bouton, me créé automatiquement une fiche FTrace.
Cette fiche est bien créé par :

function TFMesSetup.addTrace(Name: string): boolean;
var F : TFtrace;
i : integer;
begin
// ajout d'une fenetre trace
try
F:=TFtrace.Create(Application);
//F.Caption:=Name;
F.FormStyle:=fsMDIChild;
i:=1;
while ListObject.IndexOf('TRACE'+inttostr(i))>-1 do i:=i+1;
F.Name:='TRACE'+inttostr(i);
F.Caption:=F.Name;
ListObject.Add(F.Name);
FMesSetup.ListBlocRX.Add('-'+F.Name+';');
Result:=True;
except
Result:=False;
end;
end;

ListObjet me permet de garder dans une liste le nom des objet que j'ai créé. Cette fonction fonctionne parfaitement.
Cette fiche FTrace est défini comme suit :

TFTrace = class(TForm)
SG_Trace: TStringGrid;
ToolBar1: TToolBar;
B_Stop: TToolButton;
B_Pause: TToolButton;
B_TimeMode: TToolButton;
ToolButton4: TToolButton;
B_DisplayMode: TToolButton;
B_Configuration: TToolButton;
ImageList1: TImageList;
TRefresh: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure B_ConfigurationClick(Sender: TObject);
procedure B_TimeModeClick(Sender: TObject);
procedure B_DisplayModeClick(Sender: TObject);
procedure TRefreshTimer(Sender: TObject);
procedure B_StopClick(Sender: TObject);
procedure B_PauseClick(Sender: TObject);
private
{ Déclarations privées }
DispMode : integer;
TimeMode : integer;
Blank : boolean;
CyclicUpdate : integer;
BufferTrace : Array of Byte;
LengthBuffer : integer;
TraceStatus : integer; // status de la fenetre
Tracepause : integer;
n_Column : integer;
Type_Columns : array[0..13] of integer;
Procedure SetupTrace;
public
{ Déclarations publiques }
Setup : TStringList;
Procedure ReadSetup(var ListSetup : TStringList);
Procedure WriteSetup(var ListSetup : TStringList);
Procedure Start;
Procedure Stop;
Procedure Work(var Buffer : Array of byte;Count : integer);
end;

Les procédure de création de la fiche et de destruction :
procedure TFTrace.FormCreate(Sender: TObject);
begin
Setup:=Tstringlist.Create;
Setup.Clear;
Setup.Add('DISPMODE=3;');
Setup.Add('TIME=3;');
Setup.Add('BLANK=TRUE;');
Setup.Add('UPDATE=200;');
Setup.Add('COLUMNS=Time;ID;SRC;DST;Name;Dir;Length;Data;ASCII;');
SetupTrace;
end;

//******************************************************************************
procedure TFTrace.FormDestroy(Sender: TObject);
begin
Setup.Free;
end;

Le problème vient lorsque j'appui sur le bouton configuration dont le code lancé est :

procedure TFTrace.B_ConfigurationClick(Sender: TObject);
var i : integer;
begin
FTraceSetup.TraceSetupList.Clear;
for i:=0 to Setup.Count-1 do /////////////////// Mon problème est ici
begin
FTraceSetup.TraceSetupList.Add(Setup.Strings[i]);
end;
if FTraceSetup.execute then
begin
Setup.Clear;
for i:=0 to Setup.Count-1 do
begin
Setup.Add(FTraceSetup.TraceSetupList.Strings[i]);
end;
SetupTrace;
end;
end;

Lorsque mon programme essaye d'accéder à Setup (un TStringList qui est créé au moment de la création de FTrace)
que j'ai une erreur : Le projet Diaganalyzer a provoqué une classe d'exception EAccessViolation avec le message "violation d'acces à l'adresse 004981C2 dans le module 'diaganalyzer.exe'.Lecture de l'adresse FFFFFFFF"
Je ne comprend pas parce qu'en pas à pas, la création se passe bien. J'ai déja regardé si Setup était à nil, il ne l'est pas.
Je répéte, FTrace est créé pendant l'execution. quel peux bien être mon erreur.

L'aide delphi nous donne ca :
EAccessViolation est la classe des exceptions des erreurs dues àdes accès incorrects àla mémoire.

EAccessViolation est déclenchée quand une application :

Déréférence un pointeur nil (Delphi)ou NULL (C++).
Ecrit dans la mémoire réservée au code exécutable.
Essaye d'accéder àune adresse mémoire pour laquelle aucune mémoire virtuelle n'est allouée àl'application.

Les informations d'exception àl'exécution sont enregistrées dans des champs fournis par EExternal.

Remarque : Les applications ne doivent pas déclencher directement d'exception EAccessViolation,c'est l'exécution qui déclenche cette exception.

Je comprend ce qui ce passe, mon appli essaye de lire n'importe où mais pourquoi ???? là est le mystére car je n'ai pas libéré Setup pendant l'execution donc il devrait exister.

Si quelqu'un veut bien m'aider, je le remercie d'avance car ca fait 3 jours que je teste plein de chose et rien ne marche...je déprime sec sur ce coup

Merci


Oniria

2 réponses

Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 3
15 avril 2011 à 11:04
Bonjour Caribensila,

Merci de m'avoir répondu. J'ai essayé ta technique et le problème ne vient pas de là.
J'ai fini par trouver en me posant la question suivante : mon TStringList Setup provoque des erreurs de mémoire alors que le TStringGrid SG_Trace n'a pas de soucis.
Pourquoi ? Alors je me suis dis si le problème venait de l'endroit ou je déclarais "Setup". Je l'ai déplacé de la zone Public vers la zone private. Et là, magie, ca marche.
Pourquoi, je n'en sais rien mais le problème venait de l'endroit où je déclarais Setup.

Je vais donc poser une autre question sur le forum pour comprendre et ne plus faire d'erreur de ce type.

En tout cas, merci beaucoup. C'est la première fois que je m'essaye au fenetre créé dynamiquement et à volonté par l'utilisateur et ce n'est vraiment pas une paire de manche.

Cordialement

Oniria
3
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
14 avril 2011 à 21:19
Salut Oniria,

Je ne sais pas si ton problème vient de là, mais la fiche principale de ton application est bien un parent MDI ?

FormStyle :=  fsMDIForm;



Et je mettrais FormStyle:=fsMDIChild dans la déclaration de la classe TFTrace, puis :


function TFMesSetup.addTrace(Name: string): boolean;
  var 	 F : TFtrace;
         i : integer;
  begin
  Result : = true;
  Application.CreateForm(F, TFTrace);
  try
    ...
  except
    Result:=False;
  end;
end;

_______________________________________
Soutenez Wikimédia France aujourd'hui : http://dons.wikimedia.fr
0
Rejoignez-nous