Domanda
Sto scrivendo un esperto di Delphi. Devo essere in grado di scrivere un valore su una proprietà su una proprietà che è un oggetto. Per esempio. Ho un GroupBox nel modulo e voglio modificare la proprietà Margins.Left. Sto usando la seguente procedura per farlo, ma se fornisce un AV sulla linea contrassegnata.
La procedura prende un componente da (editor della proprietà) il nome della proprietà (ad esempio 'Margins.Left') e il nuovo valore, analizza il nome della proprietà, recupera l'oggetto, legge il valore corrente e tenta di cambiarlo se diverso. Quindi chiama un metodo per registrare eventuali modifiche.
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;
Soluzione
Margins.xyzzy sono tutte proprietà Integer, non Int64, quindi è necessario utilizzare GetOrdProp / SetOrdProp per leggerle e modificarle.
SetInt64Prop presuppone che sia una proprietà a 64 bit e prova a chiamare la funzione setter proprietà con un parametro a 64 bit. Poiché il setter di proprietà si aspetta un parametro a 32 bit, non riesce a ripulire correttamente lo stack e quindi provoca l'AV al ritorno.
Puoi dire quali funzioni chiamare in base alla chiamata PropIsType.
- tkInt64: Get / SetInt64Prop
- tkInteger: Get / SetOrdProp
Le funzioni Get / SetOrdProp possono essere utilizzate anche per le proprietà Char e WideChar, il che immagino sia il motivo per cui il nome non è ovvio al 100%.
Altri suggerimenti
Hai provato a utilizzare GetOrdProp, SetOrdProp invece di GetInt64Prop, SetInt64Prop?