views:

451

answers:

2

I'm writing a Delphi expert. I need to be able to write a value to a property on a property which is an object. E.g. I have a GroupBox on the form and I want to edit the Margins.Left property. I'm using the following procedure to do it but if gives an AV on the marked line.

The procedure takes a component from the (property editor) the property name (eg 'Margins.Left') and the new value, parses out the property name, fetches the object, reads the current value and attempts to change it if different. It then calls a method to log any changes.

procedure EditIntegerSubProperty(Component: IOTAComponent;const PropName: String;NewValue: Integer);
var AnObject: TObject;
  TK: TTypeKind;
  At: Integer;
  AClassName, APropName: String;
  PropInfo: PPropInfo;
  OldValue: Integer;
begin
  At := Pos('.', PropName);
  if At < 1 then
  raise Exception.Create('Invalid SubProperty Name: '+PropName);

  AClassName := Copy(PropName, 1, At-1);
  APropName := Copy(PropName, At+1, length(PropName));

  TK := Component.GetPropTypeByName(AClassName);
  if TK <> tkClass then
    EXIT;

  AnObject := GetObjectProp((Component as INTAComponent).GetComponent, AClassName);
  if PropIsType(AnObject, APropName, tkInteger) then
  begin
    OldValue := GetInt64Prop(AnObject, APropName);
    if OldValue <> NewValue then
    begin
      SetInt64Prop(AnObject, APropName, NewValue);  <----AV HERE
      ChangeLogInteger(Name, PropName, OldValue, NewValue);
    end;
  end;
end;
+1  A: 

Did you try using GetOrdProp, SetOrdProp instead of GetInt64Prop, SetInt64Prop?

TOndrej
Thanks. Worked beautifully.
Mike Sutton
+2  A: 

Margins.xyzzy are all Integer properties, not Int64 properties, so you need to use GetOrdProp/SetOrdProp to read and modify them.

SetInt64Prop assumes it's a 64-bit property, and tries calling the property setter function with a 64-bit parameter. As the property setter is expecting a 32-bit parameter, it fails to clean up the stack properly and thus causes the AV on return.

You can tell which functions to call according to the PropIsType call.

  • tkInt64 : Get/SetInt64Prop
  • tkInteger: Get/SetOrdProp

Get/SetOrdProp functions can also be used for Char and WideChar properties, which I guess is why the name isn't 100% obvious.

Roddy