2008-09-27 80 views
3

我正在写Delphi专家。我需要能够写一个属性值属性是一个对象。例如。我在窗体上有一个GroupBox,我想编辑Margins.Left属性。我正在使用以下过程来做到这一点,但是如果在标记线上给出AV。Delphi OTA和RTTI bug

该过程从(属性编辑器)属性名称(例如'Margins.Left')和新值中抽取一个组件,解析出属性名称,获取对象,读取当前值并尝试更改它如果不同。然后它调用一个方法记录任何更改。

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; 

回答

3

Margins.xyzzy都是Integer属性,而不是Int64属性,因此您需要使用GetOrdProp/SetOrdProp来读取和修改它们。

SetInt64Prop假定它是一个64位属性,并尝试使用64位参数调用属性设置器函数。由于属性设置器需要32位参数,因此无法正确清理堆栈,从而导致AV返回。

您可以根据PropIsType调用来确定要调用哪些函数。

  • tkInt64:获取/ SetInt64Prop
  • tkInteger:获取/ SetOrdProp

获取/ SetOrdProp也可用于Char和WideChar性质,我的猜测是功能为什么名字不是100 % 明显。

3

你有没有尝试使用GetOrdProp,SetOrdProp代替GetInt64Prop,SetInt64Prop?

+0

谢谢。工作很好。 – 2008-09-27 19:35:20