Please, somebody tell me that I made a mistake in this code.

Please, somebody tell me that I made a mistake in this code.
Otherwise it would mean that this has been broken since Delphi 6 days and nobody noticed.

---- report ----

The IOTAComponent method SetPropByName, when used for an integer property, always sets that property to 0 instead of the desired value.

constructor Tf_SetIntPropertyTest.Create(_Owner: TComponent);
var
i: Integer;
fe: IOTAFormEditor;
root: IOTAComponent;
cmp: IOTAComponent;
CmpName: string;
IntValue: Integer;
begin
inherited Create(_Owner);

fe := GetActiveFormEditor;
if not Assigned(fe) then begin
m_Output.Lines.Add('No active form editor');
end else begin
root := fe.GetRootComponent;
for i := 0 to root.GetComponentCount - 1 do begin
cmp := root.GetComponent;
if cmp.GetPropValueByName('Name', CmpName) then begin
m_Output.Lines.Add(CmpName + ': ' + cmp.GetComponentType);
if cmp.GetComponentType = 'TTimer' then begin
if cmp.GetPropValueByName('Interval', IntValue) then begin
m_Output.Lines.Add('Interval: ' + IntToStr(IntValue));
IntValue := 500;
if cmp.SetPropByName('Interval', IntValue) then begin
m_Output.Lines.Add('SetPropByName returned true');
if cmp.GetPropValueByName('Interval', IntValue) then begin
// --> here it returns 0, so the set operation did not set the new value
m_Output.Lines.Add('new Interval: ' + IntToStr(IntValue));
end;
end;
end;
end;
end;
end;
end;
end;

https://quality.embarcadero.com/browse/RSP-20895

Comments

  1. Thomas Bornhaupt In my tests, this happened with any integer property of any component I tried, not just TTimer.Interval. I chose to report it with TTimer.Interval because that was the one I found first and (thought I) could easily provide sample code (which turned out to be much more involved than originally planned).
    But to answer your Question: It doesn't matter whether Active is true or false.

    ReplyDelete
  2. If you set an initial interval (other than 0) for that TTimer, what does GetPropValueByName() return then?

    ReplyDelete
  3. Rik van Kekem The initial value of a TTimer for Interval is 1000.

    Thomas Mueller It looks like somewhere inside the code being called by SetPropByName something goes wrong as when debugging the IDE I can see TTimer.SetInterval being called with value being 0. My assembler knowledge is limited though to tell where exactly it goes wrong though :)

    ReplyDelete
  4. Does casting IOTAComponent.GetComponentHandle to the TTimer work? I.e. TTimer(cmp.GetComponentHandle).Interval := 500; ?

    ReplyDelete
  5. B.T.W. TTimer.Interval is a Cardinal and you use an Integer. SetPropByName uses the raw value and doesn't convert. Maybe that's why it's not working.

    ReplyDelete
  6. Rik van Kekem one workaround is to get the native component and use RTTI to set the property. That's the bug fix I made in the Rename Components Expert in GExperts.

    ReplyDelete
  7. Rik van Kekem regarding integer vs. cardinal: They are binary identical for values greater or equal 0 and less than 2^31.

    ReplyDelete

Post a Comment