初めまして、よろしくお願いします。
WinXP Home(SP3) VC++6.0 C言語
一定時間、PC操作を行わないでいるとカーソルを非表示にするソフトを開発中なのです
が、
他のウィンドウ内にカーソルがある場合にカーソルを非表示にしたいのですが、
どうしたら良いのでしょうか?
案としてSetSystemCursorで、自作したカーソルの無いカーソルを設定する方法を行った
のですが、上手く非表示になりませんでした。
(上手く非表示になるものもありましたが全てではなかったです)
ShowCursorのようにシステムカーソルの表示・非表示を切り替えることが出来るような方
法は無いのでしょうか?
非表示にした所で、クリック関係の処理は走るよね?
基本的にウインドウ内の処理は、そのウインドウのプロセスが優先のはずですから
そのプロセスでマウスカーソルの制御をしていれば、そっちが優先されるのは
仕様通りの動作ではないかと思います。
普通に外から操作するような方法では無理じゃないでしょうか。
それこそAPIをフックでもすれば可能かもしれませんけれど。
あと、仮にフックで出来たとしても各アプリで行っている処理を邪魔するような
ソフトでは使う方からみたら迷惑なソフトになってしまいます。
一時的にカーソルが消せたとしてもカーソルが表示されたら各アプリの設定状態の
通りに表示されるようにきちんとハンドリングする必要があるはずです。
あと、既に書き込まれていますが、
マウスカーソルを非表示にする目的が良くわかりません。
どういう目的で非表示にしたいのでしょう?
それとも非表示にする事自体が目的なんでしょうか。
失礼、そのウインドウのプロセスが優先と言うのは言い過ぎかも。
基本的には後勝ちですね。
設定を上書きするイメージ。
システム設定はアプリが何もしなければそれを使うでしょうけれど、
アプリ側で設定を変えていれば、そっちが優先されると思います。
システム設定と言うのはアプリで設定しない時の既定値扱いだと思えば良いかと。
ウインドウハンドルを使って外から設定することも出来るでしょうけれど、
アプリ側で設定を変えられれば、そっちが上書きされるので必ずしも思った通りには
ならないでしょうと言う話です。
>他のウィンドウ内にカーソルがある場合にカーソルを非表示にしたいのですが、
>どうしたら良いのでしょうか?
多分できません。
カーソルの形状は、その直下のウインドウに送られた
WM_SETCURSORのタイミングを含めて、常時変更可能です。
従ってこれらを適切に処理しているウインドウに対して
カーソル形状を強制する手段はありません。
当たり前ですが、カーソルなどシステムに唯一のリソースを
特定のアプリケーションが独占することは好ましくありませんし、
また簡単な方法も用意されていません。これはOSの
設計上のポリシーであると考えるべきです。
もしかして、
イメージは、DVD再生ソフトの全画面表示とかそんなやつですか?
だとしたら、そういう風に伝わってないかも。
そういうイメージだと仮定するなら、
全画面表示したときに SetCapture()すればよい気がする。
試した訳じゃないので、間違ってたら失礼。
.....さん、PATIOさん、仲澤@失業者さん、bunさん、返信ありがとうございます。
色々と説明不足で申し訳ありません。
>.....さん
>非表示にした所で、クリック関係の処理は走るよね?
はい、非表示にするだけですので、クリックやマウスの移動等は普通に出来るようにしよ
うと思っています。
>bunさん
おっしゃっているように、特定のソフトを全画面表示したときにカーソルが残ってしまい
非常に煩わしく感じたため、Toolを作成し、少しでも快適にしたいと思いました。
実は似たような機能のあるツール(ノーマウスカーソル)があるのですが、そのツールで
は特定のアプリを実行中にのみカーソルを非表示にするような設定が出来ませんでした。
※ちなみにこのツールだと、SetSystemCursorの方法では出来なかった非表示が出来ま
す。
ですから、不可能では無いと思います。
>PATIOさん
貴重なご意見ありがとうございます。
確かにカーソルを変更する場合は、色々と影響が出ますしあんまりスマートな方法ではな
いため、ShowCursorのようにカーソルを表示・非表示に変更できるシステム用の関数があ
るのではないかと考えました。
現時点での構想としましては
(1)WM_CREATE:SetWindowsHookEx関数を使い、キーボード・マウスのイベントをフック
(2) 〃 :SetTimerでタイマーを使用する
(3)WM_USER_HOOK:フックしたイベントが発生したら、KillTimer、SetTimer(タイマーを
リセット)
(4)WM_TIMER :タイマーのイベントが発生したら、KillTimer
(5) 〃 :特定のソフトが最前面の場合、カーソルを非表示にする
の流れをイメージしています。
>仲澤@失業者さん
ご意見ありがとうございます。
仲澤@失業者さんがおっしゃっているWM_SETCURSOR時にカーソルを設定する方法なのです
が、
SetWindowsHookExを使ってウィンドウプロシージャへのメッセージをフックしてカーソル
を設定するとの考えでよろしいのでしょうか?
なるほど、自アプリアクティブ時の話じゃなく、自アプリは常駐して、あらゆる
アプリにおいてカーソルを非表示にするわけですね。
であれば、先の私のコメントは無視してください。
ちなみに、[ノーマウスカーソル]はフックを使っているようですよ。
[NoMCur.dll]をDependencyWalkerでのぞいてみると分かります。
一つだけ意見を。
全画面時にうっとおしいというだけなら、
何も見えなくまでしなくても左下に移動するだけでも十分かなと思いました。
これならマウスカーソルの殆どは画面外に出てしまいますし、
カーソルを弄られていても関係無いかなと。
そのアプリがマウスの位置まで弄ってきたらどうしようもないですけれど。
>SetWindowsHookExを使ってウィンドウプロシージャへのメッセージをフックしてカーソ
ル
>を設定するとの考えでよろしいのでしょうか?
「他のウインドウがカーソルを再設定するのを禁止できない」
ということです。
例えば、カーソルを頻繁に変更するウインドウクラスは、
クラスカーソルをNULLカーソルにしてる場合があります。
従ってこのクラスは好きなタイミングでカーソルを設定
するコードを含んでいます。
デフォルトのコールバックは、このウインドウがクラスカーソルを
持たないので、設定処理を行いません。
つまり、メッセージをフックしただけではカーソルの変更
を禁止できないのではないか、と想像できるわけです。
>bunさん
フックしているのかどうかまで調べていただき本当にありがとうございます。
最終的にはシステムトレイに常駐させ、カーソルの表示・非表示を操作する予定です。
>PATIOさん
ご意見ありがとうございます。
「画面端に移動させて見えなくする」方法ですが、実際にその方法を実践中でして、
有線マウスを使用していると、マウスから手を離すとわずかに動いてしまい、
見えなくなるほど端に寄せるという操作をすることが非常に煩わしく感じています。
そのため、今回のようなツールの開発にいたりました。
>仲澤@失業者さん
解説していただきありがとうございます。
仲澤@失業者さんのクラスカーソルの話に関係するのですが、
SetSystemCursorで設定できないウィンドウ(ソフト)についてで、
そのソフトはプレイヤーでして、
動画ファイルが指定されている状態だとカーソルがプレイヤー独自のカーソル表示になる
ようです。
つまり、実行ファイル直接起動だとシステムカーソル、その状態で動画ファイルを開くと
独自カーソルを使うようになるみたいです。
その独自カーソルの場合はSetSystemCursorで非表示にすることが出来ないみたいです。
(当然と言えば当然だったのかも知れません…)
※プレイヤーのメニューバーと下部のシークバーや音量調節等の部分は常にシステムカー
ソルのようです。
ですから、カーソルを非表示にする方法として、
案1:対象のウィンドウがSetCursorしたカーソルをNULLにし、、
非表示中はプレイヤーがSetCursorの処理を行っても無視する
案2:対象のウィンドウのカーソルの表示カウンタを減らす(ShowCursor)
の案が思い浮かんだのですが、どれが現実的に可能そうでしょうか?
もしくは、他にも案があるのでしょうか?
質問ばかりで申し訳ありません;;
◆補足
参考にならないかも知れませんが、ノーマウスカーソルの
非表示にする処理をSpy++でメッセージを確認したところ、
非表示になった瞬間5つのメッセージが発生していました。
S.......WM_NCHITTEST xPos:543 yPos:573
R.......WM_NCHITTEST nHittest:HTCLIENT
S.......WM_SETCURSOR hwnd:00104C2 nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
R.......WM_SETCURSOR fHaltProcessing:False
P..WM_MOUSEMOVE fwKeys:0000 xPos:150 yPos:79
どうやら、普通にマウスを移動したときと同じメッセージが発生しているようです。
【長文失礼しました】
ノーマウスカーソルを真似して作ろうとしているならですが...
問題の動画ファイルプレイヤーで、カーソルを消せていますか?
消せていないなら、真似する方法ではできないのは当たり前なわけです。
何か別の方法を考えねばなりません。
ただ、仲澤@失業者さんが、
「他のウインドウがカーソルを再設定するのを禁止できない」
とおっしゃっていますので、かなり厳しいと思います。
> 「画面端に移動させて見えなくする」方法ですが、実際にその方法を実践中でして、
> 有線マウスを使用していると、マウスから手を離すとわずかに動いてしまい、
> 見えなくなるほど端に寄せるという操作をすることが非常に煩わしく感じています。
> そのため、今回のようなツールの開発にいたりました。
多分、意図が伝わっていないと思うので書いときますが、
要するにそのマウスカーソルを動かすという部分をツールでやれば?
という話です。
目的のウインドウが最大化されていて最前面になった時や
最前面の状態で最大化された時にマウスカーソルを画面の左下に強制的に移動する
ツールにしてしまえば、良いのではないかなと。
座標指定をしますからぴったり左下にもって行く事ができると思います。
常時、そこに移動するようにしてしまうとマウスの操作ができなくなってしまいますから
最大化や最前面に切り替わった時だけ移動するようにすれば、それ以降の操作は
可能になります。
マウスカーソルを消すよりも簡単に行なえるのではないかと思います。
これだとマウスカーソルの形を気にする必要も有りません。
bunさん、PATIOさん、返信ありがとうございます。
>問題の動画ファイルプレイヤーで、カーソルを消せていますか?
はい、ノーマウスカーソルではカーソルを非表示にすることが出来ています。
>最前面の状態で最大化された時にマウスカーソルを画面の左下に強制的に移動する
なるほど、おっしゃる通りのやり方なら実装可能だと思います。
残念ながらそのプレイヤーだと、上端にカーソルを置くと隠れていたメニューバーが表示
されてしまいます。
また、下端にカーソルを置くと上端同様に隠れていたシークバー等が表示されてしまいま
す。
左右の端だとカーソルを完全に見えなくすることは出来ないみたいです。
PATIOさんの話を聞いて、さらにノーマウスカーソルを調べてみたところ、
カーソルを非表示にしてもカーソルの位置は変わっていないようです。
そして、WM_TIMERを使ってカーソルを非表示にしているみたいです。
う~ん…一体ノーマウスカーソルはどうやって非表示にしているのでしょうか…。
やっぱり、カーソルを非表示にするツール制作は諦めるべきなのでしょうか?