4

以下に示すようなコードがあります:

インターフェイスセクション:

TControlOrganizer = class(TComponent)  // a kind of List of TControl
private
  FList : TList;  //Handling list of TControl
  ..............
end;

TControlHelperAdd = class // Just for separating value entered by user and value produced by code
  private
    FOrganizer : TControlOrganizer;
    FOrigValue : String;
    FUserValue : String;
end;

TControlHelper = class helper for TControl  //Basic helper for TControl
  private
    class var
      FAddProp : TControlHelperAdd;
  protected
    procedure SetOrganizer(Value : TControlOrganizer);
    function getOrganizer:TControlOrganizer;
  public
    class Constructor doinit;
    class Destructor deinit;
    procedure OrganizerChanged;virtual;
  published
    Property Organizer:TControlOrganizer read getOrganizer write setOrganizer; //Problem No.1
  end;

//Helper for CustomEdit inherited from TControlHelper
TCustomEditHelper = class helper(TControlHelper) for TCustomEdit
  protected
    procedure OrganizerChanged;override;
  end;
//TEdit : interceptor
TEdit= class(StdCtrls.TEdit)
  protected
    procedure Change;override;  //problem No.3
end;

実装セクション:

{TControlHelper}

class Constructor TControlHelper.doinit;
begin
  FAddProp :=TControlHelperAdd.Create;
end;

class Destructor TControlHelper.deinit;
begin
  FreeAndNil(FAddProp);
end;

procedure TControlHelper.OrganizerChanged;
begin
end;

procedure TControlHelper.SetOrganizer(Value : TControlOrganizer);
begin
  if FAddProp.FOrganizer<>value then begin
     if assigned(FAddProp.FOrganizer) then begin
       FAddProp.FOrganizer.remove(self);
     end;
     FAddProp.FOrganizer:=value;
     if assigned(FAddProp.FOrganizer) then begin
       FAddProp.FOrganizer.Add(self);
     end;
     OrganizerChanged;  //Problem No.2
  end;
end;

function TControlHelper.getOrganizer:TControlOrganizer;
begin
  result:=FAddProp.FOrganizer;
end;

{TCustomEditHelper}
procedure TCustomEditHelper.OrganizerChanged; //problem No.2
begin
  if assigned(FAddProp) then begin
    if assigned(Organizer) then begin
      FAddProp.FOrigValue:=Text;
      FAddProp.FUserValue:=Text;
    end;
  end;
end;

{TEdit = Interceptor} 
procedure TEdit.Change; //Problem No.3
begin
  inherited Change;
  FAddProp.FUserValue:=Text;
end;

自分では解決できない問題が3つ見つかりました。

問題1:公開されたプロパティプロパティがオブジェクトインスペクターに表示されません。私は間違いを犯し、ここで何かを忘れたと思います。

問題2:上記のようにクラスヘルパーからオーバーライドされたメソッドが起動しませんでした(機能しませんでした)。

問題3:上記のインターセプタークラスからオーバーライドされたメソッドが起動しませんでした(機能しませんでした)。

誰かが私がそれの何が悪いのかを見つけるのを手伝ってくれませんか?助けてくれてありがとう、そして私の英語が下手でごめんなさい。

4

4 に答える 4

8

問題1

ヘルパーで公開されたプロパティは、オブジェクトインスペクターに表示されません。

それは正しい。ヘルパーで宣言されたプロパティは、オブジェクトインスペクターに表示されません。

問題2

仮想メソッドは、クラスヘルパーには影響しません。

繰り返しますが、これは仕様によるものです。コンパイラーではヘルパーで仮想メソッドを定義できますが、効果はありません。TCustomEditHelper.OrganizerChanged発砲するTCustomEditHelperには、ターゲットオブジェクトのアクティブヘルパーである必要があります。

問題3

Changeインターセプトされたクラスのメソッドは起動TEditしません。

これは、インターセプトされたをインスタンス化していないためですTEdit。適切なクラス(定義したインターセプタークラス)をインスタンス化すると、そのメソッドが起動します。

于 2012-12-10T18:30:52.733 に答える
4

ヘルパークラスは、オブジェクトを最初のパラメーターとして受け入れる通常の非オブジェクト指向関数と考えることができます。ヘルパーを使用すると、これを非表示にして、メソッドを呼び出しているかのようにコーディングできます。それらを単純な関数として見ると、内部がないために、オブジェクトインスペクターや、オブジェクトの内部へのアクセスが使用される場所(仮想メソッドテーブル、ディスパッチメソッド、公開されたプロパティなど)に表示されない理由がわかります。オブジェクトに変更します。

于 2013-04-23T20:27:45.030 に答える
0

そのような決定はそれ自体を示唆しています。

TControlHelper = class helper for TControl
private
    function GetTest: Integer;
protected
    property Test: Integer read GetTest;
end;

TMyThing = class(TControl)
published
    property Test;
end;

デザインタイムプロパティにテストが表示されます。ただし、実際のプロジェクトをコンパイルすると、[dcc32 Fatal Error] F2084 Internal Error:AV0A967995(0A8F0000)-R00000000-0が発生します。

于 2021-07-11T10:35:23.077 に答える
0

しかし、私は解決策を見つけました。

TControlHelper = class helper for TControl
protected
function GetTest: Integer;
end;

TMyThing = class (TControl)
published
property Test: Integer read GetTest;
end;

Integer型はここでは条件付きであり、必要なクラスである可能性があります。そのインスタンスは、たとえば、最初の呼び出しで作成することによりTControlHelper、そこから切り取られます 。Spring.Services.ServiceLocatorキーは自己になります

于 2021-07-11T11:28:07.870 に答える