カンタンOLEサーバー (ActiveX EXE)


ばやき...
 どうもソフトのバージョンアップというのは期待感より不安感が大きいものです。
 バージョンアップ費用は言うまでもなく使いもしない機能ばかりが増え、悪けりゃせっかく覚えた機能すら変更されて頭の切り替えもしなけりゃならない。おまけにシステムが重くなり気分も・・・
 特に開発ソフトの場合は問題がシビアです。提供されているライブラリの少しの変更でも、今まで使っていた機能が使えなくなったり動作がおかしくなったりするのは珍しくありません。
 うまく行けば少しの手直しで逃げられることもあるけど、悪くすれば大幅なプログラム変更とデバッグ、最悪の場合設計から見直しなんてことも........
 私が今作っているプログラムでもやっぱり問題は起きました。
 そのプログラムでは他のソフトと対になっていて、プログラム間通信をするのにDDEを使っていました。といっても「マクロ実行して」とか「ファイルを開いて」といった非常に簡単なものでした。本来DDE(DynamicDataExchange)というのはアプリケーションの間でデータを共有して、片方でデータが変更されると他方にそれをイベントとして通知するという目的のものなのですが、共有するデータがなくてもVB4では問題なく動いていました。
 しかし...VB6に以降したらイベントを受け取れなくなってしまったのです。ヘルプやMSのWEBを調べたところ、「DDE で行っていた処理がある場合は OLE オートメーションで実現可能かどうかを、検討することをお勧めします」とのこと。あれこれ悩んでいても始まらないので、恐る恐るOLE化することを検討し始めました(笑)
 ところがどっこい、やってみるとOLEサーバは以外にも簡単に作れるし、DDEからの移行もスムーズに行えることが分かりました。ここでは思い切り端折って、OLEサーバ(VB6ではActiveX EXEと呼んでいる)の作成法のエッセンスを紹介します。


さて、本題に入りましょう。
(今回のサンプルプロジェクトはここを押すとダウンロードできます)

 まずVBを立ち上げ、新規プロジェクトで"ActiveX EXE"を選択、するとクラスモジュールが一つだけのプロジェクトが作成されます。
 これがOLEサーバになります。

メニューからプロジェクトのプロパティを開きます。

プロジェクト名、プロジェクトの説明を入力します。
プロジェクト名に入力した名前はOLEクライアントから参照する名前になります。
ここでは「SvrTest」とします。説明は参照設定で表示されるテキストになりますので適当で構いません。
クラスモジュールのプロパティ
オブジェクト名を「SvrClass」とします。
OLEクライアントから参照する場合、上のプロジェクト名と併せて、"SvrTest.SvrClass"となります。
Instancingプロパティは"5"にしておきます。


設定が済んだら、エディタで以下のコードを入力します。

Option Explicit

Public Sub TestCall()
 MsgBox ("Test OK!")
End Sub

Property Get SvData()
 Randomize (Time / 2)
 SvData = Int(Rnd * 10)
End Property


プログラムを実行すると、

というダイアログが出ますので、「コンポーネントが作成されるまで・・・」を選んでOKボタンを押します。
で、この状態だと何も起こっているように見えませんので、VBの終了ボタンで終了させます。
最後にEXEファイルを作り、プロジェクトを保存してサーバーの作成は終わりです。


次に新規プロジェクトで「標準 EXE」を選択します。
こちらはOLEのクライアントになります。

フォームにボタンとラベルを一つずつ乗せます。
ボタンのコードに、

Private Sub Command1_Click()
 Dim SvrObj As Object
 Set SvrObj = CreateObject("SvrTest.SvrClass")
 SvrObj.TestCall
 Label1.Caption = SvrObj.SvData
End Sub

を記述。できたら実行してボタンを押してみて下さい。
「OK!」というメッセージボックスが出て、ラベルの所に何か数字が表示されればOKです。
非常に簡単ですが、これで2つのアプリケーション間で通信が行われているのです。


それではプログラムの解説です。まずはサーバから。
最初に設定したプロジェクト名、(クラスの)オブジェクト名により、レジストリに"SvrTest.SvrClass"という名前のOLEサーバが登録されます。他のアプリケーションからは、"SvrTest.SvrClass"というオブジェクトを作ることにより、アウトプロセスでOLEサーバが起動されます。
ちなみにアウトプロセスとは呼び出したアプリケーションとは別のプロセスでサーバが起動されるEXEファイルで、インプロセスは同じプロセス内に起動されるDLLファイルです。

以下にサーバとクライアントのコードを並べ、対応を示します。

クライアントのCommand1_Click() サーバの対応するコード  
Dim SvrObj As Object
Set SvrObj = CreateObject("SvrTest.SvrClass")
  OLEサーバをオブジェクトとして作ります。
この時点でサーバが起動されます。
SvrObj.TestCall
Public Sub TestCall()
 MsgBox ("Test OK!")
End Sub
TestCall はサーバのメソッドです。
SvrObj.TestCall でオブジェクトのメソッドを呼び出しています。
Label1.Caption = SvrObj.SvData Property Get SvData()
 Randomize (Time / 2)
 SvData = Int(Rnd * 10)
End Property
SvData はプロパティです。
プロパティが参照される、Property Get が呼び出されます。
サーバ側では乱数を初期化して返しています。

クラスを使ってのプログラミングが初めての人にはには、見慣れないPropertyという語が出てきましたが、要はフォームコントロール等のプロパティと同じです。
普通Propertyは変数と結びつけて、値を取り出したり保管したりするのですが、今回は乱数を取り出すだけなのでFunctionのように直接値を返しています。値を保管する場合、普通の変数なら Property Let Property Let 、Object変数ならProperty Set を使用します。


以上で簡単なOLEサーバの作り方と使い方は終わりです。さらに詳しい解説はMSDNの"ActiveX コンポーネントの作成方法 "にあります。
MSDNではサーバを参照するのにプロジェクトの「参照設定」でさらに簡単にしていますが、上でObjectを使ったのには理由があります。下の絵を見て下さい。

これはエクセルのVBAでサーバを参照したものです。Objectを使っているため、VB6のクライアントプログラムからエクセルへの移植は非常に簡単です。
OLEオートメーションは応用範囲が広く、利用価値が高いと思いますので、是非がんばって研究してください。

戻る