DOBON.NET DOBON.NETプログラミング掲示板過去ログ

10分以内にボタンやマウスが押されたかを判定したいけどよく失敗します

環境/言語:[VB.NET XP]
分類:[.NET]

こんにちは。
10分以内に1回でもエンターキーやマウスの左クリックのいずれが押されたかどうかを判定して、席にいないと思われたら変数の値を変更したいと思っています。

そのため、タイマーコントロールを10分に設定して
下記のIF文を使用して判定しています。
If GetAsyncKeyState(vbKeyReturn) = 0 And _
GetAsyncKeyState(vbKeyLButton) = 0 Then
変数を変更
End If

しかし、2回に1回は正しく判定されません。
他のアプリケーションと緩衝したり、なんらかの注意点があるのでしょうか?
GetAsyncKeyStateは呼び出す度に初期化されるため、
デバッグもなかなか難しく困っています。

どなたかお助けください。。よろしくお願いします。
And→AndAlsoっていうか、OrElseじゃないのかな。
■No17270に返信(はいこーんさんの記事)
> And→AndAlsoっていうか、OrElseじゃないのかな。

ボタンもマスも=0つまり入力なしだったら、席にいないというステータスに
変更するのだから、あっていると思いますが、
考慮漏れがあれば教えてください。
■No17271に返信(ぱるけさんの記事)
> ■No17270に返信(はいこーんさんの記事)
>>And→AndAlsoっていうか、OrElseじゃないのかな。
>
> ボタンもマスも=0つまり入力なしだったら、席にいないというステータスに
> 変更するのだから、あっていると思いますが、
> 考慮漏れがあれば教えてください。
条件式はOKだけど、GetAsyncKeyState()の戻り値の使い方が間違っています。
一度調べてみてください。
2006/08/25(Fri) 11:05:26 編集(投稿者)

■No17268に返信(ぱるけさんの記事)
こんにちは エツです。始めまして

> しかし、2回に1回は正しく判定されません。

正しい判定とはどのような事を期待されているのかわかりませんが
タイマーが10分と長いから解り辛いだけではないでしょうか?

例えばマウスの左クリックに追従するかどうかの確認なら、タイマーを
150mSと短くしてみたら?(勿論デバッグ時の話です)
回答ありがとうございます。

> 条件式はOKだけど、GetAsyncKeyState()の戻り値の使い方が間違っています。
> 一度調べてみてください。

タイマー起動時点でボタンが押されていれば上位ビットが1になり< 0になり、
前回起動時から1回でもボタンが押されていれば下位ビットが1になり= 1に
になるとの記述がありましたので、このようにしております。
・・という意味ではないですか?


>>しかし、2回に1回は正しく判定されません。
>
> 正しい判定とはどのような事を期待されているのかわかりませんが

すみません。前回起動時から1回でもボタンが押されているか?
というIF文の結果判定が正しくないという意味です。
普通にPCで作業している次の瞬間にこの処理が稼動しても
PC未使用として処理されてしまう場合があるということです。
必ず、GetAsyncKeyState(vbKeyLButton) <> 0になるはずなんですけど・・。



> タイマーが10分と長いから解り辛いだけではないでしょうか?
>
> 例えばマウスの左クリックに追従するかどうかの確認なら、タイマーを
> 150mSと短くしてみたら?(勿論デバッグ時の話です)

そうですね。やってみました!
1秒毎だと正しく判定されます。
※別のアプリに切り替えてから3秒ほどラグがあって、その間は判定されないですが・・。

となると、別のアプリでもGetAsyncKeyState(vbKeyLButton)を
発行していて、それに消されてしまっているのでしょうか?
と思い、他のアプリを落としてやってみましたがだめでした。。
グローバルホットキーの活用も検討しましたが、リターンキーとマウス左クリックを判定に使用しているので、それはそれで弊害があるのでそちらよりもこちらの方がいいかなと考えております。
2006/08/25(Fri) 23:26:00 編集(投稿者)

■No17288に返信(ぱるけさんの記事)

私の試した結果によるとGetAsyncKeyState()は結構いいかげんな関数というイメージがあります。

>1秒毎だと正しく判定されます。
仮に1秒に設定して、デスクトップ上のメモ帳を開く、閉じる、色々なものをクリックする、ダブルクリックする等して動作確認してみてください。
結構判定ミスをすると思います。

だけど ”1秒毎だとかなり正しく判定されます” と言い換えれば正しいと思います。

余計なお世話かも知れませんが私なら
判定を1秒間隔で行い、10分間隔で変数の値を変更します。
判定は10分間の間に1度でも押されたと判定があれば押されたとします。
CPUへの負荷も1秒に1回の判定なら問題ないかと思います。

御参考までに。
エツさんありがとうございます。

■No17290に返信(エツさんの記事)
> 2006/08/25(Fri) 23:26:00 編集(投稿者)
>
> ■No17288に返信(ぱるけさんの記事)
>
> 私の試した結果によるとGetAsyncKeyState()は結構いいかげんな関数というイメージがあります。

そうですか。
sendkeyもいい加減ですが、これもそれぐらいに考えればいいんですね。
もしかしたら、windowsの内部処理で色々つかっているのかもしれませんね。


> >1秒毎だと正しく判定されます。
> 仮に1秒に設定して、デスクトップ上のメモ帳を開く、閉じる、色々なものをクリックする、ダブルクリックする等して動作確認してみてください。
> 結構判定ミスをすると思います。
>
> だけど ”1秒毎だとかなり正しく判定されます” と言い換えれば正しいと思います。
>
> 余計なお世話かも知れませんが私なら
> 判定を1秒間隔で行い、10分間隔で変数の値を変更します。
> 判定は10分間の間に1度でも押されたと判定があれば押されたとします。

やっぱりこれしかないですね。
たくさんこのAPIをコールすると他のアプリにも影響がありそうなので
乱発は避けるべきなのかなと思っています。
関数の特性上、影響しますよね?
実はこの関数を使う以外に一般的な判定の仕方があるのかなと思ってしまいます。


> CPUへの負荷も1秒に1回の判定なら問題ないかと思います。

明日試してみようとは思いますが、
1秒に1回程度の判定だと、PCには負荷はかからないんでしょうか?
人間的に考えてしまうと結構多いなあと感じてしまいます。
まあ不安だったら10秒くらいにすればいいんですけどね。

DOBON.NET | プログラミング道 | プログラミング掲示板