Beispiel #1
0
 private void InputDeviceEvents_PreProcessInput(object sender, PreProcessInputEventArgs e)
 {
     if (e.StagingItem.Input.Device is TouchDevice)
     {
         InputReportEventArgs irea = e.StagingItem.Input as InputReportEventArgs;
         if (irea != null)
         {
             RawTouchInputReport rtir = irea.Report as RawTouchInputReport;
             if (rtir != null)
             {
                 int x = rtir.Touches[0].X;
                 int y = rtir.Touches[0].Y;
                 PointToClient(ref x, ref y);
                 if (!Utils.IsWithinRectangle(x, y, ActualWidth, ActualWidth))
                     e.Cancel();
             }
         }
     }
 }
Beispiel #2
0
        private void InputDeviceEvents_PreProcessInput(object sender, PreProcessInputEventArgs e)
        {
            if (e.StagingItem.Input.Device is TouchDevice)
            {
                InputReportEventArgs irea = e.StagingItem.Input as InputReportEventArgs;
                if (irea != null)
                {
                    RawTouchInputReport rtir = irea.Report as RawTouchInputReport;
                    if (rtir != null)
                    {
                        // cancel any touch event that does not start within the modal window
                        //if (!this.ContainsPoint(rtir.Touches[0].X, rtir.Touches[0].Y))
                        //    e.Cancel();

                        int x = rtir.Touches[0].X;
                        int y = rtir.Touches[0].Y;
                        PointToClient(ref x, ref y);
                        if (!Utils.IsWithinRectangle(x, y, ActualWidth, ActualWidth))
                            e.Cancel();
                    }
                }
            }
        }
        private object ProcessStagingArea(object frame)
        {
            bool handled = false;

            // NOTE -- avalon caches the XXXEventArgs.  In our system, the costs are different,
            // so it is probably cheaper for us to just create them, since everything gets created
            // on the heap anyways, and IL is expensive.  we should reconsider this if
            // its a performance impact.

            // Because we can be reentered, we can't just enumerate over the
            // staging area - that could throw an exception if the queue
            // changes underneath us.  Instead, just loop until we find a
            // frame marker or until the staging area is empty.

            try
            {
                while (_stagingArea.Count > 0)
                {
                    _currentStagingStack = _stagingArea.Dequeue() as Stack;

                    do
                    {
                        StagingAreaInputItem item = (StagingAreaInputItem)_currentStagingStack.Pop();

                        // Pre-Process the input.  This could modify the staging
                        // area, and it could cancel the processing of this
                        // input event.
                        //

                        bool fCanceled = false;

                        int devType = (int)item.Input._inputDevice.DeviceType;

                        if (InputDeviceEvents[devType]._preProcessInput != null)
                        {
                            PreProcessInputEventArgs preProcessInputEventArgs;
                            InputDeviceEvents[devType]._preProcessInput(this, preProcessInputEventArgs = new PreProcessInputEventArgs(item));

                            fCanceled = preProcessInputEventArgs._canceled;
                        }

                        if (!fCanceled)
                        {
                            // Pre-Notify the input.
                            //
                            if (InputDeviceEvents[devType]._preNotifyInput != null)
                            {
                                InputDeviceEvents[devType]._preNotifyInput(this, new NotifyInputEventArgs(item));
                            }

                            // Raise the input event being processed.
                            InputEventArgs input = item.Input;

                            // Some input events are explicitly associated with
                            // an element.  Those that are not instead are associated with
                            // the target of the input device for this event.
                            UIElement eventSource = input._source as UIElement;

                            if (eventSource == null && input._inputDevice != null)
                            {
                                eventSource = input._inputDevice.Target;
                            }

                            if (eventSource != null)
                            {
                                eventSource.RaiseEvent(input);
                            }

                            // Post-Notify the input.
                            //
                            if (InputDeviceEvents[devType]._postNotifyInput != null)
                            {
                                InputDeviceEvents[devType]._postNotifyInput(this, new NotifyInputEventArgs(item));
                            }

                            // Post-Process the input.  This could modify the staging
                            // area.
                            if (InputDeviceEvents[devType]._postProcessInput != null)
                            {
                                InputDeviceEvents[devType]._postProcessInput(this, new ProcessInputEventArgs(item));
                            }

                            // PreviewInputReport --> InputReport
                            if (item.Input._routedEvent == InputManager.PreviewInputReportEvent)
                            {
                                if (!item.Input.Handled)
                                {
                                    InputReportEventArgs previewInputReport = (InputReportEventArgs)item.Input;
                                    InputReportEventArgs inputReport = new InputReportEventArgs(previewInputReport.Device, previewInputReport.Report);
                                    inputReport.RoutedEvent = InputManager.InputReportEvent;

                                    _currentStagingStack.Push(new StagingAreaInputItem(inputReport, item));
                                }
                            }

                            if (input.Handled)
                            {
                                handled = true;
                            }
                        }
                    } while (_currentStagingStack.Count > 0);
                }
            }
            finally
            {
                // It is possible that we can be re-entered by a nested
                // dispatcher frame.  Continue processing the staging
                // area if we need to. 
                if (_stagingArea.Count > 0)
                {
                    // Before we actually start to drain the staging area, we need
                    // to post a work item to process more input.  This enables us
                    // to process more input if we enter a nested pump.
                    Dispatcher.BeginInvoke(_continueProcessingStagingAreaCallback, Dispatcher.CurrentFrame);
                }

                _frameStagingArea.Remove(frame);
            }

            return handled;
        }
Beispiel #4
0
        private object ProcessStagingArea(object postContinue)
        {
            bool handled = false;

            // NOTE -- avalon caches the XXXEventArgs.  In our system, the costs are different,
            // so it is probably cheaper for us to just create them, since everything gets created
            // on the heap anyways, and IL is expensive.  we should reconsider this if
            // its a performance impact.

            // Because we can be reentered, we can't just enumerate over the
            // staging area - that could throw an exception if the queue
            // changes underneath us.  Instead, just loop until we find a
            // frame marker or until the staging area is empty.
           
            while (_stagingArea.Count > 0)
            {
                StagingAreaInputItem item = (StagingAreaInputItem)_stagingArea.Pop();

                // If we found a marker, we have reached the end of a
                // "section" of the staging area.  We just return from
                // the synchronous processing of the staging area.
                // If a dispatcher frame has been pushed by someone, this
                // will not return to the original ProcessInput.  Instead
                // it will unwind to the dispatcher and since we have
                // already pushed a work item to continue processing the
                // input, it will simply call back into us to do more
                // processing.  At which point we will continue to drain
                // the staging area.  This could cause strage behavior,
                // but it is deemed more acceptable than stalling input
                // processing.
                // make sure we all agree on this.  We could also
                // just delay the rest of the staging area until
                // the dispatcher frame finishes.  Unfortunately,
                // this means you could receive an input event for
                // something that happened a long time ago.

                if (item.IsMarker)
                {
                    break;
                }

                // Pre-Process the input.  This could modify the staging
                // area, and it could cancel the processing of this
                // input event.
                //

                bool fCanceled = false;

                int devType = (int)item.Input._inputDevice.DeviceType;

                if (InputDeviceEvents[devType]._preProcessInput != null)
                {
                    PreProcessInputEventArgs preProcessInputEventArgs;
                    InputDeviceEvents[devType]._preProcessInput(this, preProcessInputEventArgs = new PreProcessInputEventArgs(item));

                    fCanceled = preProcessInputEventArgs._canceled;
                }

                if (!fCanceled)
                {
                    // Pre-Notify the input.
                    //
                    if (InputDeviceEvents[devType]._preNotifyInput != null)
                    {
                        InputDeviceEvents[devType]._preNotifyInput(this, new NotifyInputEventArgs(item));
                    }

                    // Raise the input event being processed.
                    InputEventArgs input = item.Input;

                    // Some input events are explicitly associated with
                    // an element.  Those that are not instead are associated with
                    // the target of the input device for this event.
                    UIElement eventSource = input._source as UIElement;

                    if (eventSource == null && input._inputDevice != null)
                    {
                        eventSource = input._inputDevice.Target;
                    }

                    if (eventSource != null)
                    {
                        eventSource.RaiseEvent(input);
                    }

                    // Post-Notify the input.
                    //
                    if (InputDeviceEvents[devType]._postNotifyInput != null)
                    {
                        InputDeviceEvents[devType]._postNotifyInput(this, new NotifyInputEventArgs(item));
                    }

                    // Post-Process the input.  This could modify the staging
                    // area.
                    if (InputDeviceEvents[devType]._postProcessInput != null)
                    {
                        InputDeviceEvents[devType]._postProcessInput(this, new ProcessInputEventArgs(item));

                        // PreviewInputReport --> InputReport
                        if (item.Input._routedEvent == InputManager.PreviewInputReportEvent)
                        {
                            if (!item.Input.Handled)
                            {
                                InputReportEventArgs previewInputReport = (InputReportEventArgs)item.Input;
                                InputReportEventArgs inputReport = new InputReportEventArgs(previewInputReport.Device, previewInputReport.Report);
                                inputReport.RoutedEvent = InputManager.InputReportEvent;

                                _stagingArea.Push(new StagingAreaInputItem(false, inputReport, item));
                            }
                        }
                    }

                    if (input.Handled)
                    {
                        handled = true;
                    }
                }
            }

            if ((bool)postContinue == true)
            {
                _continueProcessingStagingArea = false;

                // It is possible that we can be re-entered by a nested
                // dispatcher frame.  Continue processing the staging
                // area if we need to.
                if (_stagingArea.Count > 0)
                {
                    // Before we actually start to drain the staging area, we need
                    // to post a work item to process more input.  This enables us
                    // to process more input if we enter a nested pump.
                    Dispatcher.BeginInvoke(_continueProcessingStagingAreaCallback, true);
                    _continueProcessingStagingArea = true;

                    // Now fall through to synchronously drain the staging area.
                }
            }

            return handled;
        }
        private object ProcessStagingArea(object postContinue)
        {
            bool handled = false;

            // NOTE -- avalon caches the XXXEventArgs.  In our system, the costs are different,
            // so it is probably cheaper for us to just create them, since everything gets created
            // on the heap anyways, and IL is expensive.  we should reconsider this if
            // its a performance impact.

            // Because we can be reentered, we can't just enumerate over the
            // staging area - that could throw an exception if the queue
            // changes underneath us.  Instead, just loop until we find a
            // frame marker or until the staging area is empty.

            _continueProcessingStagingArea = true;

            try
            {
                while (_stagingArea.Count > 0)
                {
                    _currentStagingStack = _stagingArea.Dequeue() as Stack;

                    do
                    {
                        StagingAreaInputItem item = (StagingAreaInputItem)_currentStagingStack.Pop();

                        // Pre-Process the input.  This could modify the staging
                        // area, and it could cancel the processing of this
                        // input event.
                        //

                        bool fCanceled = false;

                        int devType = (int)item.Input._inputDevice.DeviceType;

                        if (InputDeviceEvents[devType]._preProcessInput != null)
                        {
                            PreProcessInputEventArgs preProcessInputEventArgs;
                            InputDeviceEvents[devType]._preProcessInput(this, preProcessInputEventArgs = new PreProcessInputEventArgs(item));

                            fCanceled = preProcessInputEventArgs._canceled;
                        }

                        if (!fCanceled)
                        {
                            // Pre-Notify the input.
                            //
                            if (InputDeviceEvents[devType]._preNotifyInput != null)
                            {
                                InputDeviceEvents[devType]._preNotifyInput(this, new NotifyInputEventArgs(item));
                            }

                            // Raise the input event being processed.
                            InputEventArgs input = item.Input;

                            // Some input events are explicitly associated with
                            // an element.  Those that are not instead are associated with
                            // the target of the input device for this event.
                            UIElement eventSource = input._source as UIElement;

                            if (eventSource == null && input._inputDevice != null)
                            {
                                eventSource = input._inputDevice.Target;
                            }

                            if (eventSource != null)
                            {
                                eventSource.RaiseEvent(input);
                            }

                            // Post-Notify the input.
                            //
                            if (InputDeviceEvents[devType]._postNotifyInput != null)
                            {
                                InputDeviceEvents[devType]._postNotifyInput(this, new NotifyInputEventArgs(item));
                            }

                            // Post-Process the input.  This could modify the staging
                            // area.
                            if (InputDeviceEvents[devType]._postProcessInput != null)
                            {
                                InputDeviceEvents[devType]._postProcessInput(this, new ProcessInputEventArgs(item));
                            }

                            // PreviewInputReport --> InputReport
                            if (item.Input._routedEvent == InputManager.PreviewInputReportEvent)
                            {
                                if (!item.Input.Handled)
                                {
                                    InputReportEventArgs previewInputReport = (InputReportEventArgs)item.Input;
                                    InputReportEventArgs inputReport        = new InputReportEventArgs(previewInputReport.Device, previewInputReport.Report);
                                    inputReport.RoutedEvent = InputManager.InputReportEvent;

                                    _currentStagingStack.Push(new StagingAreaInputItem(inputReport, item));
                                }
                            }

                            if (input.Handled)
                            {
                                handled = true;
                            }
                        }
                    }while(_currentStagingStack.Count > 0);
                }
            }
            finally
            {
                _continueProcessingStagingArea = false;

                // It is possible that we can be re-entered by a nested
                // dispatcher frame.  Continue processing the staging
                // area if we need to.
                if (_stagingArea.Count > 0)
                {
                    _continueProcessingStagingArea = true;
                    // Before we actually start to drain the staging area, we need
                    // to post a work item to process more input.  This enables us
                    // to process more input if we enter a nested pump.
                    Dispatcher.BeginInvoke(_continueProcessingStagingAreaCallback, true);
                }
            }

            return(handled);
        }
Beispiel #6
0
        private object ProcessStagingArea(object postContinue)
        {
            bool handled = false;

            // NOTE -- avalon caches the XXXEventArgs.  In our system, the costs are different,
            // so it is probably cheaper for us to just create them, since everything gets created
            // on the heap anyways, and IL is expensive.  we should reconsider this if
            // its a performance impact.

            // Because we can be reentered, we can't just enumerate over the
            // staging area - that could throw an exception if the queue
            // changes underneath us.  Instead, just loop until we find a
            // frame marker or until the staging area is empty.

            while (_stagingArea.Count > 0)
            {
                StagingAreaInputItem item = (StagingAreaInputItem)_stagingArea.Pop();

                // If we found a marker, we have reached the end of a
                // "section" of the staging area.  We just return from
                // the synchronous processing of the staging area.
                // If a dispatcher frame has been pushed by someone, this
                // will not return to the original ProcessInput.  Instead
                // it will unwind to the dispatcher and since we have
                // already pushed a work item to continue processing the
                // input, it will simply call back into us to do more
                // processing.  At which point we will continue to drain
                // the staging area.  This could cause strage behavior,
                // but it is deemed more acceptable than stalling input
                // processing.
                // make sure we all agree on this.  We could also
                // just delay the rest of the staging area until
                // the dispatcher frame finishes.  Unfortunately,
                // this means you could receive an input event for
                // something that happened a long time ago.

                if (item.IsMarker)
                {
                    break;
                }

                // Pre-Process the input.  This could modify the staging
                // area, and it could cancel the processing of this
                // input event.
                //

                bool fCanceled = false;

                int devType = (int)item.Input._inputDevice.DeviceType;

                if (InputDeviceEvents[devType]._preProcessInput != null)
                {
                    PreProcessInputEventArgs preProcessInputEventArgs;
                    InputDeviceEvents[devType]._preProcessInput(this, preProcessInputEventArgs = new PreProcessInputEventArgs(item));

                    fCanceled = preProcessInputEventArgs._canceled;
                }

                if (!fCanceled)
                {
                    // Pre-Notify the input.
                    //
                    if (InputDeviceEvents[devType]._preNotifyInput != null)
                    {
                        InputDeviceEvents[devType]._preNotifyInput(this, new NotifyInputEventArgs(item));
                    }

                    // Raise the input event being processed.
                    InputEventArgs input = item.Input;

                    // Some input events are explicitly associated with
                    // an element.  Those that are not instead are associated with
                    // the target of the input device for this event.
                    UIElement eventSource = input._source as UIElement;

                    if (eventSource == null && input._inputDevice != null)
                    {
                        eventSource = input._inputDevice.Target;
                    }

                    if (eventSource != null)
                    {
                        eventSource.RaiseEvent(input);
                    }

                    // Post-Notify the input.
                    //
                    if (InputDeviceEvents[devType]._postNotifyInput != null)
                    {
                        InputDeviceEvents[devType]._postNotifyInput(this, new NotifyInputEventArgs(item));
                    }

                    // Post-Process the input.  This could modify the staging
                    // area.
                    if (InputDeviceEvents[devType]._postProcessInput != null)
                    {
                        InputDeviceEvents[devType]._postProcessInput(this, new ProcessInputEventArgs(item));

                        // PreviewInputReport --> InputReport
                        if (item.Input._routedEvent == InputManager.PreviewInputReportEvent)
                        {
                            if (!item.Input.Handled)
                            {
                                InputReportEventArgs previewInputReport = (InputReportEventArgs)item.Input;
                                InputReportEventArgs inputReport        = new InputReportEventArgs(previewInputReport.Device, previewInputReport.Report);
                                inputReport.RoutedEvent = InputManager.InputReportEvent;

                                _stagingArea.Push(new StagingAreaInputItem(false, inputReport, item));
                            }
                        }
                    }

                    if (input.Handled)
                    {
                        handled = true;
                    }
                }
            }

            if ((bool)postContinue == true)
            {
                _continueProcessingStagingArea = false;

                // It is possible that we can be re-entered by a nested
                // dispatcher frame.  Continue processing the staging
                // area if we need to.
                if (_stagingArea.Count > 0)
                {
                    // Before we actually start to drain the staging area, we need
                    // to post a work item to process more input.  This enables us
                    // to process more input if we enter a nested pump.
                    Dispatcher.BeginInvoke(_continueProcessingStagingAreaCallback, true);
                    _continueProcessingStagingArea = true;

                    // Now fall through to synchronously drain the staging area.
                }
            }

            return(handled);
        }