デバイスがデジタイザー入力に対応しているかどうかを調べる

またまた Windows デスクトップ (WPF) のお話です。

先日の めとべや東京勉強会 にて、デスクトップ アプリのタッチ エクスペリエンス的な話を少しだけさせて頂きましたが、タッチ デバイスでの操作のためにタッチ向けの UI を用意するのが理想です (Office のタッチ モードのようなやつ)。

そこで、実行中のデバイスがタッチ デバイスかどうかを調べたい場合があります。タッチ デバイスであれば、それ専用の UI に切り替える、といったことができたり。


デスクトップ アプリの場合は user32.dll の GetSystemMetrics 関数 で、引数に SM_DIGITIZER を指定すると取得できます。この関数の .NET ラッパーである SystemParameters クラス から取ってこられないものかと期待したのですが、現時点では SM_DIGITIZER にマップされるプロパティは提供されていないようです。

ちなみにストア アプリの場合は、TouchCapabilities クラス楽に取得 できるようなのですが、生憎デスクトップからは使用できない API ですのでこの方法も使えず。

つまり… P/Invoke です!
これ以外の取得方法をご存じの方いらっしゃいましたら教えて頂きたく。。。

というわけで、GetSystemMetrics 関数を C# から使用するためのコードを以下のように記述します。
SM_* 定数は他にもたくさんありますが、今回はこの 2 つしか使用しません。

MSDN より抜粋。

入力デジタイザーの機能を照会するには、GetSystemMetrics 関数を使用して、SM_DIGITIZER の nIndex 値を渡します。GetSystemMetrics は、デバイスの準備ができているかどうか、デバイスがペンまたはタッチをサポートしているかどうか、入力デバイスが統合デバイスと外付けデバイスのどちらであるか、およびデバイスが複数入力 (Windows タッチ) をサポートしているかどうかを示すビット フィールドを返します。

関数の戻り値としてデバイスのデジタイザー対応状況を表すビットフィールドを得られます。そこで、次のような列挙型を定義しました。

これらを利用し、以下のような Digitizer クラスを用意します。

GetDigitizer メソッドで、Digitizer クラスのインスタンスを生成すると共にデジタイザー対応状況を照会する感じ。nIndex に SM_DIGITIZER を指定してデジタイザーの対応状況を取得し、対応していれば更に SM_MAXIMUMTOUCHES を指定してタッチの点数を取得しています。

こんな感じで使えます。べんり! (熱い自画自賛)

なお、GetSystemMetrics 関数で SM_DIGITIZER と SM_MAXIMUMTOUCHES がサポートされているのは、Windows 7 または Windows Server 2008 R2 以降となります。それ以前の古の OS でこの API を叩いても 0 (NotSupported) しか返ってきませんのでご注意ください。当然 Windows 8 ではちゃんと動きました。

上記コードをコピペすればすぐにチェックできるようになると思いますが、WPF で サンプル アプリ も作りました (GitHub で公開済み)。

以下は、タッチ デバイスのないデスクトップ PC で実行したときのもの。 SS130710012903KD

そして、以下がタッチ デバイス (Acer ICONIA W7) で実行したときのもの。 SS130710012740KD  
10 点タッチの情報がしっかり取得できています。SS130710012923KD


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です