Код: Выделить всё
internal class GlobalMouseHook
{
#region events
// declare hook events:
public static event Action MouseMove_Event;
public static event Action LeftDown_Event;
public static event Action RightDown_Event;
public static event Action LeftUp_Event;
public static event Action RightUp_Event;
public static event Action MidDown_Event;
public static event Action MidUp_Event;
#endregion
#region constants
// declare constants:
private const int WH_MOUSE_LL = 14;
private const int WM_MOUSEMOVE = 0x0200;
private const int WM_LBUTTONDOWN = 0x0201;
private const int WM_LBUTTONUP = 0x0202;
private const int WM_RBUTTONDOWN = 0x204;
private const int WM_RBUTTONUP = 0x205;
private const int WM_MBUTTONDOWN = 0x207;
private const int WM_MBUTTONUP = 0x208;
#endregion
public static bool mouseHookActive = false;
private static IntPtr mouseHookid;
private static MouseDelegate mouseDelegate = MouseHookCallback;
private delegate IntPtr MouseDelegate(int nCode, IntPtr wParam, IntPtr lParam);
private static ProcessModule curModule = Process.GetCurrentProcess().MainModule;
private static IntPtr appHandle = GetModuleHandle(curModule.ModuleName);
public static void StartMouseHook() { mouseHookActive = true; mouseHookid = SetWindowsHookEx(WH_MOUSE_LL, mouseDelegate, appHandle, 0); }
public static void StopMouseHook() { mouseHookActive = false; UnhookWindowsHookEx(mouseHookid); }
private static IntPtr MouseHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
// detect hook trigger then select message type and execute action
if (nCode >= 0)
{
using (frmFileToy frm = new frmFileToy())
{
switch ((int)wParam)
{
case WM_MOUSEMOVE: MouseMove_Event?.Invoke(); break;
case WM_LBUTTONDOWN: LeftDown_Event?.Invoke(); break;
case WM_LBUTTONUP: LeftUp_Event?.Invoke(); break;
case WM_RBUTTONDOWN: RightDown_Event?.Invoke(); break;
case WM_RBUTTONUP: RightUp_Event?.Invoke(); break;
case WM_MBUTTONDOWN: MidDown_Event?.Invoke(); break;
case WM_MBUTTONUP: MidUp_Event?.Invoke(); break;
}
}
}
// continue to next hook
return CallNextHookEx(mouseHookid, nCode, wParam, lParam);
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, MouseDelegate lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)][return: MarshalAs(UnmanagedType.Bool)] private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName);
}
Сценарий использования предназначен специально для действия перетаскивания, которое начинается внутри мое приложение и заканчивается за пределами моего приложения перетаскиванием файла на рабочий стол или в другое приложение. Назначение крючка мыши — обнаружить отпускание кнопки мыши при перетаскивании файла.
Нет проблем с движением мыши в окне моего приложения для любого языка. Запаздывающее движение мыши начинается, как только мышь покидает окно моего приложения, то есть когда запускается крючок мыши. В моем коде нет элементов кода, специфичных для конкретного языка, кроме словаря языковых строк, который правильно работает как для «en-US», так и для «de-DE».
Информация о языке и культуре назначается перед «InitializeComponent();» вызывается с помощью следующих операторов:
Код: Выделить всё
using (RegistryKey key = Registry.CurrentUser.CreateSubKey("SOFTWARE\\" + appName))
{
lang = (string)key.GetValue("language", lang);
}
CultureInfo ci = new CultureInfo(lang);
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = ci;
Подробнее здесь: https://stackoverflow.com/questions/781 ... aggy-mouse