アプリ版:「スタンプのみでお礼する」機能のリリースについて

いつもお世話になっております。
VS2005でC++を利用してWindowsアプリケーション作成を行っています。

マウスカーソルが一定時間動かなかったらマウスカーソルを非表示、
マウスカーソルが移動したらマウスカーソルを表示させる

このようなプログラムを作成したいと考えています。
今、ShowCursorでマウスカーソルの表示・非表示はできたのですが、
「マウスムーブが一定時間無かった場合」というのは
どのように調べたらよいのでしょうか。

ご教授お願いいたします。

A 回答 (5件)

>あと3秒をチェックするのにif文を使っているため ==3 としていたのですが、それではできないのでしょうか。


きっちり動けば良いですが例えばイベント動作が遅れて
Timer関数走ったときの求めた時間秒数が
2・4のように変化していたら ==3 のチェックでは引っかかりませんよね
>=3でチェックすれば4でも引っかかりますよね
ということです

> =3 だとエラーが出てデバッグできません。
> を引用と見間違えられたかな? 比較式としての >= です
(今見たら確かに間違えそうだ)

#2さんへの補足についても一つ
>エラーはでずにデバッグできるのですがマウスカーソルの表示非表示はなりませんでした。
ShowCursor時間数の御理解がいまひとつのようです
TRUE・FALSEのパラメータでで一回呼べば表示・非表示になるという関数ではないのです
(前書いたURLの説明を再度お読みください)

内部にマウス表示のカウンターを持っていてそのカウント値が
負数だったとき初めて非表示0以上で表示と切り替わります
ですのでちゃんと動作させるためには関数の戻り値をチェックして
必要な回数分ShowCursor関数をコールし続けなければなりません
whie(ShowCursor(TRUE) >= 0 );
whie(ShowCursor(FALSE) < 0 );  のように

書いているコードではShowCursor(TRUE)は数回呼ばれる
可能性があるのにShowCursor(FALSE)は
一定時間経過後1回しか呼ばれません
その為非表示にならないのです

> CXX0017: エラーです: シンボル "ShowCursor" が見つかりません
これについてはどのような状況で出ているのか分からないので
なんともいえません
    • good
    • 0
この回答へのお礼

おはようございます。
ご丁寧な説明、とてもわかりやすく理解できました。

「>=3」だったのですね。引用と見てしまいました。失礼しました。
始めに作っていたプログラムを「>=3」のように直して実行してみたのですが、
マウスカーソルは非表示になりませんでした。
ほかの部分でプログラムの書き間違いがあるのでしょう。
断念してもう一方のプログラムをkoi1234さんのアドバイスを参考にWM_TIMERの部分を
 whie(ShowCursor(FALSE) >= 0 );
と直して実行したらプログラム成功いたしました!!

koi1234さん、titokaniさん本当に感謝いたします。
ありがとうございました。

お礼日時:2010/01/19 10:40

#4訂正


>whie(
whileの打ち間違い ついでに条件も間違ってます(FALSEとTRUEが逆)
それぞれの条件に合うように書いてください
    • good
    • 0

時間取得で一番簡単なのは GetTickCount() かと思います


※ OS連続運転などしてるならオーバフロー対策も考える必要があります
>1000ミリ秒単位でWM_TIMERを呼び出しているために
>誤差などが生じて正確に差を「3」と計算できないのでしょうか。
Windowsのタイマーはそれほど制度が良いわけではありませんので
誤差が出る事もあります
後やってないと思いますが3秒とチェックするのに == 3 等とやっちゃ駄目ですよ
>= 3 としておけば少なくても動くはずです

秒単位で測定したいならもっと時間を短くした方が良いでしょう
例) 1秒だから1000では無く500 等

(ちょっと確証が無かったので書きませんでしたが)
SetTimerで関数呼びなおして時間変わるんであれば#2さんの方法が
簡単かもしれません
    • good
    • 0
この回答へのお礼

何度もアドバイス本当に感謝いたします。

本など読んで調べてみましたが、やはりSetTimerは正確ではないのですね。
第3引数に指定した通り毎回WM_TIMERを呼ぶとは限らないと記述してありました。
おかげさまで勉強になりました。

あと3秒をチェックするのにif文を使っているため ==3 としていたのですが、それではできないのでしょうか。
=3 だとエラーが出てデバッグできません。
勉強不足で申し訳ないです。

今、これまで作ったプログラムの改良と
下記にあるtitokaniさんから頂いたアドバイスを参考に
平行してプログラムを組んでいるところです。
もう少し粘ってやってみたいと思います。

お礼日時:2010/01/19 01:00

もっと簡単にできると思います。


WM_MOUSEMOVE
 マウスを表示。
 「一定時間」を引数として、SetTimerする。

WM_TIMER
 マウスを非表示。
 KillTimerする。

これでいいんじゃないかと。
同じIDでSetTimerされた場合、以前セットされたいたタイマーは上書きされるはずですから。
    • good
    • 0
この回答へのお礼

なるほど。SetTimerは上書きされるのですね。
私もそこが不安でなかなかプログラムがかけませんでした。
アドバイスありがとうございます。
titokaniさんのを参考に、下記のようにプログラムを組んでみました。

case WM_MOUSEMOVE:
   if(::IsZoomed(hWnd)){  //最大化の時
     ShowCursor(TRUE);  //マウスカーソル 表示
     SetTimer(hWnd, 2, 3000, NULL);  //3000ミリ秒単位でWM_TIMERを呼び出す
   }
   return 0;
case WM_TIMER:
   if(::IsZoomed(hWnd)){
     ShowCursor(FALSE);  //マウスカーソル 非表示
     KillTimer(hWnd, 2);
   }
  (中略)
   return 0;

これで実行してみると、
エラーはでずにデバッグできるのですがマウスカーソルの表示非表示はなりませんでした。
ベレークポイントを置いてプログラムを見ていくと、
自動変数の場所に次のエラーメッセージが出ていました。

 CXX0017: エラーです: シンボル "ShowCursor" が見つかりません

これは何が原因なのでしょうか。
なんども質問ごめんなさい。
もう少し粘ってみます!

お礼日時:2010/01/19 00:54

考え方だけです(実装方法は色々考えられます)


マウスが移動した場合 MouseMove イベントメッセージが動作します
そこで時間を記録します  --- 最後にマウスが動作した時間になります
適当なイベント(例えばタイマーや単独の監視スレッド)などで
最後にマウス動かしたときからの時間経過をチェックします

上を実装すればお望みの動作になります
(制度をそれほど仏用としないのであればタイマーイベントで十分でしょう)
    • good
    • 0
この回答へのお礼

いつもお世話になります。
koi1234さんのご教授を参考にプログラムを作成してみました。

(1)WM_MOUSEMOVEで現在時刻を取得。
(2)SetTimer関数を使い1000ミリ秒単位でWM_TIMERを呼び出す。
(3)WM_TIMERが呼び出されるたびに時刻を取得し、
 WM_MOUSEMOVEで取得した時刻との差を計算して、(ex.3秒たったら)
 マウスカーソルを非表示にする。

といったプログラムを作成したのですが、
実行してもマウスカーソルはずっと表示されたままで非表示になりませんでした。

1つ1つ見ていくと、(1)と(2)はできているようです。
(3)は正確に3秒をはかれないため確かめることはできず、
if文で判定しているのですがそのif文はできているようです。

となると、差を求めるときの計算方法が違うのでしょうか。
現在時刻を取得し、
 (時間 * 3600) + (分 * 60) + 秒
で秒単位で計算して差を求めています。
1000ミリ秒単位でWM_TIMERを呼び出しているために
誤差などが生じて正確に差を「3」と計算できないのでしょうか。

ここに質問してしまってごめんなさい。
もう少し試行錯誤してみます。

お礼日時:2010/01/18 11:10

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!