Mondial de la souris gestionnaire d'événements
J'ai le code suivant que j'ai obtenu à partir de quelque part pour capturer les événements de la souris. Je l'ai modifié et fait un gestionnaire d'événements, de sorte que je peux y souscrire. Les événements de souris sont saisies correctement. Mais il n'est jamais déclenché le gestionnaire d'événements. Quelqu'un peut-il comprendre à quoi de mal avec le code?
public static class MouseHook
{
public static event EventHandler MouseAction = delegate { };
public static void Start()
{
_hookID = SetHook(_proc);
}
public static void stop()
{
UnhookWindowsHookEx(_hookID);
}
private static LowLevelMouseProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
private static IntPtr SetHook(LowLevelMouseProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_MOUSE_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
{
MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
MouseAction(null,new EventArgs());
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
private const int WH_MOUSE_LL = 14;
private enum MouseMessages
{
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_MOUSEMOVE = 0x0200,
WM_MOUSEWHEEL = 0x020A,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public uint mouseData;
public uint flags;
public uint time;
public IntPtr dwExtraInfo;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
Je abonnez-vous à lui comme ça.
MouseHook.Start();
MouseHook.MouseAction += new EventHandler(Event);
Fonction de la réception de l'événement.
private void Event(object sender, EventArgs e) { Console.WriteLine("Left mouse click!"); }
Mise à jour:
J'ai mis en place le code de travail dans un open source de package nuget pour l'action de l'utilisateur crochets.
- Cela ne peut pas fonctionner dans une application en mode console, votre programme doit pomper une boucle de message. Application.Run() est nécessaire.
- J'utilise le code ci-dessus à l'intérieur de mon application WPF. J'appelle le MouseHook classe à partir de l'App.cs' Onstartup méthode.
- Pour tout le sentiment que cela provoque la souris pour faire glisser, exécutez-le dans un autre processus élevés et l'utilisation des threads séparés pour gérer les événements.
Vous devez vous connecter pour publier un commentaire.
Ce code va échouer lorsque vous l'exécutez sur .NET 4 sur une version de Windows antérieure à Windows 8. Le CLR ne simule plus non géré poignées de module de gestion des assemblées. Vous ne pouvez pas détecter cette panne dans votre code, car il est absent de la nécessaire vérification des erreurs. À la fois sur GetModuleHandle et SetWindowsHookEx. Ne jamais sauter de vérification d'erreur lorsque vous pinvoke, la winapi ne jette pas des exceptions. Vérifier si ils reviennent IntPtr.Zéro et de tout simplement jeter un Win32Exception quand ils le font.
La solution est simple, SetWindowsHookEx() nécessite un valide le module de poignée mais ne fait pas l'utiliser lorsque vous définissez un faible niveau de souris crochet. Donc, une poignée allez faire, vous pouvez passer à la poignée pour user32.dll, toujours chargé en un .NET application. Correctif:
J'ai juste copié le code dans un simple formulaire de windows et de son travail comme vous l'avez décrit, il devrait. Comment l'utilisez-vous exactement? Où en êtes-vous de départ et fixation de l'événement?
Et par souci d'exhaustivité c'est le code que j'ai retrouvé avec - a commencé à partir d'une simple C# de modèle de formulaire