次の方法で共有


キーボードおよびマウス HID クライアント ドライバーの開発

この記事は、キーボードおよびマウス HID クライアント用のドライバーを作成する開発者向けです。 マウスまたはキーボードを修正する場合は、次を参照してください。

この記事では、キーボードおよびマウス HID クライアント ドライバーについて説明します。 キーボードとマウスは、HID 使用法テーブルで標準化され、Windows オペレーティング システムに実装された HID クライアントの最初のセットを表します。

キーボードおよびマウス HID クライアント ドライバーは、HID マッパー ドライバーの形式で実装されます。 HID マッパー ドライバーは、非 HID クラス ドライバーと HID クラス ドライバー間の I/O 要求の双方向インターフェイスを提供するカーネル モード フィルター ドライバーです。 マッパー ドライバーは、一方の I/O 要求とデータ プロトコルを他方にマップします。

Windows には、HID キーボードと HID マウス デバイス用のシステム提供の HID マッパー ドライバーが用意されています。

アーキテクチャと概要

次の図は、USB キーボード、マウス、タッチパッドデバイス用のシステム提供のドライバー スタックを示しています。

キーボードとマウスの HID クラス マッパー ドライバーを示すキーボードとマウス ドライバー スタックの図。

この図は、次のコンポーネントを示しています。

  • KBDHID.sys: キーボード用 HID クライアント マッパー ドライバー。 HID 使用法をスキャン コードに変換して、既存のキーボード クラス ドライバーとインターフェイスします。
  • MOUHID.sys: マウス/タッチパッド用の HID クライアント マッパー ドライバー。 HID 使用法をマウス コマンド (X/Y、ボタン、ホイール) に変換して、既存のキーボード クラス ドライバーとインターフェイスします。
  • KBDCLASS.sys: キーボード クラス ドライバー は、システム上のすべてのキーボードとキーパッドに安全な方法で機能を提供します。
  • MOUCLASS.sys: マウス クラス ドライバー は、システム上のすべてのマウスとタッチパッドの機能を提供します。 ドライバーは、絶対および相対ポインティング デバイスの両方をサポートしています。 MOUCLASS.sys タッチスクリーン用の Windows ドライバーではありません。
  • HIDCLASS.sys: HID クラス ドライバー。 HID クラス ドライバーは、KBDHID.sys と MOUHID.sys HID クライアントとさまざまなトランスポート (USB、Bluetoothなど) の間の接着です。

システムは、次のようにドライバー スタックをビルドします。

  • トランスポート スタックは、接続されている各 HID デバイスの物理デバイス オブジェクト (PDO) を作成し、適切な HID トランスポート ドライバーを読み込みます。その後、HID クラス ドライバーが読み込まれます。
  • HID クラス ドライバーは、キーボードまたはマウス のトップレベル コレクション (TLC) ごとに PDO を作成します。 複雑な HID デバイス (複数の TLC) は、HID クラス ドライバーによって作成された複数の PDO として公開されます。 たとえば、マウスが統合されたキーボードには、標準のキーボード コントロール用に 1 つのコレクションがあり、マウス用に別のコレクションがある場合があります。
  • キーボードまたはマウス HID クライアント マッパー ドライバーは、適切な機能デバイス オブジェクト (FDO) に読み込まれます。
  • HID マッパー ドライバーは、キーボードとマウスの FDO を作成し、クラス ドライバーを読み込みます。

重要な注意事項

  • サポートされている HID 使用法と最上位のコレクションに準拠しているキーボードとマウスには、ベンダー ドライバーは必要ありません。
  • ベンダーは、必要に応じて、これらの特定の TLC の機能を変更または強化する HID スタックのフィルター ドライバーを提供します。
  • ベンダーは、HID クライアントとデバイスの間で独自のデータを交換するために、個別のベンダー固有の TLC を作成する必要があります。 重要でない限り、フィルター ドライバーの使用は避けてください。
  • システムは、その排他的な使用のためにすべてのキーボードとマウスのコレクションを開きます。
  • システムは、キーボードの無効化/有効化を禁止します。
  • システムは滑らかなスクロール機能の水平/垂直車輪のサポートを提供する。

ドライバーのガイダンス

Microsoft では、独立系ハードウェア ベンダー (IHV) がドライバーを作成するためのこのガイダンスを提供しています。

  1. ドライバー開発者は、フィルター ドライバーまたは新しい HID クライアント ドライバーの形式でドライバーを追加できます。

    1. ドライバー開発者は、付加機能を持つドライバーが、フィルタードライバーとして動作し、入力スタック内の既存の Windows HID ドライバーを置き換えない(またはその代わりに使用されない)ことを確保する必要があります。

      • フィルター ドライバーは、次のシナリオで許可されます。
        • kbdhid/mouhid への上位フィルターとして
        • kbdclass/mouclass の上位フィルターとして
      • HIDCLASS と HID トランスポート ミニドライバーの間にフィルターとしてフィルタードライバーを使用することは推奨されていません。
    2. 関数ドライバー: ベンダーは、(フィルター ドライバーではなく) 関数ドライバーを作成することもできますが、ベンダー固有の HID PDO (必要に応じてユーザー モード サービスを使用) に対してのみ作成できます。

      関数ドライバーは、次のシナリオで使用できます。

      • 特定のベンダーのハードウェアにのみ読み込む
    3. トランスポート ドライバー: Windows チームは、書き込みと保守が複雑な HID トランスポート ミニドライバーをさらに作成することはお勧めしません。 パートナーが新しい HID トランスポート ミニドライバー (特に SoC システム) を作成している場合は、理由を理解し、ドライバーが正しく開発されていることを確認するために、詳細なアーキテクチャ レビューをお勧めします。

  2. ドライバー開発者は、ドライバー フレームワーク (KMDF または UMDF) を使用し、フィルター ドライバーに WDM に依存しないようにする必要があります。

  3. ドライバー開発者は、サービスとドライバー スタック間のカーネル ユーザー遷移の数を減らす必要があります。

  4. ドライバー開発者は、キーボードとタッチパッドの両方の機能 (エンド ユーザー (デバイス マネージャー) または PC の製造元によって調整可能) を介してシステムをスリープ解除する機能を確保する必要があります。 SoC システムに加えて、これらのデバイスは、システムが動作している S0 状態にある間に、低電力状態から復帰できる必要があります。

  5. ドライバー開発者は、ハードウェアが効率的に電源管理されていることを確認する必要があります。

    • デバイスがアイドル状態になると、デバイスは最小の電源状態になることがあります。
    • システムが低電力状態 (スタンバイ (S3) やコネクト スタンバイなど) の場合、デバイスは最も低い電力状態になります。

キーボード レイアウト

キーボード レイアウトには、Microsoft Windows 2000 以降のバージョンのキーボードの入力特性が完全に記述されています。 たとえば、キーボード レイアウトでは、言語、キーボードの種類とバージョン、修飾子、スキャン コードなどを指定します。

キーボード レイアウトの詳細については、次のリソースを参照してください。

  • キーボード レイアウトに関する一般的な情報を文書化する Windows Driver Development Kit (DDK) のキーボード ヘッダー ファイル kdb.h。
  • キーボード レイアウトのサンプル。

特定のキーボードのレイアウトを視覚化するには、「 Windows キーボード レイアウト」を参照してください。

キーボード レイアウトの詳細については、「コントロール パネル\Clock、Language、Region\Language」を参照してください。

マウスでサポートされているボタンとホイール

次の一覧は、Windows でサポートされているマウス機能を示しています。

  • ボタン 1 から 5
  • 垂直スクロール ホイール
  • 水平スクロール ホイール
  • スムーズスクロールホイールサポート(水平および垂直)

PS/2 マウスでボタン 4 ~ 5 とホイールをアクティブ化する

Windows で新しい 4 ボタンと 5 つのボタンとホイール モードをアクティブ化するために使用されるメソッドは、IntelliMouse 互換マウスで 3 番目のボタンとホイールをアクティブ化するために使用されるメソッドの拡張です。

  • マウスを 3 ボタン ホイール モードに設定するには、レポートレートを 1 秒あたり 200 レポート、1 秒あたり 100 レポート、1 秒あたり 80 レポートに設定します。 次に、マウスから ID を読み取る。 このシーケンスが完了すると、マウスは 3 の ID を報告する必要があります。

  • その後、レポートレートを1秒あたり200レポートに設定し、次に再び1秒あたり200レポートに設定し、その後1秒あたり80レポートに設定することで、マウスを5ボタンホイールモードにします。 次に、マウスから ID を読み取る。 シーケンスが完了すると、5 ボタン ホイール マウスは ID 4 を報告する必要があります (IntelliMouse 互換の 3 ボタン ホイール マウスでは ID が 3 のまま報告されます)。

この方法は、HIDマウスではなくPS/2マウスにのみ適用できる。 HID マウスは、レポート記述子で正確な使用状況を報告する必要があります。

標準 PS/2 互換マウス データ パケット形式 (2 つのボタン)

バイト D7 D6 D5 D4 D3 D2 D1 D0 コメント
1 Yover Xover ワイサイン Xsign タグ エム R L X/Y オーバーフローと記号、ボタン
2 X7 X6 X5 X4 X3 X2 X1 X0 Xバイトのデータ
3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 Y データ バイト数

Windows マウス ドライバーはオーバーフロー ビットをチェックしません。 オーバーフローがある場合、マウスは最大符号付き変位値を送信する必要があります。

標準 PS/2 互換マウス データ パケット形式 (3 つのボタン + 垂直ホイール)

バイト D7 D6 D5 D4 D3 D2 D1 D0 コメント
1 0 0 ワイサイン Xsign 1 エム R L X/Y 記号と R/L/M ボタン
2 X7 X6 X5 X4 X3 X2 X1 X0 Xバイトのデータ
3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 Y データバイト
4 Z7 Z6 Z5 Z4 Z3 Z2 Z1 Z0 Z/wheel データ バイト

標準 PS/2 互換マウス データ パケット形式 (5 つのボタン + 垂直ホイール)

バイト D7 D6 D5 D4 D3 D2 D1 D0 コメント
1 0 0 ワイサイン Xsign 1 エム R L X/Y 記号と R/L/M ボタン
2 X7 X6 X5 X4 X3 X2 X1 X0 Xバイトのデータ
3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 Y データ バイト
4 0 0 B5 B4 Z3 Z2 Z1 Z0 Z/ホイールのデータとボタン 4 および 5

Von Bedeutung

5 ボタン ホイール マウスの Z/ホイール データは、IntelliMouse 互換の 3 ボタン ホイール モードで使用される 8 ビットではなく、4 ビットに縮小されます。 この削減は、ホイールが通常、特定の割り込み期間中に +7/-8 の範囲を超える値を生成できないという事実によって可能になります。 Windows マウス ドライバーは、マウスが 5 ボタン ホイールモードのときに 4 つの Z/ホイールデータビットの符号拡張を行います。 マウスが3ボタンホイールモードで動作するとき、彼らはZ/ホイールデータバイト全体を符号拡張します。

ボタン 4 と 5 は、WM_APPCOMMAND メッセージにマップされ、App_BackとApp_Forwardに対応します。

ベンダー ドライバーを必要としないデバイス

ベンダー ドライバーは、次のデバイスでは必要ありません。

  • HID Standard に準拠しているデバイス。
  • システム提供の非 HIDClass ドライバーによって動作するキーボード、マウス、またはゲーム ポート デバイス。

Kbfiltr サンプル

Kbfiltr は、キーボード デバイス用のシステム クラス ドライバーである Kbdclass と、PS/2 スタイル キーボードのファンクション ドライバーである I8042prt と共に使用されます。 Kbfiltr では、I/O 要求をフィルター処理する方法と、Kbdclass と I8042prt の操作を変更するコールバック ルーチンを追加する方法を示します。

Kbfiltr 操作の詳細については、以下を参照してください。

Kbfiltr IO 制御コード

Kbfiltr では、次の IOCTL が使用されます。

IOCTL_INTERNAL_I8042_HOOK_KEYBOARD

IOCTL_INTERNAL_I8042_HOOK_KEYBOARD要求:

  • I8042prt キーボード初期化ルーチンに初期化コールバック ルーチンを追加します。
  • I8042prt キーボード ISR に ISR コールバック ルーチンを追加します。

初期化コールバックと ISR コールバックは省略可能であり、PS/2 スタイルのキーボード デバイスの上位レベルのフィルター ドライバーによって提供されます。

I8042prt は 、IOCTL_INTERNAL_KEYBOARD_CONNECT 要求を受信すると、同期 IOCTL_INTERNAL_I8042_HOOK_KEYBOARD 要求をキーボード デバイス スタックの先頭に送信します。

Kbfiltr がフック キーボード要求を受け取った後、Kbfiltr は次のように要求をフィルター処理します。

  • Kbfiltr に渡される上位レベルの情報を保存します。これには、上位レベルのデバイス オブジェクトのコンテキスト、初期化コールバックへのポインター、ISR コールバックへのポインターが含まれます。
  • 上位レベルの情報を独自の情報に置き換えます。
  • I8042prt のコンテキストと、Kbfiltr ISR コールバックで使用できるコールバックへのポインターを保存します。

IOCTL_INTERNAL_KEYBOARD_CONNECT (内部キーボード接続)

IOCTL_INTERNAL_KEYBOARD_CONNECT要求は、Kbdclass サービスをキーボード デバイスに接続します。 Kbdclass は、キーボード デバイスを開く前に、この要求をキーボード デバイス スタックに送信します。

Kbfiltr がキーボード接続要求を受信した後、Kbfiltr は次のように接続要求をフィルター処理します。

  • Kbdclass によってフィルター ドライバーに渡される Kbdclass のCONNECT_DATA (Kbdclass) 構造体のコピーを保存します。
  • クラス ドライバーの接続情報を、独自の接続情報に置き換える。
  • IOCTL_INTERNAL_KEYBOARD_CONNECT要求をデバイス スタックの下に送信します。

要求が成功しなかった場合、Kbfiltr は適切なエラー状態で要求を完了します。

Kbfiltr には、Kbdclass クラス サービス コールバック ルーチンである KeyboardClassServiceCallback の操作補足できるフィルター サービス コールバック ルーチンのテンプレートが用意されています。 フィルター サービス コールバックは、デバイス入力バッファーからクラス データ キューに転送される入力データをフィルター処理できます。

IOCTL_INTERNAL_KEYBOARD_DISCONNECT

IOCTL_INTERNAL_KEYBOARD_DISCONNECT要求は、STATUS_NOT_IMPLEMENTEDの状態で完了します。 プラグ アンド プレイ マネージャーは、プラグ アンド プレイ キーボードを追加または削除できます。

他のすべてのデバイス制御要求の場合、Kbfiltr は現在の IRP スタックをスキップし、それ以上処理せずにデバイス スタックに要求を送信します。

Kbfiltr によって実装されるコールバック ルーチン

Kbfiltr は、次のコールバック ルーチンを実装します。

KbFilter_InitializationRoutine

PI8042_KEYBOARD_INITIALIZATION_ROUTINEを参照してください

キーボードの I8042prt の既定の初期化で十分な場合、 KbFilter_InitializationRoutine は必要ありません。

I8042prt は、キーボードを初期化するときに KbFilter_InitializationRoutine を呼び出します。 既定のキーボード初期化には、次の操作が含まれます。

  • キーボードをリセットする
  • 型指定レートと遅延を設定する
  • 発光ダイオード(LED)の設定
/*
Parameters
DeviceObject [in]
Pointer to the device object that is the context for this callback.

SynchFuncContext [in]
Pointer to the context for the routines pointed to by ReadPort and Writeport.

ReadPort [in]
Pointer to the system-supplied PI8042_SYNCH_READ_PORT callback that reads from the port.

WritePort [in]
Pointer to the system-supplied PI8042_SYNCH_WRITE_PORT callback that writes to the port.

TurnTranslationOn [out]
Specifies, if TRUE, to turn translation on. Otherwise, translation is turned off.

Return value
KbFilter_InitializationRoutine returns an appropriate NTSTATUS code.
*/

NTSTATUS KbFilter_InitializationRoutine(
  In  PDEVICE_OBJECT          DeviceObject,
  In  PVOID                   SynchFuncContext,
  In  PI8042_SYNCH_READ_PORT  ReadPort,
  In  PI8042_SYNCH_WRITE_PORT WritePort,
  Out PBOOLEAN                TurnTranslationOn
);

KbFilter_IsrHook

PI8042_KEYBOARD_ISRを参照してください。 I8042prt の既定の操作で十分な場合、このコールバックは必要ありません。

I8042prt キーボード ISR は、割り込みを検証してスキャン コードを読み取った後、 KbFilter_IsrHook を呼び出します。

KbFilter_IsrHook は、I8042prt キーボードの IRQL でカーネル モードで実行されます。

/*
Parameters
DeviceObject [in]
Pointer to the filter device object of the driver that supplies this callback.

CurrentInput [in]
Pointer to the input KEYBOARD_INPUT_DATA structure that is being constructed by the ISR.

CurrentOutput [in]
Pointer to an OUTPUT_PACKET structure that specifies the bytes that are being written to the hardware device.

StatusByte [in, out]
Specifies the status byte that is read from I/O port 60 when an interrupt occurs.

DataByte [in]
Specifies the data byte that is read from I/O port 64 when an interrupt occurs.

ContinueProcessing [out]
Specifies, if TRUE, to continue processing in the I8042prt keyboard ISR after this callback returns; otherwise, processing is not continued.

ScanState [in]
Pointer to a KEYBOARD_SCAN_STATE structure that specifies the keyboard scan state.

Return value
KbFilter_IsrHook returns TRUE if the interrupt service routine should continue; otherwise it returns FALSE.
*/

KbFilter_IsrHook KbFilter_IsrHook(
  In    PDEVICE_OBJECT       DeviceObject,
  In    PKEYBOARD_INPUT_DATA CurrentInput,
  In    POUTPUT_PACKET       CurrentOutput,
  Inout UCHAR                StatusByte,
  In    PUCHAR               DataByte,
  Out   PBOOLEAN             ContinueProcessing,
  In    PKEYBOARD_SCAN_STATE ScanState
);

KbFilter_ServiceCallback

PSERVICE_CALLBACK_ROUTINEを参照してください。

関数ドライバーの ISR ディスパッチ完了ルーチンは 、KbFilter_ServiceCallbackを呼び出し、キーボード クラス ドライバーの PSERVICE_CALLBACK_ROUTINEの実装を呼び出します。 ベンダーは、フィルター サービス コールバックを実装して、デバイスの入力バッファーからクラス データ キューに転送される入力データを変更できます。 たとえば、コールバックはデータを削除、変換、または挿入できます。

/*
Parameters
DeviceObject [in]
Pointer to the class device object.

InputDataStart [in]
Pointer to the first keyboard input data packet in the input data buffer of the port device.

InputDataEnd [in]
Pointer to the keyboard input data packet that immediately follows the last data packet in the input data buffer of the port device.

InputDataConsumed [in, out]
Pointer to the number of keyboard input data packets that are transferred by the routine.

Return value
None
*/

VOID KbFilter_ServiceCallback(
  In    PDEVICE_OBJECT       DeviceObject,
  In    PKEYBOARD_INPUT_DATA InputDataStart,
  In    PKEYBOARD_INPUT_DATA InputDataEnd,
  Inout PULONG               InputDataConsumed
);

Moufiltr サンプル

Moufiltr は、マウス デバイス用のシステム クラス ドライバーである Mouclass と連携します。 また、PS/2 スタイルのマウスのファンクション ドライバーである I8042prt でも動作します。 どちらのドライバーも Windows 2000 以降のバージョンで使用されます。 Moufiltr では、I/O 要求をフィルター処理し、Mouclass と I8042prt の操作を変更するコールバック ルーチンを追加する方法を示します。

Moufiltr 操作の詳細については、次のリソースを参照してください。

  • ntddmou.h WDK ヘッダー ファイル。

  • サンプルの Moufiltr ソース コード。

Moufiltr IO 制御コード

Moufiltr では、次の IOCTL が使用されます。

IOCTL_INTERNAL_I8042_HOOK_MOUSE

IOCTL_INTERNAL_I8042_HOOK_MOUSE要求は、I8042prt マウス ISR に ISR コールバック ルーチンを追加します。 ISR コールバックは省略可能であり、上位レベルのマウス フィルター ドライバーによって提供されます。

I8042prt は、IOCTL_INTERNAL_MOUSE_CONNECT 要求を受信した後にこの要求を送信します。 I8042prt は、同期 IOCTL_INTERNAL_I8042_HOOK_MOUSE 要求をマウス デバイス スタックの先頭に送信します。

Moufiltr はフック マウス要求を受け取った後、次のように要求をフィルター処理します。

  • Moufiltr に渡される上位レベルの情報を保存します。これには、上位レベルのデバイス オブジェクトのコンテキストと ISR コールバックへのポインターが含まれます。
  • 上位レベルの情報を独自の情報に置き換えます。
  • I8042prt のコンテキストと、Moufiltr ISR コールバックで使用できるコールバックへのポインターを保存します。

IOCTL_INTERNAL_MOUSE_CONNECT

IOCTL_INTERNAL_MOUSE_CONNECT要求は、マウス デバイスに Mouclass サービスを接続します。

IOCTL_INTERNAL_MOUSE_DISCONNECT (マウスの内部接続解除)

Moufiltr は、IOCTL_INTERNAL_MOUSE_DISCONNECT 要求を STATUS_NOT_IMPLEMENTED のエラーステータスとして改訂します。

その他のすべての要求について、Moufiltr は現在の IRP スタックをスキップし、追加の処理を行わずにデバイス スタックに要求を送信します。

Moufiltr コールバック ルーチン

MouFiltr は、次のコールバック ルーチンを実装します。

MouFilter_IsrHook

PI8042_MOUSE_ISRを参照してください。

/*
Parameters
DeviceObject
Pointer to the filter device object of the driver that supplies this callback.

CurrentInput
Pointer to the input MOUSE_INPUT_DATA structure being constructed by the ISR.

CurrentOutput
Pointer to the OUTPUT_PACKET structure that specifies the bytes being written to the hardware device.

StatusByte
Specifies a status byte that is read from I/O port 60 when the interrupt occurs.

DataByte
Specifies a data byte that is read from I/O port 64 when the interrupt occurs.

ContinueProcessing
Specifies, if TRUE, that the I8042prt mouse ISR continues processing after this callback returns. Otherwise, processing is not continued.

MouseState
Pointer to a MOUSE_STATE enumeration value, which identifies the state of mouse input.

ResetSubState
Pointer to MOUSE_RESET_SUBSTATE enumeration value, which identifies the mouse reset substate. See the Remarks section.

Return value
MouFilter_IsrHook returns TRUE if the interrupt service routine should continue; otherwise it returns FALSE.
*/

BOOLEAN MouFilter_IsrHook(
   PDEVICE_OBJECT        DeviceObject,
   PMOUSE_INPUT_DATA     CurrentInput,
   POUTPUT_PACKET        CurrentOutput,
   UCHAR                 StatusByte,
   PUCHAR                DataByte,
   PBOOLEAN              ContinueProcessing,
   PMOUSE_STATE          MouseState,
   PMOUSE_RESET_SUBSTATE ResetSubState
);

I8042prt の既定の操作で十分な場合、 MouFilter_IsrHook コールバックは必要ありません。

I8042prt マウス ISR は、割り込みを検証した後、MouFilter_IsrHook を呼び出します。

マウスをリセットするために、I8042prt は一連の操作サブステートを通過します。 MOUSE_RESET_SUBSTATE列挙値は、各サブ状態を識別します。 I8042prt がマウスをリセットする方法と、対応するマウス リセット サブ状態の詳細については、ntdd8042.h のMOUSE_RESET_SUBSTATEのドキュメントを参照してください。

MouFilter_IsrHook は、I8042prt マウス ISR の IRQL でカーネル モードで実行されます。

MouFilter_ServiceCallback

PSERVICE_CALLBACK_ROUTINEを参照してください

/*
Parameters
DeviceObject [in]
Pointer to the class device object.

InputDataStart [in]
Pointer to the first mouse input data packet in the input data buffer of the port device.

InputDataEnd [in]
Pointer to the mouse input data packet immediately following the last data packet in the port device's input data buffer.

InputDataConsumed [in, out]
Pointer to the number of mouse input data packets that are transferred by the routine.

Return value
None
*/

VOID MouFilter_ServiceCallback(
  _In_    PDEVICE_OBJECT    DeviceObject,
  _In_    PMOUSE_INPUT_DATA InputDataStart,
  _In_    PMOUSE_INPUT_DATA InputDataEnd,
  _Inout_ PULONG            InputDataConsumed
);

I8042prt の ISR DPC はMouFilter_ServiceCallbackを呼び出し、その後 MouseClassServiceCallback を呼び出します。 フィルター サービス コールバックは、デバイスの入力バッファーからクラス データ キューに転送される入力データを変更するように構成できます。 たとえば、コールバックはデータを削除、変換、または挿入できます。