2

画面上でマウスが動かなくても、マウスの移動方向を取得することはできますか?たとえば、エッジと衝突します。

編集:ユーザーはマウスを上に移動し、画面の上端に衝突します。それから彼はマウスを上に動かし続けます。したがって、マウスは現実の世界では動きますが、画面上では動かないため、動きません。そして、マウスがどの方向にATMを動かしているかを知らせる信号などを取得したいと思います。

4

1 に答える 1

0

私が見ているように、基本的にあなたが求めているのは、マウスが画面の端にあり、端の方向に移動しようとしているケースをどのように検出できるかということです。当然、MouseMove座標が変更されていないため、イベントはこれを検出しません。

カーソルの位置が変わっていなくても、グローバルな低レベルのマウスフックを使用することが、マウス移動メッセージを取得する唯一の方法である可能性があります。

これにより、最後のメッセージ以降に座標が変更されたかどうかを確認できます。そうでない場合は、画面の端にいる可能性があります。

public partial class Form1 : Form
{
    private const int WH_MOUSE_LL = 14;
    private const int WM_MOUSEMOVE = 0x200;

    [DllImport("kernel32.dll")]
    static extern IntPtr GetModuleHandle(string moduleName);

    [DllImport("user32.dll")]
    static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll")]
    public static extern int UnhookWindowsHookEx(IntPtr hhook);

    [DllImport("user32.dll")]
    static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, uint wParam, IntPtr lParam);
    delegate IntPtr HookProc(int nCode, uint wParam, IntPtr lParam);

    [StructLayout(LayoutKind.Sequential)]
    public struct MSLLHOOKSTRUCT
    {
        public POINT pt;
        public int mouseData; // be careful, this must be ints, not uints (was wrong before I changed it...). regards, cmew.
        public int flags;
        public int time;
        public UIntPtr dwExtraInfo;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int X;
        public int Y;
    }

    private HookProc hookProc;
    private IntPtr hook;

    private POINT formerPoint = new POINT() { X = 0, Y = 0 };

    public Form1() { InitializeComponent(); }

    IntPtr LowLevelMouseProc(int nCode, uint wParam, IntPtr lParam)
    {
        if (wParam == WM_MOUSEMOVE)
        {
            MSLLHOOKSTRUCT infoStr = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
            if (infoStr.pt.X == formerPoint.X && infoStr.pt.Y == formerPoint.Y)
            {
                Console.WriteLine("Mouse moved without coordinates changing");
                //use the standard way of finding the direction of travel here.
            }
            formerPoint = infoStr.pt;
        }
        return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam);
    }

    protected override void OnHandleDestroyed(EventArgs e)
    {
        UnhookWindowsHookEx(hook);
        base.OnHandleDestroyed(e);
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        if (!DesignMode)
        {
            hookProc = new HookProc(LowLevelMouseProc);
            hook = SetWindowsHookEx(WH_MOUSE_LL, hookProc, GetModuleHandle(null), 0);
        } 
    }
}

*フックコードはこのブログから取得されました

この方法の問題は、マウスがマウスメッセージごとに1ピクセルより遅く移動している場合、誤検知が生成されることです。

これに対する可能な部分的な解決策は、画面の端のX値とY値を事前に検出し、それらもテストすることですが、これでも、マウスが(例)画面の右端で非常にゆっくりとに移動します(1ピクセル未満)。これでもポジティブとして検出されます。

おそらく誰かがこれらの誤検知を排除する方法についてより良い考えを持っています。

于 2012-09-06T11:29:20.567 に答える