今の仕事のチームメンバーの一人、Hには、大した仕事が与えられない。
単純作業だが量が多いものなどが、彼の担当になることが多い。
チームリーダーのTは、Hも同席しているミーティングの場で「Hさんにもできることはあるかな…」などと口にする。
そんなHに先週任された仕事は、以下のようなものだ。
フォーム上に検索条件を入力してボタンを押すと、DBから条件に合致するデータを取ってきて、グリッドに一覧表示する。
このとき、ボタンを押してから表示が完了するまでは、カーソルを待ち状態にし、検索ボタンを無効にしろというのだ。
検索処理中に見た目が変わらないと、本当に検索しているのか分からず、検索ボタンを連打してしまう可能性があるためだ。
DBに対して検索するすべての画面で必要な処理だから、まさに大量の単純作業だ。
俺は、ボタンのClickイベントでForm全体をDisableにしてしまい、処理が終わったらEnableにすればいいと思っていた。慎重を期すなら、EnableにするコードはFinallyブロックに書いてもいい。
対して、Hが出した案はこうだ。
コントロールをDisableにすると、グレーになって醜い。
モーダルダイアログを出している間は、親画面はグレーでなく操作ができない状態になる。これを利用すればいい。
では、検索中にモーダルダイアログを出すようにするのか? と言うと、「ユーザにはダイアログが見えないようにする」と言う。
百歩譲ってダイアログをよしとしたところで、その見えないダイアログを誰が閉じる?
モーダルダイアログは、閉じられるまで親の実行を阻害する。ダイアログ自身によって閉じられないのであれば、別のスレッドから閉じるしか無いが、Hにはそのあたりが分かっていないらしい。
コントロールをグレーにするのは醜いから嫌だと顧客に言われたわけでもないのに、敢えて茨の道を突き進もうとする姿勢には頭が下がる。
ちなみに、その処理は結局、画面内の各コントロールをDisableにするということで話がついたようだ。
Hが、ある画面についてその実装を終え、テストをしていると、ある問題が発生して、俺が呼ばれた。
検索中にボタンをDisableにし、検索が終わったらEnableにしているのだが、Disable状態のボタンをクリックしても、一度検索が終わった後で再度検索処理が走ってしまうというのだ。
その挙動を見て、ピンとひらめいた。あぁ、メッセージがキューにたまっていて、Enableになった直後にそれが処理されるからだと。
そこで、検索終了後、ボタンをEnableにするまえにDoEventsを入れて、強制的にメッセージを消化させることで対処した。
Hは、DoEventsの一行を入れるだけで、どうして問題が解決するのか分からないと言った。
チームには、Hと同じ会社から出向してきているKがいる。KはHの先輩で、普段Hを直接監督しているのはこのKだ。
余談だが、KもHも俺より年上である。
ボタンの問題を解決したとき、たまたまKも同じ場に居合わせたので、Kも一緒になって理由を聞きたがった。
そこで、2人に聞いてみた。CあるいはC++でWindowsプログラムを作ったことはあるか? と。
2人の答えは、いずれも「No」だった。
メッセージキューの仕組みを簡単に説明はしたが…うーむ…