DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ContextMenuを表示中他の処理が止まる

環境/言語:[VB.NET 2002]
分類:[.NET]

説明用にてきとうにプログラムを作ったのですが、

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Show()
Do
Label1.Text = DateTime.Now
Application.DoEvents()
Loop
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ContextMenu1.Show(Button1, Button1.PointToClient(MousePosition))
End Sub

これを実行すると、時刻が表示され続け、
ボタンをクリックするとメニューが表示されますが、
そのメニュー(ContextMenu)が表示されている間、
何かを選択するか何かしてContextMenuを消さない限り、
時刻は止まっていて動きませんよね?
これを止まらないようにするにはどうしたらよいのでしょうか。
■No8245に返信(smithさんの記事)
> 説明用にてきとうにプログラムを作ったのですが、
>
> Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
> Me.Show()
> Do
> Label1.Text = DateTime.Now
> Application.DoEvents()
> Loop
> End Sub
>
> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
> ContextMenu1.Show(Button1, Button1.PointToClient(MousePosition))
> End Sub
>
> これを実行すると、時刻が表示され続け、
> ボタンをクリックするとメニューが表示されますが、
> そのメニュー(ContextMenu)が表示されている間、
> 何かを選択するか何かしてContextMenuを消さない限り、
> 時刻は止まっていて動きませんよね?
> これを止まらないようにするにはどうしたらよいのでしょうか。


時刻の表示は、Formの Loadイベントではなく、タイマーで行ったほうが
良いのではないでしょうか。
>> 説明用にてきとうにプログラムを作ったのですが、

> 時刻の表示は、Formの Loadイベントではなく、タイマーで行ったほうが
> 良いのではないでしょうか。

これはここで説明するために作ったプログラムなので、
本当にただ時刻を表示させたいだけならこのようには作りません。

Do〜Loop内で別の処理をしていても止まります。
どのようにしたら止まらなくなるのでしょうか。
■No8247に返信(smithさんの記事)

> これはここで説明するために作ったプログラムなので、
> 本当にただ時刻を表示させたいだけならこのようには作りません。

何をしたいのか明記されていませんので、なんとも言えませんが、、

> Do〜Loop内で別の処理をしていても止まります。
> どのようにしたら止まらなくなるのでしょうか。

処理をスレッド化してみてはいかがでしょうか。
> 処理をスレッド化してみてはいかがでしょうか。

すみません。初心者なもので。
スレッド化とはどのようにすることを言うのでしょうか。
Do〜Loopは使えないということでしょうか。
>>時刻の表示は、Formの Loadイベントではなく、タイマーで行ったほうが
>>良いのではないでしょうか。

このご指摘は、

> Do〜Loop内で別の処理をしていても止まります。

これがダメですよ、というご指摘です。
イベントドリブンのプログラミングで、
Do〜Loopの無限ループはご法度です。

どのみち二つのイベントは同時に処理されないですし、
コンテキストメニューを表示のようなユーザがアクションするまで処理が
止まってしまうようなイベントの使い方をした場合は他のイベントは阻害されます。

マルチスレッドを使用する必要がありますが、Threadクラスを使ってマルチスレッドをしなくても、
System.Timers.Timer
System.Threading.Timer
のいずれかのタイマーを使用すれば実現できそうです。

> スレッド化とはどのようにすることを言うのでしょうか。

どぼん!さんの Tipsを参照ください。
http://dobon.net/vb/melma/dotnet19.txt

よねKENさんのおっしゃるとおり、Timerを利用したほうが
簡単そうですね。
> http://dobon.net/vb/melma/dotnet19.txt

これをよく読んでスレッド化してみたところ、
Do〜Loopを使っていても大丈夫なようになりました。
とてもよい勉強になりました。ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板