動的なCOMから飛んできたイベントによって
処理を行いたいです。
例えば
COM生成がされているのを前提として
以下のCalcメソッドの関連付け(実際の関数の受け口)は
どうやって実装すればいいのですか?
struct __declspec(uuid(d1890a6c-b213-11d4-afc1-00d0b7ad59e8))
_Class1 : IDispatch
{
//
// Raw methods provided by interface
//
virtual HRESULT __stdcall Calc (
long x,
long y,
long * _arg3 ) = 0;
};
ご教授お願いします。
この場合、Calc を呼ぶとその中からイベントが発生するのですか?
説明不足ですみません。
OCX側からCalcを呼び出し、
OCXをディスパッチしている
メインプログラム側が受け取るパターンです。
いくつか方法があるようですが、
現在作成しているプロジェクトですと
tlhファイル、tliファイルにそのヘッダ情報らしき、
コードがコンパイル毎に作成されます。
その内容をメインプログラム側と関連付ける方法が
分かればなんとかなりそうですが、、、
(継承クラスの作成??)
ご存じでしたら教えて頂けませんか?
んーと…やっぱりよくわかりません。
COM でイベントを扱う際のキーワードをいくつか挙げておきます。
・IConnectionPoint / IConnectionPointContainer インターフェイス
・IDL の [source] 属性
COMのイベントは IDispatch::Invoke で呼び出されるので
イベント受信用のクラスを自分で用意することになります。
(それを IConnectionPoint::Advise で登録する)
#tlh/tliファイルに生成されたものの使い方は私も知りません。
お返事ありがとうございます。
COMの事についてあまり理解していないもので、
どうすればといった状況です。。。
今、OCXに関連したヘッダファイルがあり、
それをもとにどのように使えばいいのか探しています。
その中ではPreSubclassWindowメソッドないで
QueryInterfaceを読んでいます。
おそらく#importしているので
>・IDL の [source] 属性
を用いた方法で扱ってるのではないかと、考えてます。
>COMのイベントは IDispatch::Invoke で呼び出されるので
>イベント受信用のクラスを自分で用意することになります。
>(それを IConnectionPoint::Advise で登録する)
現在COMの呼び出しイベントは設けてあり、
使えるのですが、今回のようなイベント受信用の機能を追加するときも、
改めてクラスを作成するのでしょうか?
なんとも、分かりずらい説明になってしまってすみません。。。
>現在COMの呼び出しイベントは設けてあり、
>使えるのですが、今回のようなイベント受信用の機能を追加するときも、
>改めてクラスを作成するのでしょうか?
_Class1::Calc は自分で呼ぶものではなくメインプログラム側で
ocxのイベントととして呼ばれることを期待しているということですよね?
しかし _Class1 を実装しようとしても結局コンパイラに
IDispatch を実装しろって怒られてしまうと思うのですが・・・
#だから使い方がよくわからない
なのでイベントの実装は _Class1 から派生して作っても
IDispatch から直接派生して作ってもたいした違いは
ないんじゃないかと思えるのです。
うーん、
COMのことはよく分からないのですが、
>今、OCXに関連したヘッダファイルがあり、
>それをもとにどのように使えばいいのか探しています。
というなら、まず
1.提供されたファイル(どんな拡張子のものか)を掲示したほうがいいですね。
2.提供者は、会社の関連の方ですか?、ネットからダウンロードしてきたか?
製品として購入(ダウンロード販売も含む)
3.提供者はどうのようにリンクするか言ってきてますか?
4.もともと、VBようですか?
について情報を掲示したほうがいいと思います。
>今、OCXに関連したヘッダファイルがあり、
というのは単にタイプライブラリから
生成されたファイルのことと解釈してました(?)
イベントを拾うために最低限必要なのは
IUnknown の実装と IDispatch::Invoke の実装です。
(他は E_NOTIMPL を返すようにしておけばよい)
#必要な ID などは OLE/COMオブジェクトビューアで確認できます。
COMのイベント呼び出しの仕組みはこちらです。
http://msdn.microsoft.com/ja-jp/library/cc482696.aspx
皆様、本当にお返事有難うございます。
>_Class1::Calc は自分で呼ぶものではなくメインプログラム側で
>ocxのイベントととして呼ばれることを期待しているということですよね?
はい、その通りです。
また、COMイベントの仕組みについて見させて頂きました。
> 1.提供されたファイル(どんな拡張子のものか)を掲示したほうがいいですね。
> 2.提供者は、会社の関連の方ですか?、ネットからダウンロードしてきたか?
> 製品として購入(ダウンロード販売も含む)
> 3.提供者はどうのようにリンクするか言ってきてますか?
> 4.もともと、VBようですか?
提供ファイルはOCXとヘッダファイルです。
取得・設定関数にてget=xxx , put=yyyと記述されているので、
おそらくVBかと思います。
>なのでイベントの実装は _Class1 から派生して作っても
>IDispatch から直接派生して作ってもたいした違いは
>ないんじゃないかと思えるのです。
>イベントを拾うために最低限必要なのは
>IUnknown の実装と IDispatch::Invoke の実装です。
>(他は E_NOTIMPL を返すようにしておけばよい)
>#必要な ID などは OLE/COMオブジェクトビューアで確認できます。
今回、提供ヘッダファイル側でCreateInstanceを行い、
QueryInterfaceで読みだしているので、
IDispatch::Invokeとは異なる方法で読みだしているのでは?
と解釈しているのは誤りでしょうか。。。
>今回、提供ヘッダファイル側でCreateInstanceを行い、
>QueryInterfaceで読みだしているので、
>IDispatch::Invokeとは異なる方法で読みだしているのでは?
>と解釈しているのは誤りでしょうか。。。
CreateInstanceしているのはイベントを呼ぶ側の
オブジェクトのことですよね。
(その実態から得られるインターフェースを通じて
操作できるだけでIDispatchかどうかは関係ない)
イベントの実体はOCX側から提供してもらうものではなく
あなたが提供するものです。
イベントとかが話に出てくるので、
単純なCOMではなく、ActiveXのようなものかな?
そうだとして、見えてこないのが、
処理を実装したいのは、
ActiveX側のプロジェクト?
それともActiveXを使用する側のプロジェクト?
想像だけで話してるので大きく外していたらすいません。
OCXファイルとのなので ActiveXコントロールのことだと思われます。
ただ、COMで起動した Internet Explorer のイベント処理方法と
WebBrowser コントロールのイベント処理方法が同じであることを考えると
コントロールかどうかというのは重要なことではないかもしれませんが。
VBなんかだと画面に貼り付けるだけで簡単にイベント処理できるけど
これはそのような仕組みが用意されているからでしょう。
#importで自動生成される tlh/tliファイルが
IDispatch::Invoke から各メソッドにリダイレクトするような
実装まで用意してくれていれば簡単なのですが
どうやらそこまでは面倒見てくれないようです。
ATLクラス(IDispEventImplなど?)を使えばMFCのメッセージマップの機能のような
ものも使えるようなのでもう少し簡単になるかもしれません。
皆様、コメント本当に有難うございます。
あれから、過去ログ等を参考にしながら、
COM機能の習得にいそしんでいます。
>イベントとかが話に出てくるので、
>単純なCOMではなく、ActiveXのようなものかな?
>OCXファイルとのなので ActiveXコントロールのことだと思われます。
はい、通常はダイアログリソース等にコントロールを張り付けて
動作させるので、ActiveXコントロールです。
>ATLクラス(IDispEventImplなど?)を使えばMFCのメッセージマップの機能のような
>ものも使えるようなのでもう少し簡単になるかもしれません。
静的なコントロールを用いる場合、
ON_EVENT等でリソースIDとイベントNoを指定すれば、
単純に飛んできます。
ただし、今回は動的にこのコントロールを作成したいもので、
その際の関連付けの方法を探しているところです。。。
どこかで(Invoke等を用いて)イベント通知の割り当てを
するような感じかなぁと考えてますが。。。