Jednou z méně známých funkcí UWP API je možnost simulace vstupu ( input injection). Tu lze s výhodou využít, když chcete uživateli nabídnout automatickou prohlídku aplikací, poskytnout zpětnou vazbu uživatelům asistenčních technologií nebo implementovat ve vaší aplikaci možnost vzdálené pomoci. V tomto článku si prohlédneme jmenný prostor Windows.UI.Input.Preview.Injection a ukážeme si, jak používat jeho členy.
Podporované formy vstupu
Windows 10 podporuje několik různých forem vstupu a všechny lze použít i se simulátorem vstupu v UWP API. Lze simulovat:
Gamepad
Klávesnici
Myš
Pero
Dotyk
V článku se podíváme na simulaci klávesnice a myši.
Deklarace simulace vstupu
Předtím než budeme moci simulaci vstupu využít, musíme to deklarovat v aplikačním manifestu, protože jde o nestandardní funkcionalitu. Patří do kategorie restricted capability, což znamená že výslednou aplikaci můžeme publikovat na Windows Store, ale vyžaduje rozšířenou kontrolu při schvalovacím procesu. Otevřeme Package.appxmanifest jako XML soubor a doplníme o novou deklaraci jmenného prostoru v elementu Package:
<Package ... xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp rescap">
Jmenný prostor rescap je domovem pro všechny restricted capabilities. Dále musíme přidat samotnou capability inputInjectionBrokered v sekci Capabilities:
<Capabilities> <Capability Name="internetClient" /> <rescap:Capability Name="inputInjectionBrokered" /> </Capabilities>
Základy
Hlavní třídou ve jmenném prostoru Windows.UI.Input.Preview.Injection je InputInjector. Její instanci vytvoříme pomocí statické metody TryCreate. Následně můžeme volat odpovídající metody pro každou z forem vstupu:
var inputInfo = new InjectedInputMouseInfo(); ... InputInjector inputInjector = InputInjector.TryCreate(); inputInjector.InjectMouseInput(new[] { inputInfo });
Jak lze vidět, tyto metody přijímají seznam instancí input info, takže můžeme provést více operací za sebou.
Vstup myši
Simulovaný vstup myši můžeme připravit pomocí třídy InjectedInputMouseInfo. Pro pohyb myší použijeme vlastnosti DeltaX a DeltaY:
var info = new InjectedInputMouseInfo(); info.MouseOptions = InjectedInputMouseOptions.Move; info.DeltaY = 100; //move down 100 points
Vlastnost MouseOptions nám umožňuje nastavit flagy, které určují operace, jež se mají provést. Mezi těmi jsou i LeftDown a LeftUp, kterými můžeme simulovat kliknutí levého tlačítka myši:
var down = new InjectedInputMouseInfo(); down.MouseOptions = InjectedInputMouseOptions.LeftDown; var up = new InjectedInputMouseInfo(); up.MouseOptions = InjectedInputMouseOptions.LeftUp; InputInjector inputInjector = InputInjector.TryCreate(); inputInjector.InjectMouseInput(new[] { down, up });
Můžeme ale simulovat i scrollovací kolečka myši a to jak vertikální tak horizontální pomocí vlastností Wheel resp. HWheel. Vzdálenost pro scrollování můžete nastavit vlastností MouseData:
var info = new InjectedInputMouseInfo(); info.MouseOptions = InjectedInputMouseOptions.Wheel; info.MouseData = 500; //scrollovat nahoru InputInjector inputInjector = InputInjector.TryCreate(); inputInjector.InjectMouseInput(new[] { info });
Scrollování nahoru je snadné, ale co dolů?
info.MouseData = -500; //chyba při kompilaci!
Překvapivě, vlastnost MouseData je typu uint, což znemožňuje přiřazení záporných hodnot. Můžeme však využít přetečení, jehož důsledek bude očekávané chování:
unchecked { info.MouseData = (uint)-500; //scrollovat dolů }
V tomto případě musíme použít unchecked blok, protože používáme konstantu a kompilátor se brání numerickému přetečení. Pokud bychom použili dočasnou lokální proměnnou, kompilátor by si již problému nemohl "všimnout" a nemuseli bychom unchecked používat. Info pro vstup myší také zahrnuje vlastnostTimeOffsetInMilliseconds, přes kterou můžete nastavit zpoždění jednotlivých akcí. To je užitečné pro korektní simulací oprací jako je dvojklik.
Vstup klávesnice
Třída InjectedInputKeyboardInfo je základem pro simulaci vstupu z klávesnice. Nejdůežitější vlastnost je VirtualKey, která určuje klávesu, se kterou pracujeme. Následující příklad vypíše do aktivního vstupního pole řetězec "hello":
InputInjector inputInjector = InputInjector.TryCreate(); foreach (var letter in "hello") { var info = new InjectedInputKeyboardInfo(); info.VirtualKey = (ushort)((VirtualKey)Enum.Parse(typeof(VirtualKey), letter.ToString(), true)); inputInjector.InjectKeyboardInput(new[] { info }); await Task.Delay(100); }
Na konci cyklu je volání metody Task.Delay, které zde není jen pro efekt :-D . Zajišťuje, že opakované stisky kláves nebudou zaregistrovány jako jedno stisknutí, což by zabránilo zaregistrování druhého písmena L.
Ukázkový kód
Zdrojový kód k tomuto článku je k dispozici na mém GitHubu.

Shrnutí
Prohlédli jsme si jmenný prostor Windows.<wbr />UI.<wbr />Input.<wbr />Preview.<wbr />Injection a ukázali, jak jej můžeme využít pro simulaci vstupních zařízení. Přestože tuto funkci příliš často nevyužijeme, je velmi pěkné ji vidět jako součást UWP API.