TObjectDispatch の保護された仮想メソッドを拡張しようとしています。しかし、このメソッドは呼び出されません。
[問題を再現するために編集]。
GetPropInfo をオーバーライドして TMyDispatch で使用すると、期待どおりに動作します。オーバーライドされたメソッドが呼び出されます。ただし、TMyDispatch によって作成されたときに TMyDispatchItem のオーバーライドされたメソッド (実際の例をシミュレートするため) は呼び出されません。
{$METHODINFO ON}
TExtDispatch = class(TObjectDispatch)
protected
function GetPropInfo(const AName: string; var AInstance: TObject;
var CompIndex: Integer): PPropInfo; override;
public
constructor Create;
end;
TMyDispatchItem = class(TExtDispatch)
private
FItemValue: string;
public
procedure ShowItemValue;
published
property ItemValue: string read FItemValue write FItemValue;
end;
TMyDispatch = class(TExtDispatch)
public
function GetItem: TMyDispatchItem;
private
FValue: string;
public
procedure ShowValue;
published
property Value: string read FValue write FValue;
end;
{$METHODINFO OFF}
TTestForm = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
TestForm: TTestForm;
implementation
{$R *.dfm}
procedure TTestForm.Button1Click(Sender: TObject);
var
V: Variant;
VI: Variant;
begin
V := IDispatch(TMyDispatch.Create);
V.Value := 100; //this calls inherited getpropinfo
V.ShowValue;
VI := V.GetItem;
VI.ItemValue := 5; //this doesn't
VI.ShowItemValue;
end;
{ TExtDispatch }
constructor TExtDispatch.Create;
begin
inherited Create(Self, False);
end;
function TExtDispatch.GetPropInfo(const AName: string; var AInstance: TObject;
var CompIndex: Integer): PPropInfo;
begin
Result := inherited GetPropInfo(AName, AInstance, CompIndex);
ShowMessage('GetPropInfo: ' + AName);
end;
{ TMyDispatch }
function TMyDispatch.GetItem: TMyDispatchItem;
begin
Result := TMyDispatchItem.Create;
end;
procedure TMyDispatch.ShowValue;
begin
ShowMessage('My dispatch: ' + Value);
end;
{ TMyDispatchItem }
procedure TMyDispatchItem.ShowItemValue;
begin
ShowMessage('My item value: ' + FItemValue);
end;
end.
TMyDispatch.GetItem
のデータ型を代わりにバリアントとして返すように変更することで、この問題を克服する方法を実際に見つけました。このような:
function TMyDispatch.GetItem: Variant;
begin
Result := IDispatch(TMyDispatchItem.Create);
end;
そして今、突然オーバーライドされたメソッドが呼び出されます。ここで何が起こっているのかを本当に理解したいと思います。
これ以上のアイデアや説明はありますか?