- PR -

[VB.NET] FormへのActiveX貼り付けについて

1
投稿者投稿内容
山椒
会議室デビュー日: 2005/09/06
投稿数: 2
投稿日時: 2005-09-06 16:19
最近VBを始めたため、仕組みがまだ分かっていません。
以下の動作について、どこか参考になるurlまたはご教示お願い致します。

(VB.NET2003)
---------------------------------------------
※sample A(一部略)
Module Module1
Sub Main()
Dim threadObj As Thread
Dim formm As Form1 = New Form1
threadObj = New Thread(AddressOf formm.form_start)
threadObj.Start()
End Sub
End Module

Public Class Form1
Inherits System.Windows.Forms.Form
Windows フォーム デザイナで生成されたコード
Public Sub form_start()
ShowDialog()
End Sub
End Class
---------------------------------------------
※sample B(一部略)
Module Module1
Sub Main()
Dim threadObj As Thread
threadObj = New Thread(AddressOf Form1.form_start)
threadObj.Start()
End Sub
End Module

Public Class Form1
Inherits System.Windows.Forms.Form
Windows フォーム デザイナで生成されたコード
Public Shared Sub form_start()
Dim formm As Form1 = New Form1
formm.ShowDialog()
End Sub
End Class
---------------------------------------------

sample Aの場合、FormにButton程度のcontrolを配置したものだと問題なく動くのですが(Formをマウスで動かしたり、ボタン押下が可能)、
ActiveX controlを貼り付けるとThreadがどこかで止まっているような感じになり、ボタン押下はおろかcontrolの描画もまともにしてくれません。貼り付けただけで、制御するコードはFormの自動生成コード以外無しです。

そこでsample Bの方法で動かすとActiveXを貼り付けても問題なく動作しました。

ActiveXの作りにもよるのかと思ったりもするのですが、3,4個のActiveXcontrolで試しましたが同じ結果でした。
このあたりの作法についてご教授ください。
#無駄にThread起こさずにFormから動かせ、という突っ込みは無しでお願いします。。。



[ メッセージ編集済み 編集者: 山椒 編集日時 2005-09-06 16:22 ]
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2005-09-06 16:44
引用:

#無駄にThread起こさずにFormから動かせ、という突っ込みは無しでお願いします。。。



でも、それが原因です。

.NET ではなく、OLE/COM の領域の話になりますが、STA で生成されたアパートメントな「ActiveX コントロール」のメソッド呼び出しを別スレッドから行うには、「マーシャリング」が必要です。

提示されたコードのように、手動でスレッドをガチャガチャいじくるような場合、マーシャリングの要・不要の判断をランタイムが自動的に行うことができなくてずっこけます。

甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2005-09-06 17:01
「Button程度のcontrol」と言うのは、Button程度の機能しか持たないActiveXコントロールと言う意味ですか?

引用:

#無駄にThread起こさずにFormから動かせ、という突っ込みは無しでお願いします。。。


#そこに突っ込まないと話が先に進まないし・・・

おそらく、コントロールのインスタンスを生成したスレッドと、コントロールの機能を呼び出しているスレッドが異なるのが原因です。

呼び出しているActiveXコンポーネントはシングルスレッドモデルかアパートメントスレッドモデルではないのですか?マルチスレッドアパートメントに対応しているActiveXコントロールなら、特に何も意識せずに複数のスレッドから呼び出せるので、sample Aの実装でもおそらく動作します。

VisualBasicがマルチスレッドアパートメントに対応していなかったこともあって、マルチスレッドに対応しているActiveXコンポーネントは少数派なんじゃないかなぁ。
山椒
会議室デビュー日: 2005/09/06
投稿数: 2
投稿日時: 2005-09-06 17:57
山椒です。早速のご教授ありがとうございます。

引用:

甕星さんの書き込み (2005-09-06 17:01) より:
「Button程度のcontrol」と言うのは、Button程度の機能しか持たないActiveXコントロールと言う意味ですか?

呼び出しているActiveXコンポーネントはシングルスレッドモデルかアパートメントスレッドモデルではないのですか?




ActiveXではなく単にButton ControlをFormに貼り付けた、ということです。
説明不足で申し訳ございません。
また、使用したActiveXのスレッドモデルは不明です。(市販Package付属のもので、手元の説明書からは読み取れませんでした。。。)

渋木宏明(ひどり)さん、甕星さんにご教授頂いた内容から私の足りない頭で無理やり動作させるコードを考えてみたところ、
FormのInitializeComponent()でActiveX Controlをnewして設定しているところを切り出して、main threadからマーシャリング呼び出ししてみるととりあえず動いていました。

ActiveX ControlだけをFormに後乗せした、という感じになります。

とりあえず、「相互運用マーシャリング」と「スレッドモデル」あたりを勉強してきます。
ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)