【问题标题】:Delphi OTA and RTTI bugDelphi OTA 和 RTTI 错误
【发布时间】:2008-09-27 16:24:51
【问题描述】:

我正在编写一个 Delphi 专家。我需要能够将值写入作为对象的属性上的属性。例如。我在表单上有一个 GroupBox,我想编辑 Margins.Left 属性。我正在使用以下过程来执行此操作,但如果在标记线上给出了 AV。

该过程从(属性编辑器)中获取一个组件的属性名称(例如“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;

【问题讨论】:

    标签: delphi plugins rtti


    【解决方案1】:

    Margins.xyzzy都是Integer属性,不是Int64属性,所以需要使用GetOrdProp/SetOrdProp来读取和修改。

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

    您可以根据 PropIsType 调用来判断要调用哪些函数。

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

    Get/SetOrdProp 函数也可用于 Char 和 WideChar 属性,我想这就是为什么名称不是 100% 明显的原因。

    【讨论】:

      【解决方案2】:

      您是否尝试使用 GetOrdProp、SetOrdProp 代替 GetInt64Prop、SetInt64Prop?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-05
        • 1970-01-01
        • 1970-01-01
        • 2012-09-22
        • 2011-04-27
        • 1970-01-01
        • 2013-06-19
        • 2010-09-15
        相关资源
        最近更新 更多