質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

Q&A

2回答

3324閲覧

マウスホイールイベント処理後、不要なイベントを削除したい。

koisann

総合スコア10

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

0グッド

1クリップ

投稿2020/10/12 09:34

#マウスホイールイベント
マウスホイールイベント処理で複数回のイベントが発生しているようです。
イベント処理で画像の拡大を行うと、必要以上に拡大してしまいます。
#不要なイベントを削除
イベント処理終了後、不要なイベントを削除するにはどうすれば良いのでしょうか。
#問題の見える化
sleepを追加すると何度も拡大しているのが見えます。
#環境
プログラムはdelphiですが、処理はWin32APIのホイールマウス処理です。
#ソースコード
//マウスホイールイベント
procedure TFormSim.FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
Msg: TMsg;
ScaleX:real;
ScrollBoxCursosPos: TPoint;
begin
ScrollBoxCursosPos := ImageXYZ.ScreenToClient(Mouse.CursorPos);//マウス位置から有意を判定
if (PtInRect(ImageXYZ.ClientRect, ScrollBoxCursosPos)) then
begin
画像の拡大処理/表示
end;
Sleep(500);//デバッグ用
while(PeekMessage(&msg, 0, WM_MOUSEFIRST, WM_MOUSELAST,PM_REMOVE))do//マウスイベント削除したい
begin // マウス系メッセージを削除
//GetMessage( &msg, 0, 0, 0 );
end;
end;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

イベント処理終了後、不要なイベントを削除するにはどうすれば良いのでしょうか。

何をもって不要と判断するのかが判らないですが、timeGetTime等でイベント発生した時間を記録して、前回のイベント発生時間からの経過時間が早すぎたらイベントを無視するとか、なら出来るかもしれません。

投稿2020/10/25 00:59

編集2020/10/25 01:18
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

koisann

2020/10/25 02:24

ホイールを1回動かした(1クリック)ことを知りたいのです。 ホイール1回クリックで拡大/縮小を一回行いたいのです。一回動かしたら17回ホイールイベントが発生していると判断しているので、であるなら(意味が解らず)16回イベントを無視したところ相応に動いるように見えています。これは正しい処理とは思っていません。
退会済みユーザー

退会済みユーザー

2020/10/25 07:41 編集

であれば、17回のメッセージを愚直に処理するしかないんじゃないでしょうか。OS上では結局ハードウェア動作がウィンドウメッセージに変換されて飛んでくるだけなので、何を持って一回かという判断基準を明確にして貰わないと判断出来ないと思いますよ。ホイール一回動かしたというのも、マウス機種や設定、ホイールの構造で違う場合があるので。
guest

0

マウスホイールイベント処理で複数回のイベントが発生しているようです。
イベント処理で画像の拡大を行うと、必要以上に拡大してしまいます。

質問者様まず「マウスホイール」では回転した方向分の値が連続して送られてきます。
(量に関してはレジストリ登録されています)
例えば
3
3
3
....
と一定回転するたびに送られます。
よって現在スクロールの値に対して拡大縮小率が多きすぎるのでは?
と思われます。

※ マウスホイールの値は「WheelDelta」にて取得できます。

投稿2020/10/12 10:37

kuma_kuma_

総合スコア2506

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

koisann

2020/10/12 13:13

ホイールの設定は3にしています。エディタホイールを回すと3行動きます。レジストリに保存も了解しています。 しかし、ソースのsleepを500にすると画像の拡大は17回行われているように見えます。デバッグ用にカウンタを入れると確かに17回カウントしています。その時、何故かPeekMessageが真の回数は3になっています。イベントカウンタが17回は矛盾ですね。何故でしょうか? 3回出ることは良しとして、3回は連続して出るのでしょうか、又は間隔はXmsとかかかるのでしょうか? 又、回数はユーザーごとに可変ですね。今回のようにホイールを別な目的に使う場合、後の2回(又はX回)を無視することは出来ないのでしょうか。while(PeekMessage() で出来ると思った次第です。
kuma_kuma_

2020/10/12 13:34

> 確かに17回カウントしています。その時、何故かPeekMessageが真の回数は3になっています。 すみません質問のコードを「コードの挿入」を使って囲んでいただけませんか? インテンドがつぶれていて正確な回答ができません。 >後の2回(又はX回)を無視することは できるとしたらマウスホイールに関して届いても無視するしかありません。 ・前回イベント取得時刻(ミリ秒)から一定期間内なら処理を無視する。 ただ結果としては「マウスホイールの動かす量によって拡大・縮小する」からは離れますが よろしいのですか?(マウスホイールの動かすと拡大・縮小する)
koisann

2020/10/12 21:19

#私は勘違いをしているようです TFormのOnMouseWheelイベントはフォームがアクティブの時にホイールが操作された時のみは発生すると思っていますが、この認識が間違っているのでしょうか。
dodox86

2020/10/13 02:10

横からすみません。 @質問者さん > ソースのsleepを500にすると画像の拡大は17回行われているように見えます。デバッグ用にカウンタを入れると確かに17回カウントしています。その時、何故かPeekMessageが真の回数は3になっています。イベントカウンタが17回は矛盾ですね。何故でしょうか? 17回と言うのはイベントハンドラであるFormMouseWheelが呼ばれ、拡大を行った回数ですね。そのイベントハンドラは通常のメッセージループからDispatchMessage()されたハンドラのはずで、Sleep(500)をしている間にメッセージキューに溜まったであろうマウス関連メッセージをPeekMesage(..., PM_REMOVE);の自前のメッセージループで取り出しているかたちになるので、PeekMessage()==TRUEの回数が違って当然だと考えます。また、ある種のWM_メッセージは同じものがあるとWindowsによってメッセージキュー上で間引きされるケースもあったと思います。Delphi特有の事情はあるかもしれませんので、それを含め、当方の指摘に間違いがあれば別途ご意見あるいは訂正ください。
koisann

2020/10/24 22:29

すみません、teratallの使い方が解らず返事が遅れました。 取り敢えず、FormMouseWheelの拡大/縮小処理を1回実行/16回捨てることでそれらしく動いています。 返信に書かれている意味が理解できていないので、もう少し時間をください。 尚、余談ですが、Vistaで実行した時はフォームの上にあるTrackBarがクリックされていると、上手く説明できませんが変な動きになります。Imageを苦リクすると元に戻ります。Windows10ではこのようなことは起きません、この件は別途考えます。
dodox86

2020/10/24 23:27

> Vistaで実行した時は ... 変な動きになります。 質問者さんが作られているプログラムがVistaで動かなければいけない要件なのかは分かりませんが、VistaはWindows7よりサポート期限が早かったほどのシェアなので、気にしなくて良いと思います。 なお、PeekMessageで扱っているMSG構造体にはメッセージがポストされたときの時間(DWORD time)が入っています。簡単に確認してみたところではGetTickCount() APIで取れる値に相当しているので、もしかしたらそれもWM_***メッセージの取捨選択のヒントになるかもしれません。 https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-msg > 返信に書かれている意味が理解できていないので、もう少し時間をください。 この記述は私にあてたものではなく、回答者であるkuma_kuma_さんへのものかもしれませんが、私に限って言うのであれば個人的な興味でコメントしているに過ぎないので、特に気にする必要はありません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問