COMのイベントをVC++で受け取る方法

解決


よっち  2007-05-13 15:33:13  No: 65138

どなたかが作られた インプロセス動作のCOM オブジェクト(アプリA)
がありまして、そこから発行されるイベントを受信(アプリB)
したいとおもっております。

●IDLファイルはここにあります。(アプリA)
http://jm7muu.mydns.jp/index.php?plugin=attach&pcmd=open&file=EchoLink.IDL&refer=SoftTSQ-bugtrack%2F18

この中にあります、
HRESULT Closing();
をつかまえたいのです。

アプリケーションはSDKを使って作成しておりまして、
 (VisualC++.NET)  MFCを使わないで単純に このイベントを
つかみたいとおもっております。
最終的には、このイベントを受信して、自分のアプリBも終了させます。

今のところ、そのアプリとの通信はできています。
インスタンスを取得して
ret = CoCreateInstance(
  CLSID_EchoLinkSession, NULL, CLSCTX_LOCAL_SERVER, 
  IID_IEchoLinkSession, 
  reinterpret_cast<void **>(&g_pIEchoLinkSession) );

取得したポインタ (g_pIEchoLinkSession) をつかって、
設定などを行うことは既に行っていて、うまくいっています。

どんな手順で進めていったらよいでしょうか?

IDLファイルをコンパイルして出来上がった 二つのファイルを
include して使っています。
#include "EchoLink_h.h"
#include "EchoLink_i.c"

ファイルはこんなかんじです。
http://jm7muu.mydns.jp/index.php?plugin=attach&pcmd=open&file=EchoLink_h.h&refer=SoftTSQ-bugtrack%2F18
http://jm7muu.mydns.jp/index.php?plugin=attach&pcmd=open&file=EchoLink_i.c&refer=SoftTSQ-bugtrack%2F18

MSDNのサイトをのぞいていると、ATLを使うと楽にイベントシンクを行うことが出来るということは知りましたが使わずに行うと大変でしょうか?
(アプリB自体は 既にそれなりの形になっていて、今のところは MFCを使わない作りになっています。m(__)m  今になってから MFCを使うようにすることって、出来るのかな・・・)

よろしくお願いします。
以上です。


Blue  2007-05-13 21:41:40  No: 65139

Wordのイベントを拾うサンプルです。
http://support.microsoft.com/default.aspx/kb/309294/ja

Word自体はMFCのラッパークラスを使っていますけど、
MFCを使わないでもできます。


よっち  2007-05-17 15:24:34  No: 65140

MFCを使っていないサンプルは
どこかにございませんでしょうか?
m(__)m

初歩的な質問ですみません。
勉強中ですが、なかなか理解に苦しんでいます。
_hook とか つかいます?


Blue  2007-05-17 17:47:44  No: 65141

ちゃんと読みましたか?肝となる部分はMFCではないですよ?

1. IDispatchから派生したイベント用のクラスを作成
2. IDispatch::QueryInterfaceを使って、IConnectionPointContainer型ポインタを取得
3. IConnectionPointContainer::FindConnectionPointを使って、IConnectionPoint型ポインタを取得
4.1で作成したクラスをIConnectionPoint::Adviseで結びつける

で、MFCの部分は2のWordのIDispath型ポインタを取得するところだけです。
(CDispatchDiverのm_lpDispatchメンバを使って取得している。)

CoCreateInstanceをつかってIDispath型ポインタを取得しているなら
なんら問題ないのではないでしょうか?

>_hook とか つかいます?
どっからそんな情報を?


よっち  2007-05-19 03:07:49  No: 65142

Blueさん アドバイス有難う御座います。

> 1. IDispatchから派生したイベント用のクラスを作成
作りました。
> 2. IDispatch::QueryInterfaceを使って、IConnectionPointContainer型ポインタを取得

これは、MS-Wordの ポインタ型と思って良いでしょうか?
私の場合は 
g_pIEchoLinkSession ポインタを使って 
ディスパッチポインタを得ればよいのかなと思い、

ret = g_pIEchoLinkSession->QueryInterface(DIID__IEchoLinkSessionEvents, (void **)&g_pIEchoLinkEvents);

こんなことをしてみましたが、NoInterface が返ってきました。

CoCreateInstanceで取得しているのは、ディスパッチインタフェース
ではなく、単純なインタフェースポインタ(IID_IEchoLinkSession)かな?
と思ってみたりしています。

お手数をおかけします。
お心当たりの事が御座いましたら、
アドバイスお願いします。m(__)m


Blue  2007-05-19 03:50:59  No: 65143

2.は
>      IConnectionPointContainer *pConnPtContainer= NULL;
>      hr = m_wordApplication.m_lpDispatch->QueryInterface(
>         IID_IConnectionPointContainer,
>         (void **)&pConnPtContainer );
より

      IConnectionPointContainer *pConnPtContainer= NULL;
      hr = g_pIEchoLinkSession->QueryInterface(
         IID_IConnectionPointContainer,
         (void **)&pConnPtContainer );

ではないでしょうか?

同様に3.は
>         hr = pConnPtContainer->FindConnectionPoint(
>            IID_IApplicationEvents2,
>            &m_pConnectionPoint
>            );
         hr = pConnPtContainer->FindConnectionPoint(
            DIID__IEchoLinkSessionEvents,
            &g_pConnectionPoint
            );

4.は
>            m_pAppEventListener = new CAppEventListener();
>            m_pAppEventListener->AddRef();
>
>            // Set up advisory connection.
>            hr = m_pConnectionPoint->Advise(m_pAppEventListener, 
>               &m_dwConnectionCookie);
            g_pIEchoLinkEvents = new CIEchoLinkEventListener(); // 1.で作成したクラス

            g_pIEchoLinkEvents->AddRef();

            // Set up advisory connection.
            hr = g_pConnectionPoint->Advise(g_pIEchoLinkEvents, 
               &g_dwConnectionCookie);

では?


よっち  2007-05-19 16:35:37  No: 65144

なるほど。了解です。
早速やってみましたら、無事イベントを受信できるようになりました。

Blueさん ご助言有難う御座いました。
<m(__)m>

これを機に、さらにCOMに対する理解を深めておきたいと
思います。


よっち  2007-05-20 07:27:47  No: 65145

解決済みのチェックを
忘れていました。

有難う御座いました。


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

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






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