Et comment fait-on quand l'objet est créé dans une unité sans fiche ?Envoyé par FAQ Delphi
Et comment fait-on quand l'objet est créé dans une unité sans fiche ?Envoyé par FAQ Delphi
Salut
Attention: je crois que tu fais un amalgame:
Tu as une TForm avec son unité et un composant avec son unité propre (comme tous les compos de la VCL d'ailleurs ).
Tu déclares une instance de ton composant sur l'unité de ta TForm et tu déclares aussi un évènement compatible sur la TForm... Et tu l'assignes après...
A moins que je n'ai pas bien pigé le problème
Pas sûr : si je déclare ma procédure en dehors de toute déclaration de type, j'ai une erreur de syntaxe à l'affectation à mon objet : "Types incompatibles : Pointeur de méthode et procédure normale"Envoyé par MD Software
Non, c'est pa ça.
Je dirais :
"En premier lieu il faut déclarer l'évènement dans la déclaration de votre classe."
en fait peut importe ou l'evenement se trouve finalement
Il faut juste 3 contraintes sur la méthode assignée dynamiquement
- que ce soit une méthode (donc procedure of object)
- qu'elle ait strictement les mêmes paramètres que l'évenement à affecter
- qu'elle soit à portée de la classe qui utilise cette méthode
Après, qu'il y ait plusieurs classe dans l'unité, classes visuelles ou non ... ca n'a pas d'importance.
on peut faire
par exemple
Code : Sélectionner tout - Visualiser dans une fenêtre à part Form1.BitBtn1.OnClick := UneClasseVisibleAutrePart.MonClick;
Je crois même qu'il n'y a pas besoin d'instancier la classe qui contient la méthode en question. (mais gare aux effets de bore si elle utilise des var. de la classe...)
Exemple pour une classe ne comportant que des outils, et qui n'est jamais instanciée
Bon, je précise :
J'ai dans un programme des routines de sauvegarde-restauration, pour lesquelles j'utilise des composants de compression Abbrevia (TurboPower).
Comme elles doivent être appelées de plusieurs endroits, je veux les placer dans une unité spécifique. Dans ces composants, les demandes de confirmations d'écrasement à la décompression se gérent dans un gestionnaire d'évènement OnConfirmOverwrite.
D'où mon pb :
- pour des raisons d'indépendance de code qui me semblent évidentes, je veux que mes composants appartiennent à l'unité. Exit (à moins que je ne me trompe ) les solutions de MD Software et Pedro204.
- je peux bien sûr associer mon unité à un DataModule, et déclarer mon événement dedans, mais ça semble un peu gros...
- j'ai tourné le problème en déclarant dans mon unité une classe dérivée de mon composant, et en surchargeant sa méthode DoConfirmOverwrite qui appelle le gestionnaire d'événement. Ca marche, mais ça n'est ni élégant, ni toujours utilisable.
IL me paraît difficile à croire qu'il y n'ait pas mieux.
D'où ma question, en écho à TicTacToe :
Peut-on déclarer une méthode en dehors d'une déclaration de type ?que ce soit une méthode (donc procedure of object)
Si j'ai bien compris (mais peut-être pas),
si ton composant gérant la décompression est du style
ensuite ton unité centralisant tes fonctions
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 Unit AbbCompress; TCompress = class( ... ) ... procedure OnConfirmOverwrite( ParamCompress) ... end
et à l'utilisation
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 Unit MesFonctionsAbb; Interface TMesOutils = class( TObject ) procedure MonConfirmOverwrite( ParamCompress ) ... end Implementation procedure TMesOutils.MonConfirOverWrite( ParamCompress) begin // je fais ce qu'il me plait end;
J'ai absolument pas vérifié la syntaxe, mais dans le principe, je pense que c'est faisable sans instancier TMesOutils.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Unit UneUnite; Uses MesFonctionsAbb; MonObjetCompress := TCompress.Create( Self ); MonObjet.OnConfirOverWrite := TMesOutils.MonConfirmOverWrite;
TicTacToe Ca m'a pas l'air bête du tout , C'est vrai que les interfaces ne font pas partie de mes réflexes. Je vais être absent, mais je teste ça vendredi.
En attendant je laisse le sujet ouvert.
Salut
ce ne sont pas des interfaces Et c'est ce qu'on t'a expliqué TicTacToe, MD Software et moiEnvoyé par rsc
J'avais décidément besoin de prendre l'air ! Maintenant que c'est fait, on va s'y remettre
J'ai une erreur à la compilation :
"Types incompatibles : 'TAbConfirmOverwriteEvent' et 'Procedure'"
sur la ligne
bien que mes paramètres soient strictement les mêmes !
Code : Sélectionner tout - Visualiser dans une fenêtre à part MonObjet.OnConfirmOverWrite := TMesOutils.MonConfirmOverWrite;
Normal, il faut que ce soit un évènement et pas une procédure simple. La différence principale, est qu'un évènement prend un objet en paramètre (l'éméteur de l'évènement).
Donc :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 Unit MesFonctionsAbb; Interface TMesOutils = class( TObject ) procedure MonConfirmOverwrite(Sender : TObject; ParamCompress ) ... end Implementation procedure TMesOutils.MonConfirOverWrite(Sender : TObject; ParamCompress) begin // je fais ce qu'il me plait end;
+1 MDSoftware
Cela fait partie des 3 contraintes enoncée plus haut.
il faut que ce soit une 'procedure of object', autrement dit, une méthode.
Par contre, j'ai vu que tu (MDSoftware) avait ajouté Sender... c'est pas dit qu'il y soit si son composant n'est pas visuel !
Le sender est obligatoire. Il me semble que tu confonds "procedure of object" et "méthode". Car une méthode est une procédure d'une classe, ce qui n'est pas forcément le cas d'une "procédure of object".Envoyé par TicTacToe
AH...
et TTable.OnCalcFields n'a pas de Sender (par exemple)...
Je suis preneur de toute infos instructives, mais voici comment je vois les définitions.
procedure of object = méthode = dénomitation d'un type désignant une procédure (ou fonction bien sur) appartenant à une classe.
Evenement = propriété publiée qui en cas de changement appelle sa méthode, si tout du moins elle est affectée.
Exemple:
Table.OnCalcFields est un évenement, affectée à rien par défaut.
Par défaut via L'IDE, on peut créé la méthode
qui est assignée automatiquement à l'évenement OnCalcFields de TTable.
Code : Sélectionner tout - Visualiser dans une fenêtre à part TableCalcFields(DataSet: TDataSet)
Excusez-moi de m'immiscer dans votre discussion
1/ Voici la déclaration de mon type d'événement original :
2/ Voici la déclaration de ma procédure :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 TAbConfirmOverwriteEvent = procedure(var Name : string; var Confirm : Boolean) of object;
3/ Voici l'implémentation :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 type TMesOutils = class(TObject) procedure MonConfirmOverwrite(var Name: String; var Confirm: Boolean); end;
Je crois donc avoir fait "tout comme on m'a dit" ce qui n'empêche pas l'incompatibilité de types à l'affectation
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 procedure TMesOutils.MonConfirmOverWrite (var Name: String; var Confirm: Boolean); begin // je fais ce qu'il me plait end;
Fait ça :et à mon avis, ça va marcher
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 type TMesOutils = class(TObject) procedure MonConfirmOverwrite(Sender:TObject;var Name: String; var Confirm: Boolean); end; {---} procedure TMesOutils.MonConfirmOverWrite (Sender : TObject;var Name: String; var Confirm: Boolean); begin // je fais ce qu'il me plait end;
@TicTacToe : Il faut que j'y réfléchisse pour donner un explication correcte.
Peux tu poster l'affectation en question et la définition de l'évenement que tu tentes d'affecter (qui doit se trouver dans la classe AB.. ou dans un de ses ancêtres) ?
@MDSoftware
voici des types prédéfinis par Delphi, pour TDBCustomGrid et utilisés par des événements divers
Certains ont Sender, d'autre pas, mais par contre il y a toujours la notion 'd'envoyeur'.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 TDrawColumnCellEvent = procedure (Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState) of object; TDBGridClickEvent = procedure (Column: TColumn) of object;
En relisant mon post, je dis méthode = procedure of object. Ca peut paraitre faux dans le sens ou 'procedure of object' est vu plutot comme un TYPE, alors que méthode est plutot vu comme VAR (comme du contenu). Mais ca vient du fait que par abbus de langage, et pour ne pas s'embeter on fait abstraction qu'une procedure est un pointeur vers du contenu. Ce qui est réellement le cas quand on fait une variable de type procedure of object.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager