本节介绍 Windows Touch 便笺簿的 C# 示例。
Windows Touch 便笺簿的 C# 示例演示如何使用 Windows Touch 消息在窗口上绘制触控点的踪迹。主手指(最先放置到数字化器上的手指)的踪迹是用黑色绘制的。辅助手指的踪迹用其他六种颜色绘制:红色、绿色、蓝色、蓝绿色、洋红色和黄色。下图演示了应用程序在运行时的可能外观。
在此示例中,将创建一个具有触控功能的表单来处理 WM_TOUCH 消息。继承此表单以便在便笺簿应用程序上启用 Windows Touch。当WM_TOUCH 消息传入到此表单时,这些消息将被解释为点并添加到笔画集合中。然后向 Graphics 对象呈现笔画集合。以下代码演示具有触控功能的表单如何注册自身以处理 WM_TOUCH 消息,以及它如何处理 WM_TOUCH 消息。
private void OnLoadHandler(Object sender, EventArgs e)
{
try
{
// Registering the window for multi-touch, using the default settings.
// p/invoking into user32.dll
if (!RegisterTouchWindow(this.Handle, 0))
{
Debug.Print("ERROR: Could not register window for multi-touch");
}
}
catch (Exception exception)
{
Debug.Print("ERROR: RegisterTouchWindow API not available");
Debug.Print(exception.ToString());
MessageBox.Show("RegisterTouchWindow API not available", "MTScratchpadWMTouch ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
}
}
(...)
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message m)
{
// Decode and handle WM_TOUCH message.
bool handled;
switch (m.Msg)
{
case WM_TOUCH:
handled = DecodeTouch(ref m);
break;
default:
handled = false;
break;
}
// Call parent WndProc for default message processing.
base.WndProc(ref m);
if (handled)
{
// Acknowledge event if handled.
m.Result = new System.IntPtr(1);
}
}
以下代码演示如何解释 Windows Touch 消息,以及如何将数据添加到笔画集合中。
private bool DecodeTouch(ref Message m)
{
// More than one touchinput may be associated with a touch message,
// so an array is needed to get all event information.
int inputCount = LoWord(m.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(m.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];
// Assign a handler to this message.
EventHandler<WMTouchEventArgs> handler = null; // Touch event handler
if ((ti.dwFlags & TOUCHEVENTF_DOWN) != 0)
{
handler = Touchdown;
}
else if ((ti.dwFlags & TOUCHEVENTF_UP) != 0)
{
handler = Touchup;
}
else if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0)
{
handler = TouchMove;
}
// Convert message parameters into touch event arguments and handle the event.
if (handler != null)
{
// Convert the raw touchinput message into a touchevent.
WMTouchEventArgs te = new WMTouchEventArgs(); // Touch event arguments
// TOUCHINFO point coordinates and contact size is in 1/100 of a pixel; convert it to pixels.
// Also convert screen to client coordinates.
te.ContactY = ti.cyContact/100;
te.ContactX = ti.cxContact/100;
te.Id = ti.dwID;
{
Point pt = PointToClient(new Point(ti.x/100, ti.y/100));
te.LocationX = pt.X;
te.LocationY = pt.Y;
}
te.Time = ti.dwTime;
te.Mask = ti.dwMask;
te.Flags = ti.dwFlags;
// Invoke the event handler.
handler(this, te);
// Mark this event as handled.
handled = true;
}
}
CloseTouchInputHandle(m.LParam);
return handled;
}
}
以下代码演示如何呈现笔画集合。
public void Draw(Graphics graphics)
{
if ((points.Count < 2) || (graphics == null))
{
return;
}
Pen pen = new Pen(color, penWidth);
graphics.DrawLines(pen, (Point[]) points.ToArray(typeof(Point)));
}
以下代码演示各个笔画对象如何使用 Graphics 对象呈现自己。
public void Draw(Graphics graphics)
{
if(points.Count < 2 || graphics == null)
{
return;
}
Pen pen = new Pen(color, penWidth);
graphics.DrawLines(pen, (Point[]) points.ToArray(typeof(Point)));
}