DotNet 4.8.1 build of DotNetBar
This commit is contained in:
968
PROMS/DotNetBar Source Code/Touch/TouchHandler.cs
Normal file
968
PROMS/DotNetBar Source Code/Touch/TouchHandler.cs
Normal file
@@ -0,0 +1,968 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Data;
|
||||
|
||||
namespace DevComponents.DotNetBar.Touch
|
||||
{
|
||||
public class TouchHandler
|
||||
{
|
||||
#region Events
|
||||
public event EventHandler<GestureEventArgs> PanBegin;
|
||||
/// <summary>
|
||||
/// Raises PanBegin event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnPanBegin(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = PanBegin;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
public event EventHandler<GestureEventArgs> PanEnd;
|
||||
/// <summary>
|
||||
/// Raises PanBegin event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnPanEnd(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = PanEnd;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
public event EventHandler<GestureEventArgs> Pan;
|
||||
/// <summary>
|
||||
/// Raises PanBegin event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnPan(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = Pan;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<GestureEventArgs> Begin;
|
||||
/// <summary>
|
||||
/// Raises Begin event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnBegin(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = Begin;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<GestureEventArgs> End;
|
||||
/// <summary>
|
||||
/// Raises End event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnEnd(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = End;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<GestureEventArgs> PressAndTap;
|
||||
/// <summary>
|
||||
/// Raises PressAndTap event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnPressAndTap(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = PressAndTap;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<GestureEventArgs> RotateBegin;
|
||||
/// <summary>
|
||||
/// Raises RotateBegin event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnRotateBegin(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = RotateBegin;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<GestureEventArgs> Rotate;
|
||||
/// <summary>
|
||||
/// Raises Rotate event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnRotate(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = Rotate;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<GestureEventArgs> RotateEnd;
|
||||
/// <summary>
|
||||
/// Raises RotateEnd event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnRotateEnd(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = RotateEnd;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<GestureEventArgs> TwoFingerTap;
|
||||
/// <summary>
|
||||
/// Raises TwoFingerTap event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnTwoFingerTap(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = TwoFingerTap;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<GestureEventArgs> ZoomBegin;
|
||||
/// <summary>
|
||||
/// Raises ZoomBegin event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnZoomBegin(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = ZoomBegin;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<GestureEventArgs> Zoom;
|
||||
/// <summary>
|
||||
/// Raises Zoom event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnZoom(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = Zoom;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<GestureEventArgs> ZoomEnd;
|
||||
/// <summary>
|
||||
/// Raises ZoomEnd event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnZoomEnd(GestureEventArgs e)
|
||||
{
|
||||
EventHandler<GestureEventArgs> handler = ZoomEnd;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
// Touch events
|
||||
public event EventHandler<TouchEventArgs> TouchDown;
|
||||
/// <summary>
|
||||
/// Raises TouchDown event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnTouchDown(TouchEventArgs e)
|
||||
{
|
||||
EventHandler<TouchEventArgs> handler = TouchDown;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<TouchEventArgs> TouchUp;
|
||||
/// <summary>
|
||||
/// Raises TouchDown event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnTouchUp(TouchEventArgs e)
|
||||
{
|
||||
EventHandler<TouchEventArgs> handler = TouchUp;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<TouchEventArgs> TouchMove;
|
||||
/// <summary>
|
||||
/// Raises TouchDown event.
|
||||
/// </summary>
|
||||
/// <param name="e">Provides event arguments.</param>
|
||||
protected virtual void OnTouchMove(TouchEventArgs e)
|
||||
{
|
||||
EventHandler<TouchEventArgs> handler = TouchMove;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
private Control _ParentControl = null;
|
||||
private eTouchHandlerType _HandlerType = eTouchHandlerType.Gesture;
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the TouchHandler class.
|
||||
/// </summary>
|
||||
/// <param name="parentControl"></param>
|
||||
public TouchHandler(Control parentControl) : this(parentControl, eTouchHandlerType.Gesture) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the TouchHandler class.
|
||||
/// </summary>
|
||||
/// <param name="parentControl"></param>
|
||||
public TouchHandler(Control parentControl, eTouchHandlerType handlerType)
|
||||
{
|
||||
_ParentControl = parentControl;
|
||||
_HandlerType = handlerType;
|
||||
if (IsTouchEnabled)
|
||||
{
|
||||
_ParentControl.HandleCreated += new EventHandler(ParentControlHandleCreated);
|
||||
if (_ParentControl.IsHandleCreated)
|
||||
Initialize();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Implementation
|
||||
void ParentControlHandleCreated(object sender, EventArgs e)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
private IntPtr _originalWindowProcId;
|
||||
private WinApi.WindowProcDelegate _windowProcDelegate;
|
||||
/// <summary>
|
||||
/// Initializes handler
|
||||
/// </summary>
|
||||
private void Initialize()
|
||||
{
|
||||
if (!RegisterTouchWindow())
|
||||
{
|
||||
throw new NotSupportedException("Cannot register window");
|
||||
}
|
||||
|
||||
_windowProcDelegate = WindowProc;
|
||||
|
||||
_originalWindowProcId = IntPtr.Size == 4 ?
|
||||
WinApi.SubclassWindow(_ParentControl.Handle, WinApi.GWLP_WNDPROC, _windowProcDelegate) :
|
||||
WinApi.SubclassWindow64(_ParentControl.Handle, WinApi.GWLP_WNDPROC, _windowProcDelegate);
|
||||
|
||||
//take the desktop DPI
|
||||
using (Graphics graphics = Graphics.FromHwnd(_ParentControl.Handle))
|
||||
{
|
||||
DpiX = graphics.DpiX;
|
||||
DpiY = graphics.DpiY;
|
||||
}
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
_ParentControl.HandleCreated -= new EventHandler(ParentControlHandleCreated);
|
||||
|
||||
if (_ParentControl.IsHandleCreated && !_ParentControl.IsDisposed && _originalWindowProcId != IntPtr.Zero)
|
||||
{
|
||||
IntPtr result = IntPtr.Size == 4 ?
|
||||
WinApi.SubclassWindow(_ParentControl.Handle, WinApi.GWLP_WNDPROC, _originalWindowProcId) :
|
||||
WinApi.SubclassWindow64(_ParentControl.Handle, WinApi.GWLP_WNDPROC, _originalWindowProcId);
|
||||
_originalWindowProcId = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public Control ParentControl
|
||||
{
|
||||
get { return _ParentControl; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Windows message handler.
|
||||
/// </summary>
|
||||
private uint WindowProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
if(msg == WinApi.WM_TOUCH && (_HandlerType & eTouchHandlerType.Touch)== eTouchHandlerType.Touch)
|
||||
{
|
||||
bool handled = false;
|
||||
foreach (TouchEventArgs arg in DecodeMessage(hWnd, msg, wParam, lParam, DpiX, DpiY))
|
||||
{
|
||||
|
||||
if (arg.IsTouchDown)
|
||||
OnTouchDown(arg);
|
||||
|
||||
if (arg.IsTouchMove)
|
||||
OnTouchMove(arg);
|
||||
|
||||
if (arg.IsTouchUp)
|
||||
OnTouchUp(arg);
|
||||
|
||||
handled |= arg.Handled;
|
||||
}
|
||||
if (handled)
|
||||
{
|
||||
WinApi.CloseTouchInputHandle(lParam);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle only gesture message
|
||||
if (msg != WinApi.WM_GESTURE)
|
||||
{
|
||||
return WinApi.CallWindowProc(_originalWindowProcId, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
WinApi.GESTUREINFO gestureInfo = new WinApi.GESTUREINFO();
|
||||
gestureInfo.cbSize = (uint)Marshal.SizeOf(typeof(WinApi.GESTUREINFO));
|
||||
|
||||
bool result = WinApi.GetGestureInfo(lParam, ref gestureInfo);
|
||||
|
||||
if (!result)
|
||||
throw new Exception("Cannot retrieve gesture information");
|
||||
|
||||
//Decode the gesture info and get the message event argument
|
||||
GestureEventArgs eventArgs = new GestureEventArgs(this, ref gestureInfo);
|
||||
try
|
||||
{
|
||||
//Fire the event using the event map
|
||||
uint gestureId = GetGestureEventId(gestureInfo.dwID, gestureInfo.dwFlags);
|
||||
if (gestureId == GestureEventId.Begin)
|
||||
OnBegin(eventArgs);
|
||||
else if (gestureId == GestureEventId.End)
|
||||
OnEnd(eventArgs);
|
||||
else if (gestureId == GestureEventId.Pan)
|
||||
OnPan(eventArgs);
|
||||
else if (gestureId == GestureEventId.PanBegin)
|
||||
OnPanBegin(eventArgs);
|
||||
else if (gestureId == GestureEventId.PanEnd)
|
||||
OnPanEnd(eventArgs);
|
||||
else if (gestureId == GestureEventId.PressAndTap)
|
||||
OnPressAndTap(eventArgs);
|
||||
else if (gestureId == GestureEventId.Rotate)
|
||||
OnRotate(eventArgs);
|
||||
else if (gestureId == GestureEventId.RotateBegin)
|
||||
OnRotateBegin(eventArgs);
|
||||
else if (gestureId == GestureEventId.RotateEnd)
|
||||
OnRotateEnd(eventArgs);
|
||||
else if (gestureId == GestureEventId.TwoFingerTap)
|
||||
OnTwoFingerTap(eventArgs);
|
||||
else if (gestureId == GestureEventId.Zoom)
|
||||
OnZoom(eventArgs);
|
||||
else if (gestureId == GestureEventId.ZoomBegin)
|
||||
OnZoomBegin(eventArgs);
|
||||
else if (gestureId == GestureEventId.ZoomEnd)
|
||||
OnZoomEnd(eventArgs);
|
||||
}
|
||||
catch (ArgumentOutOfRangeException) //In case future releases will introduce new event values
|
||||
{
|
||||
}
|
||||
|
||||
//Keep the last message for relative calculations
|
||||
LastEventArgs = eventArgs;
|
||||
|
||||
//Keep the first message for relative calculations
|
||||
if (eventArgs.IsBegin)
|
||||
LastBeginEventArgs = eventArgs;
|
||||
|
||||
if (eventArgs.Handled)
|
||||
{
|
||||
WinApi.CloseGestureInfoHandle(lParam);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return WinApi.CallWindowProc(_originalWindowProcId, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decode the message and create a collection of event arguments
|
||||
/// </summary>
|
||||
private IEnumerable<TouchEventArgs> DecodeMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, float dpiX, float dpiY)
|
||||
{
|
||||
// More than one touch input can be associated with a touch message
|
||||
int inputCount = WinApi.LoWord(DevComponents.DotNetBar.WinApi.ToInt(wParam)); // Number of touch inputs, actual per-contact messages
|
||||
|
||||
WinApi.TOUCHINPUT[] inputs; // Array of TOUCHINPUT structures
|
||||
inputs = new WinApi.TOUCHINPUT[inputCount]; // Allocate the storage for the parameters of the per-contact messages
|
||||
try
|
||||
{
|
||||
// Unpack message parameters into the array of TOUCHINPUT structures, each representing a message for one single contact.
|
||||
if (!WinApi.GetTouchInputInfo(lParam, inputCount, inputs, Marshal.SizeOf(inputs[0])))
|
||||
{
|
||||
// Touch info failed.
|
||||
throw new Exception("Error calling GetTouchInputInfo API");
|
||||
}
|
||||
|
||||
// For each contact, dispatch the message to the appropriate message handler.
|
||||
// For WM_TOUCHDOWN you can get down & move notifications and for WM_TOUCHUP you can get up & move notifications
|
||||
// WM_TOUCHMOVE will only contain move notifications and up & down notifications will never come in the same message
|
||||
for (int i = 0; i < inputCount; i++)
|
||||
{
|
||||
TouchEventArgs touchEventArgs = new TouchEventArgs(this, dpiX, dpiY, ref inputs[i]);
|
||||
yield return touchEventArgs;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
//WinApi.CloseTouchInputHandle(lParam);
|
||||
}
|
||||
}
|
||||
|
||||
private GestureEventArgs _LastBeginEventArgs;
|
||||
/// <summary>
|
||||
/// The event arguments that started the current gesture
|
||||
/// </summary>
|
||||
internal GestureEventArgs LastBeginEventArgs
|
||||
{
|
||||
get { return _LastBeginEventArgs; }
|
||||
set { _LastBeginEventArgs = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The last event in the current gesture event sequence
|
||||
/// </summary>
|
||||
private GestureEventArgs _LastEventArgs;
|
||||
internal GestureEventArgs LastEventArgs
|
||||
{
|
||||
get { return _LastEventArgs; }
|
||||
set { _LastEventArgs = value; }
|
||||
}
|
||||
|
||||
|
||||
private static class GestureEventId
|
||||
{
|
||||
public static readonly uint Begin = GetGestureEventId(WinApi.GID_BEGIN, 0);
|
||||
public static readonly uint End = GetGestureEventId(WinApi.GID_END, 0);
|
||||
public static readonly uint PanBegin = GetGestureEventId(WinApi.GID_PAN, WinApi.GF_BEGIN);
|
||||
public static readonly uint Pan = GetGestureEventId(WinApi.GID_PAN, 0);
|
||||
public static readonly uint PanEnd = GetGestureEventId(WinApi.GID_PAN, WinApi.GF_END);
|
||||
public static readonly uint PressAndTap = GetGestureEventId(WinApi.GID_PRESSANDTAP, 0);
|
||||
public static readonly uint RotateBegin = GetGestureEventId(WinApi.GID_ROTATE, WinApi.GF_BEGIN);
|
||||
public static readonly uint Rotate = GetGestureEventId(WinApi.GID_ROTATE, 0);
|
||||
public static readonly uint RotateEnd = GetGestureEventId(WinApi.GID_ROTATE, WinApi.GF_END);
|
||||
public static readonly uint TwoFingerTap = GetGestureEventId(WinApi.GID_TWOFINGERTAP, 0);
|
||||
public static readonly uint ZoomBegin = GetGestureEventId(WinApi.GID_ZOOM, WinApi.GF_BEGIN);
|
||||
public static readonly uint Zoom = GetGestureEventId(WinApi.GID_ZOOM, 0);
|
||||
public static readonly uint ZoomEnd = GetGestureEventId(WinApi.GID_ZOOM, WinApi.GF_END);
|
||||
}
|
||||
private static uint GetGestureEventId(uint dwID, uint dwFlags)
|
||||
{
|
||||
return (dwID << 3) + (dwID == WinApi.GID_TWOFINGERTAP || dwID == WinApi.GID_PRESSANDTAP
|
||||
|| dwID == WinApi.GID_BEGIN || dwID == WinApi.GID_END ?
|
||||
0 : dwFlags & 5);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register for touch event
|
||||
/// </summary>
|
||||
/// <returns>true if succeeded</returns>
|
||||
private bool RegisterTouchWindow()
|
||||
{
|
||||
bool result = false;
|
||||
if ((_HandlerType & eTouchHandlerType.Gesture) == eTouchHandlerType.Gesture)
|
||||
{
|
||||
WinApi.GESTURECONFIG[] gestureConfig = new WinApi.GESTURECONFIG[] { new WinApi.GESTURECONFIG(0, WinApi.GC_ALLGESTURES, 0) };
|
||||
result = WinApi.SetGestureConfig(_ParentControl.Handle, 0, 1, gestureConfig, (uint)Marshal.SizeOf(typeof(WinApi.GESTURECONFIG)));
|
||||
}
|
||||
|
||||
if ((_HandlerType & eTouchHandlerType.Touch) == eTouchHandlerType.Touch)
|
||||
{
|
||||
result |= WinApi.RegisterTouchWindow(_ParentControl.Handle, _DisablePalmRejection ? WinApi.TouchWindowFlag.WantPalm : 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool _DisablePalmRejection;
|
||||
/// <summary>
|
||||
/// Gets or sets whether palm rejection is enabled.
|
||||
/// </summary>
|
||||
public bool DisablePalmRejection
|
||||
{
|
||||
get
|
||||
{
|
||||
return _DisablePalmRejection;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_DisablePalmRejection == value)
|
||||
return;
|
||||
|
||||
_DisablePalmRejection = value;
|
||||
|
||||
if (_ParentControl.IsHandleCreated)
|
||||
{
|
||||
WinApi.UnregisterTouchWindow(_ParentControl.Handle);
|
||||
RegisterTouchWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float _DpiX;
|
||||
public float DpiX
|
||||
{
|
||||
get { return _DpiX; }
|
||||
set { _DpiX = value; }
|
||||
}
|
||||
|
||||
private float _DpiY;
|
||||
public float DpiY
|
||||
{
|
||||
get { return _DpiY; }
|
||||
set { _DpiY = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if Multi-touch support device is ready
|
||||
/// </summary>
|
||||
public static bool IsTouchEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return _EnableTouchSupport && ((WinApi.GetDigitizerStatus() & (WinApi.DigitizerStatus.StackReady | WinApi.DigitizerStatus.MultiInput)) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool _EnableTouchSupport = true;
|
||||
/// <summary>
|
||||
/// Gets or sets whether internal touch support is enabled for all DotNetBar controls.
|
||||
/// </summary>
|
||||
public static bool EnableTouchSupport
|
||||
{
|
||||
get { return _EnableTouchSupport; }
|
||||
set { _EnableTouchSupport = value; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
[Flags]
|
||||
public enum eTouchHandlerType : short
|
||||
{
|
||||
Gesture = 1,
|
||||
Touch = 2
|
||||
}
|
||||
|
||||
public class GestureEventArgs : EventArgs
|
||||
{
|
||||
private readonly uint _Flags;
|
||||
|
||||
/// <summary>
|
||||
/// Create new gesture event instance and decode the gesture info structure
|
||||
/// </summary>
|
||||
/// <param name="handler">The gesture handler</param>
|
||||
/// <param name="gestureInfo">The gesture information</param>
|
||||
internal GestureEventArgs(TouchHandler handler, ref WinApi.GESTUREINFO gestureInfo)
|
||||
{
|
||||
_Flags = gestureInfo.dwFlags;
|
||||
GestureId = gestureInfo.dwID;
|
||||
GestureArguments = gestureInfo.ullArguments;
|
||||
|
||||
//Get the last event from the handler
|
||||
LastEvent = handler.LastEventArgs;
|
||||
|
||||
//Get the last begin event from the handler
|
||||
LastBeginEvent = handler.LastBeginEventArgs;
|
||||
|
||||
ParseGesture(handler.ParentControl, ref gestureInfo);
|
||||
|
||||
//new gesture, clear last and first event fields
|
||||
if (IsBegin)
|
||||
{
|
||||
LastBeginEvent = null;
|
||||
LastEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
//Decode the gesture
|
||||
private void ParseGesture(Control parentControl, ref WinApi.GESTUREINFO gestureInfo)
|
||||
{
|
||||
Location = parentControl.PointToClient(new Point(gestureInfo.ptsLocation.x, gestureInfo.ptsLocation.y));
|
||||
|
||||
Center = Location;
|
||||
|
||||
switch (GestureId)
|
||||
{
|
||||
case WinApi.GID_ROTATE:
|
||||
ushort lastArguments = (ushort)(IsBegin ? 0 : LastEvent.GestureArguments);
|
||||
|
||||
RotateAngle = WinApi.GID_ROTATE_ANGLE_FROM_ARGUMENT((ushort)(gestureInfo.ullArguments - lastArguments));
|
||||
break;
|
||||
|
||||
|
||||
case WinApi.GID_ZOOM:
|
||||
Point first = IsBegin ? Location : LastBeginEvent.Location;
|
||||
Center = new Point((Location.X + first.X) / 2, (Location.Y + first.Y) / 2);
|
||||
ZoomFactor = IsBegin ? 1 : (double)gestureInfo.ullArguments / LastEvent.GestureArguments;
|
||||
//DistanceBetweenFingers = WinApi.LoDWord(gestureInfo.ullArguments);
|
||||
break;
|
||||
|
||||
case WinApi.GID_PAN:
|
||||
PanTranslation = IsBegin ? new Size(0, 0) :
|
||||
new Size(Location.X - LastEvent.Location.X, Location.Y - LastEvent.Location.Y);
|
||||
int panVelocity = WinApi.HiDWord((long)(gestureInfo.ullArguments));
|
||||
PanVelocity = new Size(WinApi.LoWord(panVelocity), WinApi.HiWord(panVelocity));
|
||||
//DistanceBetweenFingers = WinApi.LoDWord(gestureInfo.ullArguments);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private uint _GestureId;
|
||||
public uint GestureId
|
||||
{
|
||||
get { return _GestureId; }
|
||||
private set { _GestureId = value; }
|
||||
}
|
||||
|
||||
private ulong _GestureArguments;
|
||||
public ulong GestureArguments
|
||||
{
|
||||
get { return _GestureArguments; }
|
||||
private set { _GestureArguments = value; }
|
||||
}
|
||||
|
||||
private Point _Location;
|
||||
/// <summary>
|
||||
/// The client location of gesture.
|
||||
/// </summary>
|
||||
public Point Location
|
||||
{
|
||||
get { return _Location; }
|
||||
private set { _Location = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this the first event of a gesture.
|
||||
/// </summary>
|
||||
public bool IsBegin
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_Flags & WinApi.GF_BEGIN) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// It this last event of a gesture.
|
||||
/// </summary>
|
||||
public bool IsEnd
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_Flags & WinApi.GF_END) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Has gesture triggered inertia.
|
||||
/// </summary>
|
||||
public bool IsInertia
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_Flags & WinApi.GF_INERTIA) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gesture relative rotation angle for Rotate event.
|
||||
/// </summary>
|
||||
private double _RotateAngle;
|
||||
public double RotateAngle
|
||||
{
|
||||
get { return _RotateAngle; }
|
||||
private set { _RotateAngle = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates calculated gesture center.
|
||||
/// </summary>
|
||||
private Point _Center;
|
||||
public Point Center
|
||||
{
|
||||
get { return _Center; }
|
||||
private set { _Center = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gesture zoom factor for Zoom event.
|
||||
/// </summary>
|
||||
private double _ZoomFactor;
|
||||
public double ZoomFactor
|
||||
{
|
||||
get { return _ZoomFactor; }
|
||||
private set { _ZoomFactor = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gesture relative panning translation for Pan event.
|
||||
/// </summary>
|
||||
private Size _PanTranslation;
|
||||
public Size PanTranslation
|
||||
{
|
||||
get { return _PanTranslation; }
|
||||
set { _PanTranslation = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gesture velocity vector of the pan gesture for custom inertia implementations.
|
||||
/// </summary>
|
||||
private Size _PanVelocity;
|
||||
public Size PanVelocity
|
||||
{
|
||||
get { return _PanVelocity; }
|
||||
private set { _PanVelocity = value; }
|
||||
}
|
||||
|
||||
private GestureEventArgs _LastBeginEvent;
|
||||
/// <summary>
|
||||
/// The first touch arguments in this gesture event sequence.
|
||||
/// </summary>
|
||||
public GestureEventArgs LastBeginEvent
|
||||
{
|
||||
get { return _LastBeginEvent; }
|
||||
internal set { _LastBeginEvent = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The last touch arguments in this gesture event sequence.
|
||||
/// </summary>
|
||||
private GestureEventArgs _LastEvent;
|
||||
public GestureEventArgs LastEvent
|
||||
{
|
||||
get { return _LastEvent; }
|
||||
internal set { _LastEvent = value; }
|
||||
}
|
||||
|
||||
private bool _Handled = false;
|
||||
/// <summary>
|
||||
/// Gets or sets whether event is handled.
|
||||
/// </summary>
|
||||
public bool Handled
|
||||
{
|
||||
get { return _Handled; }
|
||||
set { _Handled = value; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EventArgs passed to Touch handlers
|
||||
/// </summary>
|
||||
public class TouchEventArgs : EventArgs
|
||||
{
|
||||
private readonly TouchHandler _ParentHandler;
|
||||
private readonly float _dpiXFactor;
|
||||
private readonly float _dpiYFactor;
|
||||
|
||||
/// <summary>
|
||||
/// Create new touch event argument instance
|
||||
/// </summary>
|
||||
/// <param name="hWndWrapper">The target control</param>
|
||||
/// <param name="touchInput">one of the inner touch input in the message</param>
|
||||
internal TouchEventArgs(TouchHandler parentHandler, float dpiX, float dpiY, ref WinApi.TOUCHINPUT touchInput)
|
||||
{
|
||||
_ParentHandler = parentHandler;
|
||||
_dpiXFactor = 96F / dpiX;
|
||||
_dpiYFactor = 96F / dpiY;
|
||||
DecodeTouch(ref touchInput);
|
||||
}
|
||||
|
||||
private bool CheckFlag(int value)
|
||||
{
|
||||
return (Flags & value) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Decodes and handles WM_TOUCH* messages.
|
||||
private void DecodeTouch(ref WinApi.TOUCHINPUT touchInput)
|
||||
{
|
||||
// TOUCHINFO point coordinates and contact size is in 1/100 of a pixel; convert it to pixels.
|
||||
// Also convert screen to client coordinates.
|
||||
if ((touchInput.dwMask & WinApi.TOUCHINPUTMASKF_CONTACTAREA) != 0)
|
||||
ContactSize = new Size(AdjustDpiX(touchInput.cyContact / 100), AdjustDpiY(touchInput.cyContact / 100));
|
||||
|
||||
Id = touchInput.dwID;
|
||||
|
||||
Point p = _ParentHandler.ParentControl.PointToClient(new Point(touchInput.x / 100, touchInput.y / 100));
|
||||
Location = p;// new Point(AdjustDpiX(p.X), AdjustDpiY(p.Y));
|
||||
|
||||
Time = touchInput.dwTime;
|
||||
TimeSpan ellapse = TimeSpan.FromMilliseconds(Environment.TickCount - touchInput.dwTime);
|
||||
AbsoluteTime = DateTime.Now - ellapse;
|
||||
|
||||
Mask = touchInput.dwMask;
|
||||
Flags = touchInput.dwFlags;
|
||||
}
|
||||
|
||||
|
||||
private int AdjustDpiX(int value)
|
||||
{
|
||||
return (int)(value * _dpiXFactor);
|
||||
}
|
||||
|
||||
private int AdjustDpiY(int value)
|
||||
{
|
||||
return (int)(value * _dpiYFactor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Touch client coordinate in pixels
|
||||
/// </summary>
|
||||
private Point _Location;
|
||||
public Point Location
|
||||
{
|
||||
get { return _Location; }
|
||||
private set
|
||||
{
|
||||
_Location = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A touch point identifier that distinguishes a particular touch input
|
||||
/// </summary>
|
||||
private int _Id;
|
||||
public int Id
|
||||
{
|
||||
get { return _Id; }
|
||||
private set
|
||||
{
|
||||
_Id = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A set of bit flags that specify various aspects of touch point
|
||||
/// press, release, and motion.
|
||||
/// </summary>
|
||||
private int _Flags;
|
||||
public int Flags
|
||||
{
|
||||
get { return _Flags; }
|
||||
private set
|
||||
{
|
||||
_Flags = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// mask which fields in the structure are valid
|
||||
/// </summary>
|
||||
private int _Mask;
|
||||
public int Mask
|
||||
{
|
||||
get { return _Mask; }
|
||||
private set
|
||||
{
|
||||
_Mask = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// touch event time
|
||||
/// </summary>
|
||||
private DateTime _AbsoluteTime;
|
||||
public DateTime AbsoluteTime
|
||||
{
|
||||
get { return _AbsoluteTime; }
|
||||
private set { _AbsoluteTime = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// touch event time from system up
|
||||
/// </summary>
|
||||
private int _Time;
|
||||
public int Time
|
||||
{
|
||||
get { return _Time; }
|
||||
private set
|
||||
{
|
||||
_Time = value;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// the size of the contact area in pixels
|
||||
/// </summary>
|
||||
private Size? _ContactSize;
|
||||
public Size? ContactSize
|
||||
{
|
||||
get { return _ContactSize; }
|
||||
private set { _ContactSize = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is Primary Contact (The first touch sequence)
|
||||
/// </summary>
|
||||
public bool IsPrimaryContact
|
||||
{
|
||||
get { return (Flags & WinApi.TOUCHEVENTF_PRIMARY) != 0; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that movement occurred
|
||||
/// </summary>
|
||||
public bool IsTouchMove
|
||||
{
|
||||
get { return CheckFlag(WinApi.TOUCHEVENTF_MOVE); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that the corresponding touch point was established through a new contact
|
||||
/// </summary>
|
||||
public bool IsTouchDown
|
||||
{
|
||||
get { return CheckFlag(WinApi.TOUCHEVENTF_DOWN); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that a touch point was removed
|
||||
/// </summary>
|
||||
public bool IsTouchUp
|
||||
{
|
||||
get { return CheckFlag(WinApi.TOUCHEVENTF_UP); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that a touch point is in range
|
||||
/// </summary>
|
||||
public bool IsTouchInRange
|
||||
{
|
||||
get { return CheckFlag(WinApi.TOUCHEVENTF_INRANGE); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// specifies that this input was not coalesced.
|
||||
/// </summary>
|
||||
public bool IsTouchNoCoalesce
|
||||
{
|
||||
get { return CheckFlag(WinApi.TOUCHEVENTF_NOCOALESCE); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that the touch point is associated with a pen contact
|
||||
/// </summary>
|
||||
public bool IsTouchPen
|
||||
{
|
||||
get { return CheckFlag(WinApi.TOUCHEVENTF_PEN); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The touch event came from the user's palm
|
||||
/// </summary>
|
||||
/// <remarks>Set <see cref="DisablePalmRejection"/> to true</remarks>
|
||||
public bool IsTouchPalm
|
||||
{
|
||||
get { return CheckFlag(WinApi.TOUCHEVENTF_PALM); }
|
||||
}
|
||||
|
||||
private bool _Handled = false;
|
||||
/// <summary>
|
||||
/// Gets or sets whether event is handled.
|
||||
/// </summary>
|
||||
public bool Handled
|
||||
{
|
||||
get { return _Handled; }
|
||||
set { _Handled = value; }
|
||||
}
|
||||
}
|
||||
}
|
307
PROMS/DotNetBar Source Code/Touch/WinApi.cs
Normal file
307
PROMS/DotNetBar Source Code/Touch/WinApi.cs
Normal file
@@ -0,0 +1,307 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace DevComponents.DotNetBar.Touch
|
||||
{
|
||||
internal class WinApi
|
||||
{
|
||||
#region Functions
|
||||
[DllImport("user32")]
|
||||
public static extern bool SetGestureConfig(
|
||||
IntPtr hwnd, // window for which configuration is specified
|
||||
uint dwReserved, // reserved, must be 0
|
||||
uint cIDs, // count of GESTURECONFIG structures
|
||||
GESTURECONFIG[] pGestureConfig, // array of GESTURECONFIG structures, dwIDs will be processed in the
|
||||
// order specified and repeated occurances will overwrite previous ones
|
||||
uint cbSize); // sizeof(GESTURECONFIG)
|
||||
|
||||
[DllImport("user32")]
|
||||
public static extern bool RegisterTouchWindow(System.IntPtr hWnd, TouchWindowFlag flags);
|
||||
|
||||
[DllImport("user32")]
|
||||
public static extern bool UnregisterTouchWindow(System.IntPtr hWnd);
|
||||
|
||||
[DllImport("user32")]
|
||||
public static extern bool IsTouchWindow(System.IntPtr hWnd, out uint ulFlags);
|
||||
|
||||
[DllImport("user32")]
|
||||
public static extern bool GetTouchInputInfo(System.IntPtr hTouchInput, int cInputs, [In, Out] TOUCHINPUT[] pInputs, int cbSize);
|
||||
|
||||
[DllImport("user32")]
|
||||
public static extern void CloseTouchInputHandle(System.IntPtr lParam);
|
||||
|
||||
[DllImport("user32")]
|
||||
public static extern bool SetProp(IntPtr hWnd, string lpString, IntPtr hData);
|
||||
|
||||
//Touch
|
||||
[DllImport("user32", EntryPoint = "GetSystemMetrics")]
|
||||
public static extern int GetDigitizerCapabilities(DigitizerIndex index);
|
||||
[DllImport("user32")]
|
||||
public static extern bool GetGestureInfo(IntPtr hGestureInfo, ref GESTUREINFO pGestureInfo);
|
||||
[DllImport("user32")]
|
||||
public static extern bool CloseGestureInfoHandle(IntPtr hGestureInfo);
|
||||
[DllImport("user32", EntryPoint = "SetWindowLongPtr")]
|
||||
public static extern IntPtr SubclassWindow64(IntPtr hWnd, int nIndex, WindowProcDelegate dwNewLong);
|
||||
[DllImport("user32", EntryPoint = "SetWindowLong")]
|
||||
public static extern IntPtr SubclassWindow(IntPtr hWnd, int nIndex, WindowProcDelegate dwNewLong);
|
||||
[DllImport("user32", EntryPoint = "SetWindowLongPtr")]
|
||||
public static extern IntPtr SubclassWindow64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||
[DllImport("user32", EntryPoint = "SetWindowLong")]
|
||||
public static extern IntPtr SubclassWindow(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||
|
||||
|
||||
[DllImport("user32")]
|
||||
public static extern uint CallWindowProc(IntPtr prevWndFunc, IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam);
|
||||
|
||||
public delegate uint WindowProcDelegate(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam);
|
||||
|
||||
/// <summary>
|
||||
/// Get the current Digitizer Status
|
||||
/// </summary>
|
||||
public static DigitizerStatus GetDigitizerStatus()
|
||||
{
|
||||
return (DigitizerStatus)GetDigitizerCapabilities(DigitizerIndex.SM_DIGITIZER);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Structures & Constants
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct GESTURECONFIG
|
||||
{
|
||||
public uint dwID; // gesture ID
|
||||
public uint dwWant; // settings related to gesture ID that are to be turned on
|
||||
public uint dwBlock; // settings related to gesture ID that are to be turned off
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the GESTURECONFIG structure.
|
||||
/// </summary>
|
||||
/// <param name="dwID"></param>
|
||||
/// <param name="dwWant"></param>
|
||||
/// <param name="dwBlock"></param>
|
||||
public GESTURECONFIG(uint dwID, uint dwWant, uint dwBlock)
|
||||
{
|
||||
this.dwID = dwID;
|
||||
this.dwWant = dwWant;
|
||||
this.dwBlock = dwBlock;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Specifies available digitizer capabilities
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum DigitizerStatus : byte
|
||||
{
|
||||
IntegratedTouch = 0x01,
|
||||
ExternalTouch = 0x02,
|
||||
IntegratedPan = 0x04,
|
||||
ExternalPan = 0x08,
|
||||
MultiInput = 0x40,
|
||||
StackReady = 0x80
|
||||
}
|
||||
public enum DigitizerIndex
|
||||
{
|
||||
SM_DIGITIZER = 94,
|
||||
SM_MAXIMUMTOUCHES = 95
|
||||
}
|
||||
public const int GWLP_WNDPROC = -4;
|
||||
// Gesture argument helpers
|
||||
// - Angle should be a double in the range of -2pi to +2pi
|
||||
// - Argument should be an unsigned 16-bit value
|
||||
//
|
||||
public static ushort GID_ROTATE_ANGLE_TO_ARGUMENT(ushort arg) { return ((ushort)(((arg + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0)); }
|
||||
public static double GID_ROTATE_ANGLE_FROM_ARGUMENT(ushort arg) { return ((((double)arg / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265); }
|
||||
|
||||
//Gesture flags - GESTUREINFO.dwFlags
|
||||
public const uint GF_BEGIN = 0x00000001;
|
||||
public const uint GF_INERTIA = 0x00000002;
|
||||
public const uint GF_END = 0x00000004;
|
||||
|
||||
//Gesture IDs
|
||||
public const uint GID_BEGIN = 1;
|
||||
public const uint GID_END = 2;
|
||||
public const uint GID_ZOOM = 3;
|
||||
public const uint GID_PAN = 4;
|
||||
public const uint GID_ROTATE = 5;
|
||||
public const uint GID_TWOFINGERTAP = 6;
|
||||
public const uint GID_PRESSANDTAP = 7;
|
||||
|
||||
public const uint GC_ALLGESTURES = 0x00000001;
|
||||
|
||||
public const uint WM_GESTURE = 0x0119;
|
||||
|
||||
public const uint WM_GESTURENOTIFY = 0x011A;
|
||||
|
||||
// Touch event window message constants [winuser.h]
|
||||
public const int WM_TOUCH = 0x0240;
|
||||
|
||||
// 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
|
||||
|
||||
// Touch event flags ((TOUCHINPUT.dwFlags) [winuser.h]
|
||||
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;
|
||||
public const int TOUCHEVENTF_PALM = 0x0080;
|
||||
|
||||
public enum TouchWindowFlag : uint
|
||||
{
|
||||
FineTouch = 0x1,
|
||||
WantPalm = 0x2
|
||||
}
|
||||
/// <summary>
|
||||
/// Gesture Info Interop Structure
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct GESTUREINFO
|
||||
{
|
||||
public uint cbSize; // size, in bytes, of this structure (including variable length Args field)
|
||||
public uint dwFlags; // see GF_* flags
|
||||
public uint dwID; // gesture ID, see GID_* defines
|
||||
public IntPtr hwndTarget; // handle to window targeted by this gesture
|
||||
public POINTS ptsLocation; // current location of this gesture
|
||||
public uint dwInstanceID; // internally used
|
||||
public uint dwSequenceID; // internally used
|
||||
public ulong ullArguments; // arguments for gestures whose arguments fit in 8 BYTES
|
||||
public uint cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture
|
||||
}
|
||||
/// <summary>
|
||||
/// A Simple POINTS Interop structure
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINTS
|
||||
{
|
||||
public short x;
|
||||
public short y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A Simple POINT Interop structure
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINT
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
}
|
||||
/// <summary>
|
||||
/// Touch API defined structures [winuser.h]
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TOUCHINPUT
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
public System.IntPtr hSource;
|
||||
public int dwID;
|
||||
public int dwFlags;
|
||||
public int dwMask;
|
||||
public int dwTime;
|
||||
public System.IntPtr dwExtraInfo;
|
||||
public int cxContact;
|
||||
public int cyContact;
|
||||
}
|
||||
|
||||
// Extracts lower 16-bit word from an 32-bit int.
|
||||
// in:
|
||||
// number int
|
||||
// returns:
|
||||
// lower word
|
||||
public static ushort LoWord(uint number)
|
||||
{
|
||||
return (ushort)(number & 0xffff);
|
||||
}
|
||||
|
||||
// Extracts higher 16-bit word from an 32-bit int.
|
||||
// in:
|
||||
// number uint
|
||||
// returns:
|
||||
// lower word
|
||||
public static ushort HiWord(uint number)
|
||||
{
|
||||
return (ushort)((number >> 16) & 0xffff);
|
||||
}
|
||||
|
||||
// Extracts lower 32-bit word from an 64-bit int.
|
||||
// in:
|
||||
// number ulong
|
||||
// returns:
|
||||
// lower word
|
||||
public static uint LoDWord(ulong number)
|
||||
{
|
||||
return (uint)(number & 0xffffffff);
|
||||
}
|
||||
|
||||
// Extracts higher 32-bit word from an 64-bit int.
|
||||
// in:
|
||||
// number ulong
|
||||
// returns:
|
||||
// lower word
|
||||
public static uint HiDWord(ulong number)
|
||||
{
|
||||
return (uint)((number >> 32) & 0xffffffff);
|
||||
}
|
||||
|
||||
|
||||
// Extracts lower 16-bit word from an 32-bit int.
|
||||
// in:
|
||||
// number int
|
||||
// returns:
|
||||
// lower word
|
||||
public static short LoWord(int number)
|
||||
{
|
||||
return (short)number;
|
||||
}
|
||||
|
||||
// Extracts higher 16-bit word from an 32-bit int.
|
||||
// in:
|
||||
// number int
|
||||
// returns:
|
||||
// lower word
|
||||
public static short HiWord(int number)
|
||||
{
|
||||
return (short)(number >> 16);
|
||||
}
|
||||
|
||||
// Extracts lower 32-bit word from an 64-bit int.
|
||||
// in:
|
||||
// number long
|
||||
// returns:
|
||||
// lower word
|
||||
public static int LoDWord(long number)
|
||||
{
|
||||
return (int)(number);
|
||||
}
|
||||
|
||||
// Extracts higher 32-bit word from an 64-bit int.
|
||||
// in:
|
||||
// number long
|
||||
// returns:
|
||||
// lower word
|
||||
public static int HiDWord(long number)
|
||||
{
|
||||
return (int)((number >> 32));
|
||||
}
|
||||
|
||||
// Gesture notification structure
|
||||
// - The WM_GESTURENOTIFY message lParam contains a pointer to this structure.
|
||||
// - The WM_GESTURENOTIFY message notifies a window that gesture recognition is
|
||||
// in progress and a gesture will be generated if one is recognized under the
|
||||
// current gesture settings.
|
||||
public struct GESTURENOTIFYSTRUCT
|
||||
{
|
||||
public uint cbSize; // size, in bytes, of this structure
|
||||
public uint dwFlags; // unused
|
||||
public IntPtr hwndTarget; // handle to window targeted by the gesture
|
||||
public POINTS ptsLocation; // starting location
|
||||
public uint dwInstanceID; // internally used
|
||||
};
|
||||
#endregion
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user