処理中にイベントを起こさせないためには?

解決


m  2005-05-20 20:16:04  No: 89927

10秒ぐらいかかる処理があって、その処理をしている間は「処理中です。」とラベルをフォームの最前面に表示しているのですが、
この処理中に、ラベル以外の場所をクリックすると、処理が終わった後にクリックした回数分イベントが起きてしまいます。
処理中には、そのフォームのEnabledをFalseにして処理が終わったらTrueにしているのですが、フォームのEnabledをFalseにしても、イベントが起きてしまいます。
このような場合はどうやってイベントを起こさせないようにすればよいでしょうか?
また、そのおきるイベント中にフラグをおいてフラグが立っているときは何もしないなどもやってみましたがだめでした。


たこ朗  2005-05-20 23:01:36  No: 89928

「処理中です。」を別フォームにして
ShowDialogとかにするというのはどうでしょうか。


m  2005-05-20 23:06:00  No: 89929

「処理中です。」のためだけにフォームを追加するのは止めたかったのですが、
別フォームにしたほうが処理が簡単に済みますね。

別フォームにして実現しようと思います。
ありがとうございました。


m  2005-05-20 23:24:27  No: 89930

解決していなかったです。

>ShowDialogとかにするというのはどうでしょうか。
これはVB.NETですか?

遅くなりましたが、環境はVB6です。

別フォームにしてやってみたのですが、やはりできませんでした。Modalにしてしまうと、その後のイベントが止まってしまいます。なのでvbModelessでフォームを開いているのですが、フォームが表示されている時にメインのどこかコントロールをクリックすると、「処理中です。」が終わった後にイベントが起きてしまいます。

どうやればイベントを起こさせないようにできるでしょうか?


ひでらん  2005-05-21 00:36:51  No: 89931

処理を開始する前に、押下可能なコントロールのEnable
プロパティをFalseに設定し、処理終了後にTrueに戻せば
いけませんか?

駄目だったら、DoEventsをプロパティ変更後に入れてみる
とか・・・。


ひなぐま  2005-05-21 00:54:15  No: 89932

イベントを起こさせない
イベントは起きてもよいが処理はさせない

この二つの違いは、似ているようで天と地のほどの差がある
それを理解してのイベントを起こさせないナラバ良いんだが


たこ朗  2005-05-21 01:43:46  No: 89933

>vbModelessでフォームを開いているのですが
この前に呼び出し元フォームのEnable=false にすればだいじょうぶかも


36NET  2005-05-21 02:24:28  No: 89934

Modalで呼び出したフォームから呼び出し元のフォームの関数なりを呼んで
終わったらunload meするようにする

10秒ぐらいかかる処理の最後にmsgboxを入れてみる

とかとか


m  2005-05-21 03:06:18  No: 89935

>この前に呼び出し元フォームのEnable=false にすればだいじょうぶかも
そのようにしていますがだめでした。特定のコントロールだけEnable=false にしてやってみてもだめでした。

ボタンAとボタンBがあって、Aを押すと処理が始まる。処理が始まる前にボタンBを無効化しておく。その処理中に別フォームをモードレスで呼び出す。別フォームが出ている時にボタンBを押す。押した瞬間はイベントは起きないが、処理が終わった瞬間実行される。


ぶぶ  2005-05-21 08:10:20  No: 89936

ちょっと作ってみました。
意味がちがっていたらごめんなさい。
一応ボタン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


m  2005-05-23 22:45:11  No: 89937

>ちょっと作ってみました。
少し変えました。

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秒前ぐらいに押すとイベントが起きてしまいす。


ぶぶ  2005-05-23 23:54:44  No: 89938

張られたコードで試してみましたが、
反応はありませんでした。
こちらでは現象の再現ができませんでした。


m  2005-05-24 00:00:20  No: 89939

各処理のあとに

Do Events
Sleep 1

を入れると回避できるようになりました。

>張られたコードで試してみましたが、
PCの性能によるのかな?ループを500000ぐらいにするとなるかも・・・
ぶぶさん、わざわざ検証のほうすいませんでした。
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加