2025-11-28 00:35:46 +09:00

218 lines
8.6 KiB
C#

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// MTScratchpadRTStylus application.
// Description:
// Inside the application window, user can draw using multiple fingers
// at the same time. The trace of each finger is drawn using different
// color. The primary finger trace is always drawn in black, and the
// remaining traces are drawn by rotating through the following colors:
// red, blue, green, magenta, cyan and yellow.
//
// Purpose:
// This sample demonstrates handling of the multi-touch input inside
// a C# application using Real Time Stylus inking API:
// - Setting up minimal RTS object configuration that allows the window
// to be inking-enabled (this is not multi-touch specific);
// Construction and initialization of RealTimeStylus object and
// DynamicRenderer object.
// - Registering RTS object for multi-touch;
// - Deriving and initializing synchronous RTS plugin that receives
// inking notifications that are multi-touch aware.
// - Handling multi-touch aware pen-down/up/move notifications: changing
// stroke color on pen-down.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
// Microsoft Tablet PC namespaces
using Microsoft.StylusInput;
using Microsoft.StylusInput.PluginData;
namespace Microsoft.Samples.Touch.MTScratchpadRTStylus
{
public partial class MTScratchpadRTStylusForm : Form
{
// MTScratchpadRTStylusForm constructor
public MTScratchpadRTStylusForm()
{
InitializeComponent();
// Setup event handlers
Load += new System.EventHandler(this.OnLoadHandler);
Paint += new PaintEventHandler(this.OnPaintHandler);
}
// OnLoad window event handler
// in:
// sender object that has sent the event
// e event arguments
private void OnLoadHandler(Object sender, EventArgs e)
{
// Create RealTimeStylus object and enable it for multi-touch
realTimeStylus = new RealTimeStylus(this);
realTimeStylus.MultiTouchEnabled = true;
// Create DynamicRenderer and event handler, and add them to the RTS object as synchronous plugins
dynamicRenderer = new DynamicRenderer(this);
eventHandler = new EventHandlerPlugIn(this.CreateGraphics(), dynamicRenderer);
realTimeStylus.SyncPluginCollection.Add(eventHandler);
realTimeStylus.SyncPluginCollection.Add(dynamicRenderer);
// Enable RTS and DynamicRenderer object, and enable auto-redraw of the DynamicRenderer
realTimeStylus.Enabled = true;
dynamicRenderer.Enabled = true;
dynamicRenderer.EnableDataCache = true;
}
// OnPaint window event handler
// in:
// sender object that has sent the event
// e event arguments
private void OnPaintHandler(object sender, PaintEventArgs e)
{
// Erase the background
Brush brush = new SolidBrush(SystemColors.Window);
e.Graphics.FillRectangle(brush, ClientRectangle);
// Ask DynamicRenderer to redraw itself
dynamicRenderer.Refresh();
}
// Attributes
private RealTimeStylus realTimeStylus; // RealTimeStylus object
private DynamicRenderer dynamicRenderer; // DynamicRenderer object
private EventHandlerPlugIn eventHandler; // Event handler object
}
// Notification receiver that changes pen color.
public class EventHandlerPlugIn : IStylusSyncPlugin
{
// EventHandlerPlugIn constructor
public EventHandlerPlugIn(Graphics graph, DynamicRenderer render)
{
graphics = graph;
cntContacts = 0;
touchColor = new TouchColor();
dynamicRenderer = render;
}
// Pen-down notification handler.
// Sets the color for the newly started stroke and increments finger-down counter.
// sender RTS event sender object
// data event arguments
public void StylusDown(RealTimeStylus sender, StylusDownData data)
{
// Set new stroke color to the DrawingAttributes of the DynamicRenderer
// If there are no fingers down, this is a primary contact
dynamicRenderer.DrawingAttributes.Color = touchColor.GetColor(cntContacts == 0);
++cntContacts; // Increment finger-down counter
}
// Pen-move notification handler
// In this case, does nothing, but likely to be used in a more complex application.
// RTS framework does stroke collection and rendering for us.
// sender RTS event sender object
// data event arguments
public void Packets(RealTimeStylus sender, PacketsData data)
{
}
// Pen-up notification handler.
// Decrements finger-down counter.
// sender RTS event sender object
// data event arguments
public void StylusUp(RealTimeStylus sender, StylusUpData data)
{
--cntContacts; // Decrement finger-down counter
}
// Defines which handlers are called by the framework. We set the flags for pen-down, pen-up and pen-move.
public DataInterestMask DataInterest
{
get
{
return DataInterestMask.StylusDown |
DataInterestMask.Packets |
DataInterestMask.StylusUp;
}
}
// The remaining interface methods are not used in this sample application.
public void RealTimeStylusDisabled(RealTimeStylus sender, RealTimeStylusDisabledData data) { }
public void RealTimeStylusEnabled(RealTimeStylus sender, RealTimeStylusEnabledData data) { }
public void StylusOutOfRange(RealTimeStylus sender, StylusOutOfRangeData data) { }
public void StylusInRange(RealTimeStylus sender, StylusInRangeData data) { }
public void StylusButtonDown(RealTimeStylus sender, StylusButtonDownData data) { }
public void StylusButtonUp(RealTimeStylus sender, StylusButtonUpData data) { }
public void CustomStylusDataAdded(RealTimeStylus sender, CustomStylusData data) { }
public void SystemGesture(RealTimeStylus sender, SystemGestureData data) { }
public void InAirPackets(RealTimeStylus sender, InAirPacketsData data) { }
public void TabletAdded(RealTimeStylus sender, TabletAddedData data) { }
public void TabletRemoved(RealTimeStylus sender, TabletRemovedData data) { }
public void Error(RealTimeStylus sender, ErrorData data) { }
// Attributes
private Graphics graphics; // graphics object of the window this plugin is attached to
private int cntContacts; // number of fingers currently in the contact with the touch digitizer
private TouchColor touchColor; // color generator
private DynamicRenderer dynamicRenderer; // dynamic renderer
}
// Color generator: assigns a color to the new stroke.
public class TouchColor
{
public TouchColor()
{
}
// Returns color for the newly started stroke.
// in:
// primary flag, whether the contact is the primary contact
// returns:
// color of the stroke
public Color GetColor(bool primary)
{
if (primary)
{
// The primary contact is drawn in black.
return Color.Black;
}
else
{
// Take current secondary color.
Color color = secondaryColors[idx];
// Move to the next color in the array.
idx = (idx + 1) % secondaryColors.Length;
return color;
}
}
// Attributes
static private Color[] secondaryColors = // secondary colors
{
Color.Red,
Color.LawnGreen,
Color.Blue,
Color.Cyan,
Color.Magenta,
Color.Yellow
};
private int idx = 0; // rotating secondary color index
}
}