10秒ぐらいかかる処理があって、その処理をしている間は「処理中です。」とラベルをフォームの最前面に表示しているのですが、
この処理中に、ラベル以外の場所をクリックすると、処理が終わった後にクリックした回数分イベントが起きてしまいます。
処理中には、そのフォームのEnabledをFalseにして処理が終わったらTrueにしているのですが、フォームのEnabledをFalseにしても、イベントが起きてしまいます。
このような場合はどうやってイベントを起こさせないようにすればよいでしょうか?
また、そのおきるイベント中にフラグをおいてフラグが立っているときは何もしないなどもやってみましたがだめでした。
「処理中です。」を別フォームにして
ShowDialogとかにするというのはどうでしょうか。
「処理中です。」のためだけにフォームを追加するのは止めたかったのですが、
別フォームにしたほうが処理が簡単に済みますね。
別フォームにして実現しようと思います。
ありがとうございました。
解決していなかったです。
>ShowDialogとかにするというのはどうでしょうか。
これはVB.NETですか?
遅くなりましたが、環境はVB6です。
別フォームにしてやってみたのですが、やはりできませんでした。Modalにしてしまうと、その後のイベントが止まってしまいます。なのでvbModelessでフォームを開いているのですが、フォームが表示されている時にメインのどこかコントロールをクリックすると、「処理中です。」が終わった後にイベントが起きてしまいます。
どうやればイベントを起こさせないようにできるでしょうか?
処理を開始する前に、押下可能なコントロールのEnable
プロパティをFalseに設定し、処理終了後にTrueに戻せば
いけませんか?
駄目だったら、DoEventsをプロパティ変更後に入れてみる
とか・・・。
イベントを起こさせない
イベントは起きてもよいが処理はさせない
この二つの違いは、似ているようで天と地のほどの差がある
それを理解してのイベントを起こさせないナラバ良いんだが
>vbModelessでフォームを開いているのですが
この前に呼び出し元フォームのEnable=false にすればだいじょうぶかも
Modalで呼び出したフォームから呼び出し元のフォームの関数なりを呼んで
終わったらunload meするようにする
10秒ぐらいかかる処理の最後にmsgboxを入れてみる
とかとか
>この前に呼び出し元フォームのEnable=false にすればだいじょうぶかも
そのようにしていますがだめでした。特定のコントロールだけEnable=false にしてやってみてもだめでした。
ボタンAとボタンBがあって、Aを押すと処理が始まる。処理が始まる前にボタンBを無効化しておく。その処理中に別フォームをモードレスで呼び出す。別フォームが出ている時にボタンBを押す。押した瞬間はイベントは起きないが、処理が終わった瞬間実行される。
ちょっと作ってみました。
意味がちがっていたらごめんなさい。
一応ボタンA押して、ボタンBにEnabled = false して、Form2 をモードレス表示してその間にボタンB押してみました。
ボタンBを押した動作は何も起きませんでした。
(VB6.0 Windows XP)
Form1にcommand1 command2 timer1 Label1 Label2 を貼り付けました
---------------------Form1
Option Explicit
Dim Flg_Loop%
Private Sub Command1_Click()
Label1.Caption = ""
Label2.Caption = ""
Command2.Enabled = False
' timerに10秒設定
Timer1.Enabled = True
Timer1.Interval = 10000
Label1 = "処理中です!!"
Form2.Show 0 ' モードレス表示
' 10秒仮想処理させる
Flg_Loop = False
Do While Not Flg_Loop
DoEvents
Loop
' 使用拒否の解除とTimerの解除
Command2.Enabled = True
Timer1.Enabled = False
End Sub
Private Sub Command2_Click()
Label2.Caption = "反応しました"
End Sub
Private Sub Timer1_Timer()
' 処理の終了
Flg_Loop = True
End Sub
>ちょっと作ってみました。
少し変えました。
Option Explicit
Private Sub Command1_Click()
Dim i As Long
Dim j As Long
Label1.Caption = ""
Label2.Caption = ""
Label3.Caption = ""
Label1 = "処理中です!!"
Command2.Enabled = False
Me.Refresh
Form2.Show 0, Me
For i = 0 To 100000
Label3.Caption = i & "/100000"
' DoEvents
Next i
Command2.Enabled = True
Label1.Caption = ""
End Sub
Private Sub Command2_Click()
Label2.Caption = "反応しました"
End Sub
これを実行していただくとわかるのですが、こういう感じになるのです。
このコードではDoEventsをコメントにしていますが、この場合だとDoEventsを書くと正しく動作はします。
しかし、自分が書いているコードではループしている場所のコードが違う感じです。DoEventsを入れると5秒ぐらいは大丈夫ですが、処理が終わる3秒前ぐらいに押すとイベントが起きてしまいす。
張られたコードで試してみましたが、
反応はありませんでした。
こちらでは現象の再現ができませんでした。
各処理のあとに
Do Events
Sleep 1
を入れると回避できるようになりました。
>張られたコードで試してみましたが、
PCの性能によるのかな?ループを500000ぐらいにするとなるかも・・・
ぶぶさん、わざわざ検証のほうすいませんでした。
ありがとうございました。
ツイート | ![]() |