Windows Touch 便笺簿的 C# 示例 (MTScratchpadWMTouchCS)
本节介绍 Windows Touch 便笺簿的 C# 示例。
Windows Touch 便笺簿的 C# 示例演示如何使用 Windows Touch 消息在窗口上绘制触控点的踪迹。主手指(最先放置到数字化器上的手指)的踪迹是用黑色绘制的。辅助手指的踪迹用其他六种颜色绘制:红色、绿色、蓝色、蓝绿色、洋红色和黄色。下图演示了应用程序在运行时的可能外观。
![Windows Touch 便笺簿的 C# 示例。 Windows Touch 便笺簿的 C# 示例。](https://i-msdn.sec.s-msft.com/dynimg/IC303152.png)
在此示例中,将创建一个具有触控功能的表单来处理 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))); }