Win32 API 日本語リファレンス
ホームUI.TabletPC › IStylusPlugin

IStylusPlugin

COM
IIDa81436d8-4757-4fd1-a185-133f97c6c545継承元IUnknown自前メソッド開始 vtbl3

公式ドキュメント

RealTimeStylus Class のイベントの通知を受け取り、それらのイベントに基づいたカスタム処理を実行できるようにします。

解説(Remarks)

IStylusSyncPlugin インターフェイスと IStylusAsyncPlugin インターフェイスは、いずれもこのインターフェイスから派生しており、RealTimeStylus Class のプラグインコレクションに追加できます。

メソッド 17

vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。

vtbl 3 HRESULT RealTimeStylusEnabled(IRealTimeStylus* piRtsSrc, DWORD cTcidCount, DWORD* pTcids)

RealTimeStylus Class (RTS) オブジェクトが有効になったことを、実装側のプラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class オブジェクト。
cTcidCountDWORDinRTS が検出したタブレットコンテキスト識別子の数。有効な値は 0 から 8 までです。
pTcidsDWORD*inタブレットコンテキスト識別子。

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

このメソッドは、RealTimeStylus Class オブジェクトが有効になったとき、またはプラグインがコレクションに追加されたときに呼び出されます。

次の C++ の例では、RealTimeStylus オブジェクトが収集したパケットから Ink のストロークを作成する目的で、IStrokeBuilder オブジェクトの新しいインスタンスを作成する IStylusPlugin::RealTimeStylusEnabled Method メソッドを実装しています。

STDMETHODIMP CStrokeBuilderPlugin::RealTimeStylusEnabled( 
            /* [in] */ IRealTimeStylus *piRtsSrc,
            /* [in] */ ULONG cTcidCount,
            /* [size_is][in] */ const TABLET_CONTEXT_ID *pTcids)
{
    // Create an IStrokeBuilder object
    return CoCreateInstance(CLSID_StrokeBuilder, NULL, CLSCTX_INPROC, IID_IStrokeBuilder, (VOID **)&m_pStrokeBuilder);
}
vtbl 4 HRESULT RealTimeStylusDisabled(IRealTimeStylus* piRtsSrc, DWORD cTcidCount, DWORD* pTcids)

RealTimeStylus Class (RTS) オブジェクトが無効になったことを、実装側のプラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class オブジェクト。
cTcidCountDWORDinRTS が検出したタブレットコンテキスト識別子の数。有効な値は 0 から 8 までです。
pTcidsDWORD*inタブレットコンテキスト識別子。

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

このメソッドは、RTS オブジェクトが無効になったとき、またはプラグインがコレクションから削除されたときに呼び出されます。

vtbl 5 HRESULT StylusInRange(IRealTimeStylus* piRtsSrc, DWORD tcid, DWORD sid)

スタイラスがデジタイザーの検出範囲に入ったことを、実装側のプラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class オブジェクト。
tcidDWORDinタブレットコンテキスト識別子。
sidDWORDinスタイラス識別子。

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

スタイラスがデジタイザーの範囲内にあります。ここは、スタイラスが反転しているかどうかを確認し、反転している場合に消しゴムモードへ切り替えるのに適した箇所です。

次の C++ の例では、スタイラス上のすべてのボタンの状態を取得し、TRACE マクロを使用してデバッグウィンドウに出力する IStylusPlugin::StylusInRange Method メソッドを実装しています。

STDMETHODIMP CPacketModifier::StylusInRange( 
            /* [in] */ IRealTimeStylus *piRtsSrc,
            /* [in] */ TABLET_CONTEXT_ID tcid,
            /* [in] */ STYLUS_ID sid)
{
    IInkCursor* pInkCursor;
    HRESULT hr = piRtsSrc->GetStylusForId(sid, &pInkCursor);

    if (SUCCEEDED(hr))
    {
        IInkCursorButtons* pInkCursorButtons;
        hr = pInkCursor->get_Buttons(&pInkCursorButtons);

        if (SUCCEEDED(hr))
        {
            LONG lButtonCount;
            pInkCursorButtons->get_Count(&lButtonCount);

            if (SUCCEEDED(hr))
            {
                IInkCursorButton* pInkCursorButton;
                VARIANT index;
                VariantInit(&index);
                index.vt = VT_I4;

                for (index.intVal = 0; index.intVal < lButtonCount; index.intVal++)
                {
                    hr = pInkCursorButtons->Item(index, &pInkCursorButton);

                    if (SUCCEEDED(hr))
                    {
                        InkCursorButtonState currentState;
                        hr = pInkCursorButton->get_State(&currentState);

                        if (SUCCEEDED(hr))
                        {
                            switch(currentState)
                            {
                                case ICBS_Unavailable:
                                    TRACE("ICBS_Unavailable\n");
                                    break;

                                case ICBS_Up:
                                    TRACE("ICBS_Up\n");
                                    break;

                                case ICBS_Down:
                                    TRACE("ICBS_Down\n");
                                    break;

                                default:
                                    TRACE("Cursor button state unknown.\n");
                                    break;
                            }
                        }
                    }
                }

                VariantClear(&index);
            }
        }
    }

    return hr;
}
vtbl 6 HRESULT StylusOutOfRange(IRealTimeStylus* piRtsSrc, DWORD tcid, DWORD sid)

スタイラスがデジタイザーの検出範囲から出たことを、実装側のプラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class オブジェクト。
tcidDWORDinタブレットコンテキスト識別子。
sidDWORDinスタイラス識別子。

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

スタイラスがデジタイザーの範囲外にあります。

vtbl 7 HRESULT StylusDown(IRealTimeStylus* piRtsSrc, StylusInfo* pStylusInfo, DWORD cPropCountPerPkt, INT* pPacket, INT** ppInOutPkt)

タブレットペンがデジタイザーの表面に触れたことを、実装側のプラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class (RTS) オブジェクト。
pStylusInfoStylusInfo*inスタイラスに関連付けられている RTS に関する情報を含む StylusInfo Structure
cPropCountPerPktDWORDinパケットあたりのプロパティ数。有効な値は 0 から 32 までです。
pPacketINT*inパケットデータの先頭。
ppInOutPktINT**inout変更後のスタイラスデータパケットへのポインター。プラグインはこのパラメーターを使用して、変更したパケットデータを下流のパケットに渡すことができます。NULL 以外の値は、パケットが変更されたことを示し、RTS は pPacket パラメーターを使用してこのデータをプラグインに送信します。

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

変更後のパケットの配列は、バッファー ppInOutPkt で返すことができます。IStylusPlugin::StylusUp Method メソッドと IStylusPlugin::StylusDown Method メソッドで使用されるパケットは、変更のみが可能です。IStylusPlugin::Packets Method メソッドと IStylusPlugin::InAirPackets Method メソッドで使用されるパケットは削除できます。

パケットを変更する場合、ppInOutPkt 内の LONG の数である cPropCountPerPkt は、現在の入力デバイスで利用可能な desired packet properties (DPP) の数で割り切れる必要があります。

パケットを変更するには、cPropCountPerPkt パラメーターと ppInOutPkts パラメーターを更新します。cPropCountPerPkt を有効なパケットプロパティの総数に変更し、ppInOutPkts を、各パケット内のすべての DPP の値を保持する有効なデータバッファーへのポインターに変更します。IStylusPlugin::StylusUp MethodIStylusPlugin::StylusDown Method では、その位置に配置できるパケットは 1 つだけです。

たとえば、パケットを 3 つ追加し、現在の DPP が X、Y、および Pressure である場合、このバッファーには 9 個の LONG 値が必要であり、cPropCountPerPkt には 9 を設定します。

cPropCountPerPkt の値は、NewPackets Event イベントなどで渡される整数のフラットな配列において、パケット間の境界を明確にするのに役立ちます。データ転送を効率化するためにパケットはまとめて渡されることがあるため、プラグインがパケットごとに 1 回呼び出されるとは限りません。

次の C++ のコード例では、ヘルパー関数 ModifyPacket を呼び出して X,Y データの値を変更し、指定した矩形の内側に収まるようにする StylusDown メソッドを実装しています。これは、C# のサンプルである RealTimeStylus Plug-in Sample で実装されているものと同じ機能です。2 つ目のコードスニペットは ModifyPacket 関数です。

STDMETHODIMP CPacketModifier::StylusDown( 
            /* [in] */ IRealTimeStylus *piRtsSrc,
            /* [in] */ const StylusInfo *pStylusInfo,
            /* [in] */ ULONG cPropCountPerPkt,
            /* [size_is][in] */ LONG *pPacket,
            /* [out][in] */ LONG **ppInOutPkt)
{
    return ModifyPacket(cPropCountPerPkt, pPacket, ppInOutPkt);
}
// Helper method to modify a single packet
// Called from StylusDown() and StylusUp()
HRESULT CPacketModifier::ModifyPacket(
            /* [in] */ ULONG cPropCountPerPkt,
            /* [size_is][in] */ LONG *pPacket,
            /* [out][in] */ LONG **ppInOutPkt)
{
    // Pointer to a buffer to hold changed packet values
    LONG* pTempOutPkt = NULL;
    
    // X and Y come first (0 and 1), 
    // other properties follow
    ULONG iOtherProps = 2;

    if (cPropCountPerPkt > 0)
    {
        pTempOutPkt = (LONG*)CoTaskMemAlloc(sizeof(LONG)*cPropCountPerPkt);

        if (NULL != pTempOutPkt)
        {
            // Packet data always has x followed by y followed by the rest.
            LONG x = pPacket[0];
            LONG y = pPacket[1];

            // In the packet data, check whether
            // its X,Y values fall outside of the specified rectangle.
            // If so, replace them with the nearest point that still
            // falls within the rectangle.
            x = (x < m_filterRect.left ? m_filterRect.left : x);
            x = (x > m_filterRect.right ? m_filterRect.right : x);
            y = (y < m_filterRect.top ? m_filterRect.top : y);
            y = (y > m_filterRect.bottom ? m_filterRect.bottom : y);

            // If necessary, modify the x,y packet data
            if ((x != pPacket[0]) || (y != pPacket[1]))
            {
                pTempOutPkt[0] = x;
                pTempOutPkt[1] = y;

                // Copy the properties that we haven't modified
                while (iOtherProps < cPropCountPerPkt)
                {
                    pTempOutPkt[iOtherProps] = pPacket[iOtherProps++];
                }

                *ppInOutPkt = pTempOutPkt;
            }
            else
            {
                CoTaskMemFree(pTempOutPkt);
            }
        }
    }

    return S_OK;
}
vtbl 8 HRESULT StylusUp(IRealTimeStylus* piRtsSrc, StylusInfo* pStylusInfo, DWORD cPropCountPerPkt, INT* pPacket, INT** ppInOutPkt)

ユーザーがタブレットのデジタイザー表面からタブレットペンを離したことを、実装側のプラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class (RTS) オブジェクト。
pStylusInfoStylusInfo*inペンに関連付けられている RTS に関する情報を含む StylusInfo Structure
cPropCountPerPktDWORDinパケットあたりのプロパティ数。有効な値は 0 から 32 までです。
pPacketINT*inパケットデータの先頭。
ppInOutPktINT**inout変更後のスタイラスデータパケットへのポインター。プラグインはこのパラメーターを使用して、変更したパケットデータを下流のパケットに渡すことができます。NULL 以外の値は、パケットが変更されたことを示し、RTS は pPacket パラメーターを使用してこのデータをプラグインに送信します。

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

このメソッドは、ペンがデジタイザーの表面から離れたときに使用されます。

変更後のパケットの配列は、バッファー ppInOutPkt で返すことができます。IStylusPlugin::StylusUp Method メソッドと IStylusPlugin::StylusDown Method メソッドで使用されるパケットは、変更のみが可能です。削除することはできません。IStylusPlugin::Packets Method メソッドと IStylusPlugin::InAirPackets Method メソッドで使用されるパケットは削除できます。

パケットを変更する場合、ppInOutPkt 内の LONG の数である cPropCountPerPkt は、現在の入力デバイスで利用可能な desired packet properties (DPP) の数で割り切れる必要があります。

パケットを変更するには、cPropCountPerPkt パラメーターと ppInOutPkts パラメーターを更新します。cPropCountPerPkt を有効なパケットプロパティの総数に変更し、ppInOutPkts を、各パケット内のすべての DPP の値を保持する有効なデータバッファーに変更します。IStylusPlugin::StylusUp MethodIStylusPlugin::StylusDown Method では、その位置に配置できるパケットは 1 つだけです。

たとえば、パケットを 3 つ追加し、現在の DPP が X、Y、および Pressure である場合、このバッファーには 9 個の LONG 値が必要であり、cPropCountPerPkt には 9 を設定します。

cPropCountPerPkt の値は、NewPackets Event イベントなどで渡される整数のフラットな配列において、パケット間の境界を明確にするのに役立ちます。データ転送を効率化するためにパケットはまとめて渡されることがあるため、プラグインがパケットごとに 1 回呼び出されるとは限りません。

次の C++ のコード例では、ヘルパー関数 ModifyPacket を呼び出して X,Y データの値を変更し、指定した矩形の内側に収まるようにする StylusUp メソッドを実装しています。これは、C# のサンプルである RealTimeStylus Plug-in Sample で実装されているものと同じ機能です。2 つ目のコードスニペットは ModifyPacket 関数です。

STDMETHODIMP CPacketModifier::StylusUp( 
            /* [in] */ IRealTimeStylus *piRtsSrc,
            /* [in] */ const StylusInfo *pStylusInfo,
            /* [in] */ ULONG cPropCountPerPkt,
            /* [size_is][in] */ LONG *pPacket,
            /* [out][in] */ LONG **ppInOutPkt)
{
    return ModifyPacket(cPropCountPerPkt, pPacket, ppInOutPkt);
}
// Helper method to modify a single packet
// Called from StylusDown() and StylusUp()
HRESULT CPacketModifier::ModifyPacket(
            /* [in] */ ULONG cPropCountPerPkt,
            /* [size_is][in] */ LONG *pPacket,
            /* [out][in] */ LONG **ppInOutPkt)
{
    // Pointer to a buffer to hold changed packet values
    LONG* pTempOutPkt = NULL;
    
    // X and Y come first (0 and 1), 
    // other properties follow
    ULONG iOtherProps = 2;

    if (cPropCountPerPkt > 0)
    {
        pTempOutPkt = (LONG*)CoTaskMemAlloc(sizeof(LONG)*cPropCountPerPkt);

        if (NULL != pTempOutPkt)
        {
            // Packet data always has x followed by y followed by the rest.
            LONG x = pPacket[0];
            LONG y = pPacket[1];

            // In the packet data, check whether
            // its X,Y values fall outside of the specified rectangle.
            // If so, replace them with the nearest point that still
            // falls within the rectangle.
            x = (x < m_filterRect.left ? m_filterRect.left : x);
            x = (x > m_filterRect.right ? m_filterRect.right : x);
            y = (y < m_filterRect.top ? m_filterRect.top : y);
            y = (y > m_filterRect.bottom ? m_filterRect.bottom : y);

            // If necessary, modify the x,y packet data
            if ((x != pPacket[0]) || (y != pPacket[1]))
            {
                pTempOutPkt[0] = x;
                pTempOutPkt[1] = y;

                // Copy the properties that we haven't modified
                while (iOtherProps < cPropCountPerPkt)
                {
                    pTempOutPkt[iOtherProps] = pPacket[iOtherProps++];
                }

                *ppInOutPkt = pTempOutPkt;
            }
            else
            {
                CoTaskMemFree(pTempOutPkt);
            }
        }
    }

    return S_OK;
}
vtbl 9 HRESULT StylusButtonDown(IRealTimeStylus* piRtsSrc, DWORD sid, GUID* pGuidStylusButton, POINT* pStylusPos)

ユーザーがスタイラスのボタンを押していることを、実装側のプラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class オブジェクト。
sidDWORDinセキュリティ識別子。
pGuidStylusButtonGUID*inスタイラスボタンのデータを表す GUID 型の識別子。この GUID は、このデータオブジェクトの一意の識別子を示します。
pStylusPosPOINT*inoutスタイラスに関連付けられている RealTimeStylus Class オブジェクトに関する情報を含む StylusInfo Structure

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

この通知は、スタイラスのボタンが押されており、かつスタイラスがデジタイザーの範囲内にある場合に使用されます。

vtbl 10 HRESULT StylusButtonUp(IRealTimeStylus* piRtsSrc, DWORD sid, GUID* pGuidStylusButton, POINT* pStylusPos)

ユーザーがスタイラスのボタンを離したことを、実装側のプラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class (RTS) オブジェクト。
sidDWORDinセキュリティ識別子。
pGuidStylusButtonGUID*inスタイラスボタンのデータに対するグローバル一意識別子 (GUID)。
pStylusPosPOINT*inoutスタイラスに関連付けられている RTS に関する情報を含む StylusInfo Structure

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

スタイラスのボタンは押されていない状態になり、スタイラスはデジタイザーの範囲内にあります。

vtbl 11 HRESULT InAirPackets(IRealTimeStylus* piRtsSrc, StylusInfo* pStylusInfo, DWORD cPktCount, DWORD cPktBuffLength, INT* pPackets, DWORD* pcInOutPkts, INT** ppInOutPkts)

スタイラスがデジタイザーの上方で移動していることを、プラグインを実装するオブジェクトに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class (RTS) オブジェクト。
pStylusInfoStylusInfo*inスタイラスに関連付けられている RTS に関する情報を含む StylusInfo Structure 構造体。
cPktCountDWORDinデータパケットあたりのプロパティ数。
cPktBuffLengthDWORDinpPackets が指すバッファーの長さ (バイト単位)。各パケットが占めるメモリは (cPktBuffLength / cPktCount) です。有効な値は 0 から 0x7FFF までです。
pPacketsINT*inパケットデータの先頭へのポインター。読み取り専用です。
pcInOutPktsDWORD*inoutppInOutPkt 内の LONG の数。
ppInOutPktsINT**inout変更後のスタイラスデータパケットの配列へのポインター。プラグインはこのパラメーターを使用して、変更したパケットデータを下流のパケットに渡すことができます。NULL 以外の値の場合、RTS は pPacket パラメーターを使用してこのデータをプラグインに送信します。

戻り値

戻り値の説明については、Classes and Interfaces - Ink Analysis を参照してください。

解説(Remarks)

このメソッドは、スタイラスが範囲内にあるものの、デジタイザーに触れずにその上方で移動している状態でデータパケットが生成されたときに呼び出されます。変更後のパケットの配列は、ppInOutPkt パラメーターを使用して返すことができます。バッファーを作成し、ppInOutPkts がそのバッファーを指すようにします。その位置に配置できるパケットは 1 つだけです。

メモ IStylusPlugin::Packets Method メソッドと IStylusPlugin::InAirPackets Method メソッドで使用されるパケットは削除できます。
スタイラスプラグインは、単一の RTS に関連付けられる場合も、複数の RTS に関連付けられる場合もあります。次の場合には piRtsSrc パラメーターを使用します。 データ転送を効率化するために、パケットはまとめて渡されることがあります。そのため、プラグインがパケットごとに 1 回呼び出される必要はありません。IStylusPlugin::InAirPackets MethodIStylusPlugin::Packets Method は、1 つ以上のパケットを送信できます。

次の C++ のコード例では、X,Y データを変更してパケットを矩形内に制限する IStylusPlugin::Packets Method メソッドを実装しています。同じコードは IStylusPlugin::InAirPackets Method の実装にも適用できます。

STDMETHODIMP CPacketModifier::Packets( 
            /* [in] */ IRealTimeStylus *piRtsSrc,
            /* [in] */ const StylusInfo *pStylusInfo,
            /* [in] */ ULONG cPktCount,
            /* [in] */ ULONG cPktBuffLength,
            /* [size_is][in] */ LONG *pPackets,
            /* [out][in] */ ULONG *pcInOutPkts,
            /* [out][in] */ LONG **ppInOutPkts)
{
    BOOL fModified = FALSE;                             // Did we change the packet data?
    ULONG cPropertyCount = cPktBuffLength/cPktCount;    // # of properties in a packet
    ULONG iOtherProps = 0;                              // Properties other than X and Y

    // Allocate memory for modified packets
    LONG* pTempOutPkts = (LONG*)CoTaskMemAlloc(sizeof(ULONG)*cPktBuffLength);

    // For each packet in the packet data, check whether
    // its X,Y values fall outside of the specified rectangle.  
    // If so, replace them with the nearest point that still
    // falls within the rectangle.
    for (ULONG i = 0; i < cPktCount; i += cPropertyCount)
    {
        // Packet data always has X followed by Y 
        // followed by the rest
        LONG x = pPackets[i];
        LONG y = pPackets[i+1];

        // Constrain points to the input rectangle
        x = (x < m_filterRect.left ? m_filterRect.left : x);
        x = (x > m_filterRect.right ? m_filterRect.right : x);
        y = (y < m_filterRect.top ? m_filterRect.top : y);
        y = (y > m_filterRect.bottom ? m_filterRect.bottom : y);

        // If necessary, modify the X,Y packet data
        if ((x != pPackets[i]) || (y != pPackets[i+1]))
        {
            pTempOutPkts[i] = x;
            pTempOutPkts[i+1] = y;
            iOtherProps = i+2;
        
            // Copy the properties that we haven't modified
            while (iOtherProps < (i + cPropertyCount))
            {
                pTempOutPkts[iOtherProps] = pPackets[iOtherProps++];
            }

            fModified = TRUE;
        }
    }

    if (fModified)
    {
        // Set the [out] pointer to the 
        // memory we allocated and updated
        *ppInOutPkts = pTempOutPkts;
        *pcInOutPkts = cPktCount;
    }
    else
    {
        // Nothing modified, release the memory we allocated
        CoTaskMemFree(pTempOutPkts);
    }

    return S_OK;
}
vtbl 12 HRESULT Packets(IRealTimeStylus* piRtsSrc, StylusInfo* pStylusInfo, DWORD cPktCount, DWORD cPktBuffLength, INT* pPackets, DWORD* pcInOutPkts, INT** ppInOutPkts)

タブレットペンがデジタイザー上を移動していることを、プラグインを実装するオブジェクトに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class オブジェクト。
pStylusInfoStylusInfo*inペンに関連付けられている RTS に関する情報を含む StylusInfo Structure 構造体。
cPktCountDWORDinデータパケットあたりのプロパティ数。
cPktBuffLengthDWORDinpPackets が指すバッファーの長さ (バイト単位)。各パケットが占めるメモリは (cPktBuffLength / cPktCount) です。有効な値は 0 から 0x7FFF までです。
pPacketsINT*inパケットデータの先頭へのポインター。
pcInOutPktsDWORD*inoutppInOutPkt 内の LONG の数。
ppInOutPktsINT**inout変更後のスタイラスデータパケットの配列へのポインター。プラグインはこのパラメーターを使用して、変更したパケットデータを下流のパケットに渡すことができます。NULL 以外の値は、RTS が pPacket パラメーターを使用してこのデータをプラグインに送信することを示します。

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

ペンが移動しており、デジタイザーの表面に触れているときに発生します。この通知は、パケットデータを指定した矩形内に制限するために使用します。IStylusPlugin::Packets Method メソッドと IStylusPlugin::InAirPackets Method メソッドで使用されるパケットは削除できます。

変更後のパケットの配列は、ppInOutPkt パラメーターを使用して返すことができます。

データ転送を効率化するためにパケットはまとめて渡されることがあり、プラグインがパケットごとに 1 回呼び出される必要はありません。IStylusPlugin::InAirPackets MethodIStylusPlugin::Packets Method は、1 つ以上のパケットを送信できます。

次の C++ のコード例では、X,Y データを変更してパケットを矩形内に制限する IStylusPlugin::Packets Method メソッドを実装しています。これは、RealTimeStylus Plug-in Sample で C# により実装されているものと同じ機能です。

STDMETHODIMP CPacketModifier::Packets( 
            /* [in] */ IRealTimeStylus *piRtsSrc,
            /* [in] */ const StylusInfo *pStylusInfo,
            /* [in] */ ULONG cPktCount,
            /* [in] */ ULONG cPktBuffLength,
            /* [size_is][in] */ LONG *pPackets,
            /* [out][in] */ ULONG *pcInOutPkts,
            /* [out][in] */ LONG **ppInOutPkts)
{
    BOOL fModified = FALSE;                             // Did we change the packet data?
    ULONG cPropertyCount = cPktBuffLength/cPktCount;    // # of properties in a packet
    ULONG iOtherProps = 0;                              // Properties other than X and Y

    // Allocate memory for modified packets
    LONG* pTempOutPkts = (LONG*)CoTaskMemAlloc(sizeof(ULONG)*cPktBuffLength);

    // For each packet in the packet data, check whether
    // its X,Y values fall outside of the specified rectangle.  
    // If so, replace them with the nearest point that still
    // falls within the rectangle.
    for (ULONG i = 0; i < cPktCount; i += cPropertyCount)
    {
        // Packet data always has X followed by Y 
        // followed by the rest
        LONG x = pPackets[i];
        LONG y = pPackets[i+1];

        // Constrain points to the input rectangle
        x = (x < m_filterRect.left ? m_filterRect.left : x);
        x = (x > m_filterRect.right ? m_filterRect.right : x);
        y = (y < m_filterRect.top ? m_filterRect.top : y);
        y = (y > m_filterRect.bottom ? m_filterRect.bottom : y);

        // If necessary, modify the X,Y packet data
        if ((x != pPackets[i]) || (y != pPackets[i+1]))
        {
            pTempOutPkts[i] = x;
            pTempOutPkts[i+1] = y;
            iOtherProps = i+2;
        
            // Copy the properties that we haven't modified
            while (iOtherProps < (i + cPropertyCount))
            {
                pTempOutPkts[iOtherProps] = pPackets[iOtherProps++];
            }

            fModified = TRUE;
        }
    }

    if (fModified)
    {
        // Set the [out] pointer to the 
        // memory we allocated and updated
        *ppInOutPkts = pTempOutPkts;
        *pcInOutPkts = cPktCount;
    }
    else
    {
        // Nothing modified, release the memory we allocated
        CoTaskMemFree(pTempOutPkts);
    }

    return S_OK;
}
vtbl 13 HRESULT CustomStylusDataAdded(IRealTimeStylus* piRtsSrc, GUID* pGuidId, DWORD cbData, BYTE* pbData)

カスタムスタイラスデータが利用可能になったことを、実装側のプラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class (RTS) オブジェクト。
pGuidIdGUID*inカスタムデータに対するグローバル一意識別子 (GUID)。
cbDataDWORDinバッファー pbData のサイズ (char 単位)。有効な値は 0 から 0x7FFF までです。
pbDataBYTE*inoptionalRTS オブジェクトから送信されたカスタムデータを含むバッファーへのポインター。

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

このメソッドは、IStylusPlugin::CustomStylusDataAdded Method が処理されるときに呼び出されます。カスタムデータは pbData メンバーで渡され、型情報を渡すための GUID が pGuidId メンバーで渡されます。このクラスは継承できません。

次の C++ のコード例では、ジェスチャイベントのデータを処理し、スタティックテキストコントロール m_pStatusControl にジェスチャデータの文字列表現を設定する IStylusPlugin::CustomStylusDataAdded Method メソッドを実装しています。

STDMETHODIMP CGestureHandler::CustomStylusDataAdded( 
            /* [in] */ IRealTimeStylus *piRtsSrc,
            /* [in] */ const GUID *pGuidId,
            /* [in] */ ULONG cbData,
            /* [in] */ const BYTE *pbData)
{
    // Did we get passed gesture data?
    if (*pGuidId == GUID_GESTURE_DATA)
    {
        // Another way to check for gestures is to see if the data
        // is the right size and actually points to something
        if ((cbData == sizeof(GESTURE_DATA)) && (pbData != NULL))
        {
            // Access the data coming as a GESTURE_DATA structure
            GESTURE_DATA* pGD = (GESTURE_DATA*)pbData;

            CString strStatus;
            CString strGestureId;
            
            // Helper function that maps the gesture ID to a string value
            SetGestureString(pGD->gestureId, &strGestureId);

            strStatus.Format(L"Gesture=%s\tConfidence=%d\tStrokes=%d", strGestureId, pGD->recoConfidence, pGD->strokeCount);
            m_pStatusControl->SetWindowTextW(strStatus);
        }
        else
        {
            m_pStatusControl->SetWindowTextW(L"Not gesture data.");
        }
    }
    else
    {
        m_pStatusControl->SetWindowTextW(L"Not gesture data.");
    }

    return S_OK;
}
vtbl 14 HRESULT SystemEvent(IRealTimeStylus* piRtsSrc, DWORD tcid, DWORD sid, WORD event, SYSTEM_EVENT_DATA eventdata)

システムイベントが利用可能になったことを、実装側のプラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class (RTS) オブジェクト。
tcidDWORDinイベントのタブレットコンテキスト識別子。
sidDWORDinセキュリティ識別子。
eventWORDinRTS オブジェクトから送信されたシステムイベント
eventdataSYSTEM_EVENT_DATAinシステムイベント event に関する情報を含む SYSTEM_EVENT_DATA 構造体。

戻り値

戻り値の説明については、Classes and Interfaces - Ink Analysis を参照してください。

解説(Remarks)

システムイベントが処理されるとき、RealTimeStylus Class オブジェクトは、特定のウィンドウハンドル上の特定のウィンドウ入力矩形内でリアルタイムのスタイラスイベントを提供します。

イベントでどのパケットプロパティが送信されるかを判断するには、IRealTimeStylus::GetDesiredPacketDescription Method メソッドを使用します。

vtbl 15 HRESULT TabletAdded(IRealTimeStylus* piRtsSrc, IInkTablet* piTablet)

ITablet オブジェクトがシステムに接続されたことを、実装側のプラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class オブジェクト。
piTabletIInkTablet*inoptional追加されたタブレットオブジェクト。

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

このメソッドは、RealTimeStylus Class オブジェクトが有効か無効かにかかわらず、RealTimeStylus Class オブジェクトによって呼び出されます。

vtbl 16 HRESULT TabletRemoved(IRealTimeStylus* piRtsSrc, INT iTabletIndex)

ITablet オブジェクトがシステムから取り外されたことを、実装側のプラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class (RTS) オブジェクト。
iTabletIndexINTinタブレットのインデックス。

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

このメソッドは、RTS オブジェクトが有効か無効かにかかわらず、RealTimeStylus Class オブジェクトによって呼び出されます。

vtbl 17 HRESULT Error(IRealTimeStylus* piRtsSrc, IStylusPlugin* piPlugin, RealTimeStylusDataInterest dataInterest, HRESULT hrErrorCode, INT_PTR* lptrKey)

このプラグイン、または IStylusAsyncPlugin もしくは IStylusSyncPlugin のコレクション内にある先行するプラグインのいずれかが例外をスローしたことを、実装側のオブジェクトに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class (RTS) オブジェクト。
piPluginIStylusPlugin*inoptional通知を送信した IStylusPlugin オブジェクト。
dataInterestRealTimeStylusDataInterestinエラーを発生させた IStylusPlugin メソッドの識別子。
hrErrorCodeHRESULTin発生したエラーの HRESULT コード。
lptrKeyINT_PTR*inoutシステムが内部的に使用します。

戻り値

戻り値の説明については、Classes and Interfaces - Ink Analysis を参照してください。

解説(Remarks)

このメソッドは、RTS オブジェクトが例外をキャッチしたときに呼び出されます。

次の C++ の例では、The TRACE Macro を使用して、メッセージとエラーコードをデバッグウィンドウに出力する IStylusPlugin::Error Method メソッドを実装しています。

STDMETHODIMP CPacketModifier::Error( 
            /* [in] */ IRealTimeStylus *piRtsSrc,
            /* [in] */ IStylusPlugin *piPlugin,
            /* [in] */ RealTimeStylusDataInterest dataInterest,
            /* [in] */ HRESULT hrErrorCode,
            /* [out][in] */ LONG_PTR *lptrKey)
{
    CString strError;
    strError.Format(L"An error occurred. Error code: %d", hrErrorCode);
    TRACE(strError);
    return S_OK;
}
vtbl 18 HRESULT UpdateMapping(IRealTimeStylus* piRtsSrc)

dpi や向きなどの表示プロパティが変更されたことを、プラグインに通知します。

piRtsSrcIRealTimeStylus*inoptional通知を送信した RealTimeStylus Class オブジェクト。

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

このメソッドは、dpi や向きなどの表示プロパティが変更されたときに呼び出されます。変更に関する詳細情報を取得するには、IRealTimeStylus::GetAllTabletContextIds Method メソッドを呼び出します。

IStylusPlugin::UpdateMapping Method メソッドは、タブレットの表示プロパティが変更されたタイミングをアプリケーションが判断するための仕組みを提供します。このメソッドは WM_DISPLAYCHANGE メッセージ時に呼び出されます。

vtbl 19 HRESULT DataInterest(RealTimeStylusDataInterest* pDataInterest)

プラグインが通知を受け取る対象のイベントを取得します。

pDataInterestRealTimeStylusDataInterest*outプラグインが通知を受け取る対象のイベントを示すビットマスク。

戻り値

戻り値の説明については、RealTimeStylus Classes and Interfaces を参照してください。

解説(Remarks)

既定値は RTSDI_None です。

RealTimeStylusDataInterest Enumeration 列挙体のビットマスクは、プラグインが有効または無効になるたびに取得されます。プラグインの DataInterest マスクは、そのプラグインがプラグインコレクションに追加されたときに RealTimeStylus Class オブジェクトによって照会されます。

次の C++ の例では、IStylusPlugin::StylusDown MethodIStylusPlugin::Packets MethodIStylusPlugin::StylusUp MethodIStylusPlugin::StylusInRange Method、および IStylusPlugin::Error Method の通知を受け取るようにプラグインを設定する IStylusPlugin::DataInterest Method メソッドを実装しています。

STDMETHODIMP CPacketModifier::DataInterest( 
        /* [retval][out] */ RealTimeStylusDataInterest *pDataInterest)
{
    *pDataInterest = (RealTimeStylusDataInterest)(RTSDI_StylusDown | RTSDI_Packets | 
                                                  RTSDI_StylusUp | RTSDI_StylusInRange | 
                                                  RTSDI_Error);
    return S_OK;
}
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

HSP用 COM定義

#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"

出力引数:
#define global IID_IStylusPlugin "{A81436D8-4757-4FD1-A185-133F97C6C545}"
#usecom global IStylusPlugin IID_IStylusPlugin "{}"
#comfunc global IStylusPlugin_RealTimeStylusEnabled   3 sptr,int,var
#comfunc global IStylusPlugin_RealTimeStylusDisabled  4 sptr,int,var
#comfunc global IStylusPlugin_StylusInRange           5 sptr,int,int
#comfunc global IStylusPlugin_StylusOutOfRange        6 sptr,int,int
#comfunc global IStylusPlugin_StylusDown              7 sptr,var,int,var,var
#comfunc global IStylusPlugin_StylusUp                8 sptr,var,int,var,var
#comfunc global IStylusPlugin_StylusButtonDown        9 sptr,int,var,var
#comfunc global IStylusPlugin_StylusButtonUp          10 sptr,int,var,var
#comfunc global IStylusPlugin_InAirPackets            11 sptr,var,int,int,var,var,var
#comfunc global IStylusPlugin_Packets                 12 sptr,var,int,int,var,var,var
#comfunc global IStylusPlugin_CustomStylusDataAdded   13 sptr,var,int,var
#comfunc global IStylusPlugin_SystemEvent             14 sptr,int,int,int,int
#comfunc global IStylusPlugin_TabletAdded             15 sptr,sptr
#comfunc global IStylusPlugin_TabletRemoved           16 sptr,int
#comfunc global IStylusPlugin_Error                   17 sptr,sptr,int,int,var
#comfunc global IStylusPlugin_UpdateMapping           18 sptr
#comfunc global IStylusPlugin_DataInterest            19 var
; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。
; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。
; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。
; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。