ある特定の処理実行中は、フォームやボタンの Enabled プロパティを False に設定し、2度同じ処理を実行されないようにしたりします。 しかし、Enabled が False でも True に変更する前にユーザがマウスクリックまたはEnterキーなどで処理をしていた場合、その操作に関連する処理は行われてしまいます。 今回はそのような問題への対策です。
以下の関数をボタンの Enabled を True にする際になどに実行します。
procedure PurgeMsgQueue(AHandle: HWND); var Msg: TMsg; begin // マウスのメッセージをキューから除去 while PeekMessage(Msg, AHandle, WM_CLOSE, WM_QUIT, PM_NOREMOVE) do exit; while PeekMessage(Msg, AHandle, WM_DESTROY, WM_DESTROY, PM_NOREMOVE) do exit; while PeekMessage(Msg, AHandle, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) do; // そのほかのメッセージをキューから除去 while PeekMessage(Msg, AHandle, WM_CLOSE, WM_QUIT, PM_NOREMOVE) do exit; while PeekMessage(Msg, AHandle, WM_DESTROY, WM_DESTROY, PM_NOREMOVE) do exit; while PeekMessage(Msg, AHandle, WM_KEYDOWN, WM_KEYDOWN, PM_REMOVE) do; end;
でも、この方法だと取り除きたいマウスとキーボードのメッセージの数だけ記述しないとダメなので、実用性はいかがなものだろうか?
別案として、別スレッドで処理するかマウスとキーボードの処理を別ウィンドウに処理させてしまう方法がある。