Exemple #1
0
        public void ParseInputEvent(INPUT_RECORD inputRecord, Control rootElement)
        {
            if (inputRecord.EventType == EventType.MOUSE_EVENT)
            {
                MOUSE_EVENT_RECORD mouseEvent = inputRecord.MouseEvent;

                if (mouseEvent.dwEventFlags != MouseEventFlags.PRESSED_OR_RELEASED &&
                    mouseEvent.dwEventFlags != MouseEventFlags.MOUSE_MOVED &&
                    mouseEvent.dwEventFlags != MouseEventFlags.DOUBLE_CLICK &&
                    mouseEvent.dwEventFlags != MouseEventFlags.MOUSE_WHEELED &&
                    mouseEvent.dwEventFlags != MouseEventFlags.MOUSE_HWHEELED)
                {
                    //
                    throw new InvalidOperationException("Flags combination in mouse event was not expected.");
                }
                Point rawPosition;
                if (mouseEvent.dwEventFlags == MouseEventFlags.MOUSE_MOVED ||
                    mouseEvent.dwEventFlags == MouseEventFlags.PRESSED_OR_RELEASED)
                {
                    rawPosition       = new Point(mouseEvent.dwMousePosition.X, mouseEvent.dwMousePosition.Y);
                    lastMousePosition = rawPosition;
                }
                else
                {
                    // При событии MOUSE_WHEELED в Windows некорректно устанавливается mouseEvent.dwMousePosition
                    // Поэтому для определения элемента, над которым производится прокручивание колёсика, мы
                    // вынуждены сохранять координаты, полученные при предыдущем событии мыши
                    rawPosition = lastMousePosition;
                }

                Control topMost = VisualTreeHelper.FindTopControlUnderMouse(rootElement,
                                                                            Control.TranslatePoint(null, rawPosition, rootElement));

                // если мышь захвачена контролом, то события перемещения мыши доставляются только ему,
                // события, связанные с нажатием мыши - тоже доставляются только ему, вместо того
                // контрола, над которым событие было зарегистрировано. Такой механизм необходим,
                // например, для корректной обработки перемещений окон (вверх или в стороны)
                Control source = (inputCaptureStack.Count != 0) ? inputCaptureStack.Peek() : topMost;

                // No sense to further process event with no source control
                if (source == null)
                {
                    return;
                }

                if (mouseEvent.dwEventFlags == MouseEventFlags.MOUSE_MOVED)
                {
                    MouseButtonState leftMouseButtonState   = getLeftButtonState(mouseEvent.dwButtonState);
                    MouseButtonState middleMouseButtonState = getMiddleButtonState(mouseEvent.dwButtonState);
                    MouseButtonState rightMouseButtonState  = getRightButtonState(mouseEvent.dwButtonState);
                    //
                    MouseEventArgs mouseEventArgs = new MouseEventArgs(source, Control.PreviewMouseMoveEvent,
                                                                       rawPosition,
                                                                       leftMouseButtonState,
                                                                       middleMouseButtonState,
                                                                       rightMouseButtonState
                                                                       );
                    eventsQueue.Enqueue(mouseEventArgs);
                    //
                    lastLeftMouseButtonState   = leftMouseButtonState;
                    lastMiddleMouseButtonState = middleMouseButtonState;
                    lastRightMouseButtonState  = rightMouseButtonState;

                    // detect mouse enter / mouse leave events

                    // path to source from root element down
                    List <Control> mouseOverStack = new List <Control>();
                    Control        current        = topMost;
                    while (null != current)
                    {
                        mouseOverStack.Insert(0, current);
                        current = current.Parent;
                    }

                    int index;
                    for (index = 0; index < Math.Min(mouseOverStack.Count, prevMouseOverStack.Count); index++)
                    {
                        if (mouseOverStack[index] != prevMouseOverStack[index])
                        {
                            break;
                        }
                    }

                    for (int i = prevMouseOverStack.Count - 1; i >= index; i--)
                    {
                        Control        control = prevMouseOverStack[i];
                        MouseEventArgs args    = new MouseEventArgs(control, Control.MouseLeaveEvent,
                                                                    rawPosition,
                                                                    leftMouseButtonState,
                                                                    middleMouseButtonState,
                                                                    rightMouseButtonState
                                                                    );
                        eventsQueue.Enqueue(args);
                    }

                    for (int i = index; i < mouseOverStack.Count; i++)
                    {
                        // enqueue MouseEnter event
                        Control        control = mouseOverStack[i];
                        MouseEventArgs args    = new MouseEventArgs(control, Control.MouseEnterEvent,
                                                                    rawPosition,
                                                                    leftMouseButtonState,
                                                                    middleMouseButtonState,
                                                                    rightMouseButtonState
                                                                    );
                        eventsQueue.Enqueue(args);
                    }

                    prevMouseOverStack.Clear();
                    prevMouseOverStack.AddRange(mouseOverStack);
                }
                if (mouseEvent.dwEventFlags == MouseEventFlags.PRESSED_OR_RELEASED)
                {
                    //
                    MouseButtonState leftMouseButtonState   = getLeftButtonState(mouseEvent.dwButtonState);
                    MouseButtonState middleMouseButtonState = getMiddleButtonState(mouseEvent.dwButtonState);
                    MouseButtonState rightMouseButtonState  = getRightButtonState(mouseEvent.dwButtonState);
                    //
                    MouseButtonEventArgs eventArgs = null;
                    if (leftMouseButtonState != lastLeftMouseButtonState)
                    {
                        eventArgs = new MouseButtonEventArgs(source,
                                                             leftMouseButtonState == MouseButtonState.Pressed ? Control.PreviewMouseDownEvent : Control.PreviewMouseUpEvent,
                                                             rawPosition,
                                                             leftMouseButtonState,
                                                             lastMiddleMouseButtonState,
                                                             lastRightMouseButtonState,
                                                             MouseButton.Left
                                                             );
                    }
                    if (middleMouseButtonState != lastMiddleMouseButtonState)
                    {
                        eventArgs = new MouseButtonEventArgs(source,
                                                             middleMouseButtonState == MouseButtonState.Pressed ? Control.PreviewMouseDownEvent : Control.PreviewMouseUpEvent,
                                                             rawPosition,
                                                             lastLeftMouseButtonState,
                                                             middleMouseButtonState,
                                                             lastRightMouseButtonState,
                                                             MouseButton.Middle
                                                             );
                    }
                    if (rightMouseButtonState != lastRightMouseButtonState)
                    {
                        eventArgs = new MouseButtonEventArgs(source,
                                                             rightMouseButtonState == MouseButtonState.Pressed ? Control.PreviewMouseDownEvent : Control.PreviewMouseUpEvent,
                                                             rawPosition,
                                                             lastLeftMouseButtonState,
                                                             lastMiddleMouseButtonState,
                                                             rightMouseButtonState,
                                                             MouseButton.Right
                                                             );
                    }
                    if (eventArgs != null)
                    {
                        eventsQueue.Enqueue(eventArgs);
                    }
                    //
                    lastLeftMouseButtonState   = leftMouseButtonState;
                    lastMiddleMouseButtonState = middleMouseButtonState;
                    lastRightMouseButtonState  = rightMouseButtonState;

                    if (leftMouseButtonState == MouseButtonState.Pressed)
                    {
                        if (eventArgs != null && !autoRepeatTimerRunning)
                        {
                            startAutoRepeatTimer(eventArgs);
                        }
                    }
                    else
                    {
                        if (eventArgs != null && autoRepeatTimerRunning)
                        {
                            stopAutoRepeatTimer( );
                        }
                    }
                }

                if (mouseEvent.dwEventFlags == MouseEventFlags.MOUSE_WHEELED)
                {
                    MouseWheelEventArgs args = new MouseWheelEventArgs(
                        topMost,
                        Control.PreviewMouseWheelEvent,
                        rawPosition,
                        lastLeftMouseButtonState, lastMiddleMouseButtonState,
                        lastRightMouseButtonState,
                        mouseEvent.dwButtonState > 0 ? 1 : -1
                        );
                    eventsQueue.Enqueue(args);
                }
            }
            if (inputRecord.EventType == EventType.KEY_EVENT)
            {
                KEY_EVENT_RECORD keyEvent  = inputRecord.KeyEvent;
                KeyEventArgs     eventArgs = new KeyEventArgs(
                    ConsoleApplication.Instance.FocusManager.FocusedElement,
                    keyEvent.bKeyDown ? Control.PreviewKeyDownEvent : Control.PreviewKeyUpEvent);
                eventArgs.UnicodeChar       = keyEvent.UnicodeChar;
                eventArgs.bKeyDown          = keyEvent.bKeyDown;
                eventArgs.dwControlKeyState = keyEvent.dwControlKeyState;
                eventArgs.wRepeatCount      = keyEvent.wRepeatCount;
                eventArgs.wVirtualKeyCode   = keyEvent.wVirtualKeyCode;
                eventArgs.wVirtualScanCode  = keyEvent.wVirtualScanCode;
                eventsQueue.Enqueue(eventArgs);
            }
        }