トップ回答者
スレッドからフォームのテキストボックスに文字を追加したい

質問
-
フォームを作りフォームロードの処理に
Dim Timer = New System.Timers.Timer()
で時間で動くようにしました。
呼ばれる関数は別のクラスファイルに書いてあります。
フォーム内に作ったタイマーで実行する関数
Private Sub OnTimedEvent(source As Object, e As ElapsedEventArgs)
の場合フォームのテキストボックスに文字を出力する関数は
Dim dlg As New WriteLineDelegate(AddressOf WriteLine)
Me.BeginInvoke(dlg, New Object() {"実行" & Now.ToString("mm:ss") & vbNewLine})
と書くことでデリゲートした関数
Public Function WriteLine(ByVal str As String) As Integer
txtMessage.AppendText(str)
Return txtMessage.Lines.Length
End Functionをよぶことで実現できました。
OnTimedEventからコールされた別のクラスファイルからテキストボックスに文字を出力する方法がわかりません。
クラスファイルの関数からBeginInvokeを実行しようとすると
ウィンドウ ハンドルが作成される前、コントロールで invoke または begininvoke を呼び出せません。
が発生します。
クラスファイルの関数の引数にこのフォームを入れると実行できました。
フォームを渡さないと実現できないのでしょうか。
回答
-
外池と申します。
ご質問の肝心なところが、具体的に何をされたのかが、よくわかりません。「クラスファイルの関数からBeginInvokeを実行」の部分ですが、フォームの参照を渡した上で、BeginInvokeしているんですよね? BeginInvokeが単独で現われることは無いと思うのですが。
まず、確認まで。
なお、BeginInvokeの前に、Meがついていますよね? このMeは、テキストボックスが載っているFormですよね? (あるいは、TextBoxへの参照であるtxtMessageをつかって、txtMessage.BeginInvokeでも良いですが。) で、BeginInvokeが意味するところは、Formやその上に載っているTextBoxを動作させているスレッド(メッセージポンプが動いているスレッド)で、かくかくしかじかのメソッドを実行してください、とお願いしているわけです。なので、そのFormが動き始めた(メッセージポンプが動き始めた、ウィンドウハンドルが作成された)後じゃないと、BeginInvokeは使えません。
ところで・・・、「System.Timers.Timer」をあえて使われる理由はなんでしょうか? この類のスレッドをまたいだ煩雑な操作を避けるために、「System.Windows.Forms.Timer」がわざわざ用意されているわけで・・・。後者を使えば悩まなくて良いかと。
Formが動き始める前から、Timerを動かしたい理由があるんでしょうね・・・、たぶん。
(ホームページを再開しました)- 回答としてマーク 山本春海 2011年9月2日 5:30
-
- 回答としてマーク 山本春海 2011年9月2日 5:30
すべての返信
-
外池と申します。
ご質問の肝心なところが、具体的に何をされたのかが、よくわかりません。「クラスファイルの関数からBeginInvokeを実行」の部分ですが、フォームの参照を渡した上で、BeginInvokeしているんですよね? BeginInvokeが単独で現われることは無いと思うのですが。
まず、確認まで。
なお、BeginInvokeの前に、Meがついていますよね? このMeは、テキストボックスが載っているFormですよね? (あるいは、TextBoxへの参照であるtxtMessageをつかって、txtMessage.BeginInvokeでも良いですが。) で、BeginInvokeが意味するところは、Formやその上に載っているTextBoxを動作させているスレッド(メッセージポンプが動いているスレッド)で、かくかくしかじかのメソッドを実行してください、とお願いしているわけです。なので、そのFormが動き始めた(メッセージポンプが動き始めた、ウィンドウハンドルが作成された)後じゃないと、BeginInvokeは使えません。
ところで・・・、「System.Timers.Timer」をあえて使われる理由はなんでしょうか? この類のスレッドをまたいだ煩雑な操作を避けるために、「System.Windows.Forms.Timer」がわざわざ用意されているわけで・・・。後者を使えば悩まなくて良いかと。
Formが動き始める前から、Timerを動かしたい理由があるんでしょうね・・・、たぶん。
(ホームページを再開しました)- 回答としてマーク 山本春海 2011年9月2日 5:30
-
- 回答としてマーク 山本春海 2011年9月2日 5:30