#region The MIT License (MIT) // // Copyright (c) 2011 Robert Prouse http://www.alteridem.net // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in // the Software without restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the // Software, and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #endregion #region Using Directives using System; using System.Runtime.InteropServices; #endregion namespace MaterialSkin.Gesture { internal static class NativeMethods { #region Private Delegates [UnmanagedFunctionPointer( CallingConvention.Cdecl )] private delegate bool GetGestureInfoPtr( IntPtr gestureInfoHandle, ref GestureInfo pGestureInfo ); [UnmanagedFunctionPointer( CallingConvention.Cdecl )] private delegate bool CloseGestureInfoHandlePtr( IntPtr gestureInfoHandle ); [UnmanagedFunctionPointer( CallingConvention.Cdecl )] private delegate bool SetGestureConfigPtr( IntPtr hwnd, uint reserved, uint ids, GestureConfig[] configs, uint size ); private static readonly GetGestureInfoPtr _pGetGestureInfoPtr; private static readonly CloseGestureInfoHandlePtr _pCloseGestureInfoHandle; private static readonly SetGestureConfigPtr _pSetGestureConfig; #endregion #region Static Construction static NativeMethods() { var user32 = new UnmanagedLibrary( "user32" ); _pGetGestureInfoPtr = user32.GetUnmanagedFunction( "GetGestureInfo" ); _pCloseGestureInfoHandle = user32.GetUnmanagedFunction( "CloseGestureInfoHandle" ); _pSetGestureConfig = user32.GetUnmanagedFunction( "SetGestureConfig" ); } #endregion #region Public Interface /// /// Registers the HWND to receive all gestures. /// /// /// http://msdn.microsoft.com/en-us/library/windows/desktop/dd353231%28v=vs.85%29.aspx /// /// The HWND. /// public static bool SetGestureConfig( IntPtr hwnd ) { if ( _pSetGestureConfig == null ) return false; var configs = new[] { new GestureConfig( 0, GestureConfigurationFlag.GC_ALLGESTURES, 0 ) }; return SetGestureConfig(hwnd, configs); } /// /// Registers the HWND to receive specific gestures. /// /// /// http://msdn.microsoft.com/en-us/library/windows/desktop/dd353231%28v=vs.85%29.aspx /// /// The HWND. /// The gesture configurations /// public static bool SetGestureConfig( IntPtr hwnd, GestureConfig[] configs ) { return _pSetGestureConfig( hwnd, 0, 1, configs, (uint)Marshal.SizeOf( typeof( GestureConfig ) ) ); } /// /// Gets the gesture info. /// /// The gesture info handle. /// The gesture info. /// public static bool GetGestureInfo( IntPtr gestureInfoHandle, out GestureInfo gestureInfo ) { gestureInfo = new GestureInfo(); if ( _pGetGestureInfoPtr == null ) return false; gestureInfo.size = Marshal.SizeOf( gestureInfo ); return _pGetGestureInfoPtr( gestureInfoHandle, ref gestureInfo ); } /// /// Closes the gesture info handle. /// /// The gesture info handle. /// public static bool CloseGestureInfoHandle( IntPtr gestureInfoHandle ) { if ( _pCloseGestureInfoHandle == null ) return false; return _pCloseGestureInfoHandle( gestureInfoHandle ); } #endregion } /// /// Gesture configuration flags /// internal static class GestureConfigurationFlag { public const int GC_ALLGESTURES = 0x00000001; public const int GC_ZOOM = 0x00000001; public const int GC_PAN = 0x00000001; public const int GC_PAN_WITH_SINGLE_FINGER_VERTICALLY = 0x00000002; public const int GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY = 0x00000004; public const int GC_PAN_WITH_GUTTER = 0x00000008; public const int GC_PAN_WITH_INERTIA = 0x00000010; public const int GC_ROTATE = 0x00000001; public const int GC_TWOFINGERTAP = 0x00000001; public const int GC_PRESSANDTAP = 0x00000001; } /// /// Gesture flags - GestureInfo.flags /// [Flags] public enum GestureFlags { /// /// GF_BEGIN /// Begin = 0x1, /// /// GF_INERTIA /// Inertia = 0x2, /// /// GF_END /// End = 0x4 } /// /// Gesture IDs - GestureInfo.id /// public enum GestureId { /// /// GID_BEGIN /// Begin = 1, /// /// GID_END /// End = 2, /// /// GID_ZOOM /// Zoom = 3, /// /// GID_PAN /// Pan = 4, /// /// GID_ROTATE /// Rotate = 5, /// /// GID_TWOFINGERTAP /// TwoFingerTap = 6, /// /// GID_PRESSANDTAP /// PressAndTap = 7 } /// /// Window Messages /// internal static class WindowMessage { public const int WM_TOUCH = 0x0240; public const int WM_POINTERUPDATE =0x0245; public const int WM_GESTURE = 0x0119; public const int WM_GESTURENOTIFY = 0x011A; public const int TOUCHEVENTF_MOVE = 0x0001; public const int TOUCHEVENTF_DOWN = 0x0002; public const int TOUCHEVENTF_UP = 0x0004; public const int TOUCHEVENTF_INRANGE = 0x0008; public const int TOUCHEVENTF_PRIMARY = 0x0010; public const int TOUCHEVENTF_NOCOALESCE = 0x0020; public const int TOUCHEVENTF_PEN = 0x0040; // Touch input mask values (TOUCHINPUT.dwMask) [winuser.h] public const int TOUCHINPUTMASKF_TIMEFROMSYSTEM = 0x0001; // the dwTime field contains a system generated value public const int TOUCHINPUTMASKF_EXTRAINFO = 0x0002; // the dwExtraInfo field is valid public const int TOUCHINPUTMASKF_CONTACTAREA = 0x0004; // the cxContact and cyContact fields are valid } [StructLayout( LayoutKind.Sequential )] public struct Points { public short x; public short y; } /// /// Gesture configuration structure /// /// /// Used in SetGestureConfig and GetGestureConfig /// http://msdn.microsoft.com/en-us/library/windows/desktop/dd353231%28v=vs.85%29.aspx /// [StructLayout( LayoutKind.Sequential )] public struct GestureConfig { public GestureConfig( uint id, uint want, uint block ) { Id = id; Want = want; Block = block; } /// /// The identifier for the type of configuration that will have messages enabled or disabled. /// public uint Id; /// /// The messages to enable. /// public uint Want; /// /// The messages to disable. /// public uint Block; } /// /// Stores information about a gesture. /// /// /// - Pass the HGESTUREINFO received in the WM_GESTURE message lParam into the /// GetGestureInfo function to retrieve this information. /// - If cbExtraArgs is non-zero, pass the HGESTUREINFO received in the WM_GESTURE /// message lParam into the GetGestureExtraArgs function to retrieve extended /// argument information. /// [StructLayout( LayoutKind.Sequential )] public struct GestureInfo { /// /// The size of the structure, in bytes. The caller must set this. /// public int size; /// /// The state of the gesture. Contains GestureFlags. /// public int flags; /// /// The identifier of the gesture command. Contains GestureId. /// public int id; /// /// A handle to the window that is targeted by this gesture. /// public IntPtr hwnd; /// /// A Points structure containing the coordinates associated with the gesture. These coordinates are always relative to the origin of the screen. /// public Points location; /// /// An internally used identifier for the structure. /// public int instanceId; /// /// An internally used identifier for the sequence. /// public int sequenceId; /// /// A 64-bit unsigned integer that contains the arguments for gestures that fit into 8 bytes. /// public Int64 arguments; /// /// The size, in bytes, of extra arguments that accompany this gesture. /// public int extraArguments; /// /// Gets a value indicating whether the Begin is set. /// public bool Begin { get { return ((GestureFlags)flags & GestureFlags.Begin) == GestureFlags.Begin; } } /// /// Gets a value indicating whether the End is set. /// public bool End { get { return ((GestureFlags)flags & GestureFlags.End) == GestureFlags.End; } } /// /// Gets a value indicating whether the Inertia is set /// public bool Inertia { get { return ((GestureFlags)flags & GestureFlags.Inertia) == GestureFlags.Inertia; } } } }