aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.SimulateTouch.UI
diff options
context:
space:
mode:
authorVictoria Plitt <Victoria.Plitt@twine-s.com>2020-06-03 11:45:55 +0300
committerVictoria Plitt <Victoria.Plitt@twine-s.com>2020-06-03 11:45:55 +0300
commit686937fc57d5020a55590612e8cdd50acf1794c5 (patch)
treeb9bd49dc8485f31559cd8180871268e1efaa909d /Software/Visual_Studio/Tango.SimulateTouch.UI
parentfa4b140630ff8b39bfeb85affe5e42bcb53d02e9 (diff)
downloadTango-686937fc57d5020a55590612e8cdd50acf1794c5.tar.gz
Tango-686937fc57d5020a55590612e8cdd50acf1794c5.zip
Added New project SimulateTouch.UI to Utilities
Related Work Items: #2909
Diffstat (limited to 'Software/Visual_Studio/Tango.SimulateTouch.UI')
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/App.config6
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/App.xaml9
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/App.xaml.cs17
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/MainWindow.xaml23
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/MainWindow.xaml.cs151
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/Native/TouchInjector.cs431
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/Native/TouchSimulate.cs67
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/AssemblyInfo.cs55
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Resources.Designer.cs71
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Resources.resx117
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Settings.Designer.cs30
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Settings.settings7
-rw-r--r--Software/Visual_Studio/Tango.SimulateTouch.UI/Tango.SimulateTouch.UI.csproj108
13 files changed, 1092 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/App.config b/Software/Visual_Studio/Tango.SimulateTouch.UI/App.config
new file mode 100644
index 000000000..731f6de6c
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/App.config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+ <startup>
+ <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
+ </startup>
+</configuration> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/App.xaml b/Software/Visual_Studio/Tango.SimulateTouch.UI/App.xaml
new file mode 100644
index 000000000..71b76b799
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/App.xaml
@@ -0,0 +1,9 @@
+<Application x:Class="Tango.SimulateTouch.UI.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:Tango.SimulateTouch.UI"
+ StartupUri="MainWindow.xaml">
+ <Application.Resources>
+
+ </Application.Resources>
+</Application>
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/App.xaml.cs b/Software/Visual_Studio/Tango.SimulateTouch.UI/App.xaml.cs
new file mode 100644
index 000000000..05147084b
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/App.xaml.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace Tango.SimulateTouch.UI
+{
+ /// <summary>
+ /// Interaction logic for App.xaml
+ /// </summary>
+ public partial class App : Application
+ {
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/MainWindow.xaml b/Software/Visual_Studio/Tango.SimulateTouch.UI/MainWindow.xaml
new file mode 100644
index 000000000..0a3049cb0
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/MainWindow.xaml
@@ -0,0 +1,23 @@
+<Window x:Class="Tango.SimulateTouch.UI.MainWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Tango.SimulateTouch.UI"
+ mc:Ignorable="d"
+ Title="MainWindow" Height="450" Width="800" >
+ <Grid Background="White" x:Name="GdRootZm">
+ <Border Width="200" BorderBrush="Silver" BorderThickness="1" CornerRadius="5" VerticalAlignment="Bottom" HorizontalAlignment="Right"
+ Margin="50" Background="White" x:Name="BdrSimulateZm">
+ <StackPanel Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
+ <Border Margin="3" Height="45" BorderBrush="Blue" BorderThickness="1" CornerRadius="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
+ <TextBlock x:Name="messageTextBlock" Height="45" Width="Auto" Background="Azure" ></TextBlock>
+ </Border>
+ <Border Margin="3" Height="45" BorderBrush="Blue" BorderThickness="1" CornerRadius="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
+ <TextBlock x:Name="TouchUpTextBlock" Height="45" Width="Auto" Background="Azure" ></TextBlock>
+ </Border>
+ <Button Margin="0 20 0 0 " Width="200" PreviewMouseLeftButtonDown="OnButtonLeftButtonDown">Touch Button</Button>
+ </StackPanel>
+ </Border>
+ </Grid>
+</Window>
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/MainWindow.xaml.cs b/Software/Visual_Studio/Tango.SimulateTouch.UI/MainWindow.xaml.cs
new file mode 100644
index 000000000..e652c2e55
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/MainWindow.xaml.cs
@@ -0,0 +1,151 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Interop;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using Tango.SimulateTouch.UI.Native;
+using Windows.UI.Input.Preview.Injection;
+using System.Security.Cryptography;
+
+namespace Tango.SimulateTouch.UI
+{
+ /// <summary>
+ /// Interaction logic for MainWindow.xaml
+ /// </summary>
+ public partial class MainWindow : Window
+ {
+ //Windows.UI.Input.Preview.Injection.InputInjector _inputInjector;
+ private Line ProxyLine;
+
+ public MainWindow()
+ {
+ InitializeComponent();
+ WindowState = WindowState.Maximized;
+ TouchInjector.InitializeTouchInjection();
+ this.TouchDown += MainWindow_TouchDown;
+ this.TouchMove += MainWindow_TouchMove;
+ this.TouchUp += MainWindow_TouchUp;
+ }
+ private void MainWindow_TouchUp(object sender, TouchEventArgs e)
+ {
+ System.Windows.Input.TouchPoint oPos = e.GetTouchPoint(this);
+ this.ProxyLine.X2 = oPos.Position.X;
+ this.ProxyLine.Y2 = oPos.Position.Y;
+ this.GdRootZm.Children.Add(this.ProxyLine);
+ Console.WriteLine("TouchID " + e.TouchDevice.Id + " TouchUp " + oPos.Position.X + " " + oPos.Position.Y);
+ TouchUpTextBlock.Text = "TOUCH UP";
+ }
+
+ private void MainWindow_TouchMove(object sender, TouchEventArgs e)
+ {
+ System.Windows.Input.TouchPoint oPos = e.GetTouchPoint(this);
+ Console.WriteLine("TouchID " + e.TouchDevice.Id + " TouchMove " + oPos.Position.X + " " + oPos.Position.Y);
+ }
+
+ private void MainWindow_TouchDown(object sender, TouchEventArgs e)
+ {
+ System.Windows.Input.TouchPoint oPos = e.GetTouchPoint(this);
+ Line oLine = new Line();
+ oLine.Stroke = new SolidColorBrush(Colors.Red);
+ oLine.StrokeThickness = 2;
+ oLine.X1 = oPos.Position.X;
+ oLine.Y1 = oPos.Position.Y;
+ this.ProxyLine = oLine;
+ Console.WriteLine("TouchID " + e.TouchDevice.Id + " TouchDown " + oPos.Position.X + " " + oPos.Position.Y);
+ messageTextBlock.Text = "TOUCH Down";
+ }
+
+ private void OnButtonLeftButtonDown(object sender, MouseButtonEventArgs e)
+ {
+ // Point targetLoc = messageTextBlock.PointToScreen(new Point(0, 0));
+ // HwndSource source = (HwndSource)HwndSource.FromVisual(messageTextBlock);
+ // IntPtr hWnd = source.Handle;
+
+ TouchSimulate ts = new TouchSimulate();
+
+ //TEST UWP - error COM!!!!
+ /* _inputInjector = InputInjector.TryCreate();
+ if (_inputInjector != null)
+ {
+ _inputInjector.InitializeTouchInjection( InjectedInputVisualizationMode.Default);
+ uint pointerId = 1;
+ var appBounds = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().VisibleBounds;
+ Point appBoundsTopLeft = new Point(appBounds.Left, appBounds.Top);
+ Point targetLoc = messageTextBlock.PointToScreen(new Point(0, 0));
+
+ // Get the screen coordinates (relative to the input area)
+ // of the input pointer.
+ Point screenPointPosition = button.PointToScreen(coordinates);
+ int pointerPointX = (int)screenPointPosition.X;
+ int pointerPointY = (int)screenPointPosition.Y;
+
+ // Create the point for input injection and calculate its screen location.
+ Point injectionPoint =
+ new Point(
+ appBoundsTopLeft.X + targetLoc.X + pointerPointX,
+ appBoundsTopLeft.Y + targetLoc.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);
+ }*/
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/Native/TouchInjector.cs b/Software/Visual_Studio/Tango.SimulateTouch.UI/Native/TouchInjector.cs
new file mode 100644
index 000000000..6a9035a37
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/Native/TouchInjector.cs
@@ -0,0 +1,431 @@
+using System.Threading;
+using System.Runtime.InteropServices;
+using System;
+
+namespace Tango.SimulateTouch.UI.Native
+{
+ static class IdGenerator
+ {
+ static private int _int;
+ private static uint _uint;
+ private static readonly object _mutex = new object();
+
+ public static int GetUniqueInt()
+ {
+ Interlocked.Increment(ref _int);
+ return _int;
+ }
+
+ public static uint GetUinqueUInt()
+ {
+ lock (_mutex)
+ {
+ if (_uint > 256)
+ {
+ ResetUint();
+ }
+ if (_uint == uint.MaxValue)
+ throw new IndexOutOfRangeException();
+ else
+ {
+ _uint++;
+ return _uint;
+ }
+ }
+ }
+
+ public static void ResetUint()
+ {
+ lock (_mutex)
+ {
+ _uint = uint.MinValue;
+ }
+ }
+ }
+ public class TouchInjector
+ {
+ /// <summary>
+ /// Call this first to initialize the TouchInjection!
+ /// </summary>
+ /// <param name="maxCount">The maximum number of touch points to simulate. Must be less than 256!</param>
+ /// <param name="feedbackMode">Specifies the visual feedback mode of the generated touch points</param>
+ /// <returns>true if success</returns>
+ [DllImport("User32.dll")]
+ public static extern bool InitializeTouchInjection(uint maxCount = 256, TouchFeedback feedbackMode = TouchFeedback.DEFAULT);
+
+ /// <summary>
+ /// Inject an array of POINTER_TUCH_INFO
+ /// </summary>
+ /// <param name="count">The exact number of entries in the array</param>
+ /// <param name="contacts">The POINTER_TOUCH_INFO to inject</param>
+ /// <returns>true if success</returns>
+ [DllImport("User32.dll")]
+ public static extern bool InjectTouchInput(int count, [MarshalAs(UnmanagedType.LPArray), In] PointerTouchInfo[] contacts);
+ }
+ #region Types
+ /// <summary>
+ /// Enum of touch visualization options
+ /// </summary>
+ public enum TouchFeedback
+ {
+ /// <summary>
+ /// Specifies default touch visualizations.
+ /// </summary>
+ DEFAULT = 0x1,
+ /// <summary>
+ /// Specifies indirect touch visualizations.
+ /// </summary>
+ INDIRECT = 0x2,
+ /// <summary>
+ /// Specifies no touch visualizations.
+ /// </summary>
+ NONE = 0x3
+ }
+
+ /// <summary>
+ /// The contact area.
+ /// </summary>
+ [StructLayout(LayoutKind.Explicit)]
+ public struct ContactArea
+ {
+ [FieldOffset(0)]
+ public int left;
+ [FieldOffset(4)]
+ public int top;
+ [FieldOffset(8)]
+ public int right;
+ [FieldOffset(12)]
+ public int bottom;
+ }
+
+ /// <summary>
+ /// Values that can appear in the TouchMask field of the PointerTouchInfo structure
+ /// </summary>
+ public enum TouchFlags
+ {
+ /// <summary>
+ /// Indicates that no flags are set.
+ /// </summary>
+ NONE = 0x00000000
+ }
+
+ /// <summary>
+ /// Values that can appear in the TouchMask field of the PointerTouchInfo structure.
+ /// </summary>
+ public enum TouchMask
+ {
+ /// <summary>
+ /// Default. None of the optional fields are valid.
+ /// </summary>
+ NONE = 0x00000000,
+ /// <summary>
+ /// The ContactArea field is valid
+ /// </summary>
+ CONTACTAREA = 0x00000001,
+ /// <summary>
+ /// The orientation field is valid
+ /// </summary>
+ ORIENTATION = 0x00000002,
+ /// <summary>
+ /// The pressure field is valid
+ /// </summary>
+ PRESSURE = 0x00000004
+ }
+
+ /// <summary>
+ /// Values that can appear in the PointerFlags field of the PointerInfo structure.
+ /// </summary>
+ public enum PointerFlags
+ {
+ /// <summary>
+ /// Default
+ /// </summary>
+ NONE = 0x00000000,
+ /// <summary>
+ /// Indicates the arrival of a new pointer
+ /// </summary>
+ NEW = 0x00000001,
+ /// <summary>
+ /// Indicates that this pointer continues to exist. When this flag is not set, it indicates the pointer has left detection range.
+ /// This flag is typically not set only when a hovering pointer leaves detection range (PointerFlag.UPDATE is set) or when a pointer in contact with a window surface leaves detection range (PointerFlag.UP is set).
+ /// </summary>
+ INRANGE = 0x00000002,
+ /// <summary>
+ /// Indicates that this pointer is in contact with the digitizer surface. When this flag is not set, it indicates a hovering pointer.
+ /// </summary>
+ INCONTACT = 0x00000004,
+ /// <summary>
+ /// Indicates a primary action, analogous to a mouse left button down.
+ ///A touch pointer has this flag set when it is in contact with the digitizer surface.
+ ///A pen pointer has this flag set when it is in contact with the digitizer surface with no buttons pressed.
+ ///A mouse pointer has this flag set when the mouse left button is down.
+ /// </summary>
+ FIRSTBUTTON = 0x00000010,
+ /// <summary>
+ /// Indicates a secondary action, analogous to a mouse right button down.
+ /// A touch pointer does not use this flag.
+ /// A pen pointer has this flag set when it is in contact with the digitizer surface with the pen barrel button pressed.
+ /// A mouse pointer has this flag set when the mouse right button is down.
+ /// </summary>
+ SECONDBUTTON = 0x00000020,
+ /// <summary>
+ /// Indicates a secondary action, analogous to a mouse right button down.
+ /// A touch pointer does not use this flag.
+ /// A pen pointer does not use this flag.
+ /// A mouse pointer has this flag set when the mouse middle button is down.
+ /// </summary>
+ THIRDBUTTON = 0x00000040,
+ /// <summary>
+ /// Indicates actions of one or more buttons beyond those listed above, dependent on the pointer type. Applications that wish to respond to these actions must retrieve information specific to the pointer type to determine which buttons are pressed. For example, an application can determine the buttons states of a pen by calling GetPointerPenInfo and examining the flags that specify button states.
+ /// </summary>
+ OTHERBUTTON = 0x00000080,
+ /// <summary>
+ /// Indicates that this pointer has been designated as primary. A primary pointer may perform actions beyond those available to non-primary pointers. For example, when a primary pointer makes contact with a window’s surface, it may provide the window an opportunity to activate by sending it a WM_POINTERACTIVATE message.
+ /// </summary>
+ PRIMARY = 0x00000100,
+ /// <summary>
+ /// Confidence is a suggestion from the source device about whether the pointer represents an intended or accidental interaction, which is especially relevant for PT_TOUCH pointers where an accidental interaction (such as with the palm of the hand) can trigger input. The presence of this flag indicates that the source device has high confidence that this input is part of an intended interaction.
+ /// </summary>
+ CONFIDENCE = 0x00000200,
+ /// <summary>
+ /// Indicates that the pointer is departing in an abnormal manner, such as when the system receives invalid input for the pointer or when a device with active pointers departs abruptly. If the application receiving the input is in a position to do so, it should treat the interaction as not completed and reverse any effects of the concerned pointer.
+ /// </summary>
+ CANCELLED = 0x00000400,
+ /// <summary>
+ /// Indicates that this pointer just transitioned to a “down” state; that is, it made contact with the window surface.
+ /// </summary>
+ DOWN = 0x00010000,
+ /// <summary>
+ /// Indicates that this information provides a simple update that does not include pointer state changes.
+ /// </summary>
+ UPDATE = 0x00020000,
+ /// <summary>
+ /// Indicates that this pointer just transitioned to an “up” state; that is, it broke contact with the window surface.
+ /// </summary>
+ UP = 0x00040000,
+ /// <summary>
+ /// Indicates input associated with a pointer wheel. For mouse pointers, this is equivalent to the action of the mouse scroll wheel (WM_MOUSEWHEEL).
+ /// </summary>
+ WHEEL = 0x00080000,
+ /// <summary>
+ /// Indicates input associated with a pointer h-wheel. For mouse pointers, this is equivalent to the action of the mouse horizontal scroll wheel (WM_MOUSEHWHEEL).
+ /// </summary>
+ HWHEEL = 0x00100000
+ }
+
+ /// <summary>
+ /// The TouchPoint structure defines the x- and y- coordinates of a point.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct TouchPoint
+ {
+ /// <summary>
+ /// The x-coordinate of the point.
+ /// </summary>
+ public int X;
+ /// <summary>
+ /// The y-coordinate of the point.
+ /// </summary>
+ public int Y;
+ }
+
+ /// <summary>
+ /// Identifies the pointer input types.
+ /// </summary>
+ public enum PointerInputType
+ {
+ /// <summary>
+ /// Generic pointer type. This type never appears in pointer messages or pointer data. Some data query functions allow the caller to restrict the query to specific pointer type. The PT_POINTER type can be used in these functions to specify that the query is to include pointers of all types
+ /// </summary>
+ POINTER = 0x00000001,
+ /// <summary>
+ /// Touch pointer type.
+ /// </summary>
+ TOUCH = 0x00000002,
+ /// <summary>
+ /// Pen pointer type.
+ /// </summary>
+ PEN = 0x00000003,
+ /// <summary>
+ /// Mouse pointer type
+ /// </summary>
+ MOUSE = 0x00000004,
+ /// <summary>
+ /// touchpad pointer type
+ /// </summary>
+ TOUCHPAD = 0x00000005
+ };
+
+ /// <summary>
+ /// Contains basic pointer information common to all pointer types. Applications can retrieve this information using the GetPointerInfo, GetPointerFrameInfo, GetPointerInfoHistory and GetPointerFrameInfoHistory functions.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PointerInfo
+ {
+ /// <summary>
+ /// A value from the PointerInputType enumeration that specifies the pointer type.
+ /// </summary>
+ public PointerInputType pointerType;
+
+ /// <summary>
+ /// An identifier that uniquely identifies a pointer during its lifetime. A pointer comes into existence when it is first detected and ends its existence when it goes out of detection range. Note that if a physical entity (finger or pen) goes out of detection range and then returns to be detected again, it is treated as a new pointer and may be assigned a new pointer identifier.
+ /// </summary>
+ public uint PointerId;
+
+ /// <summary>
+ /// An identifier common to multiple pointers for which the source device reported an update in a single input frame. For example, a parallel-mode multi-touch digitizer may report the positions of multiple touch contacts in a single update to the system.
+ /// Note that frame identifier is assigned as input is reported to the system for all pointers across all devices. Therefore, this field may not contain strictly sequential values in a single series of messages that a window receives. However, this field will contain the same numerical value for all input updates that were reported in the same input frame by a single device.
+ /// </summary>
+ public uint FrameId;
+
+ /// <summary>
+ /// May be any reasonable combination of flags from the Pointer Flags constants.
+ /// </summary>
+ public PointerFlags PointerFlags;
+
+ /// <summary>
+ /// Handle to the source device that can be used in calls to the raw input device API and the digitizer device API.
+ /// </summary>
+ public IntPtr SourceDevice;
+
+ /// <summary>
+ /// Window to which this message was targeted. If the pointer is captured, either implicitly by virtue of having made contact over this window or explicitly using the pointer capture API, this is the capture window. If the pointer is uncaptured, this is the window over which the pointer was when this message was generated.
+ /// </summary>
+ public IntPtr WindowTarget;
+
+ /// <summary>
+ /// Location in screen coordinates.
+ /// </summary>
+ public TouchPoint PtPixelLocation;
+
+ /// <summary>
+ /// Location in device coordinates.
+ /// </summary>
+ public TouchPoint PtPixelLocationRaw;
+
+ /// <summary>
+ /// Location in HIMETRIC units.
+ /// </summary>
+ public TouchPoint PtHimetricLocation;
+
+ /// <summary>
+ /// Location in device coordinates in HIMETRIC units.
+ /// </summary>
+ public TouchPoint PtHimetricLocationRaw;
+
+ /// <summary>
+ /// A message time stamp assigned by the system when this input was received.
+ /// </summary>
+ public uint Time;
+
+ /// <summary>
+ /// Count of inputs that were coalesced into this message. This count matches the total count of entries that can be returned by a call to GetPointerInfoHistory. If no coalescing occurred, this count is 1 for the single input represented by the message.
+ /// </summary>
+ public uint HistoryCount;
+
+ /// <summary>
+ /// A value whose meaning depends on the nature of input.
+ /// When flags indicate PointerFlag.WHEEL, this value indicates the distance the wheel is rotated, expressed in multiples or factors of WHEEL_DELTA. A positive value indicates that the wheel was rotated forward and a negative value indicates that the wheel was rotated backward.
+ /// When flags indicate PointerFlag.HWHEEL, this value indicates the distance the wheel is rotated, expressed in multiples or factors of WHEEL_DELTA. A positive value indicates that the wheel was rotated to the right and a negative value indicates that the wheel was rotated to the left.
+ /// </summary>
+ public uint InputData;
+
+ /// <summary>
+ /// Indicates which keyboard modifier keys were pressed at the time the input was generated. May be zero or a combination of the following values.
+ /// POINTER_MOD_SHIFT – A SHIFT key was pressed.
+ /// POINTER_MOD_CTRL – A CTRL key was pressed.
+ /// </summary>
+ public uint KeyStates;
+
+ /// <summary>
+ /// TBD
+ /// </summary>
+ public ulong PerformanceCount;
+
+ /// <summary>
+ /// ???
+ /// </summary>
+ public PointerButtonChangeType ButtonChangeType;
+ }
+
+ /// <summary>
+ /// Enumeration of PointerButtonChangeTypes
+ /// </summary>
+ public enum PointerButtonChangeType
+ {
+ NONE,
+ FIRSTBUTTON_DOWN,
+ FIRSTBUTTON_UP,
+ SECONDBUTTON_DOWN,
+ SECONDBUTTON_UP,
+ THIRDBUTTON_DOWN,
+ THIRDBUTTON_UP,
+ FOURTHBUTTON_DOWN,
+ FOURTHBUTTON_UP,
+ FIFTHBUTTON_DOWN,
+ FIFTHBUTTON_UP
+ }
+
+ /// <summary>
+ /// Contains information about a 'contact' (coordinates, size, pressure...)
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PointerTouchInfo
+ {
+ ///<summary>
+ /// Contains basic pointer information common to all pointer types.
+ ///</summary>
+ public PointerInfo PointerInfo;
+
+ ///<summary>
+ /// Lists the touch flags.
+ ///</summary>
+ public TouchFlags TouchFlags;
+
+ /// <summary>
+ /// Indicates which of the optional fields contain valid values. The member can be zero or any combination of the values from the Touch Mask constants.
+ /// </summary>
+ public TouchMask TouchMasks;
+
+ ///<summary>
+ /// Pointer contact area in pixel screen coordinates.
+ /// By default, if the device does not report a contact area,
+ /// this field defaults to a 0-by-0 rectangle centered around the pointer location.
+ ///</summary>
+ public ContactArea ContactArea;
+
+ /// <summary>
+ /// A raw pointer contact area.
+ /// </summary>
+ public ContactArea ContactAreaRaw;
+
+ ///<summary>
+ /// A pointer orientation, with a value between 0 and 359, where 0 indicates a touch pointer
+ /// aligned with the x-axis and pointing from left to right; increasing values indicate degrees
+ /// of rotation in the clockwise direction.
+ /// This field defaults to 0 if the device does not report orientation.
+ ///</summary>
+ public uint Orientation;
+
+ ///<summary>
+ /// Pointer pressure normalized in a range of 0 to 256.
+ ///</summary>
+ public uint Pressure;
+
+ /// <summary>
+ /// Move the touch point, together with its ContactArea
+ /// </summary>
+ /// <param name="deltaX">the change in the x-value</param>
+ /// <param name="deltaY">the change in the y-value</param>
+ public void Move(int deltaX, int deltaY)
+ {
+ PointerInfo.PtPixelLocation.X += deltaX;
+ PointerInfo.PtPixelLocation.Y += deltaY;
+ ContactArea.left += deltaX;
+ ContactArea.right += deltaX;
+ ContactArea.top += deltaY;
+ ContactArea.bottom += deltaY;
+ }
+ }
+ #endregion
+}
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/Native/TouchSimulate.cs b/Software/Visual_Studio/Tango.SimulateTouch.UI/Native/TouchSimulate.cs
new file mode 100644
index 000000000..cbe59b35a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/Native/TouchSimulate.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Security.Cryptography;
+
+namespace Tango.SimulateTouch.UI.Native
+{
+ public class TouchSimulate
+ {
+ public TouchSimulate()
+ {
+ int x = this.GetRandomSeed().Next(50, 1680 - 100);
+ int y = this.GetRandomSeed().Next(50, 1080 - 100);
+ SimulateTouch(x, y);
+ }
+ private Random GetRandomSeed()
+ {
+ byte[] bytes = new byte[4];
+ RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
+ rng.GetBytes(bytes);
+ return new Random(BitConverter.ToInt32(bytes, 0));
+ }
+
+ public void SimulateTouch(int x, int y)
+ {
+ // Touch Down Simulate
+ PointerTouchInfo contact = MakePointerTouchInfo(x, y, 5, 1);
+ PointerFlags oFlags = PointerFlags.DOWN | PointerFlags.INRANGE | PointerFlags.INCONTACT;
+ contact.PointerInfo.PointerFlags = oFlags;
+ bool bIsSuccess = TouchInjector.InjectTouchInput(1, new[] { contact });
+
+ // Touch Move Simulate
+ int nMoveIntervalX = this.GetRandomSeed().Next(-60, 60);
+ int nMoveIntervalY = this.GetRandomSeed().Next(-60, 60);
+ contact.Move(nMoveIntervalX, nMoveIntervalY);
+ oFlags = PointerFlags.INRANGE | PointerFlags.INCONTACT | PointerFlags.UPDATE;
+ contact.PointerInfo.PointerFlags = oFlags;
+ TouchInjector.InjectTouchInput(1, new[] { contact });
+
+ // Touch Up Simulate
+ contact.PointerInfo.PointerFlags = PointerFlags.UP;
+ TouchInjector.InjectTouchInput(1, new[] { contact });
+ }
+ private PointerTouchInfo MakePointerTouchInfo(int x, int y, int radius,
+ uint orientation = 90, uint pressure = 32000)
+ {
+ PointerTouchInfo contact = new PointerTouchInfo();
+ contact.PointerInfo.pointerType = PointerInputType.TOUCH;
+ contact.TouchFlags = TouchFlags.NONE;
+ contact.Orientation = orientation;
+ contact.Pressure = pressure;
+ contact.TouchMasks = TouchMask.CONTACTAREA | TouchMask.ORIENTATION | TouchMask.PRESSURE;
+ contact.PointerInfo.PtPixelLocation.X = x;
+ contact.PointerInfo.PtPixelLocation.Y = y;
+ uint unPointerId = IdGenerator.GetUinqueUInt();
+ Console.WriteLine("PointerId " + unPointerId);
+ contact.PointerInfo.PointerId = unPointerId;
+ contact.ContactArea.left = x - radius;
+ contact.ContactArea.right = x + radius;
+ contact.ContactArea.top = y - radius;
+ contact.ContactArea.bottom = y + radius;
+ return contact;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..3508b9ea7
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Tango.SimulateTouch.UI")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Tango.SimulateTouch.UI")]
+[assembly: AssemblyCopyright("Copyright © 2020")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+//In order to begin building localizable applications, set
+//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
+//inside a <PropertyGroup>. For example, if you are using US english
+//in your source files, set the <UICulture> to en-US. Then uncomment
+//the NeutralResourceLanguage attribute below. Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
+
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Resources.Designer.cs b/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..3d489c738
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Tango.SimulateTouch.UI.Properties
+{
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Tango.SimulateTouch.UI.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Resources.resx b/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Resources.resx
new file mode 100644
index 000000000..af7dbebba
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Settings.Designer.cs b/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..01e800736
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Tango.SimulateTouch.UI.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Settings.settings b/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Settings.settings
new file mode 100644
index 000000000..033d7a5e9
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.SimulateTouch.UI/Tango.SimulateTouch.UI.csproj b/Software/Visual_Studio/Tango.SimulateTouch.UI/Tango.SimulateTouch.UI.csproj
new file mode 100644
index 000000000..3186e86fe
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SimulateTouch.UI/Tango.SimulateTouch.UI.csproj
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{F15985C7-DF60-41CF-9333-D98BB8B43E6C}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <RootNamespace>Tango.SimulateTouch.UI</RootNamespace>
+ <AssemblyName>Tango.SimulateTouch.UI</AssemblyName>
+ <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <WarningLevel>4</WarningLevel>
+ <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+ <Deterministic>true</Deterministic>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Runtime.WindowsRuntime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Xml" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xaml">
+ <RequiredTargetFramework>4.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="Windows">
+ <HintPath>..\..\..\..\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17763.0\Windows.winmd</HintPath>
+ </Reference>
+ <Reference Include="WindowsBase" />
+ <Reference Include="PresentationCore" />
+ <Reference Include="PresentationFramework" />
+ </ItemGroup>
+ <ItemGroup>
+ <ApplicationDefinition Include="App.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </ApplicationDefinition>
+ <Page Include="MainWindow.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Compile Include="App.xaml.cs">
+ <DependentUpon>App.xaml</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="MainWindow.xaml.cs">
+ <DependentUpon>MainWindow.xaml</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Native\TouchInjector.cs" />
+ <Compile Include="Native\TouchSimulate.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ </ItemGroup>
+ <ItemGroup />
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file