Denne artikkelen vil dekke hvordan du skriver avanserte egenskaper, hvordan å skrive tilpasset streaming for disse egenskapene, og sub-egenskaper. 
 Denne artikkelen opprinnelig dukket opp i Delphi DeveloperCopyright Pinnacle Publishing, Inc. Alle rettigheter reservert. 
  Denne artikkelen er del to av en tre del artikkelen på komponenter. Del én dekket grunnleggende oppretting av komponenter, vil del to dekke hvordan å skrive avanserte egenskaper, hvordan å skrive tilpasset streaming for disse egenskapene, og sub-egenskaper. Den siste delen vil dekke eiendom /komponent redaktører, hvordan å skrive egne redaktører for komponenten /eiendom, og hvordan du skal skrive "skjulte" komponenter. 
 Ganske ofte er det nødvendig å skrive komponenter som utfører mer avanserte funksjoner. Disse komponentene må ofte enten referansen andre komponenter, har tilpasset eiendom dataformater, eller har en eiendom som eier en liste med verdier i stedet for en enkelt verdi. I denne delen vil vi utforske ulike eksempler som dekker nettopp disse fagene, som starter med flest simple.Component referencesSome komponenter må referere til andre komponenter. TLabel for eksempel har en "FocusControl" eiendom. Når du tar med en tegnet i "Caption" eiendom det understreker neste bokstav (& Hei blir Hallo), trykke på hurtigtasten ALT-H på tastaturet vil utløse en hendelse i etiketten. Hvis "FocusControl" eiendom har vært satt fokus vil bli sendt til kontroll specified.To ha en slik eiendom i din egen komponent er ganske enkel. Alt du gjør er å erklære en ny eiendom, og sette egenskapstypen til den laveste base klassen at det kan akseptere (TWinControl vil tillate noen etterkommer av TWinControl skal brukes), men det er implikasjoner.  skriv 
 TSimpleExample =  class product: (TComponent)  privat 
 FFocusControl: TWinControl;  beskyttet 
  prosedyre 
 SetFocusControl ( konst 
 Verdi: TWinControl);  virtuell 
;  offentlig 
  publisert 
  eiendom 
 FocusControl: TWinControl lese FFocusControl skrive SetFocusControl;  end 
;  prosedyre 
 TSimpleExample.SetFocusControl ( konst 
 Verdi: TWinControl);  begynne 
 FFocusControl: = Verdi;  end 
; Ta eksempelet ovenfor. Dette er ganske enkelt eksempel (derav komponent navnet) på hvordan du skriver en komponent som henviser til en annen komponent. Hvis du har en slik eiendom i komponenten Object Inspector vil vise en kombinasjonsboks med en liste over komponenter som oppfyller kriteriene (alle komponentene stammer fra TWinControl) .Våre komponent kan gjøre noe sånt  prosedyre 
 TSimpleExample.DoSomething;  begynne 
  hvis plakater (Assigned (FocusControl))  og plakater (FocusControl.Enabled)  så 
 FocusControl.Setfocus;  end 
; Først sjekker vi om eiendommen har blitt tildelt, hvis så vi setter fokus på det, men det finnes situasjoner når eiendommen er ikke Nil ennå komponenten den peker til er ikke lenger gyldig. Dette skjer ofte når en eiendom refererer til en komponent som har vært destroyed.Luckily Delphi gir oss en løsning. Når en komponent er ødelagt den varsler sin eier (vår form) at det blir ødelagt. På dette punktet hver komponent som eies av den samme formen er varslet om dette arrangementet også. For å felle denne hendelsen må vi overstyre en standard metode for TComponent kalt "Meldinger".  skriv 
 TSimpleExample =  class product: (TComponent)  privat 
 FFocusControl: TWinControl;  beskyttet 
  prosedyre 
 Notification (AComponent: TComponent; Operation: TOperation);  styre 
;  prosedyre 
 SetFocusControl ( konst 
 Verdi: TWinControl);  virtuell 
;  offentlig 
  publisert 
  eiendom 
 FocusControl: TWinControl lese FFocusControl skrive SetFocusControl;  end 
;  prosedyre 
 TSimpleExample.SetFocusControl ( konst 
 Verdi: TWinControl);  begynne 
 FFocusControl: = Verdi;  end 
;  prosedyre 
 TSimpleExample.Notification (AComponent: TComponent; Operation: TOperation);  begynne 
  arvet; 
  //glem aldri å kalle dette 
 < B> hvis plakater (Operation = opRemove)  og plakater (AComponent = FocusControl)  så 
 FFocusControl: =  nil 
;  end 
; Nå når vår refererte komponenten er ødelagt vi blir varslet, og da kan vi sette vår referanse til Nil. Vær imidlertid oppmerksom på at jeg sa  "hver komponent som eies av den samme formen er varslet om dette arrangementet også" 
 Dette introduserer oss med et annet problem. Vi er bare varslet at komponenten blir ødelagt hvis det er eid av samme form. Det er mulig å ha vår eiendom punkt til komponenter på andre former (eller selv uten en eier i det hele tatt), og når disse komponentene er ødelagt vi ikke blir varslet. Nok en gang er det en solution.TComponent introduserer en metode som kalles "FreeNotification". Formålet med FreeNotification er å fortelle komponenten (FocusControl) for å holde oss i tankene når det er destroyed.An gjennomføringen ville se slik ut  skriv 
 TSimpleExample =  class product: (TComponent)  privat 
 FFocusControl: TWinControl;  beskyttet 
  prosedyre 
 Notification (AComponent: TComponent; Operation: TOperation);  styre 
;  prosedyre 
 SetFocusControl ( konst 
 Verdi: TWinControl);  virtuell 
;  offentlig 
  publisert 
  eiendom 
 FocusControl: TWinControl lese FFocusControl skrive SetFocusControl;  end 
;  prosedyre 
 TSimpleExample.SetFocusControl ( konst 
 Verdi: TWinControl);  begynne 
  hvis 
 Value < > FFocusControl  da 
  begynne 
  hvis 
 Assigned (FFocusControl)  så 
 FFocusControl.RemoveFreeNotification (Selv); FFocusControl: = verdi;  hvis 
 Assigned (FFocusControl)  så 
 FFocusControl.FreeNotification (Selv); end;  end 
;  prosedyre 
 TSimpleExample.Notification (AComponent: TComponent; Operation: TOperation);  begynne 
  hvis plakater (Operation = opRemove) < B> og plakater (AComponent = FocusControl)  så 
 FFocusControl: =  nil 
;  end 
; Når du setter vår FocusControl eiendom vi først sjekke om det allerede er satt til en komponent. Hvis det allerede er satt må vi fortelle den opprinnelige komponenten som vi ikke lenger trenger å vite når det er ødelagt. Når vår eiendom er satt til den nye verdien vi informere den nye komponenten som vi trenger et varsel når det er frigjort. Resten av koden vår er den samme som den refererte komponent fortsatt kaller vår Varslings method.SetsThis delen er egentlig ganske enkel, og vil ikke ta lang tid å dekke. Jeg tviler ikke på at du allerede er kjent med å lage egne ordens typer.  skriv 
 TComponentOption = (coDrawLines, coDrawSolid, coDrawBackground); Egenskaper av denne typen vil vise en kombinasjonsboks med en liste over alle mulige verdier, men noen ganger må du angi en kombinasjon av mange (eller alle) av disse verdiene. Dette var sett kommer i å spille  skriv 
 TComponentOption = (coDrawLines, coDrawSolid, coDrawBackground); TComponentOptions =  set of 
 TComponentOption; Publisering en egenskap av typen TComponentOptions ville resultere i en [+] vises ved siden av vår eiendom navn. Når du klikker for å utvide eiendommen vil du se en liste over alternativer. For hvert element i TComponentOption vil du se en boolsk egenskap, kan du inkludere /ekskludere elementer fra settet ved å sette verdien til True /False.It er enkelt å sjekke /endre elementer i et sett innenfra vår komponent som så.  hvis 
 coDrawLines  i 
 OurComponentOptions  deretter 
 DrawTheLines; eller  prosedyre 
 TSomeComponent.SetOurComponentOptions ( konst 
 Verdi: TComponentOptions);  begynne 
  hvis plakater (coDrawSolid i verdi)  og Selge (coDrawBackground i verdi)  så product: {heve et unntak} FOurComponentOptions: = verdi; Ugyldig;  end 
; Binære propertiesSometimes er det nødvendig å skrive dine egne streaming rutiner for å lese og skrive tilpassede typer eiendom (Dette er hvordan Delphi leser /skriver øvre og venstre egenskaper for ikke synlige komponenter uten egentlig å publisere disse egenskapene i objekt inspektør) .For eksempel, jeg skrev en gang en komponent til å forme et skjema basert på et punktgrafikkbilde. Koden min på den tiden til å konvertere punktgrafikk til et vindu-regionen var ekstremt treg og ikke ville muligens være til nytte under kjøring. Min løsning var å konvertere data på design tid, og streame den binære data som resulterte fra konverteringen. For å lage binære egenskaper er en tretrinns process.1. Skriv en metode for å skrive data.2. Skriv en metode for å lese data.3. Fortell Delphi at vi har en binær egenskap, og passerer våre lese- /skrivemetoder.  skriv 
 TBinaryComponent =  class product: (TComponent)  privat 
 FBinaryData: Pointer; FBinaryDataSize: DWORD;  prosedyre 
 WriteData (S: TStream);  prosedyre 
 ReadData (S: TStream);  beskyttet 
  prosedyre 
 DefineProperties (Filer: TFiler);  styre 
;  offentlig 
  konstruktør 
 Lag (AOwner: TComponent);  styre 
;  end 
; DefineProperties kalles av Delphi når det er behov for å streame vår komponent. Alt vi trenger å gjøre er å overstyre denne metoden, og legge en eiendom ved hjelp av enten TFiler.DefineProperty eller TFiler.DefineBinaryProperty.  prosedyre 
 TFiler.DefineBinaryProperty ( konst 
 Navn:  string 
; ReadData, WriteData: TStreamProc; HasData: Boolean);  konstruktør 
 TBinaryComponent.Create ( AOwner: TComponent);  begynne 
  arvet 
; FBinaryDataSize: = 0;  end 
;  prosedyre 
 TBinaryComponent.DefineProperties (Filer: TFiler);  Var 
 HasData: Boolean;  begynne 
  arvet 
; HasData: = FBinaryDataSize < > 0; Filer.DefineBinaryProperty ( 'BinaryData', ReadData, WriteData, HasData);  end 
;  prosedyre 
 TBinaryComponent.ReadData (S: TStream);  begynne 
 S.Read ( FBinaryDataSize, sizeof (DWORD));  hvis 
 FBinaryDataSize > 0  så 
  begynne 
 GetMem (FBinaryData, FBinaryDataSize); S.Read (FBinaryData ^, FBinaryDataSize);  end 
;  end 
;  prosedyre 
 TBinaryComponent.WriteData (S: TStream);  begynne 
  //Dette vil ikke bli kalt hvis FBinaryDataSize = 0 
 S.Write (FBinaryDataSize, sizeof (DWORD)); S.Write (FBinaryData ^, FBinaryDataSize);  end 
; For det første overstyre vi DefineProperties. Når vi har gjort dette vi definere en binær egenskap med verdier - -BinaryData: Den usynlige Eiendommen navn som skal brukes. -ReadData: Fremgangsmåten er ansvarlig for å lese dataene. -WriteData: Prosedyren ansvarlig for å skrive dataene. -HasData: Hvis dette er falsk, er WriteData prosedyren ikke engang called.PersistencyA rask forklaring av utholdenhet er i orden som vi skal vise til den i de neste avsnittene. Utholdenhet er det som gjør det mulig for Delphi å lese og skrive egenskapene til alle komponentene. TComponent stammer fra en klasse kalt TPersistent. TPersistent er rett og slett en Delphi klasse i stand til å ha sine egenskaper lest og skrevet av Delphi, noe som betyr at eventuelle etterkommere av TPersistent har også denne samme capability.CollectionsAs vi fremgang gjennom denne artikkelen vil vi dekke komponentegenskapene til mer kompleksitet. Samlinger er en av de mest komplekse "standard" Delphi typer eiendom. Hvis du slipper en TDBGrid på et skjema og se på dens egenskaper i Object Inspector, vil du se en eiendom som heter "Kolonner" .Columns er en samling eiendom, når du klikker på [..] -knappen vil du se et lite vindu dukke opp. Dette vinduet er standard eiendom redaktør for TCollection egenskaper (og etterkommere av TCollection) .Når du klikker på "Ny" knappen du ser et nytt element lagt til (en TColumn element), klikke på den aktuelle gjenstanden vil velge den inn i Object Inspector slik at du kan endre sine eiendommer /hendelser. Hvordan er dette gjort? Kolonner eiendommen stammer fra TCollection. TCollection ligner på en matrise, som inneholder en liste over TCollectionItem s. Fordi TCollection stammer fra TPersistent er det i stand til å streame denne listen over elementer, på samme måte, er TCollectionItem også nedstammet fra TPersistent og kan også streame sine egenskaper. Så det vi har er en matrise-lignende element i stand til streaming alle sine elementer og deres properties.The første du må gjøre når du oppretter vår egen struktur basert på TCollection /TCollectionItem er å definere vår CollectionItem.  (Se OurCollection.pas ) 
  skriv 
 TOurCollectionItem =  class product: (TCollectionItem)  privat 
 FSomeValue:  String 
;  beskyttet 
  funksjon 
 GetDisplayName:  String 
;  styre 
;  offentlig 
  prosedyre 
 tildele (
Component skriving, del 2
Previous:Bord, felt og utenlandske keys 
Next Page:Å få datamaskiner DNS server 
			 
        
