
カーソルの移動量(GetCursorPosで可)でなく、マウス自体の移動量を取得する事は出来ないのでしょうか?
マウスカーソルはディスプレイの端に行くと動作が止まってしまいます。とにかく2次元の自由な動作を取得してアプリで使用したいのですが、マウスの動作が最適です。そこで、マウスカーソルは動作を停止させ(止めて)、マウス自体の移動量が取得できないかいろいろ試しました。
試したのが以下の方法です。
・マウスカーソルを画面の中央に強制移動、
・マウスカーソルを消す(タイプをcrNoneに設定)、
・マウスの移動を検知すると、中央からの移動量取得
・再び、見えないマウスを中央に強制移動
しかし、メッセージキューに入っている情報がFIFOの様で、移動量取得と中央への強制移動が同期せず、うまく値が取れません。
何か方法があれば御教授お願いいたします。BCBで開発しています。
A 回答 (7件)
- 最新から表示
- 回答順に表示
No.6
- 回答日時:
僕はC++を使っているので、Win32APIについて(ちなみにXP使用)。
GetMouseMovePointsEx()を使えば、カーソルが画面から出た時の座標も取得できます。ただWindowsが勝手に画面内に戻すので、「画面から出る」と「画面内に戻る」はメッセージにはならないようです。余計なお世話かもしれませんが、Windowsはカーソルの位置x、yそれぞれをshort(2バイトの2の補数表現)で扱うので、そのまま使うとマイナスの値が65500ぐらいになるかもしれません。No.5
- 回答日時:
>以下上記の繰り返し、となるのでだけれど、PeekMessageでは実際のマウスの移動でなく、
>SetCursorPosのキューに入っている移動の方を削除しているということはありえませんか。
では、順番を逆にして、SetCursorPosを呼んだ後にPeekMessageでキューから削除してみてはどうですか?
ただし、無条件に削除するのではなくmsg構造体の中を見て
座標がSetCursorPosで指定した座標が入るのを確認するまで。もちろん指定した座標が入ってたら削除しちゃだめですよ。
No.4
- 回答日時:
>例えば、右側にマウスをずーと動かし続けると、10回のサンプル間はマウスカーソルは右に動き続け、
>11回目のサンプル(FromMouseMoveが呼ばれた時)で中央に強制移動し、12回目以降はマウスカーソルは再び右側に動き始める、となります。
一応ヒントを。
SetCursorPosを呼ぶ直前に、PeekMessageでWM_MOUSEMOVEをキューから削除すれば平気かと。
念のために書いておきますが、マウスの移動情報から必ずメッセージ生成が行われているわけではありません。システムに負荷がかかると簡単にマウスカーソルの移動がとまっちゃうことから一目瞭然ですよね。
この回答への補足
やっぱりできないのでは?
マウスを見えるようして、変移量をTMemoに表示させながらチェックしました。そして、SetCursorPosの直前に以下を入れました。
MSG msg;
while(PeekMessage(&msg, NULL, WM_MOUSEMOVE,WM_MOUSEMOVE, PM_REMOVE));
WM_MOUSEFIRST/WM_MOUSELASTを指定してあげればマウスカーソルが移動中のマウスクリックは無視しますので、構文自体は合っているようです。
シーケンシャルに考えてみると
FromMouseMove (WM_MOUSEMOVE)
__X,Yの処理
__PeekMessageでWM_MOUSEMOVEの除去
__SetCursorPosでマウス移動
FromMouseMove (WM_MOUSEMOVE)
__X,Yの処理
__PeekMessageでWM_MOUSEMOVEの除去
__SetCursorPosでマウス移動
以下上記の繰り返し、となるのでだけれど、PeekMessageでは実際のマウスの移動でなく、SetCursorPosのキューに入っている移動の方を削除しているということはありえませんか。仮にそうだとすると、何時SetCursorPosが終了したかの判定は無理では無いでしょうか?宜しければコメントをいだだければ幸いです。
ヒントをありがとうございます。できるということなので、なんとかがんばりたいと思います。
ちょっとやってみたのですがうまくいかず、月曜日以降、更に試行錯誤してみようと思います(これから出かけてしまいますので)。
No.3
- 回答日時:
BCBで作ってみたけど、質問の方法で上手く動いていますよ。
void __fastcall TForm1::FormShow(TObject *Sender)
{
ShowCursor(FALSE);
int cx = ClientWidth/2;
int cy = ClientHeight/2;
TPoint pt0(cx, cy);
TPoint pt = ClientToScreen(pt0);
SetCursorPos(pt.x, pt.y);
}
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
static int sX, sY;
int cx = ClientWidth/2;
int cy = ClientHeight/2;
if (X==cx && Y==cy) return;
sX += X-cx;
sY += Y-cy;
AnsiString s;
Caption = s.sprintf("%d %d", sX, sY);
TPoint pt0(cx, cy);
TPoint pt = ClientToScreen(pt0);
SetCursorPos(pt.x, pt.y);
}
この回答への補足
実際にプログラミングして頂き大変恐縮です。
私も同じようなコードを試しました。一見うまく動いているようですが、動作のログを取ると思ったように動いていません。
最下行で SetCursorPos()でカーソルを移動しているのですが、次の FromMouseMove が呼ばれた時には未だカーソルは強制的に中央に移動していません。例えば、右側にマウスをずーと動かし続けると、10回のサンプル間はマウスカーソルは右に動き続け、11回目のサンプル(FromMouseMoveが呼ばれた時)で中央に強制移動し、12回目以降はマウスカーソルは再び右側に動き始める、となります。つまり、何時、マウスカーソルが中央に移動したかプログラム側では判定の方法が無いのです。
この方法で、マウス自体の絶対移動変移量を取る事はできないのでしょうか。
No.2
- 回答日時:
APIレベルではがんばっても無理ですね。
一番低レベルなWH_MOUSE_LLフックを使っても座標までしか取れません。
マウスカーソルではなく、マウスそのものの移動量を取得したいとなると、デバイスドライバを書かないと無理じゃないでしょうかね。
No.1
- 回答日時:
実際の処理が見えませんが、これでOKなハズです。
画面端から逆の端にマウスをワープさせるオンラインソフト
WarpPointer 2.21
http://www.vector.co.jp/soft/win95/util/se070373 …
ループ 1.05
http://www.vector.co.jp/soft/win95/util/se141539 …
Warp 1.02
http://www.vector.co.jp/soft/win95/util/se128267 …
みたいな事が実際に出来ますし。
--
> メッセージキューに入っている情報が
などの原因まで分かっているのなら、余分にメッセージを取り出すとかなんとか。
回答ありがとうございます。
マウスをワープさせるコードは何となくイメージできます。本当は、マウスカーソル自体を動作させないで、マウスからの動作量だけを取得したいと思っています。メッセージキューについてもBCBで開発していることもあり、いまいち自信もなく、もっとスマートな方法があればと思っています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Vba Replace関数について教えて...
-
CSSが全く分かりません、お助け...
-
CPUが16bitでも32bitOSでコンパ...
-
最初に聞かれたこと
-
DLLファイルの逆コンパイラにつ...
-
C言語 関数、変数の宣言について
-
C言語でファクト関数を使わずに...
-
あってる
-
DNCL(共テ用プログラミング言語...
-
バッチファイルで以下のような...
-
visual studio 2022でのC#プロ...
-
プログラミングc++を全く分か...
-
DNCL(共テ用プログラミング言語...
-
C言語 配列と関数の練習問題
-
gccを行ってもexeファイルが生...
-
c言語
-
VisualStudio2022でC言語プログ...
-
ストリームについて。
-
Cのオブジェクトファイルの逆ア...
-
Windows Formアプリからコンソ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
マウス自体の移動量の取得
-
C言語でのマウスを移動とマウス...
-
画面の範囲選択
-
ActionScript2.0での座標
-
楕円の軌道に傾斜をつける方法...
-
FlashLite1.1での当り判定
-
Actionscriptでふわふわ感を再...
-
スクリーン中央を中心にズーム...
-
VBAユーザーホームテキストボッ...
-
変数に256文字以上のテキストを...
-
VB6.0で、フォームから、別のフ...
-
四乗根を英語で言うと・・・
-
photoshopで書いた四角の枠の中...
-
python ボタンを押すと複数の関...
-
テキストボックスの中身をリセ...
-
【VB.NET】別Formのボタンが押...
-
VBAで改行の入ったデータの正規...
-
UWSCのBTN関数について。
-
テキストボックスにセルの値を...
-
FLASHで脱出ゲームを作る時の、...
おすすめ情報