VCのexeからVBのActiveX DLLを呼んでフォームをモーダル表示

解決


SS  2006-05-10 15:23:00  No: 61729  IP: 192.*.*.*

先日、
Activex DLLのイベントを拾うには?
という質問
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200604/06040044.txt
で回答いただきました。

おかげさまで、VB6.0で作ったActiveX DLLを、VC6.0のMFCで作ったexeから呼んでDLL内のフォームを表示し、そこでの発生イベントをVCのexe側で拾うこともできるようになりました。

ただ、そのActiveX DLL内のフォームをモーダルで表示した場合はうまくいくのですが、モーダレスで表示しようとすると、実行時エラーが起こってしまいます。

具体的には、


"実行時エラー '406': ActiveX DLL、ActiveX コントロール、またはプロパティ ページからこのホスト アプリケーションにモードレスフォームを表示することはできません。


というエラーです。
ActiveX DLL内で、フォームオブジェクトをshowメソッドで表示しようとしているところで発生します。

Set m_objfrmSampleX = New FrmSampleX
m_objfrmSampleX.Show vbModeless      ←ここで発生★


なお、
http://support.microsoft.com/?scid=kb;ja;233997&spid=3042&sid=88
を見て、


ActiveX DLL プロジェクトのプロパティ フォームで、[全般] タブにある [スレッド モデル] の値を [シングル スレッド] に変更します。その ActiveX DLL を再コンパイルし、MTS パッケージに配置し直します。


という解決方法を試してみたのですが、症状は変わりませんでした。
(「MTS パッケージに配置し直します」という部分がよくわからなかったので、ただビルドし直して、DLLを差し替えただけですが・・・)

ちなみに、VBで作ったexeで、同ActiveX DLLを呼んだ場合は、モーダルでもモーダレスでもうまく行きます。 
なので残るはVCの問題なのかなと思い、こちらに投稿させて頂きました。


OSはWindowsXPです。
宜しくお願い致します。

編集 削除
SS  2006-05-10 15:56:46  No: 61730  IP: 192.*.*.*

表題は、「モーダル表示」となっていますが、「モーダレス表示するには?」が正しいです。すみません。

編集 削除
SS  2006-05-11 09:54:11  No: 61731  IP: 192.*.*.*

これが近い内容でしょうか?
http://www.hey-to.net/ML-archive/vcppML/1999/msg05898.html

編集 削除
kure  2006-05-11 14:35:18  No: 61732  IP: 192.*.*.*

リンク先のKBにもありますが
まずはVB側でApp.NonModalAllowedをチェックしてみてください。
もしかしたらですが、
MTS以外にもこのKBに該当するライブラリが
読み込まれてるのかもしれません。

*MTS(Microsoft Transaction Server)らしい。IISに同梱されてる模様。

編集 削除
SS  2006-05-11 18:42:38  No: 61733  IP: 192.*.*.*

はい、VB製のActiveX DLL側でApp.NonModalAllowedを見てはみたのですが、falseになっていました。

ただし、VBで作ったexeから呼び出した場合、同じActiveX DLLの場所でログを出してもtrueになっていました。

やはりVCのexeからの呼び出しだとだめなようです。

編集 削除
kure  2006-05-11 19:01:00  No: 61734  IP: 192.*.*.*

MTSのほうは確認できました?
mmcでスナップインの追加にMTS関連のものが出ればMTSが
インストールされていると思われますので確認してみてください。

MTSでないとすれば後は他社製のライブラリを使っていないかとか
スレッドモデルが適切かとかかなぁ。。。
単純にメッセージポンプのスレッドがどこにあるかとか
そういう話なのかもしれませんが。。。

手元に現象を確認できる環境がないため、
私からはこれ以上はなんとも言えません。
識者の降臨を祈ります。

編集 削除
SS  2006-05-11 20:10:12  No: 61735  IP: 192.*.*.*

ありがとうございます。

mmcというのは初めて使ったのですが、特にMTS〜のような名前のものは追加候補に現れませんでした。
Microsoft Transaction Serverというのもありませんでした。

ところで、ここで言うKBとはどういう意味でしょうか?

編集 削除
kure  2006-05-12 00:36:31  No: 61736  IP: 192.*.*.*

KB = Knowledge Base
Microsoftでは「サポート技術情報」と訳していますね。

編集 削除
SS  2006-05-12 21:39:24  No: 61737  IP: 192.*.*.*

kureありがとうございます。


なお、
VCのexeからVBのActiveX DLLを呼んでフォームをモーダレス表示する方法
の件に関しては未だ回答募集中です。

編集 削除
SS  2006-05-15 14:25:47  No: 61738  IP: 192.*.*.*

http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdnaskdr/htm/drgui54.asp

上記URLの中ほど、
「ダイアログの不人情な様式」
という部分で、
同じような症状が、ActiveX DLLをActiveX EXEにすることで回避できるという話が出ています。

VCからのActiveX EXEの利用法は、
以前kureさんにご指導いただいた、
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200604/06040044.txt
と同様で良いのでしょうか?

編集 削除
kure  2006-05-15 14:49:16  No: 61739  IP: 192.*.*.*

Yes.

基本的にはなにも変わりません。
ActiveXを作る際のモード(オプション)とGUIDが再生成される
くらいで使う(VC++)側はそのままで大丈夫だと思いますよ。

編集 削除
SS  2006-05-15 20:29:51  No: 61740  IP: 192.*.*.*

ありがとうございます。

該当のActiveX DLLをバイナリ互換でActiveX EXEとしてビルドし直し、置き換えるだけでできました。
モードレス表示もイベント取得もうまくいっています。

ただ、画面終了時にクラスの
ReleaseDispatch

delete

IConnectionPointのUnadvise

IConnectionPointContainerのRelease

CoUninitialize
を行っているのですが、該当のActiveX EXEがタスクマネージャに残ったままになってしまいます。

何か後処理が足りないのでしょうか?

編集 削除
んー  2006-05-15 21:21:40  No: 61741  IP: 192.*.*.*

VB側で非表示のフォームが残ってたり
解放漏れがあったりしませんか?

編集 削除
SS  2006-05-16 11:34:48  No: 61742  IP: 192.*.*.*

ありがとうございます。
無駄なフォーム呼び出しがありました。
無くしたら残らなくなりました。

別の問題が残っているのですが、それは別途スレ立てました。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200605/06050042.txt

編集 削除