此範例說明在給定的螢幕位置下尋找數位墨水的兩種方法。
此範例會使用下列功能:
- 使用墨水收集器
- 執行命中測試
- 尋找最接近的點
存取 Ink API
首先,參考位於 Windows Vista 或 Windows XP Tablet PC Edition 軟體開發工具包 (SDK) 的平板電腦類別。
using Microsoft.Ink;
處理表單載入和繪製事件
表單的 Load 事件處理程式:
- 建立一個名為 ic 的 InkCollector 物件,用於表單。
- 將 InkCollector 物件的 CollectionMode 屬性設定為忽略手勢。
- 啟用 InkCollector。
- 將 InkCollector 物件的 AutoRedraw 屬性設定為 TRUE。
// Create the InkCollector, and turn it on
ic = new InkCollector(Handle); // attach it to the form's frame window
// default to ink-enabled mode
mode = ApplicationMode.Ink;
ic.CollectionMode = CollectionMode.InkOnly;
// turn the collector on
ic.Enabled = true;ic.AutoRedraw = true;
表單的 Paint 事件處理程式會檢查應用程式模式:
- 在 HitTest 模式中,它會在游標周圍繪製圓形。 主動式筆是在應用程式的 handleHitTest 方法中設定。
- 在 NearestPoint 模式中,它會在游標與最接近游標的點之間繪製紅線。 最接近的點是在應用程式的 handleNearestPoint 方法中計算。
if( mode == ApplicationMode.HitTest)
{
e.Graphics.DrawEllipse(activepen, penPt.X - HitSize/2, penPt.Y - HitSize/2, HitSize, HitSize);
}
else if( mode == ApplicationMode.NearestPoint )
{
e.Graphics.DrawLine(redPen, penPt, nearestPt);
}
此範例具有非常簡單的重新繪演算法。 當其 AutoRedraw 屬性設定為 TRUE時,筆跡收集器會在重新繪製表單時重新繪製本身。 為了簡化重新繪製表單,應用程式會追蹤一個包圍盒,即表示「invalidateRect」的成員變數,用於標記新增繪製的區域,這個區域在每次重新繪製表單時都會被無效化。
處理功能表事件
Exit 命令會在結束應用程式之前停用 InkCollector。
Ink 命令會更新應用程式模式和功能表狀態、啟用筆跡收集器,並使表單表先前繪製的區域失效。
碰撞測試和最近點命令都會變更游標、更新應用程式模式和功能表狀態、停用筆跡收集器,以及使表單先前繪製的區域失效。
清除! 命令會停用 InkCollector,同時將 InkCollector 物件的 Ink 屬性取代為新的 Ink 對象、產生 Ink 命令事件,並在控件上強制重新整理。
處理滑鼠事件
MouseMove 事件處理程式會檢查應用程式模式:
- 在 Ink 模式中,它不會執行任何動作,讓筆跡收集器正常收集筆墨。
- 在 HitTest 模式中,它會將事件自變數傳送至應用程式的 handleHitTest 方法。
- 在 NearestPoint 模式中,它會將事件自變數傳送至應用程式的 handleNearestPoint 方法。
執行碰撞測試
應用程式的 handleHitTest 方法會建立兩個點:游標位置和距離游標遠的點 HitSize 圖元,然後將這兩個點從圖元轉換成筆跡空間座標。
penPt = new Point(e.X, e.Y);
Point pt2 = new Point(e.X, e.Y);
Point pt3 = new Point(e.X + HitSize/2, e.Y);
using (Graphics g = CreateGraphics())
{
ic.Renderer.PixelToInkSpace(g, ref pt1);
ic.Renderer.PixelToInkSpace(g, ref pt2);
}
然後,InkCollector 物件會使用 Microsoft.Ink.Ink.HitTest() 方法來尋找 pt3 內的任何筆劃。X - pt2。游標的 X 筆跡空間單位 pt2。
Strokes strokes = ic.Ink.HitTest(pt2, (float)(pt3.X - pt2.X));
handleHitTest 方法會根據是否找到筆劃來設定畫筆顏色,使 invalidateRect 區域失效,接著計算繪製點擊測試圓的新區域,然後使新區域失效。
尋找最接近的點
應用程式的 handleNearestPoint 方法會建立兩個點,這兩個點都等於游標的位置,其中一個點 pt 會轉換成筆跡空間,並用於呼叫 InkCollectorInk 物件的 NearestPoint 方法中。 NearestPoint 方法會傳回最接近點的 Stroke 物件,並設定浮點索引輸出參數。
using (Graphics g = CreateGraphics())
{
// Remember pen location
Point inkPenPt = new Point(e.X, e.Y);
// Convert the pen location into a location in ink space
ic.Renderer.PixelToInkSpace(g, ref inkPenPt);
// ...
float fIndex;
Stroke stroke = ic.Ink.NearestPoint(inkPenPt, out fIndex);
如果沒有筆劃,NearestPoint 方法會傳回 NULL,而游標位置會當做最接近的點使用。 否則,會計算對應至浮點索引的筆劃位置。
然後,最近點的座標將從墨水空間轉換為像素,handleNearestPoint 方法接著會使 invalidateRect 區域失效,計算出繪製到最近點的新區域,並同樣使新區域失效。
關閉表單
表單的 Dispose 方法會釋放 InkCollector 物件。