Activeフォームにイベントを追加する
概要

Activeフォームは Delphiで作成できる ActiveXコントロールの一種で, Delphiで作成したフォームをそのまま OCXに変換できます。Activeフォームを使えば, 普通は OCXに変換できない非ビジュアルコンポーネントや, ハンドルが無いコンポーネントを簡単に OCXに組み込むことができます。しかし, これらの非ビジュアルコンポーネントのイベントを OCXコンテナアプリが拾う方法は手動で組み込む必要があります。Activeフォームのイベントの流れはパっと見では難しく感じます。

Activeフォームは生成時に Initialize手続きが実行されます。
ここですべての公開用のイベントハンドラと VCLのイベントを関連付けています。

 procedure TSockclient.Initialize;
 begin
   OnActivate := ActivateEvent;
   OnClick := ClickEvent;
   OnCreate := CreateEvent;
   OnDblClick := DblClickEvent;
   OnDeactivate := DeactivateEvent;
   OnDestroy := DestroyEvent;
   OnKeyPress := KeyPressEvent;
   OnPaint := PaintEvent;
 end; - - - - - - - - - - - - - - - - - - - - -

公開するイベントの一覧はタイプライブラリの ディスパッチインターフェイスを見ればわかります。
以下のような定義です。

 + Project
   + Interface
   - DispatchInterface
     * OnActivate
     * OnClick
     * OnCreate
     * OnDblClick
     * OnDeactivate
     * OnDestroy
     * OnKeyPress
     * OnPaint
   + CoClass
   + Enum
   + Enum
   + Enum
   + Enum - - - - - - - -

これらのイベントはこの OCXの利用者用です。ですので VCLの OnActivateイベントとここでの OnActivateイベントの名前が同じである必要はありません。
VCL内でイベントが発生した時に, これらの利用者用のイベントを発生されるのは, 先ほどの Initialize手続きで代入, と言うか関連付けられている関数内で行います。 OnActivate なら ActivateEvent関数です。initialize手続きからさらに下の方にそのコードがあります。ActivateEvent関数は以下のように記述されています。

 procedure TSockclient.ActivateEvent(Sender: TObject);
 begin
   if FEvents <> nil then FEvents.OnActivate;
 end; - - - - - - - - - - - - - - - - - - - - - - - - - - -

FEventsオブジェクト?これは DispatchInterfaceのオブジェクトです。タイプライブラリで定義したイベントはこのインターフェイスの関数になります。それをただ呼び出しているだけです。FEventsは private宣言で定義してあり, implementation部最初の手続き EventSinkChangedで値を受け取っています。

 procedure TSockclient.EventSinkChanged(const EventSink: IUnknown);
 begin
   FEvents := EventSink as ISockclientEvents;
 end; - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - -

この手続きについてはヘルプを参照してください。

手順

では, 実際にイベントを追加してみます。Activeフォーム上にボタンを配置し, そのボタンをクリックされたら利用者プログラムにクリックイベントの通知を行うようにします。

1.[新規作成]-[ActiveXライブラリ]を選びます。これは ActiveX用のプロジェクトです。(ここでは Project1と言う名前を使用します。)

2.[新規作成]-[ActiveXフォーム]を選びます。フォームが表示されます。(ここでは ActiveFormXと言う名前を使用します。)

3.ボタン(TButton)を適当に配置します。(ここでは Button1と言う名前を使用します。)

4.[表示]-[タイプライブラリ]を選びます。ディスパッチインターフェイスにメソッドを追加します。IActiveFormXEventsを選び, "Method"ボタンをクリックします。名前を "OnBtnClick", 宣言を以下のようにします。

 procedure OnBtnClick; - - -

5."更新"をクリックします。

6.フォームのコードを表示し, private宣言に以下のコードを追加します。

 procedure BtnClickEvent(Sender: TObject); - - -

7.Initialize手続きに以下のコードを追加します。

 Button1.OnClick :=  BtnClickEvent; - - -

8.最後に以下の手続きを追加します。

 procedure TActiveFormX.BtnClickEvent(Sender: TObject);
 begin
   if FEvents <> nil then FEvents.OnBtnClick;
 end; - - - - - - - - - - - - - - - - - - - - - - - - - - -

実験

コンパイルが通ったら, [実行]メニューから [ActiveXサーバーの登録]を選びます。成功のメッセージが出たらこれを VB5で使ってみましょう。

1.VBを起動します。標準Exeを選択して新しいプロジェクトを用意します。

2.[プロジェクト]メニューから[コンポーネント]を選びます。

3.コンポーネントの一覧から先ほどの ActiveXフォームを探します。名前はプロジェクト名 + Libraryです。(Project1 Library)

4.ツールボックスから Activeフォームを選びフォームに貼り付けます。

5.Activeフォームをダブルクリックしてコードを開きます。デフォルトでは OnActivate が開くので OnBtnClick に変更します。

6.適当にコードを書いて実行します。うまく動作するはずです。