5

作成された MDI 子ごとにタブを割り当てる MDI アプリケーションを開発しています。メイン (親) フォーム コードで、子フォームの OnActivate、OnCreate、および OnDestroy イベントを「キャッチ」する必要があります。MDIの子として使用される多くのフォームのクラスがあり、プラグインは独自のフォームをロードすることもできるため、子フォームでコードを呼び出すだけでは不可能です...

だから、私の質問は:子フォームのイベントを使用せずに MDI 子フォームがアクティブ化/非アクティブ化されたことをキャッチする方法は?

4

2 に答える 2

3

私は何年も前に、まさにこのタイプのことを行うタスクバー タイプのコンポーネントを作成しました。これは TrmMDITaskbar と呼ばれます。Torrysでそのコピーを見つけることができます。これは rmControls ライブラリ パッケージの一部です。アクティベーション、最小化、最大化などを処理します。

それがどのように機能するかの要点は、MDIChild イベントを探して MDIParents ウィンドウ ハンドルをフックし、それらのイベントに基づいて処理を行うことです。

自分で書きたいと思っているなら、始めるのに良い場所としてそれをお勧めします。

ライアン。

PS Torrys のバージョンは少し古いですが、まだ動作するはずです。サポート Web サイトで新しいバージョンを入手できます。(ミルズエンタープライズ)

于 2009-09-15T13:53:30.963 に答える
1

実行時にコードから「事後」にいつでもイベントをフックできます。基本的に、次のような汎用の OnActivate を作成します。

type
  TEventHolder = class
  private
    FSFActivate: TNotifyEvent;
  published
    property SavedFormActivate : TNotifyEvent 
        read FSFActivate write fSFActivate;
  end;

type
  TMainForm = class(Tform)
    :
    SavedEvents : tStringList;
    procedure ChildFormActivate(Sender: TObject);
    procedure InitChildForm(MdiForm:TForm);
  end;

procedure TMainForm.ChildFormActivate(Sender: TObject);
var
  i : integer;
begin
  // your special processing here this is called for the child form.
  i := SavedEvents.IndexOf(ClassName);
  if i <> -1 then
    tEventHolder(SavedEvents.Objects[i]).SavedFormActivate(Sender);
end;

procedure TMainForm.InitChildForm(MdiForm:TForm);
var
  OrigEvents : TEventHolder; 
begin
  if not Assigned(SavedEvents) then
    SavedEvents := tSTringlist.create;
  if Assigned(MdiForm.OnActivate) then
    begin
      OrigEvents := tEventHolder.create;
      OrigEvents.SavedFormActivate := MdiForm.OnActivate;
      SavedEvents.AddObject(MdiForm.ClassName,OrigEvents); 
    end;
  MdiForm.OnActivate := ChildFormActivate;
end;

次に、InitChildForm を呼び出して、プログラムのある時点でイベント ハンドラーを汎用バージョンに設定します (ほとんどの場合、フォームを作成した直後)。もちろん、メイン フォームを閉じると、SavedEvents (およびリンクされたオブジェクト) を解放する必要があります。

于 2009-09-15T16:21:45.513 に答える