> 静的なコントロールを用いる場合、
> ON_EVENT等でリソースIDとイベントNoを指定すれば、
> 単純に飛んできます。
>
> ただし、今回は動的にこのコントロールを作成したいもので、
> その際の関連付けの方法を探しているところです。。。
なるほど。。。
ようやく質問内容が分かりました。
そして、私では役に立たないと言うことも ^^;
> そして、私では役に立たないと言うことも ^^;
と、言いつつ、私が所有しているActiveXプロジェクトをデバッグしてみました。
なんとなくですが、
ActiveXコントロールを登録することにより、ON_EVENTがキックされるようになる
のかなぁ?そんな風に見えます。
で、登録するためのメソッドが CWnd::CreateControl() なのかな?
全部、憶測&未検証ですいません。
>静的なコントロールを用いる場合、
>ON_EVENT等でリソースIDとイベントNoを指定すれば、
>単純に飛んできます。
MFCだとこの辺は隠蔽されているけど、ダイアログ生成時に
内部で生成する IDispatch の実装(COleControlSite のインナークラス?)
との関連付けを行っているような感じです(自信なし)
ここでのイベントNoというのがDISPIDのことで実際には
このIDと引数が IDispatch::Invoke に渡されてきてイベントと認識しています。
(IDがどのメソッドに対応するかはタイプライブラリに書いてある)
>ただし、今回は動的にこのコントロールを作成したいもので、
>その際の関連付けの方法を探しているところです。。。
イベントの実装があるなら、GetContorolUnkown で得られるポインタから
QueryInterface で IConnectionPointContainer のポインタを得る。
IConnectionPointContainer::FindConnectionPoint で
IConnectionPoint のポインタが得られたら、Advise/Unadvise で
イベントとの関連付け/解除を行う。
・・・という手順をATL/MFCのヘルパー関数とかでもうちょっと簡略化できるかもしれま
せん。
subaruさん、bunさん
お返事有難うございます。
>イベントの実装があるなら、GetContorolUnkown で得られるポインタから
>QueryInterface で IConnectionPointContainer のポインタを得る。
>IConnectionPointContainer::FindConnectionPoint で
>IConnectionPoint のポインタが得られたら、Advise/Unadvise で
>イベントとの関連付け/解除を行う。
非常に分かり易い解説有難うございます。
COMの接続を試みてAtlAdvise/AtlUnadviseでしょうか。
これで関連付けを行っています。
ここまで来たので何とかなりそうな気がします。
sabaruさん有難うございます。
何とかイベントを受けることができました。
有難うございました。
興味深かったので、追跡調査してみました。
結果、以下の手順でできました。
(以下の例は、ダイアログベースアプリに、ActiveXをCreate()する場合)
1) ActiveXのラッパクラスを作成
VC++2005なら、[変数の追加]時に自動作成される。
私の場合、クラス名[CGrid], 変数名[m_Grid]とした <- m_Gridは静的生成
2) 動的生成用の変数を追加
私の場合、クラス名[CGrid], 変数名[m_TestGrid]とした <- m_TestGridは動的生
成
3) 動的生成するActiveXのリソースIDを定義
私の場合、以下のコードを追加
#define ID_TESTGRID (WM_APP + 1)
4) ダイアログのOnInitDialog()にて、ActiveXの動的生成
具体的には、以下のコードを追加
m_TestGrid.Create(_T(TestGrid),
WS_VISIBLE, CRect(10, 10, 420, 240), this, ID_TESTGRID);
5) ON_EVENTの追加
私の場合、以下のようなマッピングとしました
ON_EVENT(CxxxDlg, ID_TESTGRID, 24, CxxDlg::AfterEditGrid, VTS_I4 VTS_I4)
これで、上記ActiveXの対象イベントが発生すると、
CxxDlg::AfterEditGrid()
が呼ばれるようになりました。
>bunさん
なるほど。ActiveXのCreate()だけでマッピングでの
関連付けも行っていたのですね。
しかしマッピングの部分はマクロで固定の配列を作っていて
動的な配列の書き換えはできなさそう。
あらかじめ動的生成するコントロールの個数とIDがわかっていないと
使いづらいかもしれません。
同じIDでコントロールを作ることもできますね。。。
先ほどの書き込みは無視してください。
CDialogWnd::Createメソッドにそのような
機能があるんですね。
(実際にはCWndでしょうか。)
ActiveXの管理ラッパクラスをCWndで継承するような、
機構だと非常に簡単に作れそうですね。
非常に勉強になります。