Delphi OTA 和 RTTI 错误

标签 delphi plugins rtti

我正在写一位 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;

最佳答案

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

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

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

  • tkInt64:获取/设置Int64Prop
  • tkInteger:获取/设置OrdProp

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

关于Delphi OTA 和 RTTI 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/143938/

相关文章:

java - 我的 pom.xml 包含此 maven-formatter-plugin,但未构建。我需要定义格式目标吗?

png - 如何知道 TPNGObject 是否具有有效的 header ?

delphi - 如何从 TListBox 中删除虚线焦点矩形?

css - 更改wordpress插件的按钮颜色

ios - Firemonkey iOS CFBundleExecutable 错误部署应用程序

macos - Mail.app 插件 - 工具栏按钮

C# var 有强类型吗?

c++ - RTTI 与 final 一起使用吗?

delphi - 项目中的匿名方法泄漏内存

delphi - 从 Variant String 转换为 Double 忽略小数点