Miglioramenti
Come si era detto, apporteremo alcune semplicissime modifiche al componente creato nella Lezione1a. Elimineremo il metodo Execute e faremo in modo che la proprietà Risultato venga automaticamente aggiornata modificando le proprietà Num1 e Num2.
Scelta
Per fare ciò è possibile procedere in due modi che portano ovviamente allo stesso risultato, ma che sono strutturalmente molto diversi. La unit che stiamo per creare installerà automaticamente le due versioni del componente.
Inizio
unit T_MioVCL1;

 interface

 uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
Manteniamo identica l'Uniti Heading e l'Uses Clause del componente, ricordando che comunque potranno essere modificati in qualsiasi momento a seconda delle caratteristiche del componente e delle necessità di programmazione.
Definizione delle Classi
type
  TMioVCL1a = class(TComponent)
Definiamo, come nella lezione precedente, il tipo di componente che creeremo. Il nome è stato modificato per maggiore comodità.
Interface Part - Livelli di accesso
private
    { Private declarations }
    N1,N2,R:Integer;
Ridefiniamo le variabili interne come per il componente precedentemente creato.
Definizione delle proprietà
Property Num1:Integer Read N1 Write SetNum1;
    Property Num2:Integer Read N2 Write SetNum2;
Ridefiniamo le proprietà. La sintassi è stata modificata, in particolare allo specificatore Write non è stata assegnata una variabile, ma il nome della procedura che andrà ad assegnare il nuovo valore alla proprietà.
Definizione prototipi
Procedure SetNum1(Value:Integer);
    Procedure SetNum2(Value:Integer);
Definiamo come procedure Private i prototipi delle due procedure che vengono automaticamente chiamate da Delphi al momento dell'assegnazione del valore della proprietà.
Dettagli
Procedure SetNum1(Value:Integer);
Il parametro Value della procedura può avere un qualsiasi nome valido di variabile, ma deve assere dello stesso tipo della proprietà corrispondente.
Delhi assegnerà automaticamente il valore del parametro anche a DesignTime.
Nota
//Procedure interne del componente TMioVCL1a
Spostiamoci quindi nella sezione Implementation della unit per scrivere le due procedure che abbiamo appena dichiarato.
Procedura Interna
Procedure TMioVCL1a.SetNum1(Value:Integer);
 Begin
  N1:=Value;
  R:=N1+N2;
 End;
Scriviamo la procedura. Questa assegna il nuovo valore della variabile alla proprietà del componente ed aggiorna il valore della proprietà Risultato anche a DesignTime.
Procedure TMioVCL1a.SetNum2(Value:Integer);
 Begin
  N2:=Value;
  R:=N1+N2;
 End;
Identica alla procedura precedente, l'unica differenza sta nel fatto che aggiorna la proprità Num2 invece di Num1.
N1:=Value;
Mi sembra inutile far notare che questa riga assegna il valore della variabile Value alla variabile interna N1 (Proprietà Num1).
R:=N1+N2;
Questa è la riga che aggiorna automaticamente la variabile R (Proprietà Risultato).
Semplice vero?
L'altro modo
Vediamo adesso l'altro metodo per conseguire l'obbiettivo che ci siamo proposti.
Definizione Oggetto
type
  TMioVCL1b = class(TComponent)
  private
    { Private declarations }
    N1,N2,R:Integer;
Ridefiniamo il nome dell'oggetto, il tipo e le tre solite variabili interne.
Property Num1:Integer Read N1 Write N1;
    Property Num2:Integer Read N2 Write N2;
La definizione delle proprietà Num1 e Num2 resta identica a quella della Lezione1a.
Definizione delle propietà
Property Risultato:Integer Read GetRisultato Write R;
La sintassi è stata modificata, in particolare allo specificatore Read non è stata assegnata una variabile, ma il nome della funzione che restituirà il valore della proprietà.
Come per le Procedure in scrittura, questa Funzione viene automaticamente chiamata da Delphi ogni qual volta sia richiesto il valore della proprietà risultato. La funzione deve essere dello stesso tipo della propietà corrispondente.
Prototipo
Function GetRisultato:Integer;
Come per il componente precedente, definiamo il prototipo della funzione nella sezione Private del componente.
Implementation Part
//Funzione interna del componente TMioVCL1b
Ed ora scriviamo la funzione appena dichiarata.
Funzione
Function TMioVCL1b.GetRisultato:Integer;
 Begin
  Result:=N1+N2;
 End;
La funzione ovviamente restituisce la somma delle propietà Num1 e Num2.
Result:=N1+N2;
E' stato utilizzato Result, ma può essere tranquillamente sostituito dal nome della Funzione, in questo caso 'GetRisultato'.
Procedure Register
procedure Register;
I due Componenti sono pronti. Non scordiamoci Mai la procedura Register!
Modifica Procedura Register
procedure Register;
 begin
  RegisterComponents('Samples', [TMioVCL1a,TMioVCL1B]);
 end;
I parametri della procedura RegisterComponents sono stati modificati in modo da installare tutti e due i componenti.
RegisterComponents('Samples', [TMioVCL1a,TMioVCL1B]);

è uguale a
 
  RegisterComponents('Samples', [TMioVCL1a]);
  RegisterComponents('Samples1', [TMioVCL1B]);
Se i due componenti dovranno essere installati nella stessa sezione della ComponentPalette, è consigliabile utilizzare una sola chiamata. Altrimenti è possibile effettuare due chiamate modificando il nome della Sezione ed il nome del componente.
Conclusione
Possiamo finalmente provare i due componenti. Non vi diremo noi le differenze, provate voi a scoprirle:
Aggiungete una ShowMessage alle due Procedure e alla funzione per vedere quando e quante volte viene eseguito il calcolo (R:=N1+N2).
Nel Prossimo Numero
Non pensiate che sia finita qui...
Vedremo come creare componenti visibili, come creare nuovi eventi, come ereditare metodi e tanto altro ancora!