動的なCOMのイベント取得について – 固定ページ 2 – プログラミング – Home

動的なCOMのイベント取得について
 
通知
すべてクリア

[解決済] 動的なCOMのイベント取得について

固定ページ 2 / 2

bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

> 静的なコントロールを用いる場合、
> ON_EVENT等でリソースIDとイベントNoを指定すれば、
> 単純に飛んできます。
>
> ただし、今回は動的にこのコントロールを作成したいもので、
> その際の関連付けの方法を探しているところです。。。

なるほど。。。
ようやく質問内容が分かりました。

そして、私では役に立たないと言うことも ^^;


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

> そして、私では役に立たないと言うことも ^^;
と、言いつつ、私が所有しているActiveXプロジェクトをデバッグしてみました。

なんとなくですが、
ActiveXコントロールを登録することにより、ON_EVENTがキックされるようになる
のかなぁ?そんな風に見えます。
で、登録するためのメソッドが CWnd::CreateControl() なのかな?

全部、憶測&未検証ですいません。


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

>静的なコントロールを用いる場合、
>ON_EVENT等でリソースIDとイベントNoを指定すれば、
>単純に飛んできます。

MFCだとこの辺は隠蔽されているけど、ダイアログ生成時に
内部で生成する IDispatch の実装(COleControlSite のインナークラス?)
との関連付けを行っているような感じです(自信なし)

ここでのイベントNoというのがDISPIDのことで実際には
このIDと引数が IDispatch::Invoke に渡されてきてイベントと認識しています。
(IDがどのメソッドに対応するかはタイプライブラリに書いてある)

>ただし、今回は動的にこのコントロールを作成したいもので、
>その際の関連付けの方法を探しているところです。。。

イベントの実装があるなら、GetContorolUnkown で得られるポインタから
QueryInterface で IConnectionPointContainer のポインタを得る。
IConnectionPointContainer::FindConnectionPoint で
IConnectionPoint のポインタが得られたら、Advise/Unadvise で
イベントとの関連付け/解除を行う。
・・・という手順をATL/MFCのヘルパー関数とかでもうちょっと簡略化できるかもしれま
せん。


返信引用
飛んできたどらやき
 飛んできたどらやき
(@飛んできたどらやき)
ゲスト
結合: 15年前
投稿: 16
Topic starter  

subaruさん、bunさん
お返事有難うございます。

>イベントの実装があるなら、GetContorolUnkown で得られるポインタから
>QueryInterface で IConnectionPointContainer のポインタを得る。
>IConnectionPointContainer::FindConnectionPoint で
>IConnectionPoint のポインタが得られたら、Advise/Unadvise で
>イベントとの関連付け/解除を行う。

非常に分かり易い解説有難うございます。
COMの接続を試みてAtlAdvise/AtlUnadviseでしょうか。
これで関連付けを行っています。

ここまで来たので何とかなりそうな気がします。

sabaruさん有難うございます。


返信引用
飛んできたどらやき
 飛んできたどらやき
(@飛んできたどらやき)
ゲスト
結合: 15年前
投稿: 16
Topic starter  

何とかイベントを受けることができました。

有難うございました。


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

興味深かったので、追跡調査してみました。

結果、以下の手順でできました。
(以下の例は、ダイアログベースアプリに、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()
が呼ばれるようになりました。


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

>bunさん
なるほど。ActiveXのCreate()だけでマッピングでの
関連付けも行っていたのですね。

しかしマッピングの部分はマクロで固定の配列を作っていて
動的な配列の書き換えはできなさそう。
あらかじめ動的生成するコントロールの個数とIDがわかっていないと
使いづらいかもしれません。


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

同じIDでコントロールを作ることもできますね。。。
先ほどの書き込みは無視してください。


返信引用
飛んできたどらやき
 飛んできたどらやき
(@飛んできたどらやき)
ゲスト
結合: 15年前
投稿: 16
Topic starter  

CDialogWnd::Createメソッドにそのような
機能があるんですね。
(実際にはCWndでしょうか。)

ActiveXの管理ラッパクラスをCWndで継承するような、
機構だと非常に簡単に作れそうですね。

非常に勉強になります。


返信引用
固定ページ 2 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました