Component skriving, del 3

Denne artikkelen er den siste delen av en tredelt artikkel om komponenter. Denne siste delen vil dekke eiendom /komponent redaktører, hvordan skrive dedikerte redaktører for komponenten /eiendom, og hvordan å skrive " gjemt " komponenter.
Denne artikkelen opprinnelig dukket opp i Delphi Developer
Copyright Pinnacle Publishing, Inc. Alle rettigheter reservert.
Custom Komponent Redaktører Så snart vi begynner å skrive avanserte typer eiendom for våre komponenter, blir livet litt mer komplisert. Selv om objektet inspektør bygget inn Delphi er i stand til å gjenkjenne de fleste typer eiendom, er det umulig for den å være i stand til å håndtere alle mulige tilpasset type vi kan skrive inn våre komponenter. Noen ganger objektet inspektør er i stand til å håndtere våre tilpassede typer, men redigerer en så kompleks ordning av eiendommer i objektet inspektør er rett og slett ikke intuitivt nok. Det er på dette punktet vi kan bli pålagt å skrive eiendom /komponent redaktører. Delphi har mange forhåndsdefinerte redaktører allerede, disse redaktørene er i DsgnIntf.pas filen i $ (Delphi) \\ Source \\ ToolsAPI katalogen. Du trenger å liste denne enheten i bruk klausulen av enhver komponent redaktør /eiendom redaktør du kan skrive, er det også en god idé å holde denne filen åpen for referanse når du skriver dine egne redaktører.
Coding standarder Til å begynne med Jeg vil dekke noen koding standarder som brukes når du skriver komponent eller eiendom redaktører. Det er bare noen få, men det ville være en god idé å holde seg til disse standardene når du skriver dine egne redaktører som det gjør det lettere for andre å forstå ditt arbeid.

  • Når du oppretter en eiendom editor , avslutter navnet på redaktøren med ordet " Eiendom "; for eksempel TAngleProperty

    Når du oppretter en komponent editor, avslutter navnet på redaktøren med ordet " Editor "; for eksempel TPieChartEditor

    Når du skriver redaktørene, alltid skrive redaktøren i en egen enhet til selve komponenten. Det er godt å skille design tid og runtime-kode, og bortsett fra dette, gjør det resulterende EXE størrelse mindre (på noen versjoner av Delphi komponenten kan stoppe programmer fra kompilering hvis du ikke skille dem). Også skille pakker, slik at brukerne kan bygge med runtime pakker hvis de ønsker å

    navn redaktør enhet med samme navn som komponenten enhet, men føyer ordet "! Reg " I slutten; for eksempel en komponent med enheten navn " MyComponent.pas " ville resultere i editoren filnavnet er " MyComponentreg.pas "

    Til slutt, når du skriver en komponent redaktør /eiendom redaktør for komponenten, flytter du RegisterComponents
    uttalelse ut av komponentens enhet, og inn i komponenten redaktørens enhet. På denne måten komponenten vil ikke bli registrert uten redaktøren også blir registrert.
    Eiendoms redaktør Eiendom redaktører brukes av IDE å tillate spesiell redigering av enkelteiendommer innenfor en komponent. Noen redaktører er svært enkle, noen er mye mer komplisert. Delphi har allerede en rekke standard eiendoms redaktører, noen av disse er:
    TIntegerProperty. Brukes for å legge inn heltall.
    TCharProperty. Brukes for å legge inn et enkelt tegn.
    TEnumProperty. Brukes for valgt et enkelt element i en nummerert type (alTop, alClient etc). TBoolProperty
    . Brukes for å velge " ekte " eller " Falsk " for boolske egenskaper.
    TFloatProperty. Brukes for å legge inn flyttall (Variable typen Float /Utvidet etc. " ekte " typen bør ikke brukes til komponentegenskaper).
    TStringProperty. Brukes for å legge inn strenger opp til maksimalt 255 tegn.
    TSetProperty. Brukes for å inkludere /unntatt enkelte elementene i en Set eiendom. Hvert element vises som en boolsk sub-eiendom. Sette verdien til " ekte " inneholder element, sette den til " Falsk " utelukker det.
    TClassProperty. Dette er base klassen til å stige ned fra når du ønsker å lage en ny tilpasset editor for å kunne påberopes for egenskapene til en viss klasse (når du har en klasse som en eiendom, for eksempel TImage.Picture).
    Alle disse eiendoms redaktører ned direkte eller indirekte fra TPropertyEditor. TPropertyEditor har mange egenskaper og metoder, den viktigste er
    funksjon AllEqual. Boolsk; virtuell; funksjons GetAttributes: TPropertyAttributes; virtuell; prosedyre Edit; virtuell; funksjon GetValue: string; virtuell; prosedyre GetValues ​​(Proc: TGetStrProc); virtuell;
    AllEqual Når flere komponenter er valgt objektet inspektør filtrerer sin liste over eiendommer til bare de som alle de valgte komponentene har til felles. Dersom verdien av hver komponent for en gitt egenskap (f.eks bredde) er den samme, vil verdien bli vist at verdien vil bli vist. AllEqual er den rutine som avgjør om hver verdi er identisk
    funksjon TStringProperty.AllEqual: Boolean;. Var jeg: Integer; V: string; begynne Resultat: = False; hvis PropCount > En da begynne V: = GetStrValue; for jeg: = 1 til PropCount - en gjøre hvis GetStrValueAt (I) < > V deretter Exit; ende; Resultat: = true; slutt;
    I eksempelet ovenfor TStringProperty sammen hver verdi (ved hjelp GetStrValueAt) med verdien av den første komponenten i listen (med GetStrValue, GetStrValueAt (0) ville ha gjort det samme). Størrelsen på listen bestemmes ved hjelp PropCount, returnerer dette den totale mengden av komponenter som er valgt.
    GetAttributes GetAttributes kalles av IDE når det er behov for å samle informasjon om eiendommen editor. Objektet inspektør viser en passende redaktør basert på informasjonen som følger med. Resultatet av GetAttributes (TPropertyAttributes) er et sett, så den kan inneholde en kombinasjon av følgende verdier (dette er ikke en komplett liste) paDialog Forteller objektet inspektør for å vise et [...] -knappen etter at eiendommen navn, når brukeren klikker på denne knappen Rediger metoden er utløst.
    paSubProperties Forteller objektet inspektør for å vise en [+] utvide knappen før eiendommen navn klikke på denne knappen vil vise en utvidet liste over under egenskaper (vanligvis de publiserte egenskapene til en klasse eiendom).
    paValueList Objektet inspektør vil vise en kombinasjonsboks med en liste av verdier, er denne listen bestemmes av IDE ved å ringe GetValues ​​metoden. MERK: GetValues ​​metode, ikke GetValue metode som er helt annerledes
    paSortList Hvis kombinert med paValueList, vil verdiene som vises bli sortert alfabetisk
    paMultiSelect Dette spesifiserer til IDE at eiendommen er. lov til å bli vist når flere komponenter er valgt. Dette produktet er ikke til stede for redaktører slik TClassProperty.
    PaAutoUpdate Får SetValue metoden for å bli kalt hver gang verdien endres i objektet inspektør, heller enn å vente for brukeren å trykke eller redigere en annen eiendom. Dette brukes for " Caption " og " Text " egenskaper, for å gi en levende representasjon av verdien som brukeren skriver inn.
    paReadOnly Hvis dette elementet er inkludert verdien i objektet Inspektøren er skrivebeskyttet. Dette blir typisk brukt i forbindelse med paDialog. GetValue ville overstyres til å returnere en beskrivende representasjon av eiendommen.
    Edit Denne metoden kalles når [...] -knappen for eiendommen er klikket. Denne knappen vises hvis paDialog element er inkludert i resultatet av GetAttributes.
    GetValue Denne metoden kalles når objektet inspektør må vite hvordan du viser eiendommen som en streng. Dette brukes vanligvis når [paDialog, paReadOnly] er spesifisert innenfor et resultat av GetAttributes.
    GetValues ​​Denne metoden kalles når objektet inspektør må hente en liste over verdier som skal vises når paValueList er spesifisert innenfor et resultat av GetAttributes. GetValues ​​passerer en parameter kalt " Proc " som er av typen TGetStrProc. GetStrProc er erklært som TGetStrProc = prosedyre (konst S: string) objekt;
    IDE forventer " Proc " å bli kalt en gang for hver verdi som skal vises i objektet inspektør for denne eiendommen
    prosedyre THintProperty.GetValues ​​(Proc: TGetStrProc);. begynne Proc ('Første punkt for å vise'); Proc ('Second element for å vise'); slutt;
    Følgende eksempel viser hvordan du kan gi en liste over standardverdier for " Hint " eiendom av alle komponenter, samtidig som tillater brukeren å angi en verdi ikke er i listen
    typen THintProperty = klasse (TStringProperty) offentlig funksjon GetAttributes. TPropertyAttributes; styre; prosedyre GetValues ​​(Proc: TGetStrProc); styre; end;
    prosedyre Registrer;
    implementering
    prosedyre Registrer; begynne RegisterPropertyEditor (TypeInfo (String), nil, 'Hint', THintProperty); end;
    {THintProperty}
    funksjons THintProperty.GetAttributes: TPropertyAttributes; begynne Resultat: = arvet GetAttributes + [paValueList, paSortList]; end;
    prosedyre THintProperty.GetValues ​​(Proc: TGetStrProc); begynne Proc ('Dette er en ønsket oppføring'); Proc ('Trykk F1 for mer informasjon'); Proc ('Denne verdien er skrivebeskyttet'); slutt;
    Først GetAttributes overstyres, og [paValueList, paSortList] er inkludert i resultatet. Neste GetValues ​​overstyres og tre verdier er lagt til rullegardinlisten ved å ringe " Proc " prosedyren.
    Registrere eiendoms redaktører Endelig eiendommen redaktør er registrert bruker RegisterPropertyEditor. RegisterPropertyEditor tar fire parametere:
    PropertyType: PTypeInfo Krever en peker til en TTypeInfo posten. Dette høres mye mer komplisert enn det egentlig er, er alt vi trenger å gjøre er å legge TypInfo til vår bruk klausulen, og bruke TypeInfo funksjon for å hente pekeren for oss. TypeInfo (SomeVariableType)
    ComponentClass: TClass Dette er base klassen at denne redaktøren bør gjelde for. Redaktøren vil gjelde for denne klassen og noen klasser som går ned fra den. Hvis nil er spesifisert, vil dette redaktør gjelde for alle klasser
    konst property:. String hvis denne editoren skal kun gjelde for en bestemt eiendom deretter navnet på eiendommen bør spesifiseres her. Hvis redaktøren bør gjelde på eiendom som tilhører den type som er angitt i PropertyType denne verdien skal være ''
    EditorClass. TPropertyEditorClass Dette er den klassen som har blitt opprettet for å håndtere eiendommen. I eksempelet ovenfor klassen er THintProperty.
    Bruke RegisterPropertyEditor feil Det er viktig når du bruker RegisterPropertyEditor at du oppgir riktig informasjon. Forsyne uriktige opplysninger kan bety enten at redaktøren påvirker uriktige egenskaper (f.eks Alle streng egenskaper) eller feil komponenter.
    På den andre ytterligheten, sette parametrene feil kan bety at bare en bestemt egenskap i en spesifikk komponent (og etterkommere) er tilknyttet editor. Dette ser ikke ut som mye av et problem i starten, men etterkommer komponenter kan ønske å iverksette ytterligere eiendommer av samme type. Som disse egenskapene åpenbart vil ha et annet navn de ikke vil ha den riktige eiendommen redaktør tildelt dem.
    Et eksempel på dårlig registrert redaktør finnes allerede i VCL. Standard editor for TCollection ble registrert for alle klasser nedstammet fra TComponent. Problemet er at den laveste klassen stand til å bli vist i objektet inspektør er TPersistent (den klassen som TComponent stammer fra).
    Hvis en komponent har en egenskap av type TPersistent (som standard eksponerer sine under eiendommer i et utvid listen), og en av dens egenskaper er av typen TCollection, resultatet er en [...] -knappen i objektet inspektør som ikke gjør noe når klikket (som vi så i del to av denne artikkelserien).
    løsning på dette problemet virker ganske enkel. Snarere enn vår sub-eiendommen blir nedstammer fra TPersistent vi kunne stige ned den fra TComponent stedet. Men standard virkemåte for en egenskap av type TComponent (som bestemmes av eiendommen redaktør TComponentProperty redaktør) er å vise en liste over andre komponenter, heller enn under egenskapene til en innebygd komponent.
    Selve løsningen egentlig er enkel , men bare hvis du vet hvordan du skal skrive en eiendom redaktør
    Trinn 1:. typen TExpandingRecord = klasse (TPersistent)
    bør endres for å lese typen TExpandingRecord = klasse (TComponent) Anmeldelser
    Trinn 2: Lag en eiendom editor som så skriv TExpandingRecordProperty = klasse (TClassProperty) offentlig funksjon GetAttributes: TPropertyAttributes; styre; end;
    prosedyre Registrer;
    implementering
    prosedyre Registrer; begynne RegisterComponents ('artikkel', [TExpandingComponent]); RegisterPropertyEditor (TypeInfo (TExpandingRecord), nil, '', TExpandingRecordProperty); end;
    {TExpandingRecordProperty}
    funksjons TExpandingRecordProperty.GetAttributes: TPropertyAttributes; begynne Resultat: = [paReadOnly, paSubProperties]; slutt;
    Trinn 3: Fjern RegisterComponents ringe fra komponenten enhet, og registrere det i editoren enhet i stedet. På denne måten kan vi sikre komponenten vil ikke bli registrert uten komponenten.
    Nå er vår eiendom av typen TExpandingRecord vil vise som en ekspanderende eiendom (på grunn av oss tilbake paSubProperties fra GetAttributes), og standard editor for TCollection vil fungere som Eieren av TCollection eiendommen er en TComponent.
    Dialog eiendoms redaktører Mesteparten av tiden, når du oppretter en egendefinert egenskap redaktør, er hensikten å gi en grafisk måte å kommunisere med eiendommen.
    Dette første eksemplet er en veldig enkel måte å tillate brukeren å legge inn flere linjer i " Caption " tilhører en TLabel. Selv om dette eksemplet er ikke veldig komplisert, viser det hvordan å inkludere en form innenfor redaktør
    Trinn 1:. Velg File, New Application fra hovedmenyen. Dette vil skape en form, navngi form " fmLabelEdit ", legge en TMemo til skjemaet som heter memCaption. Legg til to knapper, " OK " og " Avbryt " med ModalResult egenskaper satt til mrOK og mrCancel henholdsvis
    Trinn 2:.. Legg DsgnIntf ​​og TypInfo til din bruk klausul
    Trinn 3:. Legg følgende egenskap redaktør kode til din enhet
    TCaptionProperty = klasse (TStringProperty) offentlig funksjon GetAttributes: TPropertyAttributes; styre; prosedyre Edit; styre; slutt;
    Og registrere eiendommen editor som så
    prosedyre Registrer;
    implementering {$ R * .DFM}
    prosedyre Registrer; begynne RegisterPropertyEditor (TypeInfo (TCaption), TLabel, 'Caption', TCaptionProperty); slutt;
    Trinn 4: Legg til følgende kode for at objektet inspektør for å vise [...] rediger-knappen etter at eiendommen navn
    funksjons TCaptionProperty.GetAttributes. TPropertyAttributes; begynne Resultat: = arvet GetAttributes + [paDialog]; slutt;
    Trinn 5:. Til slutt lager vi en forekomst av vår redaktør form, sette innholdet i notatet til dagens bildeteksten, og deretter vise form modally
    prosedyre TCaptionProperty.Edit; Var jeg: Integer; begynne med TfmLabelEdit.Create (Application) prøver memCaption.Lines.Text: = GetStrValue; ShowModal;
    {Hvis ModalResult av skjemaet er mrOK, må vi sette " Caption " tilhører hver TLabel}
    hvis ModalResult = mrOK da for jeg: = 0 til PropCount-en gjøre TLabel (GetComponent (I)) Bildetekst:.. = memCaption.Lines.Text; endelig Free; ende; slutt;
    Trinn 6: Installer enheten i pakken, og prøve ut den nye redaktøren deretter
    Avansert eiendoms redaktører Alle som noen gang har brukt TActionList eller TDataSet (TTable /TQuery) vil ha erfaring fra følgende eksempel, muligens uten selv å realisere.
    ActionList redaktør er åpenbart en tilpasset editor som gjør det mulig gruppering av handlinger, mens FieldsEditor av TDataSet kan først virke som en standard editor, men ved nærmere ettersyn har en popup-meny med elementer som " Legg feltene ". Imidlertid er det mest oppsiktsvekkende trekk ved begge disse redaktørene ikke at de er tilpasset dialog redaktører (som ligner på det vi dekket tidligere), men det faktum at varene de skaper er inkludert i hovedklassen erklæring av gjeldende enhet.
    skriv TForm1 = klasse (TForm) ActionList1: TActionList; Action1: TAction; Action2: TAction; privat {felleserklæringer}
    offentlig {offentlige erklæringer}
    slutten;
    Fordelen med dette er at IDE blir gjort oppmerksom på disse elementene, derfor tillater dem å bli valgt fra en liste over objekter når eiendommen av en komponent krever dem.
    i illustrasjonen ovenfor, er to handlinger lagt til en TActionList, klikke på " Handling " eiendom Button1 viser en liste bestående av handlingene lagt til. De to handlinger er også lagt til Form klasse erklæring, og kan derfor bli referert til ved navn (Action1, Action2).
    Trikset her ligger helt i eiendommen redaktør og ikke innenfor komponent. Når en eiendom redaktør utløses (dvs. Edit metoden kalles) Designer eiendommen inneholder et gyldig referanse til en IFormDesigner (TFormDesigner i Delphi 4). Mange av funksjonene i dette grensesnittet er ikke innenfor rammen av denne artikkelen, hvis du ønsker å vite mer om mulighetene til dette grensesnittet vil jeg anbefale en bok som heter Delphi Developer håndbok av Marco Cantu.
    Noen av metodene inkluderer
    funksjons MethodExists (konst Navn: string): Boolean; Prosedyren RenameMethod (konst CurName, newname: string); Prosedyren SelectComponent (Instance: TPersistent); Prosedyren ShowMethod (konst Navn: string); fungere GetComponent (konst Navn: string): TComponent; funksjon CreateComponent (ComponentClass: TComponentClass; Parent: TComponent, Venstre, Topp, Bredde, Høyde: Integer): TComponent;
    Noen av de ovennevnte samtalene er ganske elementære, MethodExists for eksempel vil returnere Sant eller usant avhengig av hvorvidt en metode navn finnes allerede i form av den aktuelle enheten (FormCreate, Button1Click etc). ShowMethod vil flytte markøren til den navngitte metoden, og RenameMethod vil endre navnet på en metode
    De to metodene som er av interesse for å bruke på dette punktet er:.
    CreateComponent Gitt en komponent klasse, til en forelder holde komponenten, og posisjon /dimensjoner, vil designeren opprette en forekomst av klassen som om utvikleren hadde valgt det fra komponent-paletten og lagt den til skjemaet seg selv.
    Modifiserte Informerer designeren at noe har blitt endret (en Eiendommen etc). Dette endrer tilstanden til enheten slik at IDE vet det skal lagres før stengetid (det også gjør det mulig å spare knappen i IDE).
    Når du legger til elementer i vår rekke alt vi trenger å gjøre er å få TMyProperty.Designer å skape en komponent på våre vegne. Denne komponent vil deretter bli tilsatt til form og en hvilken som helst egenskap som refererer til en klasse av denne typen vil automatisk være klar over det. I tilfelle av TActionList og TDataSet komponentene som er lagt til skjemaet er ikke synlige på design-time, eieren komponent fungerer som en slags " manager " for komponentene.
    Under design-time vil du ikke se en TAction eller en TField komponent på komponentpaletten som ville muligens gjøre deg mistenker at de ikke er registrert, men IDE er fortsatt i stand til å opprette forekomster av disse komponentene (og de er heller ikke synlig). Svaret er ikke at de ikke er registrert, er dette problemet et resultat av " hvordan " komponenten er registrert.
    Mens RegisterComponents vil legge komponentene til komponenten paletten, den RegisterNoIcon metoden vil registrere komponenten uten å legge det til komponentpaletten, registrere på denne måten også forteller IDE at komponenten ikke skal vises under design-time.
    I følgende eksempel vil vi skape en komponent kalt en TWavSound (en ekstra komponent kalt TWavButton er inkludert i kildekoden som følger denne artikkelen som et eksempel). TWavSound vil bare holde data fra en WAV-fil, og spille av lyden på etterspørselen. Selv om det ville være enkelt for oss å slippe én TWavSound på vårt skjema for hver WAV lyd vi trenger, kan vårt skjema snart begynne å bli uhåndterlig, derfor vil vi også lage en manager klasse kalt TWavList.
    Hver teknikk som brukes i kildekoden til disse komponentene ble dekket i del to av denne serie av artikler, slik kildekoden ikke vil bli dekket i noen stor grad av detalj. Imidlertid vil jeg vise klasseerklæringer disse komponentene bare for å gi deg en idé om hvordan de er strukturert
    . Merk: På bunnen av enheten, innenfor initialisering delen av enheten du kanskje legge merke til følgende Kode:
    initialisering Register (TWavSound);
    Årsaken er at RegisterNoIcon ikke synes å gjøre en fullstendig jobb. Selv om det gir oss mulighet til å opprette forekomster av registrert komponent fra vår eiendom editor noe ser ut til å gå galt når et prosjekt er re-lastet med disse komponentene. A " Class ikke registrert " meldingsboks vises og prosjektet er skadet. I tillegg registrerer klassen på denne måten synes å fikse problemet
    TWavSound
    typen PWavData = ^ TWavData; TWavData = pakket posten Størrelse: Longint; Data: array [0..0] i byte; end;
    TWavSound = klasse (TComponent) private FWavData: PWavData; FWav: TWav; Prosedyren ReadWavData (Stream: TStream); Prosedyren WriteWavData (Stream: TStream); beskyttede prosedyre DefineProperties (Filer: TFiler); styre; offentlig destructor Destroy; styre; prosedyre Clear; Prosedyren LoadFromFile (konst Name: TFilename); Prosedyren LoadFromStream (Stream: TStream); prosedyre Play; publisert slutten;
    FWavData Vil bli brukt til å lagre innholdet i WAV-filen en gang lastet fra en bekk eller en fil.
    Clear Vil frigjøre minne holder FWavData.
    Play Vil bruke sndPlaySound API kalle inn MMSystem.pas å spille data i FWavData.Data
    ReadWavData og WriteWavData Vil bli brukt internt av IDE når det er behov for å lese /skrive data lagret i FWavData
    DefineProperties Vil angi en ".. skjult " egenskap kalt WavData, og fortelle IDE som ReadWavData og WriteWavData bør brukes for streaming av data.
    FWav Er velges internt i TWav klassen når TWav.WavSound er satt til vår komponent. Årsaken er at denne samlingen elementet må bli frigjort når vår TWavSound komponenten er frigjort, for å stoppe den fra å peke på et ugyldig objekt
    TWavSound
    typen TWav = klasse (TCollectionItem) private FWavSound. TWavSound; Prosedyren SetWavSound (konst Verdi: TWavSound); beskyttet offentlig prosedyre Play; publisert eiendom WavSound: TWavSound lese FWavSound skrive SetWavSound; ende;
    SetWavSound Vil sikre at WavSound som den peker vil ha sin FWav riktig innstilt
    . TWavs Er en standard implementering av TCollection så vil ikke bli dekket i denne artikkelen. (Se del 2 av denne serien)
    TWavList TWavList er rett og slett en komponent som utgir en TWavs eiendom for å tillate oss å redigere listen over wavs på design-tiden.
    TWavsProperty TWavsProperty er eiendommen editor som er designet for å håndtere denne klassen. Selv om en standard TCollection redaktør ville bli mett (til et punkt) bestemte jeg meg for å lage en ny redaktør for å tillate spille /rydding av WAVs på design-time.
    Først jeg opprettet en ny enhet med et skjema i. Jeg . lagt noen TSpeedButtons og en TListBox å liste elementene i
    tillegg la jeg følgende elementer til Form klasse erklæring
    FWavs: TWavs; FComponent: TComponent; Thedesigner: IFormDesigner;

    FWavs vil holde en referanse til TCollection at vi redigerer.
    FComponent vil holde en referanse til den komponenten som eier samlingen. Som vår skjemaet vil ikke bli vist modally må vi lukke våre dersom denne komponenten er ødelagt (ved hjelp av varslingsmetoden vår form).
    Thedesigner vil holde en henvisning til løpende Designer objektet gått til vår eiendom editor. Dette vil bli brukt til å ringe CreateComponent, og til å velge våre skjulte TWavSound inn i objektet inspektør når et element er valgt i vår listeboksen.
    Faktisk Eiendommen redaktør er en veldig enkel en.
    Typen TWavsProperty = klasse (TClassProperty) offentlig funksjon GetAttributes: TPropertyAttributes; styre; funksjon GetDisplayName: string; prosedyre Edit; styre; ende;
    eneste virkelige metoden verdt å nevne her er den Edit metoden. Gjennomføringen av disse er
    prosedyre TWavsProperty.Edit; begynne hvis fmWavsEditor = null deretter fmWavsEditor: = TfmWavsEditor.Create (Application);
    med fmWavsEditor gjør begynne thedesigner: = Self.Designer; //Ikke glem SELF !!
    Caption: = Self.GetName;
    //Setup skjermen, og deretter vise form
    Edit (TComponent (GetComponent (0) ), TWavs (GetOrdValue)); ende; slutt;
    Først redaktøren skjemaet er opprettet (hvis det ikke allerede opprettet)
    ". thedesigner " av skjemaet er satt til Self.Designer. Ikke glem " Selv " her som TForm har også en designer egenskap som på dette punktet vil være null.
    GetComponent (0) anvendes til å hente den komponenten som eier eiendommen. FreeNotification kalles for denne komponenten for å sikre at vårt skjema er varslet om komponenten er ødelagt (slik at vi kan lukke vår form)
    GetOrdValue brukes til å hente klasseobjektet. (&Quot; wavs " eiendom ") som er å bli redigert, er resultatet typecast som TWavs.
    Edit metode som kalles er en del av TfmWavsEditor, det er en metode jeg lagt som rett og slett fjerner listeboksen og fylles elementene med navnene på de FWavs oppføringer. Det viser da skjemaet
    . Merk: Senere versjoner av Delphi retur TPersistent fra GetComponent funksjon, derfor resultatet må være typecast til TComponent.
    snakke med IFormDesigner Hoved to delene av denne editoren (unntatt for å avskjære WAV og spille WAV) er de delene der " thedesigner " er interaksjon med
    første del for å nevne bør være den delen hvor ". Nytt " knappen klikkes, er et nytt element lagt til samlingen, er en ny TWavSound lagt inn i vår skjemaets klasse erklæring, og til slutt TWavSound er valgt inn i objektet inspektør
    prosedyre TfmWavsEditor.sbNewClick (Sender: TObject.); Var Wav: TWav; WavSound: TWavSound; begynner //Legg til et element i samlingen
    Wav: = FWavs.Add;
    //Be thedesigner å opprette en ny TWavSound komponent for oss
    WavSound: = TWavSound (thedesigner. CreateComponent (TWavSound, null, 0, 0, 0, 0));
    //Sett Wav (CollectionItem) å peke på vår nye TWavSound komponent
    Wav.WavSound: = WavSound; Anmeldelser //Velg vår nye TSoundComponent inn i objektet inspektør
    //slik at den kan få nytt navn dersom det er ønskelig
    TheDesigner.SelectComponent (WavSound);
    //Internt oppdatere elementene i listeboksen
    RefreshList; lbItems.ItemIndex: = FWavs.Count-1;
    //Fortell IDE at noe har endret seg
    TheDesigner.Modified; slutt;
    andre del å nevne er der riktig TWavSound er valgt inn i objektet inspektør når et element er klikket i listeboksen
    prosedyren TfmWavsEditor.lbItemsClick (Sender: TObject.); begynne med lbItems gjøre hvis ItemIndex > = 0, så TheDesigner.SelectComponent (FWavs [ItemIndex] .WavSound); slutt;
    bilder Unngå tilgang brudd slutt må vi sørge for at vi ikke blir stående å registrere et objekt som ikke lenger er gyldig. Dette er ganske enkelt oppnås ved å følge de følgende to trinn

      Kontroller at vårt skjema varsles når komponenten som eier vår klasse eiendom er ødelagt.
    1. Styr varslingsmetoden vårt skjema og lukke skjemaet hvis relevant komponent er ødelagt
      For å sikre at vi blir varslet når komponenten er ødelagt:
      prosedyre TfmWavsEditor.Edit (AComponent: TComponent; AWavs: TWavs).; begynne //Først må vi fjerne varsling for gjeldende komponent
      hvis FComponent < > nil deretter FComponent.RemoveFreeNotification (Selv);
      //Nå må vi legge varsling for gjeldende komponent
      AComponent.FreeNotification (Selv); FComponent: = AComponent;
      FWavs: = AWavs; lbItems.ItemIndex: = -1; RefreshList;
      Show; slutt;
      Hva gjør du når en komponent er ødelagt:
      prosedyre TfmWavsEditor.Notification (AComponent: TComponent; Operation: TOperation); begynne arvet; hvis Operation = opRemove deretter begynne //Hvis eieren komponenten er ødelagt //skal vi lukke våre skjema
      if (AComponent = FComponent) deretter Lukk annet //Hvis den komponenten som er ødelagt //vi oppdatere vår liste bare incase det påvirker vår komponent
      if (AComponent er TWavSound) da RefreshList; ende; slutt;
      Oppsummering I denne artikkelen har vi dekket hvordan du skriver en komponent redaktør, vi deretter flyttet til å lage enkle eiendom redaktører, endelig vi dekket mer avanserte eiendoms redaktører (herunder minimal bruk av IFormDesigner grensesnitt). Alle de demonstrerte teknikker i denne artikkelen (og mer) har blitt brukt i mine DIB (enhetsuavhengig punktgrafikk) komponenter.
      Disse komponentene er tilgjengelige for gratis nedlasting fra http://www.StuckIndoors.com/dib og er åpne source (slik at eventuelle utbyggings bidrag vil bli verdsatt). Anmeldelser