先日、
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です。
宜しくお願い致します。
表題は、「モーダル表示」となっていますが、「モーダレス表示するには?」が正しいです。すみません。
これが近い内容でしょうか?
http://www.hey-to.net/ML-archive/vcppML/1999/msg05898.html
リンク先のKBにもありますが
まずはVB側でApp.NonModalAllowedをチェックしてみてください。
もしかしたらですが、
MTS以外にもこのKBに該当するライブラリが
読み込まれてるのかもしれません。
*MTS(Microsoft Transaction Server)らしい。IISに同梱されてる模様。
はい、VB製のActiveX DLL側でApp.NonModalAllowedを見てはみたのですが、falseになっていました。
ただし、VBで作ったexeから呼び出した場合、同じActiveX DLLの場所でログを出してもtrueになっていました。
やはりVCのexeからの呼び出しだとだめなようです。
MTSのほうは確認できました?
mmcでスナップインの追加にMTS関連のものが出ればMTSが
インストールされていると思われますので確認してみてください。
MTSでないとすれば後は他社製のライブラリを使っていないかとか
スレッドモデルが適切かとかかなぁ。。。
単純にメッセージポンプのスレッドがどこにあるかとか
そういう話なのかもしれませんが。。。
手元に現象を確認できる環境がないため、
私からはこれ以上はなんとも言えません。
識者の降臨を祈ります。
ありがとうございます。
mmcというのは初めて使ったのですが、特にMTS〜のような名前のものは追加候補に現れませんでした。
Microsoft Transaction Serverというのもありませんでした。
ところで、ここで言うKBとはどういう意味でしょうか?
KB = Knowledge Base
Microsoftでは「サポート技術情報」と訳していますね。
kureありがとうございます。
なお、
VCのexeからVBのActiveX DLLを呼んでフォームをモーダレス表示する方法
の件に関しては未だ回答募集中です。
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
と同様で良いのでしょうか?
Yes.
基本的にはなにも変わりません。
ActiveXを作る際のモード(オプション)とGUIDが再生成される
くらいで使う(VC++)側はそのままで大丈夫だと思いますよ。
ありがとうございます。
該当のActiveX DLLをバイナリ互換でActiveX EXEとしてビルドし直し、置き換えるだけでできました。
モードレス表示もイベント取得もうまくいっています。
ただ、画面終了時にクラスの
ReleaseDispatch
や
delete
や
IConnectionPointのUnadvise
や
IConnectionPointContainerのRelease
や
CoUninitialize
を行っているのですが、該当のActiveX EXEがタスクマネージャに残ったままになってしまいます。
何か後処理が足りないのでしょうか?
VB側で非表示のフォームが残ってたり
解放漏れがあったりしませんか?
ありがとうございます。
無駄なフォーム呼び出しがありました。
無くしたら残らなくなりました。
別の問題が残っているのですが、それは別途スレ立てました。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200605/06050042.txt
ツイート | ![]() |