/// <summary> /// Initializes a new instance of the <see cref="RawInputMessageFilter"/> class. /// </summary> /// <param name="keyboardDevices">The keyboard devices that are registered with the raw input provider.</param> /// <param name="pointingDevices">The pointing devices that are registered with the raw input provider.</param> /// <param name="hidDevices">The HID devices that are registered with the raw input provider.</param> /// <param name="hwnd">The window handle to the main application window.</param> /// <param name="hookDirectly"><b>true</b> to hook the windows message procedure directly, or <b>false</b> to install a WinForms message filter.</param> /// <exception cref="System.ComponentModel.Win32Exception">Thrown when the message hook could be applied to the window.</exception> public RawInputMessageFilter( Dictionary <DeviceKey, IRawInputDeviceData <GorgonRawKeyboardData> > keyboardDevices, Dictionary <DeviceKey, IRawInputDeviceData <GorgonRawMouseData> > pointingDevices, Dictionary <DeviceKey, IRawInputDeviceData <GorgonRawHIDData> > hidDevices, IntPtr hwnd, bool hookDirectly) { _keyboardDevices = keyboardDevices; _mouseDevices = pointingDevices; _hidDevices = hidDevices; if ((Interlocked.Increment(ref _hookInstalled) == 1) && (_hwnd == IntPtr.Zero)) { _hwnd = hwnd; } _directHook = hookDirectly; // Add a message filter to allow for processing of raw input. if (!hookDirectly) { Application.AddMessageFilter(this); } else { MessageFilterHook.AddFilter(hwnd, this); } }
protected override void OnClosed(EventArgs e) { if (EnableMessageBypass) { MessageFilterHook.RemoveMessageFilter(this.Handle, this); } }
/// <summary> /// Registers the devices that supply the raw input data. /// </summary> /// <param name="usagePage">The usage page.</param> /// <param name="usageId">The usage id.</param> /// <param name="flags">The flags.</param> /// <param name="target">The target.</param> /// <param name="options">The options.</param> public static void RegisterDevice(UsagePage usagePage, UsageId usageId, DeviceFlags flags, IntPtr target, RegisterDeviceOptions options = RegisterDeviceOptions.Default) { var rawInputDevices = new RawInputDevice[1]; rawInputDevices[0].UsagePage = (short)usagePage; rawInputDevices[0].Usage = (short)usageId; rawInputDevices[0].Flags = (int)flags; rawInputDevices[0].Target = target; // Register this device RawInputFunctions.RegisterRawInputDevices(rawInputDevices, 1, Utilities.SizeOf <RawInputDevice>()); if (options != RegisterDeviceOptions.NoFiltering && rawInputMessageFilter == null) { rawInputMessageFilter = new RawInputMessageFilter(); if (options == RegisterDeviceOptions.Default) { Application.AddMessageFilter(rawInputMessageFilter); } else { MessageFilterHook.AddMessageFilter(target, rawInputMessageFilter); } } }
public ProxyNativeWindow(Control form) { this._form = form; this._windowHandle = form.Handle; this._form.Disposed += new EventHandler(this._form_Disposed); MessageFilterHook.AddMessageFilter(this._windowHandle, (IMessageFilter)this); this._isAlive = true; }
/// <summary> /// Initializes a new instance of the <see cref="ProxyNativeWindow"/> class. /// </summary> public ProxyNativeWindow(Control form) { _form = form; _windowHandle = form.Handle; _form.Disposed += _form_Disposed; MessageFilterHook.AddMessageFilter(_windowHandle, this); _isAlive = true; }
public static void ClearMessageFilter() { if (m_filter != null) { MessageFilterHook.RemoveMessageFilter(m_filterWindow, m_filter); m_filter = null; m_filterWindow = IntPtr.Zero; } }
protected override void OnLoad(EventArgs e) { m_isLoaded = true; if (EnableMessageBypass) { MessageFilterHook.AddMessageFilter(this.Handle, this); } base.OnLoad(e); }
// This allocates, however it should be used only when launching app public static void RegisterDevice(UsagePage usagePage, UsageId usageId, DeviceFlags flags, IntPtr target) { Device.RegisterDevice(usagePage, usageId, flags, target, false); if (m_filter == null) { m_filterWindow = target; m_filter = new RawInputMessageFilter(); MessageFilterHook.AddMessageFilter(m_filterWindow, m_filter); } }
public static void FixKeyboard(Game game) { IntPtr hWnd = game.Window.Handle; Device.RegisterDevice(UsagePage.Generic, UsageId.GenericKeyboard, DeviceFlags.None, hWnd, RegisterDeviceOptions.Default); var filter = new RawInputMessageFilter(); filterCache[hWnd] = filter; MessageFilterHook.AddMessageFilter(hWnd, filter); }
public static void ReleaseKeyboard(Game game) { RawInputMessageFilter filter; IntPtr hWnd = game.Window.Handle; if (filterCache.TryGetValue(hWnd, out filter)) { MessageFilterHook.RemoveMessageFilter(hWnd, filter); filterCache.Remove(hWnd); } }
/// <summary> /// Stops processing the raw input messages received by the application. /// </summary> /// <remarks> /// Call this function to stop filtering and processing raw input messages through the message pump of the target window as /// previously specified by a call to <see cref="StartProcessingMessages"/>. /// <para/> /// This function removes any <see cref="IMessageFilter"/> previosly installed. /// </remarks> public static void StopProcessingMessages() { if (rawInputMessageFilter is null) { return; } Application.RemoveMessageFilter(rawInputMessageFilter); MessageFilterHook.RemoveMessageFilter(targetWindowHandle, rawInputMessageFilter); rawInputMessageFilter = null; targetWindowHandle = default; }
public static void AddMessageFilter(IntPtr hwnd, IMessageFilter messageFilter) { lock (MessageFilterHook.RegisteredHooks) { hwnd = MessageFilterHook.GetSafeWindowHandle(hwnd); MessageFilterHook local_0; if (!MessageFilterHook.RegisteredHooks.TryGetValue(hwnd, out local_0)) { local_0 = new MessageFilterHook(hwnd); MessageFilterHook.RegisteredHooks.Add(hwnd, local_0); } local_0.AddMessageMilter(messageFilter); } }
/// <summary> /// Calls this method on each frame. /// </summary> /// <returns><c>true</c> if if the control is still active, <c>false</c> otherwise.</returns> /// <exception cref="System.InvalidOperationException">An error occured </exception> public bool NextFrame() { // Setup new control // TODO this is not completely thread-safe. We should use a lock to handle this correctly if (switchControl && control != null) { controlHandle = control.Handle; control.Disposed += ControlDisposed; MessageFilterHook.AddMessageFilter(control.Handle, this); isControlAlive = true; switchControl = false; } if (isControlAlive) { if (UseCustomDoEvents) { var localHandle = controlHandle; if (localHandle != IntPtr.Zero) { // Previous code not compatible with Application.AddMessageFilter but faster then DoEvents Win32Native.NativeMessage msg; while (Win32Native.PeekMessage(out msg, localHandle, 0, 0, 0) != 0) { if (Win32Native.GetMessage(out msg, localHandle, 0, 0) == -1) { throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "An error happened in rendering loop while processing windows messages. Error: {0}", Marshal.GetLastWin32Error())); } Win32Native.TranslateMessage(ref msg); Win32Native.DispatchMessage(ref msg); } } } else { // Revert back to Application.DoEvents in order to support Application.AddMessageFilter // Seems that DoEvents is compatible with Mono unlike Application.Run that was not running // correctly. Application.DoEvents(); } } return(isControlAlive || switchControl); }
/// <summary> /// Starts processing the raw input messages received by the application. /// </summary> /// <param name="windowHandle">Handle to the target window that will receive the messages.</param> /// <param name="options">The options for the processing and filtering of messages.</param> /// <remarks> /// Call this function to start filtering and processing raw input messages through the message pump of a target window. /// <para/> /// Using this function, the raw input data is processed one message at a time. In contrast, you can use buffered processing /// by calling <see cref="ProcessMessages"/> to process the queued raw input messages in bulk. /// <para/> /// This function installs a <see cref="IMessageFilter"/> that intercepts and processes the raw input messages received by /// the application. See <see cref="MessageProcessingOptions"/> enumeration for more information. /// </remarks> public static void StartProcessingMessages(IntPtr windowHandle = default, MessageProcessingOptions options = MessageProcessingOptions.Default) { if (rawInputMessageFilter != null) { return; } targetWindowHandle = windowHandle; rawInputMessageFilter = new RawInputMessageFilter(); if (options == MessageProcessingOptions.Default) { Application.AddMessageFilter(rawInputMessageFilter); } else { MessageFilterHook.AddMessageFilter(windowHandle, rawInputMessageFilter); } }
/// <summary> /// Private rendering loop /// </summary> public void Run(RenderCallback renderCallback) { // Show the form _form.Show(); // Main rendering loop); while (_isAlive) { if (UseCustomDoEvents) { // Previous code not compatible with Application.AddMessageFilter but faster then DoEvents Win32Native.NativeMessage msg; while (Win32Native.PeekMessage(out msg, _windowHandle, 0, 0, 0) != 0) { if (Win32Native.GetMessage(out msg, _windowHandle, 0, 0) == -1) { throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "An error happened in rendering loop while processing windows messages. Error: {0}", Marshal.GetLastWin32Error())); } Win32Native.TranslateMessage(ref msg); Win32Native.DispatchMessage(ref msg); } } else { // Revert back to Application.DoEvents in order to support Application.AddMessageFilter // Seems that DoEvents is compatible with Mono unlike Application.Run that was not running // correctly. Application.DoEvents(); } if (_isAlive) { renderCallback(); } } _form.Disposed -= _form_Disposed; MessageFilterHook.RemoveMessageFilter(_windowHandle, this); }
/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { if (!_directHook) { Application.RemoveMessageFilter(this); } else { if (_hwnd != IntPtr.Zero) { MessageFilterHook.RemoveFilter(_hwnd, this); } } _directHook = false; if (Interlocked.Decrement(ref _hookInstalled) == 0) { _hwnd = IntPtr.Zero; } GC.SuppressFinalize(this); }
public void Run(RenderLoop.RenderCallback renderCallback) { this._form.Show(); while (this._isAlive) { if (RenderLoop.UseCustomDoEvents) { Win32Native.NativeMessage lpMsg; while (Win32Native.PeekMessage(out lpMsg, this._windowHandle, 0, 0, 0) != 0) { if (Win32Native.GetMessage(out lpMsg, this._windowHandle, 0, 0) == -1) { throw new InvalidOperationException(string.Format((IFormatProvider)CultureInfo.InvariantCulture, "An error happened in rendering loop while processing windows messages. Error: {0}", new object[1] { (object)Marshal.GetLastWin32Error() })); } else { Win32Native.TranslateMessage(ref lpMsg); Win32Native.DispatchMessage(ref lpMsg); } } } else { Application.DoEvents(); } if (this._isAlive) { renderCallback(); } } this._form.Disposed -= new EventHandler(this._form_Disposed); MessageFilterHook.RemoveMessageFilter(this._windowHandle, (IMessageFilter)this); }
protected override void OnClosed(EventArgs e) { MessageFilterHook.RemoveMessageFilter(base.Handle, this); }
protected override void OnLoad(EventArgs e) { MessageFilterHook.AddMessageFilter(this.Handle, this); base.OnLoad(e); }
public static void SetWindow(IntPtr windowHandle) { m_windowHandle = windowHandle; MessageFilterHook.AddMessageFilter(windowHandle, new MouseMessageFilter()); }