cs_Jean_Jean
Messages postés615Date d'inscriptiondimanche 13 août 2006StatutMembreDernière intervention13 décembre 2018
-
13 sept. 2007 à 19:44
cs_Jean_Jean
Messages postés615Date d'inscriptiondimanche 13 août 2006StatutMembreDernière intervention13 décembre 2018
-
14 sept. 2007 à 20:18
Bonjour,
Je me lance dans la création d'un composant. Mais je ne comprends pas comment fonctionne le paramètre Self de TWincontrol. Je voudrais que mon composant se dessine sur un PaintBox1 et non sur la fiche principale. Je suis en phase de test, donc le composant graphique ne peut pas être déposé sur le PaintBox1.
Dans l'unité du composant en phase de test.
Constructor TObjetGraph.Create (AOwner : TComponent);
begin
inherited Create(AOwner);
...
end;
Dans la procedure de création de la Fenêtre principale :
aObjetGraph := TObjetGraph.Create(Self);
With aObjetGraph do
begin
Parent := Self; // Puis je mettre autre chose que Self que qu'il se créer sur paintbox1? je ne trouve pas.
Visible := True;
...
end;
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 13 sept. 2007 à 20:50
Self est la reference de la classe/objet dans laquelle il est appelé.
en gros, quand tu appel Self dans TForm1, Self est la reference de l'instance en cours de cette classe.
exemple :
Constructor TObjetGraph.Create (AOwner : TComponent);
begin
inherited Create(AOwner);
Self < fait reference a l'instance en cours de la classe TObjetGraph
end;
procedure TForm1.FormCreate(Sender : TObject)
begin
aObjetGraph := TObjetGraph.Create(Self);
With aObjetGraph do
begin
Parent := Self; < self fait reference a TForm1
Visible := True;
...
end;
end;
ensuite, plutot que d'utiliser un TWinControl qui utilise une paintbox, il ne faut pas prendre TWinControl qui est une classe plus evoluée que TPaintBox :)
le mieux est de prendre un TComponent, non visuel donc, qui vas se servir d'une PaintBox pour l'affichage.
tu conviendras que dans ce cas, l'utilisation d'un TWinControl n'est pas justifié.
pour linker un composant avec un autre, c'est assé simple.
il suffit de faire :
type
TLinkedCompo = class(TComponent)
private
fPaintBox : TPaintBox; // le compo TPaintBox
fPBAssigned: boolean; // true si fPaintbox est assigné
fOnChange : TNotifyEvent; // evenement onChange de TLinkedCompo
procedure SetPaintBox(value : TPaintBox); // setter pour fPaintbox
protected
procedure Change; virtual; // a appeler a chaque modification de TLinkedCompo
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
// permet de notifier TLinkedCompo de la destruction de fPaintbox (si assigné)
public
constructor Create(AOwner: TComponent); overload; override; // constructeur par defaut
constructor Create(AOwner: TComponent; APaintBox : TPaintBox); reintroduce; overload;
// constructeur pour l'utilisation en dynamique (creer la paintbox avant)
published
property Paintbox : TPaintBox read fPaintBox write SetPaintBox; // vers la paintbox
property IsAssignedPaintbox : boolean read fPBAssigned; // est assigné ?
property OnChange : TNotifyEvent read fOnChange write fOnChange; // TLinkedCompo a changé ?
end;
{ TLinkedCompo }
procedure TLinkedCompo.Change;
begin
// appel de l'evenement OnChange
if Assigned(fOnChange) then
fOnChange(self);
end;
constructor TLinkedCompo.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// par defaut
fPaintBox := nil;
fPBAssigned := false;
end;
constructor TLinkedCompo.Create(AOwner: TComponent; APaintBox: TPaintBox);
begin
Create(AOwner);
// assignation directe de Paintbox
SetPaintBox(APaintBox);
end;
procedure TLinkedCompo.Notification(AComponent: TComponent;
Operation: TOperation);
begin
// si c'est la paintbox qui vas etre detruite if (AComponent fPaintBox) and (Operation opRemove) then
begin
// on remet a nil
fPaintBox := nil;
// on remet a false
fPBAssigned := false;
end;
// on appel la methode Notification heritée pour les autres actions
inherited Notification(AComponent, Operation);
end;
procedure TLinkedCompo.SetPaintBox(value: TPaintBox);
begin
// si fPaintBox deja assigné
if fPBAssigned and (Value <> fPaintBox) then
// on supprime la notification de liberation
fPaintBox.RemoveFreeNotification(Self);
// on la reference
fPaintBox := Value;
// c'est assigné ou pas ?
fPBAssigned := Assigned(fPaintBox);
// si c'est assigné
if fPBAssigned then
// on dit a fPaintbox de nous prevenir de sa liberation
fPaintBox.FreeNotification(Self);
end;
cs_Jean_Jean
Messages postés615Date d'inscriptiondimanche 13 août 2006StatutMembreDernière intervention13 décembre 20183 13 sept. 2007 à 22:29
Merci Foxi!
La voix du maître a parlé! J'aime bien quand tu dis que c'est simple.
Je ne suis pas sûr d'avoir bien compris. Ton code est un linkage supplémentaire pour dire que le composant que je vais creer appartiendra en fait (assign) à TPaintBox1? Ou bien est-ce que je dois remplacer ma procedure constructor par la tienne :constructor TLinkedCompo.Create(AOwner: TComponent);
Mon Objet Graphic est un descendant de TGraphicControl:
TObjetGraph = Class(TgraphicControl)
Que deviens ma procedure Constructor TObjetGraph.Create (AOwner : TComponent);? Bon je vais me coucher, j'essayerai ça si possible demain et te tiens au courant.
Jean_Jean
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 14 sept. 2007 à 00:32
ma classe est l'exemple pour toi avec ta classe derivée de TGraphicControl.
en gros, tu n'as qu'a inclure ce que contient ma classe dans ton compo.
ici la propriété PaintBox fonctionne comme les propriété PopupMenu, Action etc des composant delphi.
en gros, tu mets une paintbox sur ta fiche, tu mets ton composant (avec mes ajouts) et dans le gestionnaire de propriété tu selection PaintBox1 dans la propriété PaintBox de ton composant ...
et HOP :)
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_Jean_Jean
Messages postés615Date d'inscriptiondimanche 13 août 2006StatutMembreDernière intervention13 décembre 20183 14 sept. 2007 à 12:56
Il doit y avoir encore qlq chose qui m'échappe dans cette histoire de référencement des composants propriétaires.
L'assignation semble se faire telle que tu l'as écrit mais le graphique ne s'écrit pas dans le PaintBox. Peut-être est-ce mon initialisation qui ne colle pas :
procedure TForm1.FormCreate(Sender : TObject)
begin
aObjetGraph := TObjetGraph.Create(Self);
With aObjetGraph do
begin
Parent := Self ; Parent attend toujours un TwinControl. Dois-je laisser Self?
Visible : = True;
PaintBox:= PaintBox1;
Left := (Paintbox1.width - LongSide) div 2;
Top := (PaintBox1.Height - Smallside) div 2;
TypeObjet := tlRectangle;
LongSide := 200;
SmallSide := 100;
...
end;
end;
Bon, pas si transparent que cel cette affaire?
A+
cs_Jean_Jean
Messages postés615Date d'inscriptiondimanche 13 août 2006StatutMembreDernière intervention13 décembre 20183 14 sept. 2007 à 20:18
OK Foxi, je garde ton code sous le coude, on ne sait jamais!
En fait, je voulais avoir un canvas sur lequel, je pouvais travailler des effets visuels de très bonne résolution.
J'avais lu ici et là que TPaintBox était mieux que TImage pour cela. Peut-être que je me trompe.
La question (la vraie) était donc de trouver une zone très précise au niveau pixel en augmentant une zone graphique délimitée qui ne demanderait pas à changer la résolution de tout l'écran.
Bon, je ne sais pas si je suis clair?
Jean_Jean