sp40
Messages postés1276Date d'inscriptionmardi 28 octobre 2003StatutContributeurDernière intervention 3 juillet 2015
-
26 juil. 2006 à 16:07
sp40
Messages postés1276Date d'inscriptionmardi 28 octobre 2003StatutContributeurDernière intervention 3 juillet 2015
-
2 août 2006 à 10:57
Je crée un petit composant sur la base d'un TPanel. Sur ce panel sont
posés différents controles dont un bouton (avec une petite croix) qui
est censé libérer le composant.
1) Est-ce possible ? (j'ai quelques doutes...)
2) Je n'arrive pas à lier le OnClick de ce bouton au destructor sans
avoir d'erreur abstraite ou de violation d'accès. Est-ce normal ? sinon
comment puis-je faire ?
ThWilliam
Messages postés418Date d'inscriptionmardi 3 janvier 2006StatutMembreDernière intervention26 novembre 20134 27 juil. 2006 à 12:47
Salut Simon,
Loda a tout-a-fait raison : ne pas libérer un composant dans un de ses événements et, à fortiori, dans un événement d'un composant enfant !
C'est peut-être possible en envoyant un message au proprio...
Ceci dit, ton composant ne contient qu'un TEdit et un TButton, c.à.d. presque rien en "bouffage mémoire". Pourquoi tiens-tu à le libérer ? Le rendre invisible ne suffit pas ?
procedure TMyPanel.BTNFreeOnClick(Sender : TObject);
begin
Visible:= false;
end;
Solution de paresse, mais comme dit Matt, "la paresse est la mère du génie".
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 27 juil. 2006 à 13:17
".. et évidemment, ne pas oublier de libérer ton mypanel p.ex. dans l'événement OnClose de ta Form."
il me semble plus simple (et plus sur) de créer ton composant avec un .Create(self) et non .Create(nil). Comme ça, la lib detruit le composant tout seul!
C'est le mecanisme utilisé pour tout les boutons que tu pose sur ta form. C'est là que réside l'interêt de la class TComponent.
cite de l'help:
Components are persistent objects that have the following capabilities:
- Ownership. The ability to manage other components. If component A owns component B, then A is responsible for destroying B when A is destroyed.
- ...
" inherited Create(AOwner); // <- ici"
Bonne remarque Japee, C'est très important !
bon code,
Vous n’avez pas trouvé la réponse que vous recherchez ?
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 28 juil. 2006 à 17:12
Bon alors voici le même code (modifié, testé, homologué)
il crée 10 TMyPanel sur la form
tu peux en supprimer autant que tu veux et dans n’importe quel ordre et tout fonctionne !!!!
destructor TMyPanel.Destroy;
begin EDValeur.Free;
BtnFree.Free;
inherited destroy;
end;
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
Var I, X, Y : Integer;
begin X : = 0;
Y := 0;
For I : = 1 to 10 do Begin MyPanelArray[I] := TMyPanel.Create(Nil);
MyPanelArray[I].Parent := Self;
MyPanelArray[I].Name := 'MyPanel'+IntToStr(I);
// la suite n'est la que pour avoir un positionnement correcte sur la form
MyPanelArray[I].Left := X;
MyPanelArray[I].Top := Y;
Inc(X, 300);
If X > (Width - 300) Then Begin X : = 0;
Inc(Y,90);
End End;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
Var I : Integer;
begin For I := 1 to 10 do if MyPanelArray[I] <> NilThen MyPanelArray[I].Free;
end;
procedure TForm1.WMFREE_MY_PANEL(var Msg: TMessage);
Var I : Integer;
begin // Récupération du Message et Action
For I : = 1 to 10 do If (MyPanelArray[I] <> Nil) and (MyPanelArray[I].Handle = Msg.WParam) Then
Begin MyPanelArray[I].Free;
MyPanelArray[I] : = Nil;
End;
end;
end.
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 27 juil. 2006 à 12:30
salut,
je suis désolé de contredire Cirec, mais il me semble que ce n'est pas possible (du moins pas depuis un event)
selon l'aide de Delphi (Tobject.Free):
Never explicitly free a component within one of its own event handlers or the event handler of a component it owns or contains. For example, don?t free a button, or the form that owns the button, in its OnClick event handler.
je crois que c'est clair. De plus, c'est logique, tu ne peux pas détruire un composant depuis "l'intérieur" de celui-ci.
Tu devrait plustot chercher du côté des messages, genre CM_DESTROYHANDLE. Mais je sais pas du tout le quel il te faudrait utiliser. le mieux que t'ai a faire, c'est de chercher comment la lib libère les componsants.
Sinon, tu peux essayer de déléger la destruction du componsant a son parent (la destruction doit commencer après la fin de l'event). Je sais pas si c'est faissable sans message.
ThWilliam
Messages postés418Date d'inscriptionmardi 3 janvier 2006StatutMembreDernière intervention26 novembre 20134 27 juil. 2006 à 13:35
@japee : mypanel.free provoque chez moi (delphi7) une violation d'accès.
@Loda : évidemment : inherited Create(AOwner). Tu as raison, le composant sera détruit automatiquement par le Owner, mais j'ai l' habitude de libérer ce qui est créé dynamiquement...
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 27 juil. 2006 à 13:53
@ ThWilliam : si tu le detruit toi même, il ne faut PAS le crée avec .Create(self) mais .Create(nil). Je précis au cas où ce ne serrait pas clair pour qqun.
sp40
Messages postés1276Date d'inscriptionmardi 28 octobre 2003StatutContributeurDernière intervention 3 juillet 201515 27 juil. 2006 à 14:14
Merci pour toutes vos réponses, je vais regarder ça. J'avais trouvé un
truc sinon, mais je trouve pas ça très propre (?). Sur le OnClick du
bouton "Free", je lance un timer à 1ms qui libère l'objet...
N_M_B
Messages postés94Date d'inscriptionmardi 9 mai 2006StatutMembreDernière intervention 1 mars 2008 27 juil. 2006 à 22:06
slt !
éxusez moi j'ai une ptite question .
quand on cree un compo avec des sous composant c un peut comme un chainage?
le compo principale doit etre crée par la fiche ou un panel ...ect et inci de suite ?si non quese qui se passe ?
svp faites moi une ptite éxpliquation (je ne l'éxije pas....mdrr)
merci a vous et vive CodesSources...lol
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 28 juil. 2006 à 07:03
on ne parle pas de chainage mais plutot d'imbrication d'object.
-declaration du composant :
unit UMonCompo;
interface
uses ... ;
type
TMonCompo = class(TComponent)
private
fLaurieOwner : TLaurieContainer;
fLaurie : TLaurie;
fOnChange : TNotifyEvent;
procedure SetLaurieContainer(val : TLaurieContainer);
procedure SetLaurie(val : TLaurie);
protected
procedure Change; virtual;
public
// constructeur / destructeur, obligé si on veut controler un minimum la
// creation / destruction du composant. la direction Override est obligatoire
// dans la plupart des cas.
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
// objets interne, attention write necessite la creation d'une fonction
// d'assignation de valeur quand les composants sont créés en interne.
// si il s'agit de composant externe a assigner manuellement on mettrat
// property Objet : ObjetClasse read fObjet write fObjet;
property LaurieContainer : TLaurieContainer read fLaurieContainer write SetLaurieContainer;
property Laurie : TLaurie read fLaurie write SetLaurie;
// evenements, on leurs assigne un gestionnaire d'evenements ...
property OnChange : TNotifyEvent read fOnChange write fOnChange;
end;
implementation
constructor TMonCompo.Create(AOwner : TComponent;
begin
// obligatoire
inherited create(AOwner);
// on fait gaffe au sens de creation
fLaurieOwner := TLaurieContainer.Create(Self);
fLaurie := TLaurie.Create(fLaurieOwner);
Change;
end;
destructor TMonCompo.Destroy;
begin
// on fait gaffe au sens de liberation
fLaurie.Free;
fLaurieOwner.Free;
// obligatoire
inherited Destroy;
end;
procedure Change;
begin
if assigned(fOnChange) then fOnChange(Self);
end;
procedure SetLaurieContainer(val : TLaurieContainer);
begin
fLaurieContainer.Assign(Val); // ou Val.AssignTo(fLaurieContainer);
Change;
end;
procedure SetLaurie(val : TLaurie);
begin
fLaurie.Assign(Val); // ou Val.AssignTo(fLaurie);
Change;
end;
end.
- creation/utilisation du compo dans un programme :
unit Unit1.pas;
interface
uses ...;
type
TFormX = class(TForm)
private
procedure FormXCreate(Sender : TObject);
procedure FormXClose(Sender : TObject);
protected
public
published
procedure DoChange(Sender : TObject); // gestionnaire d'evenement dynamique pour MonCompo
end;
var
FormX : TFormX;
implementation
var
MonCompo : TMonCompo = nil;
procedure TFormX.FormCreate(Sender : TObject);
begin
// on crée
MonCompo := TMonCompo.Create(Self);
MonCompo.OnChange := DoChange;
end;
procedure TFormX.FormClose(Sender : TObject);
begin
// on libere
MonCompo.Free;
end;
procedure TFormX.DoChange(Sender : TObject);
begin
// rafraichir les données par exemple (affichage, calculs ect...)
end;