/// <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;
        }
        /// <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);
            }
        }