非同期のActiveX EXEでデータのやりとりをするには?

解決


紅閃光  URL  2008-09-21 04:30:51  No: 101104

環境:VB6+WinXP(+BASP21.FTPオブジェクト)

非同期で動作するActiveX EXEを作ろうとしています。

ActiveX EXEにはフォームとタイマーコントロールを貼り付けておき、
クラスイニシャライズイベントでフォームを呼び出します。
タイマーイベントでフラグをチェックします。

メインのexeからActiveX EXEを実体化し、メソッドが呼び出されたらフラグをONすることにより、タイマーイベントで非同期の時間のかかる処理を行う事はできそうです。

ActiveX EXE内のクラスからは自分で呼び出したフォームの変数にデータを渡すことは出来ましたが、
・フォームで処理が終わった後の結果データをクラスに返す方法
もしくは
・メインexeに渡す方法
がわかりません。

ActiveX EXEではどのようにデータをやり取りすれば良いのでしょうか?


K.J.K.  2008-09-24 21:33:25  No: 101105

イベントを使うとか。


紅閃光  URL  2008-09-27 06:42:08  No: 101106

ActivX EXE内のクラスからはイベントを出すにしろ制御の主体はActivXクラスから起動したフォームおよびインターバルタイマにあるわけで、
やはりActivXフォームからActivXクラスへアクセスする必要があると思いますが・・・

あ、それとも別のイベント用のクラスを作るということでしょうか。

似たような内容の過去ログはけーん
「ACTIVEX.EXEで独自イベントを発生させ、標準EXEでイベント処理するには?」
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200508/05080092.txt

この件は並列で動作させることが前提となってるので、
もともと
    Private Sub timFTP_Timer(Index As Integer)
        Dim Ftp As MyFtp.clsFtp
としていました。
インデックスの違う別のタイマーイベントでオブジェクトのインスタンスが自動的に量産されるので、オブジェクトが並列動作さえしてくれれば文句は無かったのですが・・・
「複数のFTPサーバーから並列でファイルをゲットするには」
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200809/08090017.txt

で、非同期で走らせるようにするわけですから、当然オブジェクトはモジュールスコープにならなければならないので、
    Private mFTP(15) As MyFtp.clsFtp
という風にしたいのですが、これだとイベントが受け取れません。

    Private WithEvents mFTP(15) As MyFtp.clsFtp    ・・・構文エラー
としたくても、
WithEvents ではオブジェクト配列を受け入れてくれないようです。
まぁ、その前に制御の主体がフォームなので、ActivXクラスのイベントが起こせないから困っているわけですが。

魔界の仮面弁士さまが別スレでおっしゃるとおり、
>今回の場合、通信クラスのインスタンスを共有せねばならないので、
>  案1. 標準EXE側でClassTestを生成し、それをActiveX EXE側でも使う。
>・・・外部で生成されたインスタンスをForm1が使えるよう、
>ClassTestを受け渡す為のメソッドを用意する、という手法があります。

やり方がサパーリだけど、これが出来ればActivXフォームはActivXクラスのインスタンスにアクセスは可能になるのかな・・・

だとすれば、メインフォームにイベントを投げるためのメソッドをActivXクラスに追加して、ActivXフォームからそれをコールすると・・・

なんかぐちゃぐちゃになってきちゃった・・・

クラスに制御の主体を持つことが出来れば楽なのに・・・

coffeeでも飲みこんでこよう・・・


魔界の仮面弁士  2008-09-27 09:45:20  No: 101107

> Private mFTP(15) As MyFtp.clsFtp
コントロール配列のように、イベント管理のコレクションを実装してみては。

たとえば、コマンドボタンのコントロール配列があったとします。
この場合のイベントは、
  Private Sub Command1_Click()
ではなく、
  Private Sub Command1_Click(Index As Integer)
で受け取りますよね。

また、コントロール配列の場合、個々の要素
  Debug.Print TypeName(Command1(0))
は『CommandButton』という型ですが、管理コレクションであるところの
コントロール配列そのもの
  Debug.Print TypeName(Command1)
は、CommandButton 型にはなっていませんよね。

それと同様で、個々の clsFTP にイベントを持たせるのではなく、
clsFTP のコレクションクラス側でイベントを持たせれば良いのかな、と。

http://groups.google.co.jp/group/fj.comp.lang.visualbasic/browse_thread/thread/32a42c7b0792ea17/b99ee3a25da1e244?hl=ja

> coffeeでも飲みこんでこよう・・・
# VB6 付属の coffee2.vbp サンプルを連想してしまった…。


紅閃光  URL  2008-09-28 19:26:37  No: 101108

もちろん、MSDNにあるcoffeeのことです(ノ∀`)ペチ
多少は飲み込めました。

さて、APIでタイマーオブジェクトを作成することでActivXクラスに制御の主体を持つことが出来ました。
これでActivXフォームを持つ必要が無いのでいろいろな問題がすっきりしました。

あとはオブジェクト配列ではイベントが受け取れない件です。

とりあえず
    Private WithEvents mFTP00 As MyFtp.clsFtp
    Private WithEvents mFTP01 As MyFtp.clsFtp
    Private WithEvents mFTP02 As MyFtp.clsFtp
        :
としました。

むー・・・番号違いのコードがたくさん・・・
本当はオブジェクトの数は動的に決定したいのですが・・・

そうするとやっぱりここでコレクションクラスの登場ですか。
でも作り方の情報が少ないのでチャレンジはまた別の機会にでも・・・

ま、なんにせよこれで非同期のActiveX EXEと並列でデータをやり取りすることが出来ましたので解決とさせていただきます。
なにかお気づきのことがあれば突っ込みお願いします。

どもありがとでした。


K.J.K.  2008-09-29 23:35:29  No: 101109

ActiveX EXE のクラスとして ClassA があり、それが FormB を所有して
いるのならば、 ClassA で、
Private WithEvents mfrmB As FormB
とすれば、 FormB から ClassA にイベントとして通知できますよね。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加