在画布子项上方禁用鼠标焦点

时间:2019-06-04 20:39:28

标签: c# wpf winapi canvas

我正在创建全屏透明窗口,以显示Revit插件中某些交互的十字准线。 但是,当在画布中创建的线条与鼠标位置交叉时,鼠标光标会集中在线条上。但是光标必须聚焦在Revit的窗口上

我尝试使用属性(用于窗口,画布和线条): IsHitTestVisible="False" IsEnable="False" IsManipulationEnabled="False" FocusVisualStyle="{x:Null}"

Xaml:

<Window
    x:Class="mprPatterns.Views.PickCrosshairWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    AllowsTransparency="True" SnapsToDevicePixels="True"
    WindowStyle="None" Background="Transparent"
    ShowActivated="True" ShowInTaskbar="False"
    Topmost="True" IsHitTestVisible="False">
    <Canvas x:Name="Canvas"/>
</Window>

CodeBehind:

namespace mprPatterns.Views
{
    using System.Diagnostics;
    using System.Windows;
    using System.Windows.Forms;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using Gma.System.MouseKeyHook;

    public partial class PickCrosshairWindow
    {
        private IKeyboardMouseEvents _keyboardMouseEvents;

        public PickCrosshairWindow()
        {
            InitializeComponent();
            if (Screen.AllScreens.Length > 1)
            {
                var totalSize = ScreenTotalSize();

                Width = totalSize.Width;
                Height = totalSize.Height;
                Left = 0;
                Top = 0;
            }
            else
            {
                WindowState = WindowState.Maximized;
            }
            Closing += (sender, args) => { StopShowCrosshair(); };
        }

        public void StartShowCrosshair()
        {
            SubscribeGlobal();
        }

        public void StopShowCrosshair()
        {
            ClearCanvas();
            Unsubscribe();
        }

        public void ClearCanvas()
        {
            Canvas.Children.Clear();
        }

        private void SubscribeGlobal()
        {
            Unsubscribe();
            Subscribe(Hook.GlobalEvents());
        }

        private void Subscribe(IKeyboardMouseEvents events)
        {
            _keyboardMouseEvents = events;

            _keyboardMouseEvents.MouseMove += HookManager_MouseMove;
        }

        private void Unsubscribe()
        {
            if (_keyboardMouseEvents == null) return;

            _keyboardMouseEvents.MouseMove -= HookManager_MouseMove;

            _keyboardMouseEvents.Dispose();
            _keyboardMouseEvents = null;
        }


        private void HookManager_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            Debug.Print($"x={e.X:0000}; y={e.Y:0000}");
            Debug.Print(Screen.PrimaryScreen.Bounds.Width.ToString());
            var screenTotalSize = ScreenTotalSize();
            Canvas.Children.Clear();
            Line line = new Line();
            line.Stroke = System.Windows.Media.Brushes.Red;
            line.StrokeDashArray = new DoubleCollection { 10, 5 };
            line.X1 = 0;
            line.Y1 = e.Y;
            line.X2 = screenTotalSize.Width;
            line.Y2 = e.Y;

            Line line2 = new Line();
            line2.Stroke = System.Windows.Media.Brushes.Red;
            line2.StrokeDashArray = new DoubleCollection { 10, 5 };
            line2.X1 = e.X;
            line2.Y1 = 0;
            line2.X2 = e.X;
            line2.Y2 = screenTotalSize.Height;

            Canvas.Children.Add(line);
            Canvas.Children.Add(line2);
        }

        private static System.Drawing.Rectangle ScreenTotalSize()
        {
            System.Drawing.Rectangle totalSize = System.Drawing.Rectangle.Empty;
            foreach (Screen s in Screen.AllScreens)
                totalSize = System.Drawing.Rectangle.Union(totalSize, s.Bounds);
            return totalSize;
        }
    }
}

实施:

_parentWindow.Hide();

try
{
    PickCrosshairWindow.StartShowCrosshair();
    ObjectSnapTypes snapTypes = ObjectSnapTypes.Endpoints | ObjectSnapTypes.Intersections;
    XYZ point = RevitInterop.UiDocument.Selection.PickPoint(snapTypes, "Select an end point or intersection");
    PickCrosshairWindow.ClearCanvas();

    PickCrosshairWindow.StartShowCrosshair();
    point = RevitInterop.UiDocument.Selection.PickPoint(snapTypes, "Select an end point or intersection");
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
    // todo ignore?
}
catch (Exception exception)
{
    ExceptionBox.Show(exception);
}
finally
{
    PickCrosshairWindow.StopShowCrosshair();
    _parentWindow.Show();
}

唯一有用的是将光标从光标位置移开

Line line = new Line();
line.Stroke = System.Windows.Media.Brushes.Red;
line.StrokeDashArray = new DoubleCollection { 10, 5 };
line.X1 = 0;
line.Y1 = e.Y + 5;
line.X2 = screenTotalSize.Width;
line.Y2 = e.Y + 5;

Line line2 = new Line();
line2.Stroke = System.Windows.Media.Brushes.Red;
line2.StrokeDashArray = new DoubleCollection { 10, 5 };
line2.X1 = e.X + 5;
line2.Y1 = 0;
line2.X2 = e.X + 5;
line2.Y2 = screenTotalSize.Height;

但这不是解决方案

0 个答案:

没有答案