11

Delphiオブジェクトインスペクタは、設計上、TFrameの子孫の追加のプロパティを表示しません。人々は、オブジェクトインスペクターでTFormの子孫のプロパティを表示するために一般的に使用される既知のトリックを使用することを提案する傾向があります。秘訣は次のとおりです。TFormの子孫のカスタムモジュールを次のようなデザインタイムパッケージを介してDelphiIDEに登録します。

RegisterCustomModule(TMyFrame, TCustomModule);

オブジェクトインスペクターは、この方法でTFrame子孫のインスタンスの追加のプロパティを表示できますが、フォームに埋め込まれている間はフレームの動作を失います。再設計できず、サブコンポーネントのイベントを実装できず、子コントロールを受け入れます(これはできません)。ただし、独自の設計領域では正常に動作します。

DelphiIDEがTFrame専用に提供する動作のように見えます。それらはおそらく一種の一般的な施設ではありません。

フレームの動作を失うことなくこれを達成する他の方法はありますか?

Delphi2007を使用しています


@ Tondrej、

事前に感謝し、問題のコメントを読んでください。

frameunit.dfm:

object MyFrame: TMyFrame
  Left = 0
  Top = 0
  Width = 303
  Height = 172
  TabOrder = 0
  object Edit1: TEdit
    Left = 66
    Top = 60
    Width = 151
    Height = 21
    TabOrder = 0
    Text = 'Edit1'
  end
end

unit frameunit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls;

type
  TBaseFrame = Class(TFrame)
  protected
    Fstr: string;
    procedure Setstr(const Value: string);virtual;
  published
    Property str:string read Fstr write Setstr;
  End;

  TMyFrame = class(TBaseFrame)
    Edit1: TEdit;
  private
    // This won't be called in designtime. But i need this to be called in designtime
    Procedure Setstr(const Value: string);override;
  end;

implementation

{$R *.dfm}

{ TBaseFrame }

procedure TBaseFrame.Setstr(const Value: string);
begin
  Fstr := Value;
end;

{ TMyFrame }

procedure TMyFrame.Setstr(const Value: string);
begin
  inherited;
  Edit1.Text := Fstr;
  // Sadly this code won't work and Edit1 won't be updated in designtime.
end;

end.

unit RegisterUnit;

interface

procedure Register;

implementation

uses
  Windows, DesignIntf, frameunit;

procedure Register;
var
  delphivclide: THandle;
  TFrameModule: TCustomModuleClass;
begin
  delphivclide := GetModuleHandle('delphivclide100.bpl');
  if delphivclide <> 0 then
  begin
    TFrameModule := GetProcAddress(delphivclide, '@Vclformcontainer@TFrameModule@');
    if Assigned(TFrameModule) then
    begin
      RegisterCustomModule(frameunit.TBaseFrame, TFrameModule);
      // Just registering that won't cause Tmyframe to loose its frame behaviours
      // but additional properties won't work well.

      //RegisterCustomModule(frameunit.TMyFrame, TFrameModule);  
      // That would cause Tmyframe to lose its frame behaviours
      // But additional properties would work well.

    end;
  end;
end;


end.
4

4 に答える 4

4

フレームに登録しているカスタム モジュール クラスはどれですか? どのバージョンの Delphi を使用していますか?

Delphi 2007 での私の実験から、機能しているように見えるカスタム モジュール クラスは TFrameModule です。このクラスは、delphivclide100.bpl に含まれています。対応する delphivclide.dcp がないため、手動でロードする必要があります。

unit FrameTestReg;

interface

procedure Register;

implementation

uses
  Windows, DesignIntf,
  FrameTest;

procedure Register;
var
  delphivclide: THandle;
  TFrameModule: TCustomModuleClass;
begin
  delphivclide := GetModuleHandle('delphivclide100.bpl');
  if delphivclide <> 0 then
  begin
    TFrameModule := GetProcAddress(delphivclide, '@Vclformcontainer@TFrameModule@');
    if Assigned(TFrameModule) then
      RegisterCustomModule(TTestFrame, TFrameModule);
  end;
end;

end.

私の FrameTest ユニットは非常に単純です。FrameTest.dfm はなく、新しい TFrame の子孫の宣言のみです。

unit FrameTest;

interface

uses
  Forms;

type
  TTestFrame = class(TFrame)
  private
    FHello: string;
  published
    property Hello: string read FHello write FHello;
  end;

implementation

end.

TFrameModule クラスを使用すると、これまでのところすべて正常に動作しているようです。TTestFrame の新しい子孫を作成してプロジェクトに含め、公開されたプロパティをオブジェクト インスペクタで編集し、この新しい子孫のインスタンスを IDE のフォームに配置し、新しく公開されたプロパティをオブジェクト インスペクタで編集し、イベント ハンドラを記述します。それらの子コンポーネントなど。これまでのところ問題は発生していないので、おそらくこれが解決策です。

于 2008-11-14T12:32:49.693 に答える
0
procedure TMyFrame.Setstr(const Value: string);
begin
  inherited;
  Edit1.Text := Fstr;
  // Sadly this code won't work and Edit1 won't be updated in designtime.
end;

設計時に機能しないはずだからだと思います。TBaseFrame をカスタム モジュールとして登録したので、設計時に編集できるのは TBaseFrame の (子孫ではありません!!!) プロパティです。Delphi IDE は、登録したクラスの公開されたプロパティのみを認識します。プロジェクトで作成した子孫とオーバーライドについては何も知りません。設計時にコードを機能させるには、TBaseFrame 定義にコードを含める必要があります。

procedure TBASEFrame.Setstr(const Value: string);
begin
  inherited;
  Edit1.Text := Fstr; 
end;

または (TBaseFrame に加えて) TMyFrame 定義をカスタム モジュールとして登録します。

理解しよう: 設計時の Delphi IDE は、そこに登録されていることしか認識していません。それはハンディキャップではありません。それは論理的な行動です。

于 2012-03-11T04:22:36.760 に答える
0

いいえ、これが完全に可能だとは思いません。

同様のニーズがある場合に私が通常行うことは、フレームの子孫を独自のコンポーネントとして単純にインストールすることです。しかし、そうすると、典型的なフレームの動作の多くが失われます (特に設計時)。たとえば、サブコンポーネントを直接操作できなくなり、フレームへの変更が設計時にそれを使用するフォームに自動的に反映されなくなります。最初にフレームを含むランタイム パッケージを再コンパイルします。

繰り返しますが、OOP の観点からは、これはそれほど悪くありません。実際には、実装の隠蔽の概念を強制します。フレーム自体の新しいプロパティとメソッドを介して、サブコンポーネントの個々のプロパティと機能を引き続き公開できます。

于 2008-11-14T12:27:24.060 に答える