- - PR -
ボタン押下処理中の誤作動について
1
| 投稿者 | 投稿内容 | ||||
|---|---|---|---|---|---|
|
投稿日時: 2004-11-17 18:22
開発 :VB.NET
データベース:SQL Server VB.NETで帳票を出力するアプリケーションを開発しています。 帳票作成のボタンを押下してから結果が出るまでの間に、画面上を何度もクリックをすると誤作動が起こってしまいます。原因が分からず困っているのですが、詳しい方は是非教えていただけませんか? 事象について、詳しくは以下の通りです。 1.画面上で印刷ボタンを押し、データベースからデータを抽出して帳票を作成するプログラムです。 2.ボタンを押してから結果の出力まで数十秒かかる時があり、その間にForm上を連打し続けると、タイトルバーに「(応答なし)」の文字が出ます。 3.そのまま少し待つと、エラーメッセージ「オブジェクト参照がオブジェクト インスタンスに設定されていません。」が表示され、帳票は出力されません。 4.Form上のコントロールは、ボタン押下とほぼ同時に無効化しています。 以上です。 返信していただけるよう、よろしくお願いします。 | ||||
|
投稿日時: 2004-11-17 19:11
しみこさん、こんばんは。
再入防止フラグを用意するとか。
| ||||
|
投稿日時: 2004-11-17 19:32
しみこさん、こんばんは。
ボタン連打で、ボタン処理が再度走っているとしたら・・って仮定で。 再入してるのがボタン処理が終わってからだったとしたら、 メッセージの空読みで対応出来ないでしょうか。 Private Sub Button1_Click(・・・・) Test(); ← 帳票出力処理で非常に重い Do While PeekMessage(tpMsg, hwnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) Loop End Sub #VB6.0の時にこんな事をやっておりました。 | ||||
|
投稿日時: 2004-11-18 11:02
とりあえず、ボタンなどはEnabled = Falseにしているようなので、 最後にEnabled = Trueとやる直前にApplication.DoEvents()を 実行してみたらどうでしょうか? # つまるところ、マミさんのとおおよそ同じことをやっていることになります。 ※応答なしを解決するのは、もちょっとだけややこしいです。条件にもよりますし。 | ||||
|
投稿日時: 2004-11-18 17:42
きくちゃんさん、マミさん、なちゃさん、ありがとうございました!
エラーを解決することが出来ました。 最終的に、なちゃさんに教えていただいたDoEvents()を帳票作成のループ中で実行し、解決しました。 --------------------------------------------------------------------------- ところで、エラーについて調べていて少し疑問を持ったので、よかったら教えていただけませんか? 疑問は、ボタンの無効化に関することです。 自分なりにエラーを分析し、2種類のエラーが存在すると考えました。 エラー@:タイトルバーに(応答なし)と表示される。 原因 :時間がかかる処理の実行中に、処理待ちのWindowsメッセージが溜まってしまうことによる。 対策 :DoEvents()によってたまったWindowsメッセージを明示的に処理する。 エラーA:エラーメッセージ「オブジェクト参照に…」が表示される。 (インスタンスが null 参照になっている例外。) 原因 :帳票作成処理の再入による。 (処理中にインスタンスの破棄を行っているからと考えます。) 対策 :ボタンの無効化(Enabled = False)、再入防止処理 疑問 → それぞれのエラーはそれぞれの対策によって解決されると考えられるのに、 DoEvents()を行わないと、ボタンの無効化を行っても、再入防止処理を行っ ても、エラーAが発生してしまいました。 (エラー@ももちろん発生しました。) 上記の解釈自体が間違っているのでしょうか? 長々しい質問で申し訳ありません。 もしお分かりになる方がいたら、教えてください。よろしくお願いします。 | ||||
|
投稿日時: 2004-11-18 21:00
ご自身で書いてらっしゃるように、Windowsメッセージはどんどんキューにたまっていきます。で、処理可能になった時点で一気に処理されていくわけですが… ここで、Enabledとの絡みが出てきます。 Enabled = Falseの状態とは、簡単に言えば、キューから取り出したメッセージを破棄する様にしているということです。 で、この破棄という動作をするためには、メッセージをキューから取り出せないといけないわけで、つまり、メッセージを処理できずにキューにたまっていくだけの状態では、メッセージを破棄することもできていないということです。 で、最後にEnabled = Trueとしてイベントハンドラを抜けると、一気にたまったメッセージが処理されます。メッセージ処理が可能になった時点では、既にEnabled = Trueですから、結局Enabled=Falseによる防止はできていないということです。 Enabled = Trueの前にDoEventsを実行すると、そこで一旦メッセージの処理が行われますから、Enabled = Falseによる動作、つまりメッセージの破棄が行えるということです。 | ||||
|
投稿日時: 2004-11-19 19:54
なちゃさん、わかりやすいご説明ありがとうございます。
Enabled=Falseの設定が他の処理と影響しあっているとは思いませんでした。 とても勉強になりました。 | ||||
1
