此前我们将了win32传统的模拟鼠标的方法,今天我们再来看下在UWP应用程序中,如何模拟鼠标事件。

在UWP应用中,要模拟鼠标或者触摸事件,微软有特意提供相应的方法给我们使用。在命名空间Windows.UI.Input.Preview下。 先来看下如何使用它:

        //关闭模拟器
        public static void Dispose()
        {
            if (_inputInjector == null) return;

            _inputInjector.UninitializeTouchInjection();
            _inputInjector = null;
        }

        //模拟鼠标左键单击
        public static void LeftButtonMouseDown()
        {
            Dispose();
            //尝试创建一个注入器
            _inputInjector = InputInjector.TryCreate();
            //初始化触摸注入器
            _inputInjector.InitializeTouchInjection(InjectedInputVisualizationMode.Default);
            //注入鼠标操作
            _inputInjector.InjectMouseInput(new List<InjectedInputMouseInfo>
                         {
                            new InjectedInputMouseInfo()
                            {
                                MouseOptions=InjectedInputMouseOptions.LeftDown
                            }
                         });
        }

        //模拟触摸操作
        public static void PointerPressed(uint pointerId, Point position, Windows.Foundation.Rect rect)
        {
            
            Dispose();

            _inputInjector = InputInjector.TryCreate();

            if (_inputInjector != null)
            {
                _inputInjector.InitializeTouchInjection(InjectedInputVisualizationMode.Default);

                //获取当前窗体的边界值
                Windows.Foundation.Rect appBounds = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().VisibleBounds;

                List<InjectedInputTouchInfo> touchData =
                    new List<InjectedInputTouchInfo>
                    {
                        new InjectedInputTouchInfo
                        {
                            //设置触摸范围
                            Contact =new InjectedInputRectangle{
                                Bottom= (int)rect.Bottom,
                                Left=(int) rect.Left,
                                Top=(int) rect.Top,
                                Right=(int) rect.Right
                            },
                            PointerInfo = new InjectedInputPointerInfo
                            {
                                PointerId = pointerId,
                                //设置属性值
                                PointerOptions =   
                                InjectedInputPointerOptions.PointerDown|                             
                                InjectedInputPointerOptions.InContact |
                                InjectedInputPointerOptions.CaptureChanged,
                                TimeOffsetInMilliseconds = 0,
                                //设置触摸坐标,这里需要考虑下多屏情况
                                PixelLocation = new InjectedInputPoint
                                {
                                    PositionX = (int)appBounds.Left+ (int)position.X ,
                                    PositionY = (int)appBounds.Top+ (int)position.Y
                                }
                        },
                        //设置压感值
                        Pressure = 0.5,
                        TouchParameters =
                            InjectedInputTouchParameters.Pressure |
                            InjectedInputTouchParameters.Contact
                    }
                };

                //触发触摸按下操作
                _inputInjector.InjectTouchInput(touchData);

                //触发抬起操作
                touchData = new List<InjectedInputTouchInfo>
                {
                    new InjectedInputTouchInfo
                    {
                        PointerInfo = new InjectedInputPointerInfo
                        {
                            PointerId = pointerId,
                            PointerOptions = InjectedInputPointerOptions.PointerUp
                        }
                    }
                };
                
                _inputInjector.InjectTouchInput(touchData);
            }
        }

说明:

InjectedInputMouseInfo 表示鼠标的相关操作参数,具体参数根据不同的鼠标定义而不同。 触发鼠标按下事件时,鼠标是以当前鼠标的坐标作为传递值,如果需要新的坐标位置,可通过DeltaX和DeltaY参数来传递坐标的偏移量。 使用该方法时,要注意多屏情况,避免触摸的点不是想要的坐标点。 在模拟触摸按下操作时,会同时触发抬起操作,即便是没有发送抬起信息。

通过以上方法,我们就可以模拟触摸相关的模拟动作了。但是放到UWP程序中运行时,我们会发现程序会报错:拒绝访问!! 这是因为UWP的安全策略问题,不允许使用,所以我们需要告诉程序,需要开启该功能。

开启方法:

在启动项目中,以文本方式打开Package.appxmanifest文件。 在文件命名空间中添加xmlns:restcap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"命名空间的引用。 在Capabilities节点中添加<restcap:Capability Name="inputInjectionBrokered" />。 这里注意,是设置为inputInjectionBrokered的属性值。


<?xml version="1.0" encoding="utf-8"?>

<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  
  xmlns:restcap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"

  IgnorableNamespaces="uap mp">

	<!-- 此处省略………… -->

	<Capabilities>
		<Capability Name="internetClient" />

		<restcap:Capability Name="inputInjectionBrokered" />

	</Capabilities>
</Package>

参考文献: https://docs.microsoft.com/en-us/windows/uwp/design/input/input-injection


本文会经常更新,请阅读原文: https://huchengv5.gitee.io//post/UWP-%E6%A8%A1%E6%8B%9F%E9%BC%A0%E6%A0%87%E6%88%96%E6%8C%87%E9%92%88%E6%93%8D%E4%BD%9C%E7%9A%84%E5%AE%9E%E7%8E%B0%E6%96%B9%E6%B3%95.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名胡承(包含链接: https://huchengv5.gitee.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系