using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
namespace TouchDelayTestDemo
{
///
/// Interaction logic for
MainWindow.xaml
///
public partial class
MainWindow : Window
{
// Touch API defined structures [winuser.h]
[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;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINTS
{
public
short x;
public
short y;
}
private IntPtr _handle;
// Attributes
private int touchInputSize; // size of
TOUCHINPUT structure
/// 定义触摸消息,来自winuser.h
public const int WM_TOUCH = 0x0240;
// Touch event flags ((TOUCHINPUT.dwFlags)
[winuser.h]
private const int TOUCHEVENTF_MOVE = 0x0001;
private const int TOUCHEVENTF_DOWN = 0x0002;
private const int TOUCHEVENTF_UP = 0x0004;
// Currently touch/multitouch access is done
through unmanaged code
// We must p/invoke into user32 [winuser.h]
[DllImport("user32")]
public static extern bool
RegisterTouchWindow(System.IntPtr hWnd, int flags);
[DllImport("user32")]
public static extern bool
GetTouchInputInfo(System.IntPtr hTouchInput, int cInputs,
[In, Out]
TOUCHINPUT[] pInputs, int cbSize);
public MainWindow()
{
InitializeComponent();
DisableWPFTabletSupport();
this.Show();
_handle =
(new System.Windows.Interop.WindowInteropHelper(this)).Handle;
if
(!RegisterTouchWindow(_handle, 0))
{
Debug.Print("ERROR: Could not
register window for multi-touch");
}
//
GetTouchInputInfo needs to be
// passed
the size of the structure it will be filling.
// We get
the size upfront so it can be used later.
touchInputSize = Marshal.SizeOf(new TOUCHINPUT());
var
hwndSource = HwndSource.FromHwnd(_handle);
if
(hwndSource != null)
hwndSource.AddHook(WndProc);
}
// 详见:使WPF自身触摸不可用
public static void DisableWPFTabletSupport()
{
// Get a
collection of the tablet devices for this window.
TabletDeviceCollection devices =
System.Windows.Input.Tablet.TabletDevices;
if
(devices.Count > 0)
{
// Get the Type of
InputManager.
Type inputManagerType =
typeof(System.Windows.Input.InputManager);
// Call the StylusLogic
method on the InputManager.Current instance.
object stylusLogic =
inputManagerType.InvokeMember("StylusLogic",
BindingFlags.GetProperty | BindingFlags.Instance
| BindingFlags.NonPublic,
null, InputManager.Current, null);
if (stylusLogic != null)
{
// Get the type of the
stylusLogic returned from the call to StylusLogic.
Type stylusLogicType =
stylusLogic.GetType();
// Loop until there are no more devices to
remove.
while (devices.Count > 0)
{
// Remove
the first tablet device in the devices collection.
stylusLogicType.InvokeMember("OnTabletRemoved",
BindingFlags.InvokeMethod |
BindingFlags.Instance | BindingFlags.NonPublic,
null, stylusLogic, new
object[] { (uint)0 });
}
}
}
}
private IntPtr WndProc(IntPtr hwnd, int msg,
IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch
(msg)
{
case WM_TOUCH:
handled = DecodeTouch(wParam, lParam);
break;
}
return
(IntPtr)0;
}
// Extracts lower 16-bit word from an 32-bit
int.
// in:
//
number
int
// returns:
//
lower word
private static int LoWord(int number)
{
return
(number & 0xffff);
}
// Decodes and handles WM_TOUCH message.
// Unpacks message arguments and invokes
appropriate touch events.
// returns:
//
whether the message has been handled
private bool DecodeTouch(IntPtr wParam, IntPtr
lParam)
{
// More
than one touchinput may be associated with a touch message,
// so an
array is needed to get all event information.
int
inputCount = LoWord(wParam.ToInt32()); // Number of touch inputs,
actual per-contact messages
TOUCHINPUT[] inputs; // Array of TOUCHINPUT structures
inputs =
new TOUCHINPUT[inputCount]; // Allocate the storage for the
parameters of the per-contact messages
// Unpack
message parameters into the array of TOUCHINPUT structures,
each
//
representing a message for one single contact.
if
(!GetTouchInputInfo(lParam, inputCount, inputs,
touchInputSize))
{
// Get touch info failed.
return false;
}
// For
each contact, dispatch the message to the appropriate message
//
handler.
bool
handled = false; // Boolean, is message handled
for (int i
= 0; i < inputCount; i++)
{
TOUCHINPUT ti =
inputs[i];
int screenPointX = ti.x /
100;
int screenPointY = ti.y /
100;
// Assign a handler to this
message.
if ((ti.dwFlags &
TOUCHEVENTF_DOWN) != 0) /// 按下
{
}
else if ((ti.dwFlags &
TOUCHEVENTF_UP) != 0) /// 移动
{
}
else if ((ti.dwFlags &
TOUCHEVENTF_MOVE) != 0) /// 弹起
{
}
// Mark this event as
handled.
handled = true;
}
return
handled;
}
}
}
加载中,请稍候......