using System; using System.Runtime.InteropServices; namespace Vanara.PInvoke { public static partial class User32 { /// Gesture configurations used by . [Flags] public enum GC { /// Indicates all of the gestures. GC_ALLGESTURES = 0x00000001, /// Indicates the zoom gesture. GC_ZOOM = 0x00000001, /// Indicates all pan gestures. GC_PAN = 0x00000001, /// Indicates vertical pans with one finger. GC_PAN_WITH_SINGLE_FINGER_VERTICALLY = 0x00000002, /// Indicates horizontal pans with one finger. GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY = 0x00000004, /// Limits perpendicular movement to primary direction until a threshold is reached to break out of the gutter. GC_PAN_WITH_GUTTER = 0x00000008, /// Indicates panning with inertia to smoothly slow when pan gestures stop. GC_PAN_WITH_INERTIA = 0x00000010, /// Indicates the rotation gesture. GC_ROTATE = 0x00000001, /// Indicates the two-finger tap gesture. GC_TWOFINGERTAP = 0x00000001, /// Indicates the press and tap gesture. GC_PRESSANDTAP = 0x00000001, /// Indicates the press and tap gesture. GC_ROLLOVER = GC_PRESSANDTAP, } /// Flags for . [PInvokeData("winuser.h", MSDNShortId = "8b7a594c-e9e4-4215-8946-da170c957a2b")] [Flags] public enum GCF { /// /// If specified, GetGestureConfig returns consolidated configuration for the specified window and its parent window chain. /// GCF_INCLUDE_ANCESTORS = 0x00000001 } /// Flags used by . [PInvokeData("winuser.h", MSDNShortId = "f5b8b530-ff1e-4d78-a12f-86990fe9ac88")] [Flags] public enum GF { /// A gesture is starting. GF_BEGIN = 0x00000001, /// A gesture has triggered inertia. GF_INERTIA = 0x00000002, /// A gesture is ending. GF_END = 0x00000004, } /// Gesture IDs used by and . public enum GID { /// Indicates a generic gesture is beginning. GID_BEGIN = 1, /// Indicates a generic gesture end. GID_END = 2, /// Indicates configuration settings for the zoom gesture. GID_ZOOM = 3, /// Indicates the pan gesture. GID_PAN = 4, /// Indicates the rotation gesture. GID_ROTATE = 5, /// Indicates the two-finger tap gesture. GID_TWOFINGERTAP = 6, /// Indicates the press and tap gesture. GID_PRESSANDTAP = 7, /// Indicates the press and tap gesture. GID_ROLLOVER = GID_PRESSANDTAP, } /// Flags for . [PInvokeData("winuser.h", MSDNShortId = "79cc2a05-d8ee-4d87-9c7b-fa7d5354b04f")] public enum TOUCH_FEEDBACK { /// Specifies default touch visualizations. TOUCH_FEEDBACK_DEFAULT = 0x1, /// Specifies indirect touch visualizations. TOUCH_FEEDBACK_INDIRECT = 0x2, /// Specifies no touch visualizations. TOUCH_FEEDBACK_NONE = 0x3, } /// Flags for [PInvokeData("winuser.h", MSDNShortId = "52e48cea-b5c7-405f-8df6-26052304b62c")] public enum TOUCH_HIT_TESTING { /// The touch hit testing default TOUCH_HIT_TESTING_DEFAULT = 0x0, /// The touch hit testing client TOUCH_HIT_TESTING_CLIENT = 0x1, /// The touch hit testing none TOUCH_HIT_TESTING_NONE = 0x2 } /// Flags used by . [PInvokeData("winuser.h", MSDNShortId = "fc382759-3a1e-401e-a6a7-1bf209a5434b")] [Flags] public enum TOUCHEVENTF { /// Movement has occurred. Cannot be combined with TOUCHEVENTF_DOWN. TOUCHEVENTF_MOVE = 0x0001, /// /// The corresponding touch point was established through a new contact. Cannot be combined with TOUCHEVENTF_MOVE or TOUCHEVENTF_UP. /// TOUCHEVENTF_DOWN = 0x0002, /// A touch point was removed. TOUCHEVENTF_UP = 0x0004, /// /// A touch point is in range. This flag is used to enable touch hover support on compatible hardware. Applications that do not /// want support for hover can ignore this flag. /// TOUCHEVENTF_INRANGE = 0x0008, /// /// Indicates that this TOUCHINPUT structure corresponds to a primary contact point. See the following text for more information /// on primary touch points. /// TOUCHEVENTF_PRIMARY = 0x0010, /// When received using GetTouchInputInfo, this input was not coalesced. TOUCHEVENTF_NOCOALESCE = 0x0020, /// The touch event came from a pen. TOUCHEVENTF_PEN = 0x0040, /// The touch event came from the user's palm. TOUCHEVENTF_PALM = 0x0080, } /// Masks used by . [PInvokeData("winuser.h", MSDNShortId = "fc382759-3a1e-401e-a6a7-1bf209a5434b")] [Flags] public enum TOUCHINPUTMASKF { /// The system time was set in the TOUCHINPUT structure. TOUCHINPUTMASKF_TIMEFROMSYSTEM = 0x0001, /// dwExtraInfo is valid. TOUCHINPUTMASKF_EXTRAINFO = 0x0002, /// cxContact and cyContact are valid. See the following text for more information on primary touch points. TOUCHINPUTMASKF_CONTACTAREA = 0x0004, } /// Flags used by . [Flags] public enum TWF { /// Specifies that hWnd prefers non-coalesced touch input. TWF_FINETOUCH = 0x00000001, /// /// Clearing this flag disables palm rejection which reduces delays for getting WM_TOUCH messages. This is useful if you want as /// quick of a response as possible when a user touches your application. Setting this flag enables palm detection and will /// prevent some WM_TOUCH messages from being sent to your application. This is useful if you do not want to receive WM_TOUCH /// messages that are from palm contact. /// TWF_WANTPALM = 0x00000002 } /// Closes resources associated with a gesture information handle. /// The gesture information handle. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, use the GetLastError function. /// /// /// /// If an application processes a WM_GESTURE message, it is responsible for closing the handle using this function. Failure to do so /// may result in process memory leaks. /// /// /// If the message is passed to DefWindowProc, or is forwarded using one of the PostMessage or SendMessage classes of API functions, /// the handle is transferred with the message and need not be closed by the application. /// /// Examples /// The following code shows a handler that closes the GESTUREINFO handle if the gesture has been handled. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-closegestureinfohandle BOOL CloseGestureInfoHandle( // HGESTUREINFO hGestureInfo ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "f2bf98b2-a4f7-4b63-b9ae-b2534415cb4b")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CloseGestureInfoHandle(HGESTUREINFO hGestureInfo); /// Closes a touch input handle, frees process memory associated with it, and invalidates the handle. /// /// The touch input handle received in the LPARAM of a touch message. The function fails with ERROR_INVALID_HANDLE if /// this handle is not valid. Note that the handle is not valid after it has been used in a successful call to /// CloseTouchInputHandle or after it has been passed to DefWindowProc, PostMessage, SendMessage or one of their variants. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, use the GetLastError function. /// /// /// Calling CloseTouchInputHandle will not free memory associated with values retrieved in a call to GetTouchInputInfo. Values /// in structures passed to GetTouchInputInfo will be valid until you delete them. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-closetouchinputhandle BOOL CloseTouchInputHandle( // HTOUCHINPUT hTouchInput ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "bdc8bb94-3126-4183-9dfd-ba4844d98f29")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CloseTouchInputHandle(HTOUCHINPUT hTouchInput); /// /// Returns the score of a polygon as the probable touch target (compared to all other polygons that intersect the touch contact /// area) and an adjusted touch point within the polygon. /// /// /// The number of vertices in the polygon. This value must be greater than or equal to 3. /// This value indicates the size of the array, as specified by the controlPolygon parameter. /// /// /// The array of x-y screen coordinates that define the shape of the UI element. /// The numVertices parameter specifies the number of coordinates. /// /// The TOUCH_HIT_TESTING_INPUT structure that holds the data for the touch contact area. /// /// The TOUCH_HIT_TESTING_PROXIMITY_EVALUATION structure that holds the score and adjusted touch-point data. /// /// /// If this function succeeds, it returns TRUE. /// Otherwise, it returns FALSE. To retrieve extended error information, call the GetLastError function. /// /// /// For consistency with Windows, frameworks that handle WM_TOUCHHITTESTING should use the following principles for targeting: /// /// /// Inclusion: If the touch point is within the boundaries of a control, the touch point is not changed. /// /// /// Intersection: Include only controls that intersect the contact geometry. /// /// /// /// Z-order: If more than one control intersects the contact geometry, and the controls overlap, the control that's highest in the /// z-order receives priority. /// /// /// /// /// Ambiguity: If more than one control intersects the contact geometry, and the controls don't overlap, the control that's closest /// to the original touch point receives priority. /// /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-evaluateproximitytopolygon BOOL // EvaluateProximityToPolygon( UINT32 numVertices, const POINT *controlPolygon, const TOUCH_HIT_TESTING_INPUT *pHitTestingInput, // TOUCH_HIT_TESTING_PROXIMITY_EVALUATION *pProximityEval ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "443d12f2-9f26-4e1e-9bf3-cd97b4026399")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EvaluateProximityToPolygon(uint numVertices, [In] POINT[] controlPolygon, in TOUCH_HIT_TESTING_INPUT pHitTestingInput, out TOUCH_HIT_TESTING_PROXIMITY_EVALUATION pProximityEval); /// /// Returns the score of a rectangle as the probable touch target, compared to all other rectangles that intersect the touch contact /// area, and an adjusted touch point within the rectangle. /// /// The RECT structure that defines the bounding box of the UI element. /// The TOUCH_HIT_TESTING_INPUT structure that holds the data for the touch contact area. /// /// The TOUCH_HIT_TESTING_PROXIMITY_EVALUATION structure that holds the score and adjusted touch-point data. /// /// /// If this function succeeds, it returns TRUE. /// Otherwise, it returns FALSE. To retrieve extended error information, call the GetLastError function. /// /// /// For consistency with Windows, frameworks that handle WM_TOUCHHITTESTING should use the following principles for targeting: /// /// /// Inclusion: If the touch point is within the boundaries of a control, the touch point is not changed. /// /// /// Intersection: Include only controls that intersect the contact geometry. /// /// /// /// Z-order: If more than one control intersects the contact geometry, and the controls overlap, the control that's highest in the /// z-order receives priority. /// /// /// /// /// Ambiguity: If more than one control intersects the contact geometry, and the controls don't overlap, the control that's closest /// to the original touch point receives priority. /// /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-evaluateproximitytorect BOOL EvaluateProximityToRect( // const RECT *controlBoundingBox, const TOUCH_HIT_TESTING_INPUT *pHitTestingInput, TOUCH_HIT_TESTING_PROXIMITY_EVALUATION // *pProximityEval ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "269ef4c1-9c9f-4bd7-9852-e82c4a707d3c")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EvaluateProximityToRect(in RECT controlBoundingBox, in TOUCH_HIT_TESTING_INPUT pHitTestingInput, out TOUCH_HIT_TESTING_PROXIMITY_EVALUATION pProximityEval); /// Retrieves the configuration for which Windows Touch gesture messages are sent from a window. /// A handle to the window to get the gesture configuration from. /// This value is reserved and must be set to 0. /// /// A gesture command flag value indicating options for retrieving the gesture configuration. See Remarks for additional information /// and supported values. /// /// The size, in number of gesture configuration structures, that is in the pGestureConfig buffer. /// An array of gesture configuration structures that specify the gesture configuration. /// The size of the gesture configuration (GESTURECONFIG) structure. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, use the GetLastError function. /// /// /// /// Passing a value other than sizeof(GESTURECONFIG) for the cbSize parameter will cause calls to this function to fail and /// GetLastError will return ERROR_INVALID_PARAMETER (87 in decimal). /// /// The following table lists the gesture configuration values: /// /// /// Name /// Value /// Description /// /// /// GCF_INCLUDE_ANCESTORS /// 0x00000001 /// If specified, GetGestureConfig returns consolidated configuration for the specified window and its parent window chain. /// /// /// Examples /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getgestureconfig BOOL GetGestureConfig( HWND hwnd, DWORD // dwReserved, DWORD dwFlags, PUINT pcIDs, PGESTURECONFIG pGestureConfig, UINT cbSize ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "8b7a594c-e9e4-4215-8946-da170c957a2b")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetGestureConfig(HWND hwnd, [Optional] uint dwReserved, GCF dwFlags, ref uint pcIDs, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] GESTURECONFIG[] pGestureConfig, [In] uint cbSize); /// Retrieves additional information about a gesture from its GESTUREINFO handle. /// The handle to the gesture information that is passed in the lParam of a WM_GESTURE message. /// A count of the bytes of data stored in the extra arguments. /// A pointer to the extra argument information. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, use the GetLastError function. /// /// /// This function is reserved for future use and should only be used for testing. Windows 7 gestures do not use extra arguments. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getgestureextraargs BOOL GetGestureExtraArgs( HGESTUREINFO // hGestureInfo, UINT cbExtraArgs, PBYTE pExtraArgs ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "f7775d88-6a5b-4283-ab40-65c2da218f81")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetGestureExtraArgs(HGESTUREINFO hGestureInfo, uint cbExtraArgs, IntPtr pExtraArgs); /// Retrieves a GESTUREINFO structure given a handle to the gesture information. /// The gesture information handle. /// A pointer to the gesture information structure. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, use the GetLastError function. /// /// /// /// The cbSize member of the GESTUREINFO structure passed in to the function must be set before the function is called. /// Otherwise, calls to GetLastError will return ERROR_INVALID_PARAMETER (87 in decimal). If an application processes a /// WM_GESTURE message, it is responsible for closing the handle using CloseGestureInfoHandle. Failure to do so may result in process /// memory leaks. /// /// /// If the message is passed to DefWindowProc, or is forwarded using one of the PostMessage or SendMessage classes of API functions, /// the handle is transferred with the message and need not be closed by the application. /// /// Examples /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getgestureinfo BOOL GetGestureInfo( HGESTUREINFO // hGestureInfo, PGESTUREINFO pGestureInfo ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "407ed585-09aa-4174-8907-8bb9590f1795")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetGestureInfo(HGESTUREINFO hGestureInfo, ref GESTUREINFO pGestureInfo); /// Retrieves detailed information about touch inputs associated with a particular touch input handle. /// /// The touch input handle received in the LPARAM of a touch message. The function fails with ERROR_INVALID_HANDLE if /// this handle is not valid. Note that the handle is not valid after it has been used in a successful call to CloseTouchInputHandle /// or after it has been passed to DefWindowProc, PostMessage, SendMessage or one of their variants. /// /// /// The number of structures in the pInputs array. This should ideally be at least equal to the number of touch points associated /// with the message as indicated in the message WPARAM. If cInputs is less than the number of touch points, the function will /// still succeed and populate the pInputs buffer with information about cInputs touch points. /// /// /// A pointer to an array of TOUCHINPUT structures to receive information about the touch points associated with the specified touch /// input handle. /// /// /// The size, in bytes, of a single TOUCHINPUT structure. If cbSize is not the size of a single TOUCHINPUT structure, the /// function fails with ERROR_INVALID_PARAMETER. /// /// /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error /// information, use the GetLastError function. /// /// /// Calling CloseTouchInputHandle will not free memory associated with values retrieved in a call to GetTouchInputInfo. Values /// in structures passed to GetTouchInputInfo will be valid until you delete them. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-gettouchinputinfo BOOL GetTouchInputInfo( HTOUCHINPUT // hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "18caab11-9c22-46ac-b89f-dd3e662bea1e")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetTouchInputInfo(HTOUCHINPUT hTouchInput, uint cInputs, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] TOUCHINPUT[] pInputs, int cbSize); /// /// The GID_ROTATE_ANGLE_FROM_ARGUMENT macro is used to interpret the GID_ROTATE ullArgument value when receiving the /// value in the WM_GESTURE structure. /// /// A value from a WM_GESTURE message. /// The angle of rotation as a double in radians. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-gid_rotate_angle_from_argument void // GID_ROTATE_ANGLE_FROM_ARGUMENT( _arg_ ); [PInvokeData("winuser.h", MSDNShortId = "8967e870-b444-402e-a343-9ac427ce1f07")] public static double GID_ROTATE_ANGLE_FROM_ARGUMENT(ulong arg) => (double)arg / ushort.MaxValue * 4.0 * Math.PI - 2.0 * Math.PI; /// Converts a radian value to an argument for rotation gesture messages. /// The angle of rotation as a double in radians. /// Value to pass to WM_GESTURE. /// Note The macro assumes that the input value for the radian value is between -2*pi and 2*pi. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-gid_rotate_angle_to_argument void // GID_ROTATE_ANGLE_TO_ARGUMENT( _arg_ ); [PInvokeData("winuser.h", MSDNShortId = "058c914e-82c7-40f9-8d0d-2a6a8e77cee0")] public static ushort GID_ROTATE_ANGLE_TO_ARGUMENT(double arg) => (ushort)((arg + 2.0 * Math.PI) / (4.0 * Math.PI) * ushort.MaxValue); /// /// Configures the touch injection context for the calling application and initializes the maximum number of simultaneous contacts /// that the app can inject. /// /// /// The maximum number of touch contacts. /// The maxCount parameter must be greater than 0 and less than or equal to MAX_TOUCH_COUNT (256) as defined in winuser.h. /// /// /// The contact visualization mode. /// The dwMode parameter must be TOUCH_FEEDBACK_DEFAULT, TOUCH_FEEDBACK_INDIRECT, or TOUCH_FEEDBACK_NONE. /// /// /// If the function succeeds, the return value is TRUE. /// If the function fails, the return value is FALSE. To get extended error information, call GetLastError. /// /// /// /// If TOUCH_FEEDBACK_DEFAULT is set, the injected touch feedback may get suppressed by the end-user settings in the Pen and /// Touch control panel. /// /// /// If TOUCH_FEEDBACK_INDIRECT is set, the injected touch feedback overrides the end-user settings in the Pen and Touch /// control panel. /// /// /// If TOUCH_FEEDBACK_INDIRECT or TOUCH_FEEDBACK_NONE are set, touch feedback provided by applications and controls may not be affected. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-initializetouchinjection BOOL InitializeTouchInjection( // UINT32 maxCount, DWORD dwMode ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "79cc2a05-d8ee-4d87-9c7b-fa7d5354b04f")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InitializeTouchInjection(uint maxCount, TOUCH_FEEDBACK dwMode); /// Simulates touch input. /// /// The size of the array in contacts. /// The maximum value for count is specified by the maxCount parameter of the InitializeTouchInjection function. /// /// /// Array of POINTER_TOUCH_INFO structures that represents all contacts on the desktop. The screen coordinates of each contact must /// be within the bounds of the desktop. /// /// /// If the function succeeds, the return value is non-zero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// The injected input is sent to the desktop of the session where the injection process is running. /// /// There are two input states for touch input injection (interactive and hover) that are indicated by the following combinations of /// pointerFlags in contacts: /// /// /// /// pointerFlags (POINTER_FLAG_*) /// Status /// /// /// INRANGE | UPDATE /// Touch hover starts or moves /// /// /// INRANGE | INCONTACT | DOWN /// Touch contact down /// /// /// INRANGE | INCONTACT | UPDATE /// Touch contact moves /// /// /// INRANGE | UP /// Touch contact up and transition to hover /// /// /// UPDATE /// Touch hover ends /// /// /// UP /// Touch ends /// /// /// /// Note Interactive state represents a touch contact that is on-screen and able to interact with any touch-capable app. Hover /// state represents touch input that is not in contact with the screen and cannot interact with applications. Touch injection can /// start in hover or interactive state, but the state can only transition through INRANGE | INCONTACT | DOWN for hover to /// interactive state, or through INRANGE | UP for interactive to hover state. /// /// All touch injection sequences end with either UPDATE or UP. /// /// The following diagram demonstrates a touch injection sequence that starts with a hover state, transitions to interactive, and /// concludes with hover. /// /// /// For press and hold gestures, multiple frames must be sent to ensure input is not cancelled. For a press and hold at point (x,y), /// send WM_POINTERDOWN at point (x,y) followed by WM_POINTERUPDATE messages at point(x,y). /// /// /// Listen for WM_DISPLAYCHANGE to handle changes to display resolution and orientation and manage screen coordinate updates. All /// active contacts are cancelled when a WM_DISPLAYCHANGE is received. /// /// /// Cancel individual contacts by setting POINTER_FLAG_CANCELED with POINTER_FLAG_UP or POINTER_FLAG_UPDATE. Cancelling touch /// injection without POINTER_FLAG_UP or POINTER_FLAG_UPDATE invalidates the injection. /// /// /// When POINTER_FLAG_UP is set, ptPixelLocation of POINTER_INFO should be the same as the value of the previous touch injection /// frame with POINTER_FLAG_UPDATE. Otherwise, the injection fails with ERROR_INVALID_PARAMETER and all active injection contacts are /// cancelled. The system modifies the ptPixelLocation of the WM_POINTERUP event as it cancels the injection. /// /// /// The input timestamp can be specified in either the dwTime or PerformanceCount field of POINTER_INFO. The value cannot be more /// recent than the current tick count or QueryPerformanceCounter value of the injection thread. Once a frame is injected with a /// timestamp, all subsequent frames must include a timestamp until all contacts in the frame go to the UP state. The custom /// timestamp value must be provided for the first element in the contacts array. The timestamp values after the first element are /// ignored. The custom timestamp value must increment in every injection frame. /// /// /// When a PerformanceCount field is specified, the timestamp is converted into current time in .1 millisecond resolution upon actual /// injection. If a custom PerformanceCount resulted in the same .1 millisecond window from previous injection, the API will return /// an error (ERROR_NOT_READY) and will not inject the data. While injection is not immediately invalidated by the error, next /// successful injection must have PerformanceCount value that is at least 0.1 milliseconds apart from the previously successful /// injection. Similarly a custom dwTime value must be at least 1 millisecond apart if the field was used. /// /// /// If both dwTime and PerformanceCount are specified in the injection parameter, InjectTouchInput fails with an Error Code /// (ERROR_INVALID_PARAMETER). Once the injection application starts with either a dwTime or PerformanceCount parameter, the /// timestamp field must be filled correctly. Injection cannot switch the custom timestamp field from one to another once the /// injection sequence has started. /// /// /// When neither dwTime or PerformanceCount values are specified, the InjectTouchInput allocates the timestamp based on the timing of /// the API call. If the calls are less than 0.1 millisecond apart, the API may return an error (ERROR_NOT_READY). The error will not /// invalidate the input immediately, but the injection application needs to retry the same frame again to ensure injection is successful. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-injecttouchinput BOOL InjectTouchInput( UINT32 count, // const POINTER_TOUCH_INFO *contacts ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "c3c1425e-2af6-4ecb-a0b2-a456654f7a53")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InjectTouchInput(uint count, [In] POINTER_TOUCH_INFO[] contacts); /// /// Checks whether a specified window is touch-capable and, optionally, retrieves the modifier flags set for the window's touch capability. /// /// /// The handle of the window. The function fails with ERROR_ACCESS_DENIED if the calling thread is not on the same desktop as /// the specified window. /// /// /// The address of the ULONG variable to receive the modifier flags for the specified window's touch capability. /// /// /// Returns TRUE if the window supports Windows Touch; returns FALSE if the window does not support Windows Touch. /// /// /// The following table lists the values for the pulFlags output parameter. /// /// /// Flag /// Description /// /// /// TWF_FINETOUCH /// Specifies that hWnd prefers non-coalesced touch input. /// /// /// TWF_WANTPALM /// /// Clearing this flag disables palm rejection which reduces delays for getting WM_TOUCH messages. This is useful if you want as /// quick of a response as possible when a user touches your application. Setting this flag enables palm detection and will prevent /// some WM_TOUCH messages from being sent to your application. This is useful if you do not want to receive WM_TOUCH messages that /// are from palm contact. /// /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-istouchwindow BOOL IsTouchWindow( HWND hwnd, PULONG // pulFlags ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "080b9d18-5975-4d38-ae3b-151f74120bb3")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsTouchWindow(HWND hwnd, out TWF pulFlags); /// /// Returns the proximity evaluation score and the adjusted touch-point coordinates as a packed value for the WM_TOUCHHITTESTING callback. /// /// The TOUCH_HIT_TESTING_INPUT structure that holds the data for the touch contact area. /// /// The TOUCH_HIT_TESTING_PROXIMITY_EVALUATION structure that holds the score and adjusted touch-point data that the /// EvaluateProximityToPolygon or EvaluateProximityToRect function returns. /// /// /// If this function succeeds, it returns the score and adjustedPoint values from /// TOUCH_HIT_TESTING_PROXIMITY_EVALUATION as an LRESULT. To retrieve extended error information, call the GetLastError function. /// /// Usually, this is the last function that's called in a WM_TOUCHHITTESTING handler. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-packtouchhittestingproximityevaluation LRESULT // PackTouchHitTestingProximityEvaluation( const TOUCH_HIT_TESTING_INPUT *pHitTestingInput, const // TOUCH_HIT_TESTING_PROXIMITY_EVALUATION *pProximityEval ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "c4061285-2d0f-4404-9b63-bda2ec61b764")] public static extern IntPtr PackTouchHitTestingProximityEvaluation(in TOUCH_HIT_TESTING_INPUT pHitTestingInput, out TOUCH_HIT_TESTING_PROXIMITY_EVALUATION pProximityEval); /// /// Registers a window to process the /// WM_TOUCHHITTESTING notification. /// /// The window that receives the WM_TOUCHHITTESTING notification. /// /// One of the following values: /// /// /// TOUCH_HIT_TESTING_CLIENT: Send WM_TOUCHHITTESTING messages to the target window. /// /// /// /// TOUCH_HIT_TESTING_DEFAULT: Don't send WM_TOUCHHITTESTING messages to the target window but continue to send the messages to child windows. /// /// /// /// TOUCH_HIT_TESTING_NONE: Don't send WM_TOUCHHITTESTING messages to the target window or child windows. /// /// /// /// /// If this function succeeds, it returns TRUE. /// Otherwise, it returns FALSE. To retrieve extended error information, call the GetLastError function. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-registertouchhittestingwindow BOOL // RegisterTouchHitTestingWindow( HWND hwnd, ULONG value ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "52e48cea-b5c7-405f-8df6-26052304b62c")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool RegisterTouchHitTestingWindow(HWND hwnd, TOUCH_HIT_TESTING value); /// Registers a window as being touch-capable. /// /// The handle of the window being registered. The function fails with ERROR_ACCESS_DENIED if the calling thread does not own /// the specified window. /// /// /// A set of bit flags that specify optional modifications. This field may contain 0 or one of the following values. /// /// /// Value /// Meaning /// /// /// TWF_FINETOUCH /// Specifies that hWnd prefers noncoalesced touch input. /// /// /// TWF_WANTPALM /// /// Setting this flag disables palm rejection which reduces delays for getting WM_TOUCH messages. This is useful if you want as quick /// of a response as possible when a user touches your application. By default, palm detection is enabled and some WM_TOUCH messages /// are prevented from being sent to your application. This is useful if you do not want to receive WM_TOUCH messages that are from /// palm contact. /// /// /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, use the GetLastError function. /// /// /// /// NoteRegisterTouchWindow must be called on every window that will be used for touch input. This means that if you /// have an application that has multiple windows within it, RegisterTouchWindow must be called on every window in that /// application that uses touch features. Also, an application can call RegisterTouchWindow any number of times for the same /// window if it desires to change the modifier flags. A window can be marked as no longer requiring touch input using the /// UnregisterTouchWindow function. /// /// /// If TWF_WANTPALM is enabled, packets from touch input are not buffered and palm detection is not performed before the /// packets are sent to your application. Enabling TWF_WANTPALM is most useful if you want minimal latencies when processing /// WM_TOUCH messages. /// /// Examples /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-registertouchwindow BOOL RegisterTouchWindow( HWND hwnd, // ULONG ulFlags ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "a70a7418-f79d-40c8-9219-3ce38a74da9f")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool RegisterTouchWindow(HWND hwnd, TWF ulFlags); /// Configures the messages that are sent from a window for Windows Touch gestures. /// A handle to the window to set the gesture configuration on. /// This value is reserved and must be set to 0. /// A count of the gesture configuration structures that are being passed. /// An array of gesture configuration structures that specify the gesture configuration. /// The size of the gesture configuration (GESTURECONFIG) structure. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, use the GetLastError function. /// /// /// /// If you don't expect to change the gesture configuration, call SetGestureConfig at window creation time. If you want to /// dynamically change the gesture configuration, call SetGestureConfig in response to WM_GESTURENOTIFY messages. /// /// /// The following table shows the identifiers for gestures that are supported by the dwID member of the GESTURECONFIG structure. Note /// that setting dwID to 0 indicates that global gesture configuration flags are set. /// /// /// /// Name /// Value /// Description /// /// /// GID_ZOOM /// 3 /// Configuration settings for the zoom gesture. /// /// /// GID_PAN /// 4 /// The pan gesture. /// /// /// GID_ROTATE /// 5 /// The rotation gesture. /// /// /// GID_TWOFINGERTAP /// 6 /// The two-finger tap gesture. /// /// /// GID_PRESSANDTAP /// 7 /// The press and tap gesture. /// /// /// The following flags are used when dwID is set to zero. /// /// /// Name /// Value /// Description /// /// /// GC_ALLGESTURES /// 0x00000001 /// All of the gestures. /// /// /// The following flags are used when dwID is set to GID_ZOOM. /// /// /// Name /// Value /// Description /// /// /// GC_ZOOM /// 0x00000001 /// The zoom gesture. /// /// /// The following flags are used when dwID is set to GID_PAN. /// /// /// Name /// Value /// Description /// /// /// GC_PAN /// 0x00000001 /// All pan gestures. /// /// /// GC_PAN_WITH_SINGLE_FINGER_VERTICALLY /// 0x00000002 /// Vertical pans with one finger. /// /// /// GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY /// 0x00000004 /// Horizontal pans with one finger. /// /// /// GC_PAN_WITH_GUTTER /// 0x00000008 /// /// Panning with a gutter boundary around the edges of pannable region. The gutter boundary limits perpendicular movement to a /// primary direction until a threshold is reached to break out of the gutter. /// /// /// /// GC_PAN_WITH_INTERTIA /// 0x00000010 /// Panning with inertia to smoothly slow when pan gestures stop. /// /// /// /// Note Pan gestures can be used in conjunction with each other to control behavior. For example, setting the dwWant /// bits to panning with single-finger horizontal and setting the dwBlock bits to single-finger vertical will restrict panning /// to horizontal pans. Changing the dwWant bit to have and removing single-finger vertical pan from the dwBlock bit /// will enable both vertical and horizontal panning. /// /// Note By default, panning has inertia enabled. /// Note A single call to SetGestureConfig cannot include other GIDs along with 0. /// The following flags are used when dwID is set to GID_ROTATE. /// /// /// Name /// Value /// Description /// /// /// GC_ROTATE /// 0x00000001 /// The rotation gesture. /// /// /// The following flags are used when dwID is set to GID_TWOFINGERTAP. /// /// /// Name /// Value /// Description /// /// /// GC_TWOFINGERTAP /// 0x00000001 /// The two-finger tap gesture. /// /// /// The following flags are used when dwID is set to GID_PRESSANDTAP. /// /// /// Name /// Value /// Description /// /// /// GC_PRESSANDTAP /// 0x00000001 /// The press and tap gesture. /// /// /// /// Note Calling SetGestureConfig will change the gesture configuration for the lifetime of the Window, not just for /// the next gesture. /// /// Examples /// /// The following example shows how you could receive horizontal and vertical single-finger panning with no gutter and no inertia. /// This is a typical configuration for a 2-D navigation application such as the Microsoft PixelSense Globe application. /// /// /// The following example shows how to receive single-finger pan gestures and disable gutter panning. This is a typical configuration /// for applications that scroll text such as Notepad. /// /// Note You should explicitly set all the flags that you want enabled or disabled when controlling single-finger panning. /// The following example shows how you can disable all gestures. /// The following example shows how you could enable all gestures. /// The following example shows how you could enable all Windows 7 gestures. /// /// The following example configuration would set the parent window to enable support for zoom, horizontal pan, and vertical pan /// while the child window would just support horizontal pan. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setgestureconfig BOOL SetGestureConfig( HWND hwnd, DWORD // dwReserved, UINT cIDs, PGESTURECONFIG pGestureConfig, UINT cbSize ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "7df5a18e-5e65-4dd5-a59d-853a91ead710")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetGestureConfig(HWND hwnd, [Optional] uint dwReserved, uint cIDs, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] GESTURECONFIG[] pGestureConfig, uint cbSize); /// Converts touch coordinates to pixels. /// The value to be converted from touch coordinates to pixels. /// The pixel value. /// /// /// The TOUCH_COORD_TO_PIXEL macro is used to convert from touch coordinates (currently centipixels) to pixels. Touch /// coordinates are finer grained than pixels so that application developers can use subpixel granularity for specialized /// applications such as graphic design. /// /// Examples /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-touch_coord_to_pixel void TOUCH_COORD_TO_PIXEL( l ); [PInvokeData("winuser.h", MSDNShortId = "719b6800-aeda-424a-86ea-d8c307bd6ad2")] public static int TOUCH_COORD_TO_PIXEL(int l) => l / 100; /// Registers a window as no longer being touch-capable. /// /// The handle of the window. The function fails with ERROR_ACCESS_DENIED if the calling thread does not own the specified window. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, use the GetLastError function. /// /// /// The UnregisterTouchWindow function succeeds even if the specified window was not previously registered as being touch-capable. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-unregistertouchwindow BOOL UnregisterTouchWindow( HWND // hwnd ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "19b83312-b52b-45a5-9595-23d4621c4342")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool UnregisterTouchWindow(HWND hwnd); /// Gets and sets the configuration for enabling gesture messages and the type of this configuration. /// /// /// It is impossible to disable two-finger panning and keep single finger panning. You must set the want bits for GC_PAN before you /// can set them for GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY or GC_PAN_WITH_SINGLE_FINGER_VERTICALLY. /// /// An inertia vector is included in the GID_PAN message with the GF_END flag if inertia was disabled by a call to SetGestureConfig. /// /// When you pass this structure, the dwID member contains information for a set of gestures. This determines what the other flags /// will mean. If you set flags for pan messages, they will be different from those flags that are set for rotation messages. /// /// /// The following table indicates the various identifiers for gestures that are supported by the dwID member of the /// GESTURECONFIG structure. Note that setting dwID to 0 indicates that global gesture configuration flags are set. /// /// /// /// Name /// Value /// Description /// /// /// GID_ZOOM /// 3 /// Indicates configuration settings for the zoom gesture. /// /// /// GID_PAN /// 4 /// Indicates the pan gesture. /// /// /// GID_ROTATE /// 5 /// Indicates the rotation gesture. /// /// /// GID_TWOFINGERTAP /// 6 /// Indicates the two-finger tap gesture. /// /// /// GID_PRESSANDTAP /// 7 /// Indicates the press and tap gesture. /// /// /// The following flags are used when dwID is set to 0. /// /// /// Name /// Value /// Description /// /// /// GC_ALLGESTURES /// 0x00000001 /// Indicates all of the gestures. /// /// /// The following flags are used when dwID is set to GID_ZOOM. /// /// /// Name /// Value /// Description /// /// /// GC_ZOOM /// 0x00000001 /// Indicates the zoom gesture. /// /// /// The following flags are used when dwID is set to GID_PAN. /// /// /// Name /// Value /// Description /// /// /// GC_PAN /// 0x00000001 /// Indicates all pan gestures. /// /// /// GC_PAN_WITH_SINGLE_FINGER_VERTICALLY /// 0x00000002 /// Indicates vertical pans with one finger. /// /// /// GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY /// 0x00000004 /// Indicates horizontal pans with one finger. /// /// /// GC_PAN_WITH_GUTTER /// 0x00000008 /// Limits perpendicular movement to primary direction until a threshold is reached to break out of the gutter. /// /// /// GC_PAN_WITH_INERTIA /// 0x00000010 /// Indicates panning with inertia to smoothly slow when pan gestures stop. /// /// /// /// Note Setting the GID_PAN flags in SetGestureConfig will affect the default gesture handler for panning. You should /// not have both dwWant and dwBlock set for the same flags; this will result in unexpected behavior. See Windows Touch /// Gestures for more information on panning and legacy panning support; see SetGestureConfig for examples of enabling and /// blocking gestures. /// /// The following flags are used when dwID is set to GID_ROTATE. /// /// /// Name /// Value /// Description /// /// /// GC_ROTATE /// 0x00000001 /// Indicates the rotation gesture. /// /// /// The following flags are used when dwID is set to GID_TWOFINGERTAP. /// /// /// Name /// Value /// Description /// /// /// GC_TWOFINGERTAP /// 0x00000001 /// Indicates the two-finger tap gesture. /// /// /// The following flags are used when dwID is set to GID_PRESSANDTAP. /// /// /// Name /// Value /// Description /// /// /// GC_PRESSANDTAP /// 0x00000001 /// Indicates the press and tap gesture. /// /// /// Examples /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-taggestureconfig typedef struct tagGESTURECONFIG { DWORD // dwID; DWORD dwWant; DWORD dwBlock; } GESTURECONFIG, *PGESTURECONFIG; [PInvokeData("winuser.h", MSDNShortId = "4ec5050e-7fef-4f52-89af-5237e8cdbdb8")] [StructLayout(LayoutKind.Sequential)] public struct GESTURECONFIG { /// /// The identifier for the type of configuration that will have messages enabled or disabled. For more information, see Remarks. /// public GID dwID; /// The messages to enable. public GC dwWant; /// The messages to disable. public GC dwBlock; /// Initializes a new instance of the struct. /// The identifier for the type of configuration that will have messages enabled or disabled. public GESTURECONFIG(GID id) : this() => dwID = id; } /// Stores information about a gesture. /// /// The HIDWORD of the ullArguments member is always 0, with the following exceptions: /// /// /// /// For GID_PAN, it is 0 except when there is inertia. When GF_INERTIA is set, the HIDWORD is an inertia vector /// (two 16-bit values). /// /// /// /// For GID_PRESSANDTAP, it is the distance between the two points. /// /// /// /// The GESTUREINFO structure is retrieved by passing the handle to the gesture information structure to the GetGestureInfo function. /// /// The following flags indicate the various states of the gestures and are stored in dwFlags. /// /// /// Name /// Value /// Description /// /// /// GF_BEGIN /// 0x00000001 /// A gesture is starting. /// /// /// GF_INERTIA /// 0x00000002 /// A gesture has triggered inertia. /// /// /// GF_END /// 0x00000004 /// A gesture has finished. /// /// /// /// Note Most applications should ignore the GID_BEGIN and GID_END messages and pass them to /// DefWindowProc. These messages are used by the default gesture handler. Application behavior is undefined when the /// GID_BEGIN and GID_END messages are consumed by a third-party application. /// /// The following table indicates the various identifiers for gestures. /// /// /// Name /// Value /// Description /// /// /// GID_BEGIN /// 1 /// A gesture is starting. /// /// /// GID_END /// 2 /// A gesture is ending. /// /// /// GID_ZOOM /// 3 /// The zoom gesture. /// /// /// GID_PAN /// 4 /// The pan gesture. /// /// /// GID_ROTATE /// 5 /// The rotation gesture. /// /// /// GID_TWOFINGERTAP /// 6 /// The two-finger tap gesture. /// /// /// GID_PRESSANDTAP /// 7 /// The press and tap gesture. /// /// /// /// Note The GID_PAN gesture has built-in inertia. At the end of a pan gesture, additional pan gesture messages are /// created by the operating system. /// /// The following type is defined to represent a constant pointer to a GESTUREINFO structure. /// Examples /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-taggestureinfo typedef struct tagGESTUREINFO { UINT // cbSize; DWORD dwFlags; DWORD dwID; HWND hwndTarget; POINTS ptsLocation; DWORD dwInstanceID; DWORD dwSequenceID; ULONGLONG // ullArguments; UINT cbExtraArgs; } GESTUREINFO, *PGESTUREINFO; [PInvokeData("winuser.h", MSDNShortId = "f5b8b530-ff1e-4d78-a12f-86990fe9ac88")] [StructLayout(LayoutKind.Sequential)] public struct GESTUREINFO { /// The size of the structure, in bytes. The caller must set this to . public uint cbSize; /// The state of the gesture. For additional information, see Remarks. public GF dwFlags; /// The identifier of the gesture command. public GID dwID; /// A handle to the window that is targeted by this gesture. public HWND hwndTarget; /// /// A POINTS structure containing the coordinates associated with the gesture. These coordinates are always relative to /// the origin of the screen. /// public POINTS ptsLocation; /// An internally used identifier for the structure. public uint dwInstanceID; /// An internally used identifier for the sequence. public uint dwSequenceID; /// A 64-bit unsigned integer that contains the arguments for gestures that fit into 8 bytes. public ulong ullArguments; /// The size, in bytes, of extra arguments that accompany this gesture. public uint cbExtraArgs; /// A default value for with the field value set correctly. public static readonly GESTUREINFO Default = new GESTUREINFO { cbSize = (uint)Marshal.SizeOf(typeof(GESTUREINFO)) }; } /// When transmitted with WM_GESTURENOTIFY messages, passes information about a gesture. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-taggesturenotifystruct typedef struct // tagGESTURENOTIFYSTRUCT { UINT cbSize; DWORD dwFlags; HWND hwndTarget; POINTS ptsLocation; DWORD dwInstanceID; } // GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT; [PInvokeData("winuser.h", MSDNShortId = "e887c026-9300-4d20-8925-9939a664cd53")] [StructLayout(LayoutKind.Sequential)] public struct GESTURENOTIFYSTRUCT { /// The size of the structure. public uint cbSize; /// Reserved for future use. public uint dwFlags; /// The target window for the gesture notification. public HWND hwndTarget; /// The location of the gesture in physical screen coordinates. public POINTS ptsLocation; /// A specific gesture instance with gesture messages starting with GID_START and ending with GID_END. public uint dwInstanceID; /// A default value for with the field value set correctly. public static readonly GESTURENOTIFYSTRUCT Default = new GESTURENOTIFYSTRUCT { cbSize = (uint)Marshal.SizeOf(typeof(GESTURENOTIFYSTRUCT)) }; } /// Provides a handle to a gesture info. [StructLayout(LayoutKind.Sequential)] public struct HGESTUREINFO : IHandle { private IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public HGESTUREINFO(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . public static HGESTUREINFO NULL => new HGESTUREINFO(IntPtr.Zero); /// Gets a value indicating whether this instance is a null handle. public bool IsNull => handle == IntPtr.Zero; /// Performs an explicit conversion from to . /// The handle. /// The result of the conversion. public static explicit operator IntPtr(HGESTUREINFO h) => h.handle; /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. public static implicit operator HGESTUREINFO(IntPtr h) => new HGESTUREINFO(h); /// Implements the operator !=. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator !=(HGESTUREINFO h1, HGESTUREINFO h2) => !(h1 == h2); /// Implements the operator ==. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator ==(HGESTUREINFO h1, HGESTUREINFO h2) => h1.Equals(h2); /// public override bool Equals(object obj) => obj is HGESTUREINFO h ? handle == h.handle : false; /// public override int GetHashCode() => handle.GetHashCode(); /// public IntPtr DangerousGetHandle() => handle; } /// Provides a handle to a touch input. [StructLayout(LayoutKind.Sequential)] public struct HTOUCHINPUT : IHandle { private IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public HTOUCHINPUT(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . public static HTOUCHINPUT NULL => new HTOUCHINPUT(IntPtr.Zero); /// Gets a value indicating whether this instance is a null handle. public bool IsNull => handle == IntPtr.Zero; /// Performs an explicit conversion from to . /// The handle. /// The result of the conversion. public static explicit operator IntPtr(HTOUCHINPUT h) => h.handle; /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. public static implicit operator HTOUCHINPUT(IntPtr h) => new HTOUCHINPUT(h); /// Implements the operator !=. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator !=(HTOUCHINPUT h1, HTOUCHINPUT h2) => !(h1 == h2); /// Implements the operator ==. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator ==(HTOUCHINPUT h1, HTOUCHINPUT h2) => h1.Equals(h2); /// public override bool Equals(object obj) => obj is HTOUCHINPUT h ? handle == h.handle : false; /// public override int GetHashCode() => handle.GetHashCode(); /// public IntPtr DangerousGetHandle() => handle; } /// Contains information about the touch contact area reported by the touch digitizer. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-touch_hit_testing_input typedef struct // tagTOUCH_HIT_TESTING_INPUT { UINT32 pointerId; POINT point; RECT boundingBox; RECT nonOccludedBoundingBox; UINT32 orientation; } // TOUCH_HIT_TESTING_INPUT, *PTOUCH_HIT_TESTING_INPUT; [PInvokeData("winuser.h", MSDNShortId = "d2103f6e-6aa9-4260-bef9-cfcbec35e675")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct TOUCH_HIT_TESTING_INPUT { /// /// The ID of the pointer. You cannot pass this value to the input message process and retrieve additional pointer info through GetPointerInfo. /// public uint pointerId; /// The screen coordinates of the touch point that the touch digitizer reports. public POINT point; /// /// /// The bounding rectangle of the touch contact area. Valid touch targets are identified and scored based on this bounding box. /// /// Note This bounding box may differ from the contact area that the digitizer reports when: /// public RECT boundingBox; /// /// The touch contact area within a specific targeted window that's not occluded by other objects that are higher in the z-order. /// Any area that's occluded by another object is an invalid target. /// public RECT nonOccludedBoundingBox; /// The orientation of the touch contact area. public uint orientation; } /// /// Contains the hit test score that indicates whether the object is the likely target of the touch contact area, relative to other /// objects that intersect the touch contact area. /// /// The EvaluateProximityToRect or EvaluateProximityToPolygon function returns the values. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-touch_hit_testing_proximity_evaluation typedef struct // tagTOUCH_HIT_TESTING_PROXIMITY_EVALUATION { UINT16 score; POINT adjustedPoint; } TOUCH_HIT_TESTING_PROXIMITY_EVALUATION, *PTOUCH_HIT_TESTING_PROXIMITY_EVALUATION; [PInvokeData("winuser.h", MSDNShortId = "a26facc3-fe63-4657-9bd6-821dd89cb11d")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct TOUCH_HIT_TESTING_PROXIMITY_EVALUATION { /// The score, compared to the other objects that intersect the touch contact area. public ushort score; /// The adjusted touch point that hits the closest object that's identified by the value of Score. public POINT adjustedPoint; } /// Encapsulates data for touch input. /// /// The following table lists the flags for the dwFlags member. /// /// /// Flag /// Value /// Description /// /// /// TOUCHEVENTF_MOVE /// 0x0001 /// Movement has occurred. Cannot be combined with TOUCHEVENTF_DOWN. /// /// /// TOUCHEVENTF_DOWN /// 0x0002 /// The corresponding touch point was established through a new contact. Cannot be combined with TOUCHEVENTF_MOVE or TOUCHEVENTF_UP. /// /// /// TOUCHEVENTF_UP /// 0x0004 /// A touch point was removed. /// /// /// TOUCHEVENTF_INRANGE /// 0x0008 /// /// A touch point is in range. This flag is used to enable touch hover support on compatible hardware. Applications that do not want /// support for hover can ignore this flag. /// /// /// /// TOUCHEVENTF_PRIMARY /// 0x0010 /// /// Indicates that this TOUCHINPUT structure corresponds to a primary contact point. See the following text for more information on /// primary touch points. /// /// /// /// TOUCHEVENTF_NOCOALESCE /// 0x0020 /// When received using GetTouchInputInfo, this input was not coalesced. /// /// /// TOUCHEVENTF_PALM /// 0x0080 /// The touch event came from the user's palm. /// /// /// /// Note If the target hardware on a machine does not support hover, when the TOUCHEVENTF_UP flag is set, the /// TOUCHEVENTF_INRANGE flag is cleared. If the target hardware on a machine supports hover, the TOUCHEVENTF_UP and /// TOUCHEVENTF_INRANGE flags will be set independently. /// /// The following table lists the flags for the dwMask member. /// /// /// Flag /// Value /// Description /// /// /// TOUCHINPUTMASKF_CONTACTAREA /// 0x0004 /// cxContact and cyContact are valid. See the following text for more information on primary touch points. /// /// /// TOUCHINPUTMASKF_EXTRAINFO /// 0x0002 /// dwExtraInfo is valid. /// /// /// TOUCHINPUTMASKF_TIMEFROMSYSTEM /// 0x0001 /// The system time was set in the TOUCHINPUT structure. /// /// /// /// A touch point is designated as primary when it is the first touch point to be established from a previous state of no touch /// points. The TOUCHEVENTF_PRIMARY flag continues to be set for all subsequent events for the primary touch point until the /// primary touch point is released. Note that a TOUCHEVENTF_UP event on the primary touch point does not necessarily /// designate the end of a Windows Touch operation; the current Windows Touch operation proceeds from the establishment of the /// primary touch point until the last touch point is released. /// /// /// Note that a solitary touch point or, in a set of simultaneous touch points, the first to be detected, is designated the primary. /// The system mouse position follows the primary touch point and, in addition to touch messages, also generates /// WM_LBUTTONDOWN, WM_MOUSEMOVE, and WM_LBUTTONUP messages in response to actions on a primary touch point. The /// primary touch point can also generate WM_RBUTTONDOWN and WM_RBUTTONUP messages using the press and hold gesture. /// /// /// Note that the touch point identifier may be dynamic and is associated with a given touch point only as long as the touch point /// persists. If contact is broken and then resumed (for example, if a finger is removed from the surface and then pressed down /// again), the same touch point (the same finger, pen, or other such device) may receive a different touch point identifier. /// /// The following type is defined to represent a constant pointer to a TOUCHINPUT structure. /// Examples /// /// Note In the following example, the pInputs array is not sorted. Use the dwID value to track specific touch points. /// /// /// The following example shows how to get the device information from the hSource member. This example uses GetRawInputDevice /// to retrieve information about the device. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagtouchinput typedef struct tagTOUCHINPUT { LONG x; LONG // y; HANDLE hSource; DWORD dwID; DWORD dwFlags; DWORD dwMask; DWORD dwTime; ULONG_PTR dwExtraInfo; DWORD cxContact; DWORD cyContact; // } TOUCHINPUT, *PTOUCHINPUT; [PInvokeData("winuser.h", MSDNShortId = "fc382759-3a1e-401e-a6a7-1bf209a5434b")] [StructLayout(LayoutKind.Sequential)] public struct TOUCHINPUT { /// /// The x-coordinate (horizontal point) of the touch input. This member is indicated in hundredths of a pixel of physical screen coordinates. /// public int x; /// /// The y-coordinate (vertical point) of the touch input. This member is indicated in hundredths of a pixel of physical screen coordinates. /// public int y; /// /// A device handle for the source input device. Each device is given a unique provider at run time by the touch input provider. /// public HANDLE hSource; /// /// A touch point identifier that distinguishes a particular touch input. This value stays consistent in a touch contact sequence /// from the point a contact comes down until it comes back up. An ID may be reused later for subsequent contacts. /// public uint dwID; /// /// A set of bit flags that specify various aspects of touch point press, release, and motion. The bits in this member can be any /// reasonable combination of the values in the Remarks section. /// public TOUCHEVENTF dwFlags; /// /// A set of bit flags that specify which of the optional fields in the structure contain valid values. The availability of valid /// information in the optional fields is device-specific. Applications should use an optional field value only when the /// corresponding bit is set in dwMask. This field may contain a combination of the dwMask flags mentioned in the Remarks section. /// public TOUCHINPUTMASKF dwMask; /// /// The time stamp for the event, in milliseconds. The consuming application should note that the system performs no validation /// on this field; when the TOUCHINPUTMASKF_TIMEFROMSYSTEM flag is not set, the accuracy and sequencing of values in this /// field are completely dependent on the touch input provider. /// public uint dwTime; /// An additional value associated with the touch event. public UIntPtr dwExtraInfo; /// /// The width of the touch contact area in hundredths of a pixel in physical screen coordinates. This value is only valid if the /// dwMask member has the TOUCHEVENTFMASK_CONTACTAREA flag set. /// public uint cxContact; /// /// The height of the touch contact area in hundredths of a pixel in physical screen coordinates. This value is only valid if the /// dwMask member has the TOUCHEVENTFMASK_CONTACTAREA flag set. /// public uint cyContact; } } }