Self, Parent du composant?

Résolu
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 - 13 sept. 2007 à 19:44
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 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;


Merci pour vos éclaircissements!
Jean_Jean


 


 

6 réponses

f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
14 sept. 2007 à 13:01
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.
3
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
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;
0
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
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
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
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 :)
0

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

Posez votre question
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
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+
0
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
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
0
Rejoignez-nous