Aracılığıyla paylaş


Kullanıcı girdisini girdi enjeksiyonu yoluyla simüle edin

Windows uygulamalarınızda klavye, fare, dokunma, kalem ve oyun yüzeyi gibi cihazlardan kullanıcı girişinin simülasyonunu yapın ve otomatikleştirin.

Önemli API'ler: Windows.UI.Input.Preview.Injection

Genel Bakış

Giriş ekleme, Windows uygulamanızın çeşitli giriş cihazlarından gelen girişlerin benzetimini yapmalarına ve bu girişi uygulamanızın istemci alanı dışında (Kayıt Defteri Düzenleyicisi gibi Yönetici ayrıcalıklarıyla çalışan uygulamalara bile) her yere yönlendirmesine olanak tanır.

Giriş ekleme, erişilebilirlik, test (geçici, otomatik) ve uzaktan erişim ve destek özellikleri içeren işlevler sağlaması gereken Windows uygulamaları ve araçları için kullanışlıdır.

Kurulum

Windows uygulamanızda giriş ekleme API'lerini kullanmak için uygulama bildirimine aşağıdakileri eklemeniz gerekir:

  1. Package.appxmanifest dosyasına sağ tıklayın ve Kodu görüntüle'yi seçin.
  2. Aşağıdakileri Package düğümüne ekleyin.
    • xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
    • IgnorableNamespaces="rescap"
  3. Düğüme Capabilities aşağıdakileri ekleyin:
    • <rescap:Capability Name="inputInjectionBrokered" />

Yinelenen kullanıcı girişi

Dokunmatik giriş ekleme örneği
Dokunmatik giriş ekleme örneği

Bu örnekte, bir uygulamanın bir bölgesindeki fare girişi olaylarını dinlemek ve başka bir bölgedeki ilgili dokunmatik giriş olaylarının benzetimini yapmak için giriş ekleme API'lerinin (Windows.UI.Input.Preview.Injection) nasıl kullanılacağını göstereceğiz.

Bu örneği Giriş ekleme örneğinden (fareden dokunmaya) indirin

  1. İlk olarak kullanıcı arabirimini (MainPage.xaml) ayarlayacağız.

    İki Kılavuz alanımız var (biri fare girişi için, diğeri eklenmiş dokunmatik girişi için), her biri dört düğmeli.

    Uyarı

    Kılavuz arka planına bir değer atanmalıdır (Transparentbu örnekte), aksi takdirde işaretçi olayları algılanmaz.

    Giriş alanında fare tıklamaları algılandığında, giriş ekleme alanına karşılık gelen bir dokunma olayı eklenir. Girişe enjekte edilen düğme tıklamaları başlık alanında bildirilir.

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0"
                    Margin="10">
            <TextBlock Style="{ThemeResource TitleTextBlockStyle}" 
                       Name="titleText"
                       Text="Touch input injection"
                       HorizontalTextAlignment="Center" />
            <TextBlock Style="{ThemeResource BodyTextBlockStyle}"
                       Name="statusText"
                       HorizontalTextAlignment="Center" />
        </StackPanel>
        <Grid HorizontalAlignment="Center"
                        Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" 
                       Grid.Row="0" 
                       Style="{ThemeResource CaptionTextBlockStyle}"
                       Text="User mouse input area"/>
            <!-- Background must be set to something, otherwise pointer events are not detected. -->
            <Grid Name="ContainerInput" 
                  Grid.Column="0" 
                  Grid.Row="1"
                  HorizontalAlignment="Stretch" 
                  Background="Transparent" 
                  BorderBrush="Green" 
                  BorderThickness="2" 
                  MinHeight="100" MinWidth="300" 
                  Margin="10">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Button Name="B1" 
                        Grid.Column="0" 
                        HorizontalAlignment="Center" 
                        Width="50" Height="50"
                        Content="B1" />
                <Button Name="B2" 
                        Grid.Column="1" 
                        HorizontalAlignment="Center" 
                        Width="50" Height="50"
                        Content="B2" />
                <Button Name="B3" 
                        Grid.Column="2" 
                        HorizontalAlignment="Center" 
                        Width="50" Height="50"
                        Content="B3" />
                <Button Name="B4" 
                        Grid.Column="3" 
                        HorizontalAlignment="Center" 
                        Width="50" Height="50"
                        Content="B4" />
            </Grid>
            <TextBlock Grid.Column="1" 
                       Grid.Row="0"                         
                       Style="{ThemeResource CaptionTextBlockStyle}"
                       Text="Injected touch input area"/>
            <Grid Name="ContainerInject"
                  Grid.Column="1"  
                  Grid.Row="1"
                  HorizontalAlignment="Stretch"
                  BorderBrush="Red" 
                  BorderThickness="2" 
                  MinHeight="100" MinWidth="300" 
                  Margin="10">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Button Name="B1i" Click="Button_Click_Injected"
                        Content="B1i"
                        Grid.Column="0" 
                        HorizontalAlignment="Center" 
                        Width="50" Height="50" />
                <Button Name="B2i" Click="Button_Click_Injected"
                        Content="B2i"
                        Grid.Column="1" 
                        HorizontalAlignment="Center" 
                        Width="50" Height="50" />
                <Button Name="B3i" Click="Button_Click_Injected"
                        Content="B3i"
                        Grid.Column="2" 
                        HorizontalAlignment="Center" 
                        Width="50" Height="50" />
                <Button Name="B4i" Click="Button_Click_Injected"
                        Content="B4i"
                        Grid.Column="3" 
                        HorizontalAlignment="Center" 
                        Width="50" Height="50" />
            </Grid>
        </Grid>
    </Grid>
    
  2. Ardından uygulamamızı başlatacağız.

    Bu kod parçacığında, genel nesnelerimizi tanımlar ve düğme tıklama olaylarında işlenmiş olarak işaretlenebilen fare giriş alanında işaretçi olayları için dinleyiciler (AddHandler) bildiririz.

    InputInjector nesnesi, giriş verilerini göndermek için sanal giriş cihazını temsil eder.

    İşleyicide ContainerInput_PointerPressed dokunma ekleme işlevini çağırıyoruz.

    İşleyici ContainerInput_PointerReleased içinde, InputInjector nesnesini kapatmak için UninitializeTouchInjection çağrısını yaparız.

    public sealed partial class MainPage : Page
    {
        /// <summary>
        /// The virtual input device.
        /// </summary>
        InputInjector _inputInjector;
    
        /// <summary>
        /// Initialize the app, set the window size, 
        /// and add pointer input handlers for the container.
        /// </summary>
        public MainPage()
        {
            this.InitializeComponent();
    
            ApplicationView.PreferredLaunchViewSize =
                new Size(600, 200);
            ApplicationView.PreferredLaunchWindowingMode =
                ApplicationViewWindowingMode.PreferredLaunchViewSize;
    
            // Button handles PointerPressed/PointerReleased in 
            // the Tapped routed event, but we need the container Grid 
            // to handle them also. Add a handler for both 
            // PointerPressedEvent and PointerReleasedEvent on the input Grid 
            // and set handledEventsToo to true.
            ContainerInput.AddHandler(PointerPressedEvent,
                new PointerEventHandler(ContainerInput_PointerPressed), true);
            ContainerInput.AddHandler(PointerReleasedEvent,
                new PointerEventHandler(ContainerInput_PointerReleased), true);
        }
    
        /// <summary>
        /// PointerReleased handler for all pointer conclusion events.
        /// PointerPressed and PointerReleased events do not always occur 
        /// in pairs, so your app should listen for and handle any event that 
        /// might conclude a pointer down (such as PointerExited, PointerCanceled, 
        /// and PointerCaptureLost).  
        /// </summary>
        /// <param name="sender">Source of the click event</param>
        /// <param name="e">Event args for the button click routed event</param>
        private void ContainerInput_PointerReleased(
            object sender, PointerRoutedEventArgs e)
        {
            // Prevent most handlers along the event route from handling event again.
            e.Handled = true;
    
            // Shut down the virtual input device.
            _inputInjector.UninitializeTouchInjection();
        }
    
        /// <summary>
        /// PointerPressed handler.
        /// PointerPressed and PointerReleased events do not always occur 
        /// in pairs. Your app should listen for and handle any event that 
        /// might conclude a pointer down (such as PointerExited, 
        /// PointerCanceled, and PointerCaptureLost).  
        /// </summary>
        /// <param name="sender">Source of the click event</param>
        /// <param name="e">Event args for the button click routed event</param>
        private void ContainerInput_PointerPressed(
            object sender, PointerRoutedEventArgs e)
        {
            // Prevent most handlers along the event route from 
            // handling the same event again.
            e.Handled = true;
    
            InjectTouchForMouse(e.GetCurrentPoint(ContainerInput));
    
        }
        ...
    }
    
  3. İşte dokunmatik giriş enjeksiyon işlevi.

    İlk olarak, InputInjector nesnesini örneklemek için TryCreate'ı çağırırız.

    Ardından, InitializeTouchInjectionInjectedInputVisualizationMode ile Default çağırırız.

    Ekleme noktasını hesapladıktan sonra, enjekte edilecek dokunma noktaları listesini başlatmak için InjectedInputTouchInfo adını diyoruz (bu örnekte, fare giriş işaretçisine karşılık gelen bir dokunma noktası oluşturuyoruz).

    Son olarak, InjectTouchInput fonksiyonunu iki kez çağırırız; ilkinde dokunmatik indirme (pointer down), ikincisinde ise dokunmatik kaldırma (pointer up) işlemi için.

    /// <summary>
    /// Inject touch input on injection target corresponding 
    /// to mouse click on input target.
    /// </summary>
    /// <param name="pointerPoint">The mouse click pointer.</param>
    private void InjectTouchForMouse(PointerPoint pointerPoint)
    {
        // Create the touch injection object.
        _inputInjector = InputInjector.TryCreate();
    
        if (_inputInjector != null)
        {
            _inputInjector.InitializeTouchInjection(
                InjectedInputVisualizationMode.Default);
    
            // Create a unique pointer ID for the injected touch pointer.
            // Multiple input pointers would require more robust handling.
            uint pointerId = pointerPoint.PointerId + 1;
    
            // Get the bounding rectangle of the app window.
            Rect appBounds =
                Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().VisibleBounds;
    
            // Get the top left screen coordinates of the app window rect.
            Point appBoundsTopLeft = new Point(appBounds.Left, appBounds.Top);
    
            // Get a reference to the input injection area.
            GeneralTransform injectArea =
                ContainerInject.TransformToVisual(Window.Current.Content);
    
            // Get the top left screen coordinates of the input injection area.
            Point injectAreaTopLeft = injectArea.TransformPoint(new Point(0, 0));
    
            // Get the screen coordinates (relative to the input area) 
            // of the input pointer.
            int pointerPointX = (int)pointerPoint.Position.X;
            int pointerPointY = (int)pointerPoint.Position.Y;
    
            // Create the point for input injection and calculate its screen location.
            Point injectionPoint =
                new Point(
                    appBoundsTopLeft.X + injectAreaTopLeft.X + pointerPointX,
                    appBoundsTopLeft.Y + injectAreaTopLeft.Y + pointerPointY);
    
            // Create a touch data point for pointer down.
            // Each element in the touch data list represents a single touch contact. 
            // For this example, we're mirroring a single mouse pointer.
            List<InjectedInputTouchInfo> touchData =
                new List<InjectedInputTouchInfo>
                {
                    new InjectedInputTouchInfo
                    {
                        Contact = new InjectedInputRectangle
                        {
                            Left = 30, Top = 30, Bottom = 30, Right = 30
                        },
                        PointerInfo = new InjectedInputPointerInfo
                        {
                            PointerId = pointerId,
                            PointerOptions =
                            InjectedInputPointerOptions.PointerDown |
                            InjectedInputPointerOptions.InContact |
                            InjectedInputPointerOptions.New,
                            TimeOffsetInMilliseconds = 0,
                            PixelLocation = new InjectedInputPoint
                            {
                                PositionX = (int)injectionPoint.X ,
                                PositionY = (int)injectionPoint.Y
                            }
                    },
                    Pressure = 1.0,
                    TouchParameters =
                        InjectedInputTouchParameters.Pressure |
                        InjectedInputTouchParameters.Contact
                }
            };
    
            // Inject the touch input. 
            _inputInjector.InjectTouchInput(touchData);
    
            // Create a touch data point for pointer up.
            touchData = new List<InjectedInputTouchInfo>
            {
                new InjectedInputTouchInfo
                {
                    PointerInfo = new InjectedInputPointerInfo
                    {
                        PointerId = pointerId,
                        PointerOptions = InjectedInputPointerOptions.PointerUp
                    }
                }
            };
    
            // Inject the touch input. 
            _inputInjector.InjectTouchInput(touchData);
        }
    }
    
  4. Son olarak, girdi enjeksiyon alanındaki Button Click yönlendirilmiş etkinliklerini işler ve kullanıcı arabirimini tıklanan düğmenin adıyla güncelleriz.

Ayrıca bakınız

Konu örnekleri