0

シナリオは次のとおりです。

  • 質問するための COM オブジェクトがあります。名前はアイコム。
  • COM オブジェクトでは、イベントを通知する IComEvents の子孫である IDispatch を実装する必要があります。
  • IDispatch を実装し、それを COM インターフェイスに接続します。

ここまでは順調ですね。イベントが発生すると、私の IComEvents 子孫の Invoke() が呼び出されます。

ポイントは、Invoke() パラメーターを手動で解析する必要があるということです。たとえば、通知関数が HRESULT OnMouseHit(int x) の場合、DispID からこの関数を検出し、手動で呼び出す必要があります。

if (dispIdMember == 0xfa)
 {
 OnMouseHit(pDispParams->rgvarg[0].pIntVal); 
 }

実装したいすべての機能に対してそれを行う必要があります。ただし、おそらく自動的にこれを実行し、適切なパラメーターを使用して dispId の適切なオーバーロードされたメソッドを呼び出す DispInvoke() 関数を見ました。

DispInvoke(this,m_ptinfo,dispIdMember,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);

m_ptinfo を生成するにはどうすればよいですか? COM オブジェクトの libid を指定して LoadRegTypeLib を呼び出し、次に IComEvents の IID を指定して ITypeLib::GetTypeInfoOfGuid() を呼び出します。ただし、DispInvoke() は常に「メンバーが見つかりません」を返します。

何が間違っているでしょうか?DispInvoke が型情報を解析し、DispID からメンバー関数名を見つけてから、「this」ポインターを使用して vtbl から関数アドレスを取得することを期待しています。

私は何を間違っていますか?

どうもありがとう。マイケル。

4

1 に答える 1

0

IComEventsデュアル インターフェイスですか、それともディスパッチ インターフェイスですか? 純粋なディスパッチ インターフェイスの場合、vtable はありません。DispInvokeインターフェイスに vtable が必要です (つまり、デュアル インターフェイスである必要があります)。

于 2011-08-25T15:17:37.170 に答える