Self, Parent du composant? [Résolu]

cs_Jean_Jean 639 Messages postés dimanche 13 août 2006Date d'inscription 5 mai 2016 Dernière intervention - 13 sept. 2007 à 19:44 - Dernière réponse : cs_Jean_Jean 639 Messages postés dimanche 13 août 2006Date d'inscription 5 mai 2016 Dernière intervention
- 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;


Merci pour vos éclaircissements!
Jean_Jean


 


 
Afficher la suite 

Votre réponse

6 réponses

Meilleure réponse
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 14 sept. 2007 à 13:01
3
Merci
mmm ...

alors, en fait, c'est surtout qu'il faut voir par rapport a ce que tu veux faire et au code de ton compo.

Merci f0xi 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 92 internautes ce mois-ci

Commenter la réponse de f0xi
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 13 sept. 2007 à 20:50
0
Merci
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;
Commenter la réponse de f0xi
cs_Jean_Jean 639 Messages postés dimanche 13 août 2006Date d'inscription 5 mai 2016 Dernière intervention - 13 sept. 2007 à 22:29
0
Merci
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
Commenter la réponse de cs_Jean_Jean
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 14 sept. 2007 à 00:32
0
Merci
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 :)
Commenter la réponse de f0xi
cs_Jean_Jean 639 Messages postés dimanche 13 août 2006Date d'inscription 5 mai 2016 Dernière intervention - 14 sept. 2007 à 12:56
0
Merci
 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+
Commenter la réponse de cs_Jean_Jean
cs_Jean_Jean 639 Messages postés dimanche 13 août 2006Date d'inscription 5 mai 2016 Dernière intervention - 14 sept. 2007 à 20:18
0
Merci
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
Commenter la réponse de cs_Jean_Jean

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.