[Delphi]Waarom in 'Create' een tegenstelling met default?

Pagina: 1
Acties:

  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 14:45
Ik ben zelf bezig met een unit die een event afgeeft als er een cd wordt gewisseld, en die werkt ook. (gelukkig)
Maar ik merk iets geks op, wat zich ook voordoet in TTimer:

In de definitie van TTimer: (exctrls.pas)
Delphi:
1
2
3
4
...
  published
    property Enabled: Boolean read FEnabled write SetEnabled default True;
...


staat aan het einde default True

En in de 'create'-code:

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
constructor TTimer.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FEnabled := True;
  FInterval := 1000;
{$IFDEF MSWINDOWS}   
  FWindowHandle := Classes.AllocateHWnd(WndProc);
{$ENDIF}
{$IFDEF LINUX}   
  FWindowHandle := WinUtils.AllocateHWnd(WndProc);
{$ENDIF}   
end;


Staat FEnabled:=True. Ik heb zitten experimenteren, en het maakt niet uit, wat er in de property-definitie staat, het werkt zodra hij in Create ook wordt genoemd. Dus of er nou staat:
Delphi:
1
2
3
    property Enabled: Boolean read FEnabled write SetEnabled default True;
 ...
  FEnabled := True;

of
Delphi:
1
2
3
    property Enabled: Boolean read FEnabled write SetEnabled default False;
...
  FEnabled := True;


of maakt niet uit wat, het werkt altijd. De enige manier wanneer het niet werkt is als die laatste regel 'FEnabled:=...' wordt weggelaten.

Kan iemand mij de logica uitleggen, want ik snap de reden niet dat het steeds werkt.

* jvdmeer is tijden aan het debuggen geweest van zijn TCdChange, omdat ik de onderste regel niet had staan.

  • CyberSnooP
  • Registratie: Augustus 2000
  • Laatst online: 31-03 16:47

CyberSnooP

^^^^ schrijft --->

De Delphi-help hierover:
The optional stored, default, and nodefault directives are called storage specifiers. They have no effect on program behavior, but control the way runtime type information (RTTI) is maintained.

[knip]

When saving a component’s state, the storage specifiers of the component’s published properties are checked. If a property’s current value is different from its default value (or if there is no default value) and the stored specifier is True, then the property’s value is saved. Otherwise, the property’s value is not saved.
Ik vermoed dat jij gedrag voorspeld aan de hand van de naam "default". Help hebben die jongens (m/v) van Borland niet voor niks aan gewerkt.

|_____vakje______|


Verwijderd

Ik denk meer dat het een redundantie is in de code. Het is netjes om defaults te zetten, en het is netjes om je variabelen te initialiseren. Niet meer en niet minder.

Bij procedures en functies maakt het wel uit, omdat je dan in de aanroep ervoor kunt kiezen die variabele gewoon weg te laten (hij pakt dan de default).

//edit
toen ik dit typte stond CyberSnooP's reactie er nog niet. Zijn verklaring lijkt me beter :)

[ Voor 14% gewijzigd door Verwijderd op 19-12-2002 23:36 ]


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Zo als CyberSnoop al zegt. Als FEnabled hetzelfde is als die default waarde wordt ie niet opgeslagen in de DFM. De default zegt dus niets over de werking, maar is alleen een optimalisatie die gedaan kan worden. FEnabled wordt intern op Enabled gezetet, maar nadat de properties uit de DFM zijn ingeladen veranderd ie naar de waarde die ingesteld is door de programmeur. Dit is heel normaal voor componenten.

We adore chaos because we like to restore order - M.C. Escher


  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 14:45
ik zal de volgende regel uit mijn 1e posting nog even toelichten, want daar bestaat onduidelijkheid over:
De enige manier wanneer het niet werkt is als die laatste regel 'FEnabled:=...' wordt weggelaten.
Als ik FEnabled:=True weghaal uit de 'create' code, staat de timer ALTIJD uit, ongeacht wat ik in de properties invul.

En dat vond ik dus vreemd. Als je de waarde niet initieerd (ongeacht met welke waarde) in Create, wordt de waarde uit de property-inspector NIET overgenomen in de component. Hier zoek ik dus een verklaring voor.

Hetgeen Cybersnoop typte, was mij als gedrag al opgevallen. Wat er achter default staat, is in de property-inspector vet gedrukt als default.

  • CyberSnooP
  • Registratie: Augustus 2000
  • Laatst online: 31-03 16:47

CyberSnooP

^^^^ schrijft --->

jvdmeer schreef op 20 december 2002 @ 13:54:
Als ik FEnabled:=True weghaal uit de 'create' code, staat de timer ALTIJD uit, ongeacht wat ik in de properties invul.
En als je FEnabled := True er wel bij is hij dan wel uit te zetten met je property?

Het lijkt me sowieso handig dat je de "SetEnabled"-procedure code er even bijgeeft denk ik :)

|_____vakje______|


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

jvdmeer schreef op 20 december 2002 @ 13:54:
ik zal de volgende regel uit mijn 1e posting nog even toelichten, want daar bestaat onduidelijkheid over:

Als ik FEnabled:=True weghaal uit de 'create' code, staat de timer ALTIJD uit, ongeacht wat ik in de properties invul.

En dat vond ik dus vreemd. Als je de waarde niet initieerd (ongeacht met welke waarde) in Create, wordt de waarde uit de property-inspector NIET overgenomen in de component. Hier zoek ik dus een verklaring voor.

Hetgeen Cybersnoop typte, was mij als gedrag al opgevallen. Wat er achter default staat, is in de property-inspector vet gedrukt als default.
Het vetgedrukte (pas vanaf D7) is niet het enige en zeker niet van enig belang. De waarde wordt dus ook niet opgeslagen in de DFM. Ze worden weer uit de DFM geladen als je het component weer laad (scherm sluiten/openen, applicatie starten). De default waarde is niet de waarde waarop die property door Delphi automatisch geinitialiseerd wordt. Dat is, zoals ik al eerder zei, de taak van de programmeur.

Stap 1:
Stel je nu voor dat je alles laad zoals het is en je verwijderd alleen die FEnabled := True; in de Create die je noemt. Je gooit het aangepaste TTimer component op je form en daarmee wordt het component al gecreeerd door Delphi's designer. Default wordt het geheugen van een classe op 0 gezet. Dat betekend dat een Boolean de waarde False krijgt. FEnabled dus ook.

Stap 2:
Jij zet je Timer1.Enabled op True daardoor wordt intern ook FEnabled op True gezet en alles lijkt gewoon te werken. Je slaat je form op. De DFM wordt geschreven en Delphi komt op een gegeven aan op het punt dat je Enabled property weggeschreven moet worden. De default waarde is True zoals aangegeven en wordt vergeleken met de huidige waarde van Enabled. FEnabled is True en dat is dus gelijk met de default waarde. Niets wordt er dus opgeslagen in de DFM.

Stap 3:
Je sluit je form en je opend hem weer. Je component wordt weer gecreeerd en FEnabled (en daarmee Enabled) wordt, zoals we eerder zagen in stap 1, standaard False. Daarna wordt je DFM weer ingeladen, maar de property Enabled komt er niet in voor en wordt dus niet gezet en blijft dus op False!

Dat is wat er gebeurd. Had je zoals hoort FEnabled op True geinitaliseerd in de TTimer.Create had het wel gewerkt. Er had dan nogsteeds niets in de DFM gestaan, maar FEnabled stond al netjes op True.

Had je bij stap 2 Timer.Enabled op False gezet was Enabled := False in de DFM opgeslagen. De waarde is immers anders dan de default waarde True. Bij stap 3 kwam tijdens het laden van de DFM de instelling weer naar boven en wordt gezet.

Ik hoop dat het hoe en wat van de interne werking van een component nu een beetje duidelijk is :)

[ Voor 1% gewijzigd door LordLarry op 20-12-2002 20:21 . Reden: typo ]

We adore chaos because we like to restore order - M.C. Escher


  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 14:45
Bedankt, voor deze duidelijke uitleg

  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06-2025

Varienaja

Wie dit leest is gek.

Ik was laatst meer eens zelf een componentjes in elkaar aan het knoeien.

De default-waarde is de waarde die je in de property-editor ziet.

De waarde die je bij de OnCreate in een variabele stopt is een andere.

Je moet bij beide dingen exact hetzelfde invullen, anders gebeuren er rare dingen.

Siditamentis astuentis pactum.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 17:16

Tomatoman

Fulltime prutser

Varienaja schreef op 23 December 2002 @ 07:55:
De default-waarde is de waarde die je in de property-editor ziet.
Dat is onjuist, de default-identifier geeft aan dat als de property de defaultwaarde heeft, de waarde niet wordt gestreamd (bijvoorbeeld in een .dfm file). Alle andere waarden dan de defaultwaarde worden wel gestreamd.
Je moet bij beide dingen exact hetzelfde invullen, anders gebeuren er rare dingen.
Ook onjuist. Beide waarden mogen best verschillen.

Een goede grap mag vrienden kosten.


  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06-2025

Varienaja

Wie dit leest is gek.

Oh, dan heb ik het niet helemaal goed onthouden. Ik vond het in ieder geval nogal een geklier.

Wat me vooral opviel, was dat de default-waarde voor een property als 'Left' niet via de SetLeft-procedure werd toegekend. Daardoor was de interne variabele fLeft anders dan wat de property aangaf. Onlogisch.

Siditamentis astuentis pactum.


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 26-08 19:49

Creepy

Tactical Espionage Splatterer

Varienaja schreef op 23 december 2002 @ 18:47:
[...]

Oh, dan heb ik het niet helemaal goed onthouden. Ik vond het in ieder geval nogal een geklier.

Wat me vooral opviel, was dat de default-waarde voor een property als 'Left' niet via de SetLeft-procedure werd toegekend. Daardoor was de interne variabele fLeft anders dan wat de property aangaf. Onlogisch.
Ook dit lijkt me sterk, tenzij je left property niet de fleft uileest... overigens benader je normaal gesproken properties in je object zelf rechtstreeks (dus fleft:=..), en niet via de get/set procedures.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney

Pagina: 1