很晚了,但我想我会分享一些东西。从这里收集有一些提示,例如将 SetWindowsHookEx 放在单独的线程中,这更像是一个调度问题。
我还注意到 Application.DoEvents 使用了相当多的 CPU,并发现 PeekMessage 使用较少。
public static bool active = true;
[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
public IntPtr handle;
public uint msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool PeekMessage(out NativeMessage message,
IntPtr handle, uint filterMin, uint filterMax, uint flags);
public const int PM_NOREMOVE = 0;
public const int PM_REMOVE = 0x0001;
protected void MouseHooker()
{
NativeMessage msg;
using (Process curProcess = Process.GetCurrentProcess())
{
using (ProcessModule curModule = curProcess.MainModule)
{
// Install the low level mouse hook that will put events into _mouseEvents
_hookproc = MouseHookCallback;
_hookId = User32.SetWindowsHookEx(WH.WH_MOUSE_LL, _hookproc, Kernel32.GetModuleHandle(curModule.ModuleName), 0);
}
}
while (active)
{
while (PeekMessage(out msg, IntPtr.Zero,
(uint)WM.WM_MOUSEFIRST, (uint)WM.WM_MOUSELAST, PM_NOREMOVE))
;
Thread.Sleep(10);
}
User32.UnhookWindowsHookEx(_hookId);
_hookId = IntPtr.Zero;
}
public void HookMouse()
{
active = true;
if (_hookId == IntPtr.Zero)
{
_mouseHookThread = new Thread(MouseHooker);
_mouseHookThread.IsBackground = true;
_mouseHookThread.Priority = ThreadPriority.Highest;
_mouseHookThread.Start();
}
}
所以只需在 Deactivate 事件中将 active bool 更改为 false 并在 Activated 事件中调用 HookMouse。
高温高压
编辑:我注意到游戏因此变慢了,所以决定在应用程序不活动时使用 Activated 和 Deactivate 事件取消挂钩。