共用方式為


RealTimeStylus 外掛程式範例

此應用程式示範如何使用 RealTimeStylus 類別。 如需 StylusInput API 的詳細概觀,包括 RealTimeStylus 類別,請參閱 存取和操作手寫筆輸入。 如需同步和非同步外掛程式的相關資訊,請參閱 外掛程式和 RealTimeStylus 類別

範例概觀

外掛程式,實作 IStylusSyncPluginIStylusAsyncPlugin 介面的物件可以新增至 RealTimeStylus 物件。 此範例應用程式會使用數種類型的外掛程式:

  • 封包篩選外掛程式:修改封包。 此範例中的封包篩選外掛程式會藉由限制矩形區域內的所有 (x,y) 封包資料,來修改封包資訊。
  • 自訂動態轉譯器外掛程式:修改動態轉譯品質。 此範例中的自訂動態轉譯外掛程式會修改筆跡轉譯的方式,方法是在筆劃上繪製每個 (x,y) 點周圍的小型圓形。
  • 動態轉譯器外掛程式:修改動態轉譯品質。 此範例示範如何使用 DynamicRenderer 物件做為外掛程式來處理筆跡的動態轉譯。
  • 手勢辨識器外掛程式:辨識應用程式手勢。 此範例示範在具有 Microsoft 手勢辨識器的系統上執行時, 使用 GestureRecognizer 物件做為外掛程式來辨識應用程式手勢 () 。

此外,此範例提供使用者介面,可讓使用者新增、移除和變更集合中每個外掛程式的順序。 範例解決方案包含兩個專案:RealTimeStylusPluginApp 和 RealTimeStylusPlugins。 RealTimeStylusPluginApp 包含範例的使用者介面。 RealTimeStylusPlugins 包含外掛程式的實作。RealTimeStylusPlugins 專案會定義 RealTimeStylusPlugins 命名空間,其中包含封包篩選和自訂動態轉譯器外掛程式。RealTimeStylusPluginApp 專案會參考此命名空間。 RealTimeStylusPlugins 專案使用 Microsoft.InkMicrosoft.StylusInputMicrosoft.StylusInput.PluginData 命名空間。

如需 Microsoft.StylusInputMicrosoft.StylusInput.PluginData 命名空間的概觀,請參閱 StylusInput API 的架構

封包篩選外掛程式

封包篩選外掛程式是示範封包修改的同步外掛程式。 具體而言,它會定義表單上的矩形。 在區域外部繪製的任何封包,會在區域內轉譯。 外掛程式類別 PacketFilterPlugin 會註冊 、 StylusUpPackets 手寫筆輸入事件的通知 StylusDown 。 類別會實作IStylusSyncPlugin類別上定義的StylusDownStylusUpPackets方法。

PacketFilterPlugin 公用建構函式需要 Rectangle 結構。 此矩形會定義矩形區域,在筆跡空間座標中, (.01mm = 1 HIMETRIC 單位) ,其中會包含封包。 矩形會保留在私用欄位中。 rectangle

public class PacketFilterPlugin:IStylusSyncPlugin  
{
    private System.Drawing.Rectangle rectangle = System.Drawing.Rectangle.Empty;
    public PacketFilterPlugin(Rectangle r)
    {
        rectangle = r;
    }
    // ...

類別 PacketFilterPlugin 會藉由實作 DataInterest 屬性的 get 存取子來註冊事件通知。 在此情況下,外掛程式有興趣回應 StylusDownPacketsStylusUpError 通知。 此範例會傳回 DataInterestMask 列舉中所定義的這些值。 手寫筆提示接觸數位板表面時,會呼叫手寫筆 Down 方法。 手寫筆尖離開數位板表面時,會呼叫 寫筆提示方法。 當 RealTimeStylus物件收到封包時,會呼叫Packets方法。 當目前的外掛程式或先前的外掛程式擲回例外狀況時,就會呼叫 Error 方法。

public DataInterestMask DataInterest
{
    get
    {
        return DataInterestMask.StylusDown | 
               DataInterestMask.Packets | 
               DataInterestMask.StylusUp | 
               DataInterestMask.Error;
    }
}           
    //...

類別 PacketFilterPlugin 會在協助程式方法 ModifyPacketData 中處理大部分的這些通知。 方法 ModifyPacketData 會從 PacketsData 類別取得每個新封包的 x 和 y 值。 如果任一值在矩形之外,方法會將值取代為仍然落在矩形內的最接近點。 這是外掛程式從手寫筆輸入資料流程接收封包資料時,如何取代封包資料的範例。

private void ModifyPacketData(StylusDataBase data)
{
    for (int i = 0; i < data.Count ; i += data.PacketPropertyCount)
    {
        // packet data always has x followed by y followed by the rest
        int x = data[i];
        int y = data[i+1];

        // Constrain points to the input rectangle
        x = Math.Max(x, rectangle.Left);
        x = Math.Min(x, rectangle.Right);
        y = Math.Max(y, rectangle.Top);
        y = Math.Min(y, rectangle.Bottom);

        // If necessary, modify the x,y packet data
        if (x != data[i])
        {
            data[i] = x;
        }
        if (y != data[i+1])
        {
            data[i+1] = y;
        } 
    }
}

自訂動態轉譯器外掛程式

類別 CustomDynamicRenderer 也會實作 IStylusSyncPlugin 類別,以接收手寫筆輸入通知。 然後它會處理通知, Packets 以在每個新的封包點周圍繪製一個小圓圈。

類別包含 Graphics 變數,其中包含傳遞至類別建構函式之繪圖物件的參考。 這是用於動態轉譯的繪圖物件。

private Graphics myGraphics;

public CustomDynamicRendererPlugin(Graphics g)
{
    myGraphics = g;
}
        //...
            

當自訂動態轉譯器外掛程式收到封包通知時,它會擷取 (x,y) 資料,並在點周圍繪製一個小綠色圓圈。 這是以手寫筆輸入資料流程為基礎的自訂轉譯範例。

public void Packets(RealTimeStylus sender,  PacketsData data)
{           
    for (int i = 0; i < data.Count; i += data.PacketPropertyCount)
    {
        // Packet data always has x followed by y followed by the rest
        Point point = new Point(data[i], data[i+1]);

        // Since the packet data is in Ink Space coordinates, we need to convert to Pixels...
        point.X = (int)Math.Round((float)point.X * (float)myGraphics.DpiX/2540.0F);
        point.Y = (int)Math.Round((float)point.Y * (float)myGraphics.DpiY/2540.0F);

        // Draw a circle corresponding to the packet
        myGraphics.DrawEllipse(Pens.Green, point.X - 2, point.Y - 2, 4, 4);
    }
}

RealTimeStylusPluginApp 專案

RealTimeStylusPluginApp 專案示範先前所述的外掛程式,以及 GestureRecognizerDynamicRenderer 外掛程式。專案的使用者介面包含:

  • 表單,包含用來定義筆跡輸入區域的 GroupBox 控制項。
  • 要列出並選取可用外掛程式的 CheckedListBox 控制項。
  • 一對 Button 物件 ,可重新排序外掛程式。

專案會定義 結構 , PlugInListItem 讓管理專案中所使用的外掛程式變得更容易。 結構 PlugInListItem 包含外掛程式和描述。

類別 RealTimeStylusPluginApp 本身會實作 IStylusAsyncPlugin 類別。 這是必要的,如此一來, RealTimeStylusPluginApp當 GestureRecognizer 外掛程式將手勢資料新增至輸出佇列時,即可通知 類別。 應用程式會註冊 CustomStylusDataAdded的通知。 收到手勢資料時, RealTimeStylusPluginApp 將它的描述放在表單底部的狀態列上。

public void CustomStylusDataAdded(RealTimeStylus sender, CustomStylusData data)
{
    if (data.CustomDataId == GestureRecognizer.GestureRecognitionDataGuid)
    {
        GestureRecognitionData grd = data.Data as GestureRecognitionData;
        if (grd != null)
        {
            if (grd.Count > 0)
            {
                GestureAlternate ga = grd[0];
                sbGesture.Text = "Gesture=" + ga.Id + ", Confidence=" + ga.Confidence;
            }
        }
    }
}

注意

CustomStylusDataAdded 實作中,您可以使用 GestureRecognitionDataGuid 欄位 (來識別輸出佇列中的自訂手勢資料,方法是使用 GestureRecognitionDataGuid 欄位) ,或使用 as 語句的結果 () 。 此範例會使用這兩種識別技術進行示範。 任一種方法也有效。

 

在表單的 Load 事件處理常式中,應用程式會建立 和 CustomDynamicRenderer 類別的 PacketFilter 實例,並將其新增至清單方塊。 然後,應用程式會嘗試建立 GestureRecognizer 類別的實例,如果成功,請將它新增至清單方塊。 如果系統上沒有手勢辨識器,就會失敗。 接下來,應用程式會具現化 DynamicRenderer 物件,並將其新增至清單方塊。 最後,應用程式會啟用每個外掛程式和 RealTimeStylus 物件本身。

關於範例的另一個重要事項是,在協助程式方法中,在新增或移除外掛程式之前,會先停用 RealTimeStylus 物件,然後在新增或移除完成後重新啟用。

private void RemoveFromPluginCollection(int index)
{
    IStylusSyncPlugin plugin = ((PluginListItem)chklbPlugins.Items[index]).Plugin;

    bool rtsEnabled = myRealTimeStylus.Enabled;
    myRealTimeStylus.Enabled = false;
    myRealTimeStylus.SyncPluginCollection.Remove(plugin);
    myRealTimeStylus.Enabled = rtsEnabled;
}

Microsoft.StylusInput.DynamicRenderer

Microsoft.StylusInput.GestureRecognizer

Microsoft.StylusInput.RealTimeStylus

Microsoft.StylusInput.DataInterestMask

Microsoft.StylusInput.IStylusSyncPlugin

Microsoft.StylusInput.IStylusAsyncPlugin

Microsoft.StylusInput.PluginData.PacketsData

存取及操作手寫筆輸入

外掛程式和 RealTimeStylus 類別

RealTimeStylus Ink 集合範例