Méthode de pointeur et de procédure régulière incompatible
J'ai une application qui a de multiples formes. Toutes ces formes ont un PopupMenu. - Je construire les éléments de menu par programmation, le tout sous une racine commune élément de menu. Je veux que TOUS les éléments de menu pour appeler la même procédure, et l'élément de menu lui-même est fondamentalement agissant comme un argument....
J'ai eu ce travail quand j'ai juste eu une forme de faire de cette fonctionnalité. J'ai maintenant plusieurs formes de devoir faire cela. Je suis passer tout mon code à une unité commune.
Example.
Form A has PopupMenu 1. When clicked, call code in Unit CommonUnit.
Form B has PopupMenu 2. When clicked, call code in unit CommonUnit.
Quand j'ai besoin d'appeler mon menu contextuel de chaque forme, je l'appelle mon haut niveau de la procédure (qui est dans l'unité CommonUnit), en passant le nom de la partie supérieure de l'élément de menu de chaque forme de haut niveau de la procédure dans l'unité commune.
Je suis ajoutant des articles à mon PopupMenu avec code.
M1 := TMenuItem.Create(TopMenuItem);
M1.Caption := FieldByName('NAME').AsString;
M1.Tag := FieldByName('ID').AsInteger;
M1.OnClick := BrowseCategories1Click;
TopMenuItem.Add(M1);
Je reçois un message d'erreur quand je compile. Plus précisément, le OnClick ligne est de se plaindre
Types incompatibles: 'pointeur de méthode et de procédure régulière'.
J'ai défini BrowseCategories1Click exactement comme il était avant, quand je faisais cela sur un seul formulaire. La seule différence est qu'il est maintenant définie dans une unité commune, plutôt que comme faisant partie d'un formulaire.
Il est défini comme
procedure BrowseCategories1Click(Sender: TObject);
begin
//
end;
Quelle est la façon la plus simple de contourner ce problème?
Merci
GS
Vous devez vous connecter pour publier un commentaire.
Un peu de fond...
Delphi a 3 les types de procédure:
Autonome ou de l'unité d'étendue de la fonction/procédure pointeurs déclarés comme suit:
var Func: function(arg1:string):string;
var Proc: procedure(arg1:string);
Méthode pointeurs déclarés comme suit:
var Func: function(arg1:string):string of object;
var Proc: procedure(arg1:string) of object;
Et, depuis Delphi 2009, anonyme(voir ci-dessous) fonction/méthode de pointeurs déclarés comme suit:
var Func: reference to function(arg1:string):string;
var Proc: reference to procedure(arg1:string);
Autonome pointeurs et méthode les pointeurs ne sont pas interchangeables. La raison pour cela est implicite
Self
paramètre est accessible dans les méthodes. Delphi modèle d'événement s'appuie sur méthode pointeurs, c'est pourquoi vous ne pouvez pas affecter un autonome fonction d'un objet d'événement de la propriété.Afin que vos gestionnaires d'événements devront être définies dans le cadre de certains définition de classe, tout définition de classe pour apaiser le compilateur.
Comme TOndrej suggéré vous pouvez pirater autour du compilateur mais si ces gestionnaires d'événements sont dans la même unité alors qu'ils doivent déjà être liés de toute façon donc vous pouvez aussi bien aller de l'avant et de les encapsuler dans une classe.
Une suggestion supplémentaire, je n'ai pas encore vu, est de revenir en arrière un peu. Laissez chaque formulaire de mettre en place son propre gestionnaire d'événement mais a ce gestionnaire de déléguer la responsabilité à une fonction déclarée dans votre nouvelle unité.
Cela a l'avantage de séparer la réponse à l'action de l'utilisateur, de la commande qui a déclenché l'action. Vous pouvez facilement avoir les gestionnaires d'événements pour un bouton de barre d'outils et un menu contextuel de l'élément de délégué à la même fonction.
Le choix de la direction est finalement à vous, mais je préfère la prudence de vous concentrer sur l'option qui va rendre la maintenance plus facile à l'avenir, plutôt que celle qui est la plus rapide dans le présent.
Méthodes anonymes
Méthodes anonymes sont une bête différente tous ensemble. Une méthode anonyme pointeur peut pointer vers un autonome fonction, un méthode ou une fonction sans nom déclarées en ligne. Ce dernier type de fonction est d'où le nom anonyme de. Anonyme fonctions/méthodes ont la capacité unique de capture de variables déclarées en dehors de leur champ d'application
Cela fait d'eux la plus flexible de la procédure de type pointeur, mais ils ont aussi potentiellement plus généraux. Variable de capture consomme plus de ressources que ne inline déclarations. Le compilateur utilise un caché un décompte de références de l'interface pour les déclarations qui ajoute quelques petits frais généraux.
Vous pouvez envelopper vos procédures dans une classe. Cette classe pourrait ressembler à ceci dans une unité distincte:
Et affecter l'action d'un élément de menu dans une autre unité est suffisant pour utiliser ce:
Mise à jour:
Mis à jour pour utiliser la classe des procédures (au lieu des méthodes de l'objet), par David de la suggestion. Pour ceux qui veulent utiliser les méthodes de l'objet avec la nécessité d'une instance de l'objet, de suivre
cette version
de la poste.self
paramètre (c'est à dire le propriétaire de forme) à l'intérieur du gestionnaire de clic?C'est la différence entre un "intérieur" et un "procédure d'objet"
La
OnClick
est défini comme unTNotifyEvent
:Vous ne pouvez pas affecter une procédure à l'
OnClick
comme c'est le mauvais type. Il doit y avoir une procédure d'objet.Vous pouvez choisir l'un de ces:
class procedure
est ajouté de sorte qu'une instance n'ont même pas à être créé avant de l'utiliser.Une solution est de placer la méthode OnClick dans un TDatamodule.