Probleme de Parent

anisb Messages postés 22 Date d'inscription mercredi 16 novembre 2005 Statut Membre Dernière intervention 19 février 2007 - 5 sept. 2006 à 10:27
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 - 7 sept. 2006 à 08:56
Bonjour à tous,

Je vais essayer d'être clair...
1) Mon projet contient une Form: dans le formCreate, j'instancie un certain nombre de Panel dont le Owner et le Parent est la Form. Dans le Create des Panels, j'utilise des fonctions qui font appels au canvas du Panel et tout ce passe bien (car le Parent est bien positionné avant l'utilisation de ces fonctions ).

2) J'ai changé certaines choses : maintenant, j'ai décidé de placer tous les composants qui étaient sur la Form dans un Panel. Ce Panel Englobant est instancié dans le FormCreate de la Form. Le Parent et le Owner de ce Panel est la Form. Les Panels Englobés sont instanciés dans le Panel Englobant, leur Owner et leur Parent seront donc le Panel Englobant. Mais maintenant, ça plante à l'éxecution lorsque j'arrive sur des instructions qui font appels au Canvas des Panels Englobés. Et je ne comprends pas ce qui se passe...

N.B : Toutes les créations sont éffectuées en Run Time (à l'éxécution) et non en Design Time (Conception)

Quelqu'un pourrait-il m'aider?
Amicalement,

Anis B.

8 réponses

cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
5 sept. 2006 à 11:02
salut,

t'as posé ta question de manière très clair. bravo.

Et, pour moi du moins, tu instancies correctement tes panels. Ca devrait marcher.

Pourrais tu nous indiquer l'erreur (message et emplacement)? une AV?

Pour contourner le problème, peut-être pourrais-tu executer ton code sur le canvas dans le formShow et non le form create. (vu que de toute façon le canevas ne serra pas visible avant et redessiner au pèremier affichage)


un test qui marche chez moi (pas d'erreur au runtime):


unit CanvasTest_frm;

interface

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

type TPanelACESS = class (TPanel); // to access to protected .Canvas

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
pnl1, pnl2 : TPanelACESS;
end;


var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var r : trect;
begin
pnl1 := TPanelACESS.Create(self);
pnl1.Parent := self;
pnl1.SetBounds(10,10,200,200);
pnl2 := TPanelACESS.Create(pnl1);
pnl2.Parent := pnl1;
pnl2.SetBounds(10,10,100,100);

r.Left := 10;
r.right := 20;
r.top := 10;
r.bottom := 20;

pnl1.Canvas.Brush.Color := clRed;
pnl1.Canvas.FillRect(r);
end;

end.

bon code,
0
anisb Messages postés 22 Date d'inscription mercredi 16 novembre 2005 Statut Membre Dernière intervention 19 février 2007 1
5 sept. 2006 à 11:10
Bonjour et merci pour la rapidité de ta réaction.

Le code que tu viens de poster est effectivement le cas que nous avions auparavant, et ça marchait bien.
C'est lors de l'appel d'une fonction de Canvas sur le sous panel pnl2 que ça ne fonctionnerait pas.

Voici un exemple de ce qui ne marche pas:

Form.FormCreate( Sender : TObject );
begin
   Panel1 := TMonPanel.Create( Self );
   Panel1.Parent := Self;
   Panel1.PanelCreate;
end;

TMonPanel.PanelCreate;
begin
   SousPanel := TMonSousPanel.Create( Self );
   SousPanel.Parent := Self;
   SousPanel.PanelCreate;
end;

TMonSousPanel.PanelCreate;
var
  h : integer;
begin
  h := Canvas.TextWidth('Test'); // Plantage à l'appel de cette instruction
end;

L'erreur est une violation d'accès lorsqu'on utilise les
fonctions du Canvas : mais le Canvas n'est pas nil.
0
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
5 sept. 2006 à 11:56
ho,

désolé, j'ai mis pnl1 dans le test.... *sleepy*

notes que si ton seul problème est des trucs genre TextWidth, tu peux appeler ces methode depuis un autre canvas. si la font est la même, t'aurras le même resultat.

avec ton exemple:

pnl2.Canvas.Brush.Color := clRed;
pnl2.Canvas.FillRect(r);
ShowMessage('[Debug] ' + inttostr(pnl2.Canvas.TextWidth('Test')));


fonctionne aussi. "21" si tu veux savoir ;-)

pourrais tu essayer ce code chez toi?


as-tu essayer de mettre un break point sur l'appel et de faire du "trace into"? si tu trouve ou ça crash exactement, ça pourrait aider.
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
5 sept. 2006 à 18:16
Je suis d'accord avec Loda, pour une fois, la question est bien posée

Le problème ne se situerait-il pas ici ?
TMonPanel.PanelCreate;
begin
   SousPanel := TMonSousPanel.Create( Self );
   SousPanel.Parent := Self;
   SousPanel.PanelCreate;
end;

Chaque composant visuel créé sur une fiche a comme propriétaire la fiche.
Par conséquent, tout en gardant une souplesse dans le code, tu peux donc écrire :

TMonPanel.PanelCreate;
begin
   SousPanel := TMonSousPanel.Create( Self.Owner );
   SousPanel.Parent := Self;
   SousPanel.PanelCreate;
end;

Ce qui a pour effet de ne pas rendre ton composant TMonPanel dépendant d'une classe nommée TForm1.

May Delphi be with you !
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0

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

Posez votre question
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
5 sept. 2006 à 21:17
Deja separe les Classe TMonPanel et TMonSousPanel de l'unitée de la fiche ce serat 100 fois mieux.

Ensuite, tu devrais lister les tpanel pour pouvoir y acceder plus facilement.
Sois en utilisant une TList, sois avec les TCollection, TCollectionItem.
De plus cela faciliteras les creations/liberations, avec des fonctions Add et Delete, sans parler de l'indexation des TPanel qui faciliteras l'accés a ces derniers, comme cela on obtient un contenant principal et des objet pouvant contenir a leurs tours des objets, un peu dans l'esprit d'un TTreeView.

aprés tout depend des besoins.

<hr size="2" width="100%" />Croc (click me)
0
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
6 sept. 2006 à 09:09
une précision:

Si tu veux faire une liste de tes Instance de panel, utilise TComponentList. C'est plein de truc très pratique.

Si t'as des gros besoins au niveau de la list des panels, crée une class descendant de TComponentList.

Comme dit F0xi, ça dépend de tes besoins
0
anisb Messages postés 22 Date d'inscription mercredi 16 novembre 2005 Statut Membre Dernière intervention 19 février 2007 1
6 sept. 2006 à 17:16
En fait il s'agit d'une erreur de ma part ... le plantage ne se situe pas au niveau du Canvas (j'ai dit qu'elle n'était pas Nil ) mais en fait parce que ces appels declenchent un évenement de Resize. Or ayant reimplémenté cette méthode pour resizer tous les composants de ce panel elle me fait planter... Voici ce qui se passe :
MonPanel.Create --> TMonSousPanel.Create dans ce create je fais appel au fonction de canvas
---> Resize Appelée (je ne sais pas pk) --> Dans Resize j'ai des opérations sur d'autres Panels et de composants non encore crées ... donc plantage
J'espère que la solution est aussi claire que la question et vous remercie pour votre aide et votre réactivité
Vive DelphiFR
   
0
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
7 sept. 2006 à 08:56
essai d'ajuter ça (sans garanti)

CanvasResize:
begin
if csLoading in self.ComponentState then exit;
// reste du code


au pire, tu te fait ton propre flag.
0
Rejoignez-nous