掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
マウスホイールのイベントとCtrlキーの組み合わせ検出で誤動作 (ID:33269)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
当方、Delphi5です。 バグなのか仕様なのかわかりませんが、 FormMouseWheelDownとFormMouseWheelUp で、以下の一行を追加してみてください。 Handled := True; これで、'Ctrl + up'、'Ctrl + down' が表示されるでしょう。 で、どんなメッセージの流れになっているのか追ってみると・・・ (説明が通じるのかわかりませんが) 1)フォーカスのあるコントロールでWM_MOUSEWHEEL を受け取ります (TWinControl.WMMouseWheel) 2)受け取ったコントロールは、まず自分が乗っているフォームに WM_MOUSEWHEELを投げます(TWinControl.MouseWheelHandler)。 このとき、CM_MOUSEWHEELを投げるために、ShiftState の変換を行います。 TCMMouseWheel(Message).ShiftState := KeysToShiftState(Message.Keys); これで、Message.WParamが変更されます。 3)フォームは、フォーカスのあるコントロールにCM_MOUSEWHEELを送信します (TCustomForm.MouseWheelHandler)。 WParam,LParamは、WM_MOUSEWHEELで受け取った値をそのまま使用。 4)CM_MOUSEWHEELを受け取ったコントロールは、OnMouseWheel〜イベントを 発生させたりして、処理されたか判定(イベント引数のHandledね) Handled = True にならない場合、Parent に、CM_MOUSEWHEELを送ります。 5)ここでParentが無くなるか、Handled=Trueになるまで処理します。 フォームのOnMouseWheel〜が発生するのは、ココ ここでは、正常にShiftStateが入ってきています。 6)以上が、フォーカスのあるコントロールでWM_MOUSEWHEELを受け取った時の、VCLの処理。 ここまででHandled = True にしていない場合、TWinControl.DefaultHandler から、 CallWindowProcを呼んで、OS側に処理をおまかせします。 7)OSは、メッセージ処理が終わっていないと判断して、(たぶん)Parentに 向けてWM_MOUSEWHEELを投げます。 (もしかしたら、最上位Parentのフォームにいきなり投げるのかも) 8)Parentは、1)からの処理を、同じように行いますが、ここで注意すべきなのが、 2)で、WParamを書き換えている点。 書き換えられたWParamを、CM_MOUSEWHEELを投げるために、再度書き換えを 行うため、ShiftStateがおかしくなります。 おかしくなったShiftStateで、OnMouseWheel〜イベントが発生するから、 ShiftStateが正しくないのは当然。 2回目(以降)のイベントで、誤った結果を表示し、それしか見えないから 正しく入ってきていないと思ってしまう。 TWinControl.WMMouseWheel が、以下のようになっていたら、大丈夫と思う。 TCMMouseWheel(Message).ShiftState := KeysToShiftState(Message.Keys); MouseWheelHandler(TMessage(Message)); if Message.Result = 0 then inherited; ↓ TCMMouseWheel(Message).ShiftState := KeysToShiftState(Message.Keys); MouseWheelHandler(TMessage(Message)); if Message.Result = 0 then begin //逆変換(ShiftStateToKey)の関数は自作するしかないのかな? TCMMouseWheel(Message).ShiftState := ShiftStateToKey(Message.Keys); inherited; end;
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.