views:

87

answers:

3

Hi,

I would like to use a float property in my component, but set it to some non-zero default value (let's say it is 1000.0). If I try to do this in the Create, the property start to behave wildly since the default value for floats it 0 (see classes.TWriter.WriteProperty.WriteFloatProp.IsDefaultValue) so when I override some value with 0 in the form designer, delphi doesn't save this value (it's default in this case), but my Create will set it to 1000.0 when the compoent will be loaded the next time, so the actually I have the value I didn't set.

The problem is that there is no way to set default with 'default' directive (the compiler says 'Default values must be of ordinal, pointer or small set type') and it's also not possible to force storing with stored directive, it doesn't work (Delphi 5)

So is there a chance to find a workaround?

Thanks,

Max

A: 

As the compiler says, floating-point values cannot have a default value. The only thing I can think of is to store the floating-point value in a scaled integer. For instance, if you only need three decimals of yourFloat, you can store yourInt = 1000 * yourFloat instead. The default value would then be yourInt := 1000000, corresponding to yourFloat := 1000.000.

Of course, you can do this a bit more elegantly, like

  private
    FMyFloat: real;
    function GetValue: integer;
    procedure SetValue(Value: integer);

  published
    property MyInteger: integer read GetValue write SetValue default 1000000;

implementation

function TMyClass.GetValue: integer;
begin
  result := round(1000 * FMyFloat);
end;

procedure TMyClass.SetValue(Value: integer);
begin
  FMyFloat := Value / 1000;
end;

This way you will still only see the floating-point field FMyFloat from inside the class itself. But the property will be a scaled integer, and thus perfectly storable.

Andreas Rejbrand
Thanks, but unfortunately it should behave like float in the designer. Just thought that a string property (that accepts only correctly formatted floats) could be another alternative
Maksee
A: 

The Default value actually only tells the stream code what the default value is, and if it is that value, then it is not streamed. This saves having to stream all the default values. The component must actually set the default in the .Create anyway. The compiler does not do any magic to set the default for you.

In this case, it will not matter, as you can set the default value in your .Create constructor, and then just leave out the default in the definition. The value will always be stored, but it will work as you want.

mj2008
No, the actual code from VCL breaks my intentions. Look, if you change the value to 0 for float, the value won't be streamed. in this case there's no overriding of the property I set in Create. in other words my hand (when I pressed Enter) wanted to change some value to zero, but when the form is loaded it will return to my non-zero default (since there was no streaming).
Maksee
+1  A: 

Maybe you can used the stored directive:

property MyFloat: Float read GetValue write SetValue stored IsMyFloatStored;

with a Boolean function IsMyFloatStored that returns True iff MyFloat doesn't have its default value.

Ulrich Gerhardt
Ulrich, I hoped that it would help, but it looks like stored filter works before the default value processing so it can't be used to overwrite default comparison processing
Maksee