La composante écriture, partie 1

La composante écriture, partie 1


Premier dans une série en trois parties couvrant composant écrit en Delphi.




Cet article est paru initialement dans les Développeur Delphi



le droit d'Auteur Pinnacle Publishing, Inc. Tous droits réservés.







Cette première partie illustre quelques-unes des meilleures approches pour la construction de composants, et en même temps fournit des conseils sur le choix de la meilleure de la classe de base pour hériter de, à l'aide de virtual déclarations, le processus de remplacement, et ainsi de suite.



Les deux premières choses à vous poser sont les raisons pour lesquelles vous devriez faire usage de la composante écriture, et quand vous avez besoin d'écrire un composant. La première question est facile à résoudre, en fait, il a beaucoup de réponses.


  • Facilité d'utilisation: Encapsulé code signifie que vous pouvez simplement supprimer le même composant sur diverses formes, encore et encore, sans écrire une seule ligne de code.

  • Débogage: centraliser le code facilite la réparation de la totalité d'une application (ou un ensemble d'applications) par la fixation d'une erreur dans un seul composant et de le recompiler.

  • de l'Argent: Il y a beaucoup d'entreprises qui ne sont que trop heureux de payer pour le privilège de ne pas réinventer la roue.



La deuxième question n'est pas trop difficile de répondre. Chaque fois que vous vous trouvez avoir à écrire le même code plus d'une fois c'est une bonne idée d'écrire un composant, surtout si le code effectue différemment, en fonction des paramètres donnés.



Comment les composants sont créés

La première étape est de décider quel classe de base, vous devez tirer votre composant. Lorsque vous dériver d'une autre classe d'hériter de biens, de méthode et d'événements que ce composant possède. Ci-dessous est un exemple de la façon de choisir le cours auquel vous devez hériter de lors de l'écriture de votre propre composant.



(Cliquer pour afficher)



Cliquez pour afficher en taille réelle



Dans le cas d'Une méthode et la méthode B, présumer que le composant en question est TMemo.





& ! & ! & ! & nbsp

& ! & ! & ! & nbsp


Méthodela Solution



& ! & ! & ! & nbsp



& ! & ! & ! & nbsp
Dériver de TMemo






& ! & ! & ! & nbsp
B



& ! & ! & ! & nbsp
Dériver de TCustomMemo






& ! & ! & ! & nbsp
C



& ! & ! & ! & nbsp
Dériver de TCustomControl






& ! & ! & ! & nbsp
D



& ! & ! & ! & nbsp
Dériver de TGraphicControl






& ! & ! & ! & nbsp
E



& ! & ! & ! & nbsp
Dériver de TComponent









Cela peut sembler un peu compliqué, donc laissez-moi vous expliquer le processus.



A: Lorsque vous avez simplement besoin d'ajouter des fonctionnalités supplémentaires à un composant existant vous tirer de cette composante. Cela va automatiquement donner à votre nouveau composant de toutes les fonctionnalités existantes et les propriétés du composant existant.



B: Parfois, vous n'avez pas seulement besoin d'ajouter des fonctionnalités, mais vous avez besoin de l'enlever en même temps. La pratique standard lors de l'écriture d'un composant est le premier à écrire un TCustomXXXXX composant où toutes les propriétés, les événements et les méthodes sont déclarées dans la section Protégée du composant. La composante réelle est dérivé de cette classe de base. L'astuce est donc de ne pas cacher les fonctionnalités, mais de retirer votre composant de la 'coutume' version du composant et publier uniquement les propriétés que vous souhaitez conserver (effectivement supprimer des propriétés ou des événements).



C: Tout composant qui doit recevoir le focus a besoin d'un handle de fenêtre. Twincontrol a est où cette poignée est d'abord présenté. TCustomControl est tout simplement un twincontrol a avec sa propre Toile de propriété.



D: TGraphicControl ne dispose pas d'un handle de fenêtre et, par conséquent, ne peut pas recevoir le focus. Les composants tels que TLabel sont dérivées de cette classe de base.



E: Certains composants ne sont pas créés pour améliorer l'interface graphique de l'interactivité, mais pour rendre votre vie plus facile. Quoi que ce soit dérivé de TComponent n'est visible qu'au moment de la conception. Une utilisation typique de ce type de composant est pour les connexions de base de données, les timers, etc ...



une Fois que nous avons décidé de ce que notre classe de base doit être, la prochaine étape est de créer le composant. À partir du menu Composant, sélectionnez Nouveau Composant et vous verrez la boîte de dialogue suivante.



Nouvelle partie






& ! & ! & ! & nbsp
type d'Ancêtre



& ! & ! & ! & nbsp
C'est le type de base que nous avons besoin de descendre de






& ! & ! & ! & nbsp
nom de la Classe



& ! & ! & ! & nbsp
C'est le nom de la classe de notre nouvel élément

(commençant avec la lettre 'T')






& ! & ! & ! & nbsp
Palette



& ! & ! & ! & nbsp
C'est qui sur l'onglet de la palette de composants que vous souhaitez que votre

composant pour apparaître sur, en entrant dans une inexistant onglet dire

Delphi que vous aimeriez un nouvel onglet créé.







code

Déjà, il est temps pour nous d'écrire quelque chose. Ce premier exemple n'aura pas d'utiliser à tout, sauf à démontrer certains des concepts de base de la composante de l'écriture.



tout d'Abord, sélectionner un Composant à partir de la principale Delphi menu, puis sélectionnez Nouveau Composant. Entrez TComponent comme 'l'Ancêtre de type' et TFirstComponent que le nom de votre composant. Ensuite, cliquez sur le bouton 'Installer'.



À ce stade, vous pouvez soit installer votre nouveau composant dans un package existant (un paquet est un ensemble de composants) ou de l'installer dans un nouveau package. Cliquez sur 'en nouveau package' et cliquez sur le bouton 'Parcourir'.



Installer le composant



une Fois que vous avez sélectionné un chemin d'accès et nom de fichier pour votre nouveau package et entra dans une description, cliquez sur 'OK'. Lors de la prochaine boîte de dialogue vous demandant si vous souhaitez recompiler votre package) cliquez sur 'Oui'. Une fois que le paquet est compilé et installé, économiser votre forfait et à l'unité.



a ce stade, nous avons précisé notre classe de base, et aussi notre nouveau nom de la classe. Nous avons créé un nouveau package pour contenir notre composant et ont été présentés avec un squelette de la structure de la classe par Delphi.



Si vous regardez le code source fourni par Delphi, vous verrez désormais le Private, Protected, Public, et a Publié des articles.



l'Encapsulation

l'Encapsulation est un concept simple à comprendre, mais très important pour la composante écriture. L'Encapsulation est mis en œuvre avec l'utilisation de quatre mots réservés: Privé, Protected, Public et Publié, vous verrez Delphi a inclus ces articles automatiquement dans le code source de votre nouveau composant.





& ! & ! & ! & nbsp

& ! & ! & ! & nbsp





& ! & ! & ! & nbsp

& ! & ! & ! & nbsp





& ! & ! & ! & nbsp

& ! & ! & ! & nbsp





& ! & ! & ! & nbsp

& ! & ! & ! & nbsp







& ! & ! & ! & nbsp

& ! & ! & ! & nbsp





Accessibilité
Privateles Méthodes, les Propriétés et les Événements déclarés à l'intérieur de cette section ne seront

accessible à l'unité du composant est

à l'intérieur. Les composants de la même unité peut accéder à chaque

des autres éléments Privés.
ProtectedMéthodes, Les propriétés et les Événements déclarés à l'intérieur de cette section sera également

accessible à toute la classe les descendants de cette classe.
PublicMéthodes, Les propriétés et les Événements déclarés ici accessible à partir de n'importe où.
PubliéCette section vous permet de déclarer des propriétés ou des événements qui apparaissent dans le

l'inspecteur d'objet. Ces paramètres sont les temps de conception des valeurs

qui sont enregistrées avec votre projet. (Pas tous les types de

prise en charge, les tableaux par exemple ne le sont pas).







Commencer à écrire notre composant

Delphi a maintenant besoin de tout savoir sur notre nouveau composant. Entrez le code suivant dans le code de source de composant.





& ! & ! & ! & nbsp





privé

& nbsp & nbsp { Private declarations }

& nbsp & nbsp FStartTime,

& nbsp & nbsp FStopTime :DWord

protected

& nbsp & nbsp { déclarations Protégées }

& nbsp & nbsp fonction Tempsecoule: string virtual

public

& nbsp & nbsp { déclarations Publiques }

& nbsp & nbsp procédure Démarrer virtual

& nbsp & nbsp procédure Stop virtual



& nbsp & nbsp propriétés StartTime:DWord lire FStartTime

& nbsp & nbsp propriétés StopTime:DWord lire FStopTime

& nbsp & nbsp propriétés Délai: chaîne de lire Tempsecoule

publié

& nbsp & nbsp { Publié des déclarations }

fin

& ! & ! & ! & nbsp





Ce que nous avons fait ici est ajouté deux variables FStartTime et FStopTime (c'est la norme pour précéder les noms de variables avec la lettre F). Il existe deux méthodes pour le contrôle de ces variables, de Démarrage et d'Arrêt. Nous avons ajouté un Tempsecoule fonction qui sera de retour FStopTime - FStartTime comme une chaîne de caractères. Enfin, nous avons ajouté trois propriétés en lecture seule.



Appuyez sur MAJ-CTRL-C et Delphi complète automatiquement le code de votre classe (ou cliquez sur le bouton droit de la souris et sélectionnez 'classe Complète à l'emplacement du curseur'). Ensuite, entrez le code suivant pour chaque méthode.







& ! & ! & ! & nbsp







{ TFirstComponent }

fonction TFirstComponent.Tempsecoule: string

démarrer

& nbsp & nbsp Résultat := IntToStr(FStopTime - FStartTime)

fin



procédure TFirstComponent.Début

démarrer

& nbsp & nbsp FStartTime := GetTickCount

fin



procédure TFirstComponent.Stop

démarrer

& nbsp & nbsp FStopTime := GetTickCount

fin



fin.

& ! & ! & ! & nbsp





Test drive

Enregistrez votre appareil, et rouvrez votre package (Fichier, Ouvrez le Projet dans le menu, et sélectionnez 'Delphi Paquet' pour le type de fichier), une fois que votre colis est ouvert, cliquez sur le bouton Compile. Vous pouvez également ouvrir votre colis en sélectionnant le Composant dans le menu principal, puis Installer les Paquets. Sélectionnez votre package, puis cliquez sur le bouton 'Modifier'.



Vous pouvez maintenant déposer une TFirstComponent sur un formulaire, en fait, vous pouvez déposer autant que vous le souhaitez. Ajoutez deux boutons (btnStart et btnStop) et ajoutez le code suivant à votre formulaire, puis exécutez votre application de test'.







& ! & ! & ! & nbsp







procédure TForm1.btnStartClick(Sender: TObject)

démarrer

& nbsp & nbsp FirstComponent1.Début

fin



procédure TForm1.btnStopClick(Sender: TObject)

démarrer

& nbsp & nbsp FirstComponent1.Stop

& nbsp & nbsp Caption := FirstComponent1.ElapsedTime

fin

& ! & ! & ! & nbsp





en Cliquant sur le bouton 'Démarrer' va marquer l'heure de début (GetTickCount est un WinAPI de commande qui retourne le nombre de millisecondes écoulées depuis le démarrage de Windows).



en Cliquant sur le bouton 'Stop' marquera un temps d'arrêt, et modifier la légende de la forme.



Virtuel, Dynamique, Abstrait et Remplacer

Vous avez peut-être remarqué le virtual déclaration après le Démarrage, l'Arrêt et Tempsecoule. L'exercice suivant vous expliquer leurs utilisations.



Créer un nouveau composant, tirent cette composante de TFirstComponent (nom, il TSecondComponent) et de l'installer.



Le Virtuel et Dynamique identificateurs sont une composante de l'écrivain façon de dire Delphi que la méthode peut être remplacé dans un descendant de la classe. Si nous Remplacer une méthode dans une classe, notre nouveau code sera exécuté à la place du code d'origine.







& ! & ! & ! & nbsp







protected

& nbsp & nbsp { Déclarations protégées }

& nbsp & nbsp fonction Tempsecoule: chaîne de remplacer

& ! & ! & ! & nbsp





Nous avons ensuite mettre en œuvre le code ci-dessus comme suit.







& ! & ! & ! & nbsp







fonction TSecondComponent.Tempsecoule: string

var

& nbsp & nbsp S: string

démarrer

& nbsp & nbsp S := hérité Tempsecoule

& nbsp & nbsp Résultat := S ' millisecondes ou '

& ! & ! & ! & nbsp Format('%.2f secondes',

& ! & ! & ! & ! & ! & nbsp [(StopTime - StartTime) / 1000])

fin

& ! & ! & ! & nbsp





Notre nouveau code est maintenant appelée en remplacement de l'original Tempsecoule, même les appels mis en œuvre dans TFirstComponent à GetElapsed temps fera alors appel à notre nouveau code (si nous avons créé une instance de TSecondComponent que c'est). Le code d'origine est invoquée par le biais de l'utilisation de l'héritage de commande.



Remarque : Si vous n'avez pas de 'remplacer' une méthode de base (parce que la base n'a pas été déclarée comme virtual ou parce que vous avez oublié). TSecondComponent appelle votre nouveau code, alors que le code mis en œuvre dans TFirstComponent va encore continuer à appeler le code d'origine de TFirstComponent.



Le Résumé de l'identificateur dit Delphi ne pas attendre le code de la méthode. Vous ne devez pas créer une instance d'objet avec des méthodes abstraites (comme TStrings). La pratique standard consiste à créer un descendant d'une telle classe et de remplacer toutes les méthodes abstraites (comme TStringList n').



Dynamique Vs Virtuel est tout simplement une question de vitesse et de taille. Une méthode Dynamique, chaque instance d'une classe, nécessitant moins de mémoire, alors qu'une méthode Virtuelle s'exécutera plus rapidement au prix d'un peu de mémoire supplémentaire.



Il y a quelques étapes simples pour ajouter des événements à votre composant. Les événements de permettre le composant à communiquer avec votre application, pour l'informer lorsque quelque chose d'important s'est passé. Un événement est simplement une propriété en lecture / écriture, au lieu d'être une simple variable de type chaîne de caractères, entier, etc) c'est une procédure ou une fonction.



Créer un nouveau composant, le descendre de TSecondComponent et nom il TThirdComponent. Enregistrer l'appareil, installez votre composant, puis ajoutez le code suivant.





& ! & ! & ! & nbsp







type

& nbsp & nbsp TState = (stStarted, stStopped)

& nbsp & nbsp TStateChangeEvent = procédure Sender : TObject État : TState) de objet



& nbsp & nbsp TThirdComponent = class(TSecondComponent)

& nbsp & nbsp privé

& ! & ! & ! & nbsp { Private declarations }

& ! & ! & ! & nbsp FState: TState

& ! & ! & ! & nbsp FOnStart,

& ! & ! & ! & nbsp FOnStop: TNotifyEvent

& ! & ! & ! & nbsp FOnStateChange: TStateChangeEvent

& nbsp & nbsp protected

& ! & ! & ! & nbsp { déclarations Protégées }

& nbsp & nbsp public

& ! & ! & ! & nbsp { déclarations Publiques }

& ! & ! & ! & nbsp constructeur Create(AOwner : TComponent) remplacer

& ! & ! & ! & nbsp destructeur Détruire remplacer

& ! & ! & ! & nbsp procédure Démarrer remplacer

& ! & ! & ! & nbsp procédure Stop remplacer

& ! & ! & ! & nbsp propriétés État: TState lire FState

& nbsp & nbsp publié

& ! & ! & ! & nbsp { Publié des déclarations }

& ! & ! & ! & nbsp propriétés Démarrage: TNotifyEvent lire FOnStart écrire FOnStart

& ! & ! & ! & nbsp propriétés OnStateChange: TStateChangeEvent lire FOnStateChange

& ! & ! & ! & ! & ! & nbsp écrire FOnStateChange

& ! & ! & ! & nbsp propriétés OnStop: TNotifyEvent lire FOnStop écrire FOnStop

& nbsp & nbsp fin

& ! & ! & ! & nbsp





les Événements sont simplement des procédures ou des fonctions (rarement) qui appartiennent à une classe (d'où le 'de l'objet' clause de vous voir dans le TStateChangeEvent). Par exemple, TNotifyEvent est un standard type d'événement mis en œuvre par Delphi, qui vient de se passe à l'objet qui a déclenché l'événement, il est toujours bon d'envoyer 'Auto' (Sender : TObject) comme premier paramètre de n'importe quel événement que le même code d'événement peut être utilisé pour plusieurs composants.



TNotifyEvent est défini comme





& ! & ! & ! & nbsp







type

& nbsp & nbsp TNotifyEvent = procédure (Sender: TObject) de l'objet

& ! & ! & ! & nbsp





À l'appel d'un événement au sein d'un composant est juste une affaire de vérifier si l'événement a été attribué et, le cas échéant, l'appel à elle. J'ai annulé le Démarrage et l'Arrêt des méthodes de TSecondComponent afin de déclencher ces événements, comme si.







& ! & ! & ! & nbsp







procédure TThirdComponent.Début

démarrer

& nbsp & nbsp hérité //les appels TSecondComponent.Démarrer

& nbsp & nbsp FState := stStarted

& nbsp & nbsp si Assigné(Démarrage) OnStart(Auto)

& nbsp & nbsp si Assigné(OnStateChange) OnStateChange(de Soi, de l'État)

fin



procédure TThirdComponent.Stop

démarrer

& nbsp & nbsp hérité //les appels TSecondComponent.Stop

& nbsp & nbsp FState := stStopped

& nbsp & nbsp si Assigné(OnStop) OnStop(Auto)

& nbsp & nbsp si Assigné(OnStateChange) OnStateChange(de Soi, de l'État)

fin



constructeur TThirdComponent.Create(AOwner: TComponent)

démarrer

& nbsp & nbsp hérité

& nbsp & nbsp //C'est là que vous définissez les propriétés, et créer

& nbsp & nbsp //et les objets de votre composant peut utiliser en interne

& nbsp & nbsp FState := stStopped

fin



destructeur TThirdComponent.Détruire

démarrer

& nbsp & nbsp //C'est là que vous détruirait

& nbsp & nbsp //tous les objets


& nbsp & nbsp hérité

fin

& ! & ! & ! & nbsp





Recompiler votre colis, n'oubliez pas d'enregistrer votre colis quand vous ajoutez un nouveau composant). Lors de la chute de votre nouveau composant sur le formulaire, vous remarquerez qu'il y a trois événements. Démarrage, OnStop et OnStateChange. Si vous regardez Demo3 vous allez voir comment j'ai utilisé ces événements.



Démarrage définit la légende de la 'Main'

OnStop affiche le temps écoulé

OnStateChange active / désactive la pertinente Start / Stop bouton







& ! & ! & ! & nbsp







procédure TForm1.ThirdComponent1Start(Sender: TObject)

démarrer

& nbsp & nbsp Caption := 'Démarrer'

fin



procédure TForm1.ThirdComponent1Stop(Sender: TObject)

démarrer

& nbsp & nbsp Caption := ThirdComponent1.ElapsedTime

fin



procédure TForm1.ThirdComponent1StateChange(Sender: TObject État: TState)

démarrer

& nbsp & nbsp btnStart.Enabled := ThirdComponent1.Etat = stStopped

& nbsp & nbsp btnStop.Enabled := ThirdComponent1.Etat = stStarted

fin

& ! & ! & ! & nbsp





Normes en composant écrit

Enfin, nous aborderons quelques points de plus sur la composante écriture, y compris certaines des méthodes de base de composants, et les normes pour l'écriture.



de la Création et de la destruction de votre composant:

les Objets sont créés par le biais d'un constructeur et détruit par un destructeur. Le but de la substitution d'un constructeur est triple


  1. Pour créer les objets qu'il contient à l'intérieur de lui-même (sous-objets)

  2. Pour initialiser les valeurs de la classe (propriétés, etc)

  3. Pour lever une exception et arrêter la classe d'être créé.



Il est courant d'appeler le constructeur hérité de l'intérieur de votre propre constructeur de sorte que le parent de la classe peut effectuer ses initialisations, bien qu'il n'est pas nécessaire de le faire afin de créer votre composant. (Votre composant est créé dès que votre constructeur est fini, il n'est pas créé par l'appel de l'héritage constructeur)



le but de La substitution d'un destructeur est tout simplement pour libérer toutes les ressources qui ont été allouées au cours de la durée de vie du composant. Appel hérité seulement après avoir libéré ces ressources.



Standard de composants:

Peinture:

Vous pouvez remplacer cette méthode pour fournir votre propre dessin personnalisé de votre composant.



Chargement:

Ceci est appelé par Delphi dès que l'ensemble de ses propriétés ont fini d'être défini lors de son parent formulaire est créé. Vous pouvez remplacer cette méthode pour effectuer toutes les actions qui dépendent d'un groupe de propriétés de tous.



Invalide: Chaque fois qu'une propriété est modifiée, qui affecte l'apparence visuelle d'un composant, vous devez appeler cette méthode.



ComponentState: Cette propriété est très utile lorsque vous devez vérifier si votre composant existe actuellement à la conception/exécution, ou si ses propriétés sont actuellement en cours de lecture par un processus de diffusion.



l'Encapsulation de votre composant correctement

Il est standard pour écrire votre composant comme TCustomMyClass et puis tirer votre composant à partir de cette classe de base. La 'coutume' composant de vous écrire aurez la plupart (si pas tous) de ses propriétés / méthodes déclarées à l'intérieur de son Protégé.



Lorsque vous descendez de votre 'custom' classe que vous simplement redeclare vos propriétés dans le Public ou Publiés les articles.







& ! & ! & ! & nbsp







type

& nbsp & nbsp TCustomMyClass = class(TComponent)

& nbsp & nbsp privé

& ! & ! & ! & nbsp FSomeString: string

& nbsp & nbsp protected

& ! & ! & ! & nbsp procédure SetSomeString(const Value : string) virtual

& ! & ! & ! & nbsp propriétés SomeString: chaîne de lire FSomeString écrire SetSomeString

& nbsp & nbsp fin



& nbsp & nbsp TMyClass = class(TCustomMyClass)

& nbsp & nbsp publié

& ! & ! & ! & nbsp propriétés SomeString

& nbsp & nbsp fin

& ! & ! & ! & nbsp





C'est une bonne pratique car il permet à d'autres personnes pour établir leurs propres composants basés sur le vôtre, tout en leur permettant de supprimer certaines propriétés.



Notez comment SetSomeString a été déclarée virtuelle dans la zone protégée. C'est aussi bien l'étiquette car elle permet de les descendants des classes pour répondre aux changements dans les valeurs de propriété par substitution de la procédure qui définit. Ceci s'applique également à des événements, où vous voyez une OnStateChange événement, vous trouverez souvent un DoStateChange méthode, par exemple:







& nbsp & nbsp

& ! & ! & ! & nbsp



& ! & ! & ! & nbsp






& ! & ! & ! & nbsp



& ! & ! & ! & nbsp






& ! & ! & ! & nbsp



& ! & ! & ! & nbsp






& ! & ! & ! & nbsp



& ! & ! & ! & nbsp






& ! & ! & ! & nbsp



& ! & ! & ! & nbsp









Cela peut sembler un peu complique, donc laissez-moi vous expliquer le processus.



A: Lorsque vous avez simplement besoin d'ajouter des fonctionnalites supplementaires a un composant existant vous tirer de cette composante. Cela va automatiquement donner a votre nouveau composant de toutes les fonctionnalites existantes et les proprietes du composant existant.



B: Parfois, vous n'avez pas seulement besoin d'ajouter des fonctionnalites, mais vous avez besoin de l'enlever en meme temps. La pratique standard lors de l'ecriture d'un composant est le premier a ecrire un TCustomXXXXX composant ou toutes les proprietes, les evenements et les methodes sont declarees dans la section Protegee du composant. La composante reelle est derive de cette classe de base. L'astuce est donc de ne pas cacher les fonctionnalites, mais de retirer votre composant de la 'coutume' version du composant et publier uniquement les proprietes que vous souhaitez conserver (effectivement supprimer des proprietes ou des evenements).



C: Tout composant qui doit recevoir le focus a besoin d'un handle de fenetre. Twincontrol a est ou cette poignee est d'abord presente. TCustomControl est tout simplement un twincontrol a avec sa propre Toile de propriete.



D: TGraphicControl ne dispose pas d'un handle de fenetre et, par consequent, ne peut pas recevoir le focus. Les composants tels que TLabel sont derivees de cette classe de base.



E: Certains composants ne sont pas crees pour ameliorer l'interface graphique de l'interactivite, mais pour rendre votre vie plus facile. Quoi que ce soit derive de TComponent n'est visible qu'au moment de la conception. Une utilisation typique de ce type de composant est pour les connexions de base de donnees, les timers, etc ...



une Fois que nous avons decide de ce que notre classe de base doit etre, la prochaine etape est de creer le composant. A partir du menu Composant, selectionnez Nouveau Composant et vous verrez la boîte de dialogue suivante.



Nouvelle partie





type

& nbsp & nbsp TCustomMyClass = class(TComponent)

& nbsp & nbsp privé

& ! & ! & ! & nbsp FOnStateChange: TStateChangeEvent

& nbsp & nbsp protected








La composante ecriture, partie 1


La composante ecriture, partie 1 : Plusieurs milliers de conseils pour vous faciliter la vie.


Premier dans une serie en trois parties couvrant composant ecrit en Delphi.




Cet article est paru initialement dans les Developpeur Delphi



le droit d'Auteur Pinnacle Publishing, Inc. Tous droits reserves.







Cette premiere partie illustre quelques-unes des meilleures approches pour la construction de composants, et en meme temps fournit des conseils sur le choix de la meilleure de la classe de base pour heriter de, a l'aide de virtual declarations, le processus de remplacement, et ainsi de suite.



Les deux premieres choses a vous poser sont les raisons pour lesquelles vous devriez faire usage de la composante ecriture, et quand vous avez besoin d'ecrire un composant. La premiere question est facile a resoudre, en fait, il a beaucoup de reponses.


  • Facilite d'utilisation: Encapsule code signifie que vous pouvez simplement supprimer le meme composant sur diverses formes, encore et encore, sans ecrire une seule ligne de code.

  • Debogage: centraliser le code facilite la reparation de la totalite d'une application (ou un ensemble d'applications) par la fixation d'une erreur dans un seul composant et de le recompiler.

  • de l'Argent: Il y a beaucoup d'entreprises qui ne sont que trop heureux de payer pour le privilege de ne pas reinventer la roue.



La deuxieme question n'est pas trop difficile de repondre. Chaque fois que vous vous trouvez avoir a ecrire le meme code plus d'une fois c'est une bonne idee d'ecrire un composant, surtout si le code effectue differemment, en fonction des parametres donnes.



Comment les composants sont crees

La premiere etape est de decider quel classe de base, vous devez tirer votre composant. Lorsque vous deriver d'une autre classe d'heriter de biens, de methode et d'evenements que ce composant possede. Ci-dessous est un exemple de la façon de choisir le cours auquel vous devez heriter de lors de l'ecriture de votre propre composant.



(Cliquer pour afficher)



Cliquez pour afficher en taille reelle



Dans le cas d'Une methode et la methode B, presumer que le composant en question est TMemo.





& ! & ! & ! & nbsp

& ! & ! & ! & nbsp


Methodela Solution

Deriver de TMemo
BDeriver de TCustomMemo
CDeriver de TCustomControl
DDeriver de TGraphicControl
EDeriver de TComponent



& ! & ! & ! & nbsp
type d'Ancetre



& ! & ! & ! & nbsp
C'est le type de base que nous avons besoin de descendre de






& ! & ! & ! & nbsp
nom de la Classe



& ! & ! & ! & nbsp
C'est le nom de la classe de notre nouvel element

(commençant avec la lettre 'T')






& ! & ! & ! & nbsp
Palette



& ! & ! & ! & nbsp
C'est qui sur l'onglet de la palette de composants que vous souhaitez que votre

composant pour apparaître sur, en entrant dans une inexistant onglet dire

Delphi que vous aimeriez un nouvel onglet cree.







code

Deja, il est temps pour nous d'ecrire quelque chose. Ce premier exemple n'aura pas d'utiliser a tout, sauf a demontrer certains des concepts de base de la composante de l'ecriture.



tout d'Abord, selectionner un Composant a partir de la principale Delphi menu, puis selectionnez Nouveau Composant. Entrez TComponent comme 'l'Ancetre de type' et TFirstComponent que le nom de votre composant. Ensuite, cliquez sur le bouton 'Installer'.



A ce stade, vous pouvez soit installer votre nouveau composant dans un package existant (un paquet est un ensemble de composants) ou de l'installer dans un nouveau package. Cliquez sur 'en nouveau package' et cliquez sur le bouton 'Parcourir'.



Installer le composant



une Fois que vous avez selectionne un chemin d'acces et nom de fichier pour votre nouveau package et entra dans une description, cliquez sur 'OK'. Lors de la prochaine boîte de dialogue vous demandant si vous souhaitez recompiler votre package) cliquez sur 'Oui'. Une fois que le paquet est compile et installe, economiser votre forfait et a l'unite.



a ce stade, nous avons precise notre classe de base, et aussi notre nouveau nom de la classe. Nous avons cree un nouveau package pour contenir notre composant et ont ete presentes avec un squelette de la structure de la classe par Delphi.



Si vous regardez le code source fourni par Delphi, vous verrez desormais le Private, Protected, Public, et a Publie des articles.



l'Encapsulation

l'Encapsulation est un concept simple a comprendre, mais tres important pour la composante ecriture. L'Encapsulation est mis en œuvre avec l'utilisation de quatre mots reserves: Prive, Protected, Public et Publie, vous verrez Delphi a inclus ces articles automatiquement dans le code source de votre nouveau composant.





& ! & ! & ! & nbsp

& ! & ! & ! & nbsp





& ! & ! & ! & nbsp

& ! & ! & ! & nbsp





& ! & ! & ! & nbsp

& ! & ! & ! & nbsp





& ! & ! & ! & nbsp

& ! & ! & ! & nbsp







& ! & ! & ! & nbsp

& ! & ! & ! & nbsp





Accessibilite
Privateles Methodes, les Proprietes et les Evenements declares a l'interieur de cette section ne seront

accessible a l'unite du composant est

a l'interieur. Les composants de la meme unite peut acceder a chaque

des autres elements Prives.
ProtectedMethodes, Les proprietes et les Evenements declares a l'interieur de cette section sera egalement

accessible a toute la classe les descendants de cette classe.
PublicMethodes, Les proprietes et les Evenements declares ici accessible a partir de n'importe ou.
PublieCette section vous permet de declarer des proprietes ou des evenements qui apparaissent dans le

l'inspecteur d'objet. Ces parametres sont les temps de conception des valeurs

qui sont enregistrees avec votre projet. (Pas tous les types de

prise en charge, les tableaux par exemple ne le sont pas).







Commencer a ecrire notre composant

Delphi a maintenant besoin de tout savoir sur notre nouveau composant. Entrez le code suivant dans le code de source de composant.





& ! & ! & ! & nbsp





prive

& nbsp & nbsp { Private declarations }

& nbsp & nbsp FStartTime,

& nbsp & nbsp FStopTime :DWord

protected

& nbsp & nbsp { declarations Protegees }

& nbsp & nbsp fonction Tempsecoule: string virtual

public

& nbsp & nbsp { declarations Publiques }

& nbsp & nbsp procedure Demarrer virtual

& nbsp & nbsp procedure Stop virtual



& nbsp & nbsp proprietes StartTime:DWord lire FStartTime

& nbsp & nbsp proprietes StopTime:DWord lire FStopTime

& nbsp & nbsp proprietes Delai: chaîne de lire Tempsecoule

publie

& nbsp & nbsp { Publie des declarations }

fin

& ! & ! & ! & nbsp





Ce que nous avons fait ici est ajoute deux variables FStartTime et FStopTime (c'est la norme pour preceder les noms de variables avec la lettre F). Il existe deux methodes pour le controle de ces variables, de Demarrage et d'Arret. Nous avons ajoute un Tempsecoule fonction qui sera de retour FStopTime - FStartTime comme une chaîne de caracteres. Enfin, nous avons ajoute trois proprietes en lecture seule.



Appuyez sur MAJ-CTRL-C et Delphi complete automatiquement le code de votre classe (ou cliquez sur le bouton droit de la souris et selectionnez 'classe Complete a l'emplacement du curseur'). Ensuite, entrez le code suivant pour chaque methode.







& ! & ! & ! & nbsp







{ TFirstComponent }

fonction TFirstComponent.Tempsecoule: string

demarrer

& nbsp & nbsp Resultat := IntToStr(FStopTime - FStartTime)

fin



procedure TFirstComponent.Debut

demarrer

& nbsp & nbsp FStartTime := GetTickCount

fin



procedure TFirstComponent.Stop

demarrer

& nbsp & nbsp FStopTime := GetTickCount

fin



fin.

& ! & ! & ! & nbsp





Test drive

Enregistrez votre appareil, et rouvrez votre package (Fichier, Ouvrez le Projet dans le menu, et selectionnez 'Delphi Paquet' pour le type de fichier), une fois que votre colis est ouvert, cliquez sur le bouton Compile. Vous pouvez egalement ouvrir votre colis en selectionnant le Composant dans le menu principal, puis Installer les Paquets. Selectionnez votre package, puis cliquez sur le bouton 'Modifier'.



Vous pouvez maintenant deposer une TFirstComponent sur un formulaire, en fait, vous pouvez deposer autant que vous le souhaitez. Ajoutez deux boutons (btnStart et btnStop) et ajoutez le code suivant a votre formulaire, puis executez votre application de test'.







& ! & ! & ! & nbsp







procedure TForm1.btnStartClick(Sender: TObject)

demarrer

& nbsp & nbsp FirstComponent1.Debut

fin



procedure TForm1.btnStopClick(Sender: TObject)

demarrer

& nbsp & nbsp FirstComponent1.Stop

& nbsp & nbsp Caption := FirstComponent1.ElapsedTime

fin

& ! & ! & ! & nbsp





en Cliquant sur le bouton 'Demarrer' va marquer l'heure de debut (GetTickCount est un WinAPI de commande qui retourne le nombre de millisecondes ecoulees depuis le demarrage de Windows).



en Cliquant sur le bouton 'Stop' marquera un temps d'arret, et modifier la legende de la forme.



Virtuel, Dynamique, Abstrait et Remplacer

Vous avez peut-etre remarque le virtual declaration apres le Demarrage, l'Arret et Tempsecoule. L'exercice suivant vous expliquer leurs utilisations.



Creer un nouveau composant, tirent cette composante de TFirstComponent (nom, il TSecondComponent) et de l'installer.



Le Virtuel et Dynamique identificateurs sont une composante de l'ecrivain façon de dire Delphi que la methode peut etre remplace dans un descendant de la classe. Si nous Remplacer une methode dans une classe, notre nouveau code sera execute a la place du code d'origine.







& ! & ! & ! & nbsp







protected

& nbsp & nbsp { Declarations protegees }

& nbsp & nbsp fonction Tempsecoule: chaîne de remplacer

& ! & ! & ! & nbsp





Nous avons ensuite mettre en œuvre le code ci-dessus comme suit.







& ! & ! & ! & nbsp







fonction TSecondComponent.Tempsecoule: string

var

& nbsp & nbsp S: string

demarrer

& nbsp & nbsp S := herite Tempsecoule

& nbsp & nbsp Resultat := S ' millisecondes ou '

& ! & ! & ! & nbsp Format('%.2f secondes',

& ! & ! & ! & ! & ! & nbsp [(StopTime - StartTime) / 1000])

fin

& ! & ! & ! & nbsp





Notre nouveau code est maintenant appelee en remplacement de l'original Tempsecoule, meme les appels mis en œuvre dans TFirstComponent a GetElapsed temps fera alors appel a notre nouveau code (si nous avons cree une instance de TSecondComponent que c'est). Le code d'origine est invoquee par le biais de l'utilisation de l'heritage de commande.



Remarque : Si vous n'avez pas de 'remplacer' une methode de base (parce que la base n'a pas ete declaree comme virtual ou parce que vous avez oublie). TSecondComponent appelle votre nouveau code, alors que le code mis en œuvre dans TFirstComponent va encore continuer a appeler le code d'origine de TFirstComponent.



Le Resume de l'identificateur dit Delphi ne pas attendre le code de la methode. Vous ne devez pas creer une instance d'objet avec des methodes abstraites (comme TStrings). La pratique standard consiste a creer un descendant d'une telle classe et de remplacer toutes les methodes abstraites (comme TStringList n').



Dynamique Vs Virtuel est tout simplement une question de vitesse et de taille. Une methode Dynamique, chaque instance d'une classe, necessitant moins de memoire, alors qu'une methode Virtuelle s'executera plus rapidement au prix d'un peu de memoire supplementaire.



Il y a quelques etapes simples pour ajouter des evenements a votre composant. Les evenements de permettre le composant a communiquer avec votre application, pour l'informer lorsque quelque chose d'important s'est passe. Un evenement est simplement une propriete en lecture / ecriture, au lieu d'etre une simple variable de type chaîne de caracteres, entier, etc) c'est une procedure ou une fonction.



Creer un nouveau composant, le descendre de TSecondComponent et nom il TThirdComponent. Enregistrer l'appareil, installez votre composant, puis ajoutez le code suivant.





& ! & ! & ! & nbsp







type

& nbsp & nbsp TState = (stStarted, stStopped)

& nbsp & nbsp TStateChangeEvent = procedure Sender : TObject Etat : TState) de objet



& nbsp & nbsp TThirdComponent = class(TSecondComponent)

& nbsp & nbsp prive

& ! & ! & ! & nbsp { Private declarations }

& ! & ! & ! & nbsp FState: TState

& ! & ! & ! & nbsp FOnStart,

& ! & ! & ! & nbsp FOnStop: TNotifyEvent

& ! & ! & ! & nbsp FOnStateChange: TStateChangeEvent

& nbsp & nbsp protected

& ! & ! & ! & nbsp { declarations Protegees }

& nbsp & nbsp public

& ! & ! & ! & nbsp { declarations Publiques }

& ! & ! & ! & nbsp constructeur Create(AOwner : TComponent) remplacer

& ! & ! & ! & nbsp destructeur Detruire remplacer

& ! & ! & ! & nbsp procedure Demarrer remplacer

& ! & ! & ! & nbsp procedure Stop remplacer

& ! & ! & ! & nbsp proprietes Etat: TState lire FState

& nbsp & nbsp publie

& ! & ! & ! & nbsp { Publie des declarations }

& ! & ! & ! & nbsp proprietes Demarrage: TNotifyEvent lire FOnStart ecrire FOnStart

& ! & ! & ! & nbsp proprietes OnStateChange: TStateChangeEvent lire FOnStateChange

& ! & ! & ! & ! & ! & nbsp ecrire FOnStateChange

& ! & ! & ! & nbsp proprietes OnStop: TNotifyEvent lire FOnStop ecrire FOnStop

& nbsp & nbsp fin

& ! & ! & ! & nbsp





les Evenements sont simplement des procedures ou des fonctions (rarement) qui appartiennent a une classe (d'ou le 'de l'objet' clause de vous voir dans le TStateChangeEvent). Par exemple, TNotifyEvent est un standard type d'evenement mis en œuvre par Delphi, qui vient de se passe a l'objet qui a declenche l'evenement, il est toujours bon d'envoyer 'Auto' (Sender : TObject) comme premier parametre de n'importe quel evenement que le meme code d'evenement peut etre utilise pour plusieurs composants.



TNotifyEvent est defini comme





& ! & ! & ! & nbsp







type

& nbsp & nbsp TNotifyEvent = procedure (Sender: TObject) de l'objet

& ! & ! & ! & nbsp





A l'appel d'un evenement au sein d'un composant est juste une affaire de verifier si l'evenement a ete attribue et, le cas echeant, l'appel a elle. J'ai annule le Demarrage et l'Arret des methodes de TSecondComponent afin de declencher ces evenements, comme si.







& ! & ! & ! & nbsp







procedure TThirdComponent.Debut

demarrer

& nbsp & nbsp herite //les appels TSecondComponent.Demarrer

& nbsp & nbsp FState := stStarted

& nbsp & nbsp si Assigne(Demarrage) OnStart(Auto)

& nbsp & nbsp si Assigne(OnStateChange) OnStateChange(de Soi, de l'Etat)

fin



procedure TThirdComponent.Stop

demarrer

& nbsp & nbsp herite //les appels TSecondComponent.Stop

& nbsp & nbsp FState := stStopped

& nbsp & nbsp si Assigne(OnStop) OnStop(Auto)

& nbsp & nbsp si Assigne(OnStateChange) OnStateChange(de Soi, de l'Etat)

fin



constructeur TThirdComponent.Create(AOwner: TComponent)

demarrer

& nbsp & nbsp herite

& nbsp & nbsp //C'est la que vous definissez les proprietes, et creer

& nbsp & nbsp //et les objets de votre composant peut utiliser en interne

& nbsp & nbsp FState := stStopped

fin



destructeur TThirdComponent.Detruire

demarrer

& nbsp & nbsp //C'est la que vous detruirait

& nbsp & nbsp //tous les objets


& nbsp & nbsp herite

fin

& ! & ! & ! & nbsp





Recompiler votre colis, n'oubliez pas d'enregistrer votre colis quand vous ajoutez un nouveau composant). Lors de la chute de votre nouveau composant sur le formulaire, vous remarquerez qu'il y a trois evenements. Demarrage, OnStop et OnStateChange. Si vous regardez Demo3 vous allez voir comment j'ai utilise ces evenements.



Demarrage definit la legende de la 'Main'

OnStop affiche le temps ecoule

OnStateChange active / desactive la pertinente Start / Stop bouton







& ! & ! & ! & nbsp







procedure TForm1.ThirdComponent1Start(Sender: TObject)

demarrer

& nbsp & nbsp Caption := 'Demarrer'

fin



procedure TForm1.ThirdComponent1Stop(Sender: TObject)

demarrer

& nbsp & nbsp Caption := ThirdComponent1.ElapsedTime

fin



procedure TForm1.ThirdComponent1StateChange(Sender: TObject Etat: TState)

demarrer

& nbsp & nbsp btnStart.Enabled := ThirdComponent1.Etat = stStopped

& nbsp & nbsp btnStop.Enabled := ThirdComponent1.Etat = stStarted

fin

& ! & ! & ! & nbsp





Normes en composant ecrit

Enfin, nous aborderons quelques points de plus sur la composante ecriture, y compris certaines des methodes de base de composants, et les normes pour l'ecriture.



de la Creation et de la destruction de votre composant:

les Objets sont crees par le biais d'un constructeur et detruit par un destructeur. Le but de la substitution d'un constructeur est triple


  1. Pour creer les objets qu'il contient a l'interieur de lui-meme (sous-objets)

  2. Pour initialiser les valeurs de la classe (proprietes, etc)

  3. Pour lever une exception et arreter la classe d'etre cree.



Il est courant d'appeler le constructeur herite de l'interieur de votre propre constructeur de sorte que le parent de la classe peut effectuer ses initialisations, bien qu'il n'est pas necessaire de le faire afin de creer votre composant. (Votre composant est cree des que votre constructeur est fini, il n'est pas cree par l'appel de l'heritage constructeur)



le but de La substitution d'un destructeur est tout simplement pour liberer toutes les ressources qui ont ete allouees au cours de la duree de vie du composant. Appel herite seulement apres avoir libere ces ressources.



Standard de composants:

Peinture:

Vous pouvez remplacer cette methode pour fournir votre propre dessin personnalise de votre composant.



Chargement:

Ceci est appele par Delphi des que l'ensemble de ses proprietes ont fini d'etre defini lors de son parent formulaire est cree. Vous pouvez remplacer cette methode pour effectuer toutes les actions qui dependent d'un groupe de proprietes de tous.



Invalide: Chaque fois qu'une propriete est modifiee, qui affecte l'apparence visuelle d'un composant, vous devez appeler cette methode.



ComponentState: Cette propriete est tres utile lorsque vous devez verifier si votre composant existe actuellement a la conception/execution, ou si ses proprietes sont actuellement en cours de lecture par un processus de diffusion.



l'Encapsulation de votre composant correctement

Il est standard pour ecrire votre composant comme TCustomMyClass et puis tirer votre composant a partir de cette classe de base. La 'coutume' composant de vous ecrire aurez la plupart (si pas tous) de ses proprietes / methodes declarees a l'interieur de son Protege.



Lorsque vous descendez de votre 'custom' classe que vous simplement redeclare vos proprietes dans le Public ou Publies les articles.







& ! & ! & ! & nbsp







type

& nbsp & nbsp TCustomMyClass = class(TComponent)

& nbsp & nbsp prive

& ! & ! & ! & nbsp FSomeString: string

& nbsp & nbsp protected

& ! & ! & ! & nbsp procedure SetSomeString(const Value : string) virtual

& ! & ! & ! & nbsp proprietes SomeString: chaîne de lire FSomeString ecrire SetSomeString

& nbsp & nbsp fin



& nbsp & nbsp TMyClass = class(TCustomMyClass)

& nbsp & nbsp publie

& ! & ! & ! & nbsp proprietes SomeString

& nbsp & nbsp fin

& ! & ! & ! & nbsp





C'est une bonne pratique car il permet a d'autres personnes pour etablir leurs propres composants bases sur le votre, tout en leur permettant de supprimer certaines proprietes.



Notez comment SetSomeString a ete declaree virtuelle dans la zone protegee. C'est aussi bien l'etiquette car elle permet de les descendants des classes pour repondre aux changements dans les valeurs de propriete par substitution de la procedure qui definit. Ceci s'applique egalement a des evenements, ou vous voyez une OnStateChange evenement, vous trouverez souvent un DoStateChange methode, par exemple:







& nbsp & nbsp


type

& nbsp & nbsp TCustomMyClass = class(TComponent)

& nbsp & nbsp prive

& ! & ! & ! & nbsp FOnStateChange: TStateChangeEvent

& nbsp & nbsp protected

La composante écriture, partie 1

La composante écriture, partie 1 : Plusieurs milliers de conseils pour vous faciliter la vie.
Recommander aux amis
  • gplus
  • pinterest

Messages récents

Commentaire

Laisser un commentaire

évaluation

commentfaire www.commentfaire.net PARIS 6 Place de la Madeleine FR-75 75012 Île-de-France +33.01.23.45.67.89