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.