此應用程式示範使用 RealTimeStylus 類別時的墨跡收集與渲染。
InkCollection 專案
此範例包含包含一個專案 InkCollection 的單一解決方案。 應用程式會定義包含單一類別的 InkCollection
命名空間,也稱為 InkCollection
。 類別繼承自 Form 類別,並實作 IStylusAsyncPlugin 介面。
namespace InkCollection
{
public class InkCollection : Form, IStylusAsyncPlugin
{
//...
InkCollection 類別會定義一組私用常數,用來指定各種筆墨粗細。 類別也會宣告 RealTimeStylus 類別、myRealTimeStylus
、DynamicRenderer 類別、myDynamicRenderer
和 Renderer 類別 myRenderer
的私人實例。
DynamicRenderer 會渲染目前正在收集的 Stroke。 Renderer 物件 myRenderer
負責渲染已經收集的 Stroke 物件。
private const float ThinInkWidth = 10;
private const float MediumInkWidth = 100;
private const float ThickInkWidth = 200;
private RealTimeStylus myRealTimeStylus;
private DynamicRenderer myDynamicRenderer;
private Renderer myRenderer;
類別也會宣告 Hashtable 物件 myPackets
,用來儲存由一個或多個 Cursor 物件所收集的封包數據。
手寫筆 物件的 標識子 值會作為哈希表索引鍵,以唯一識別為指定 Cursor 物件收集的封包數據。
Ink 物件的私人實例 myInk
儲存了由 myRealTimeStylus
收集的 Stroke 物件。
private Hashtable myPackets;
private Ink myInk;
表單載入事件
在表單的 Load 事件處理程式中,myDynamicRenderer
會使用採用控件做為自變數的 DynamicRenderer 具現化,並使用無自變數建構函式建構 myRenderer
。
private void InkCollection_Load(object sender, System.EventArgs e)
{
myDynamicRenderer = new DynamicRenderer(this);
myRenderer = new Renderer();
// ...
請注意繪製器實例化後的註釋,因為 myDynamicRenderer
在繪製筆跡時,DrawingAttributes 使用預設值。 這是標準行為。 不過,如果您想要讓 myDynamicRenderer
呈現的筆跡與 myRenderer
所呈現的筆跡不同外觀,您可以在 myDynamicRenderer
上變更 DrawingAttributes 屬性。 若要這樣做,請先取消批注下列幾行,再建置並執行應用程式。
// myDynamicRenderer.DrawingAttributes.PenTip = PenTip.Rectangle;
// myDynamicRenderer.DrawingAttributes.Height = (.5F)*MediumInkWidth;
// myDynamicRenderer.DrawingAttributes.Transparency = 128;
接下來,應用程式會建立用來接收手寫筆通知的 RealTimeStylus 物件,並將 DynamicRenderer 物件新增至同步外掛程式通知佇列。 具體而言,myRealTimeStylus
會將 myDynamicRenderer
新增至 SyncPluginCollection 屬性。
myRealTimeStylus = new RealTimeStylus(this, true);
myRealTimeStylus.SyncPluginCollection.Add(myDynamicRenderer);
表單接著會新增至異步外掛程式通知佇列。 具體而言,InkCollection
會新增至 AsyncPluginCollection 屬性。 最後,會啟用 myRealTimeStylus
和 myDynamicRenderer
,並具現化 myPackets 和 myInk。
myRealTimeStylus.AsyncPluginCollection.Add(this);
myRealTimeStylus.Enabled = true;
myDynamicRenderer.Enabled = true;
myPackets = new Hashtable();
myInk = new Ink();
}
除了連結功能表處理程式來變更筆跡色彩和大小之外,實作 介面之前,還需要一個簡短的程式代碼區塊。 此範例必須處理表單的 Paint 事件。 在事件處理程式中,應用程式必須重新整理 myDynamicRenderer
,因為在 Paint 事件發生時,可能會收集 Stroke 物件。 在此情況下,必須重新繪製已經收集的 Stroke 物件部分。 靜態 轉譯器 用來重新繪製已經收集的 Stroke 物件。 這些筆劃位於 Ink 物件中,因為在繪圖時會放置於該處,下一節將會展示這一點。
private void InkCollection_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
myDynamicRenderer.Refresh();
myRenderer.Draw(e.Graphics, myInk.Strokes);
}
實作 IStylusAsyncPlugin 介面
範例應用程式會定義在實作 DataInterest 屬性時,它感興趣的通知類型。 因此,DataInterest 屬性會定義 RealTimeStylus 物件轉送至表單的通知。 在此範例中,DataInterest 屬性會透過 DataInterestMask 列舉定義對 StylusDown、Packets、StylusUp,以及 Error 通知的興趣。
public DataInterestMask DataInterest
{
get
{
return DataInterestMask.StylusDown |
DataInterestMask.Packets |
DataInterestMask.StylusUp |
DataInterestMask.Error;
}
}
手寫筆觸碰數位板表面時,會發生 StylusDown 通知。 發生這種情況時,此範例會配置陣列,將用來儲存 手寫筆 物件的封包資料。 stylusDown 方法的 StylusDownData 會新增至陣列,然後使用 Stylus 物件的 Id 屬性作為鍵,將該陣列插入哈希表中。
public void StylusDown(RealTimeStylus sender, StylusDownData data)
{
ArrayList collectedPackets = new ArrayList();
collectedPackets.AddRange(data.GetData());
myPackets.Add(data.Stylus.Id, collectedPackets);
}
當觸控筆在數位板表面移動時,就會發生 封包 通知。 發生此情況時,應用程式會將 StylusDownData 新增到 Stylus 物件的封包陣列中。 它會使用觸控筆物件的 Id 屬性作為鍵,從哈希表中檢索觸控筆的封包陣列。 然後,新的封包數據會插入擷取的陣列中。
public void Packets(RealTimeStylus sender, PacketsData data)
{
((ArrayList)(myPackets[data.Stylus.Id])).AddRange(data.GetData());
}
當手寫筆離開數位板表面時,會發生 StylusUp 通知。 發生此通知時,此範例會從哈希表擷取此 手寫筆的封包陣列, 物件從哈希表中移除,因為不再需要該哈希表、新增封包數據,並使用封包數據的陣列來建立新的 Stroke 物件,stroke
。
public void StylusUp(RealTimeStylus sender, StylusUpData data)
{
ArrayList collectedPackets = (ArrayList)myPackets[data.Stylus.Id];
myPackets.Remove(data.Stylus.Id);
collectedPackets.AddRange(data.GetData());
int[] packets = (int[])(collectedPackets.ToArray(typeof(int)));
TabletPropertyDescriptionCollection tabletProperties =
myRealTimeStylus.GetTabletPropertyDescriptionCollection(data.Stylus.TabletContextId);
Stroke stroke = myInk.CreateStroke(packets, tabletProperties);
if (stroke != null)
{
stroke.DrawingAttributes.Color = myDynamicRenderer.DrawingAttributes.Color;
stroke.DrawingAttributes.Width = myDynamicRenderer.DrawingAttributes.Width;
}
}
如需顯示更強固使用 RealTimeStylus 類別的範例,包括使用自定義外掛程式建立,請參閱 RealTimeStylus 外掛程式範例。
相關主題