/// <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);
     }
 }
Exemple #3
0
        /// <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);
                }
            }
        }
Exemple #4
0
 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;
 }
Exemple #5
0
 /// <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;
 }
Exemple #6
0
 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);
 }
Exemple #8
0
 // 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);
        }
Exemple #10
0
        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);
            }
        }
Exemple #11
0
        /// <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;
        }
Exemple #12
0
 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);
       }
 }
Exemple #13
0
        /// <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);
        }
Exemple #14
0
        /// <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);
            }
        }
Exemple #15
0
            /// <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);
        }
Exemple #17
0
 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);
 }
Exemple #18
0
 protected override void OnClosed(EventArgs e)
 {
     MessageFilterHook.RemoveMessageFilter(base.Handle, this);
 }
Exemple #19
0
 protected override void OnLoad(EventArgs e)
 {
     MessageFilterHook.AddMessageFilter(this.Handle, this);
     base.OnLoad(e);
 }
Exemple #20
0
 public static void SetWindow(IntPtr windowHandle)
 {
     m_windowHandle = windowHandle;
     MessageFilterHook.AddMessageFilter(windowHandle, new MouseMessageFilter());
 }