2 Stimmen

c# Wie kann man die Bewegungsrichtung der Maus ermitteln?

Ist es möglich, die Bewegungsrichtung der Maus zu bestimmen, obwohl sich die Maus auf dem Bildschirm nicht bewegt? Zum Beispiel kollidiert sie mit einer Kante.

bearbeiten: Der Benutzer bewegt die Maus nach oben und stößt mit dem oberen Rand des Bildschirms zusammen. Dann bewegt er die Maus weiter nach oben. Die Maus bewegt sich also in der realen Welt, aber sie bewegt sich nicht auf dem Bildschirm, weil sie das nicht kann. Und ich möchte ein Signal oder irgendetwas anderes bekommen, das mir sagt, in welche Richtung sich die Maus gerade bewegt.

0voto

Rotem Punkte 20943

So wie ich das sehe, fragen Sie im Grunde, wie Sie einen Fall erkennen können, in dem sich die Maus am Rand des Bildschirms befindet und versucht, sich in Richtung des Randes zu bewegen. Natürlich ist ein MouseMove wird dies nicht erkannt, da sich die Koordinate nicht geändert hat.

Die Verwendung eines globalen Low-Level-Maus-Hooks ist möglicherweise die einzige Möglichkeit, eine Mausbewegungsmeldung zu erhalten, auch wenn der Cursor seine Position nicht verändert hat.

Damit kann überprüft werden, ob sich die Koordinate seit der letzten Meldung geändert hat oder nicht. Wenn dies nicht der Fall ist, befinden wir uns möglicherweise am Rand des Bildschirms.

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);
        } 
    }
}

*Der Hakencode stammt aus este Blog

Das Problem bei dieser Methode ist, dass, wenn sich die Maus langsamer als 1 Pixel pro Mausmeldung bewegt, ein falsches positives Ergebnis erzeugt wird.

Eine mögliche Teillösung wäre, die X- und Y-Werte der Bildschirmränder im Voraus zu erkennen und auch auf diese zu testen, aber auch dies wird nicht 100 % der falsch-positiven Ergebnisse ausschließen, da es möglich ist, dass sich die Maus (zum Beispiel) auf dem rechts Rand des Bildschirms und bewegen Sie sich sehr langsam links (weniger als 1 Pixel), und dies würde immer noch als positiv erkannt werden.

Vielleicht hat jemand eine bessere Idee, wie man diese Fehlalarme beseitigen kann.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X