キーボードの作り方(1) で予告したとおり、リモートキーボードの SIP 版 NetKeySip を作ってみました。
PocketPC の入力パネル (SIP) として組み込みます。 実際に汎用の入力パネルとして機能します。 同時に SIP が開いている状態で リモートキーの入力を受け付けます。
キーボード送信側 WindowsPC, H/PC など ppckeyClient |
LAN ────→ シリアル 赤外線 |
キーボード受信側 PocketPC 2002/2003 NetKeySip |
例えば WindowsPC (Win2000/XP) や他の H/PC, PocketPC 等で ppckeyClient を起動し、 キー入力するとそのまま NetKeySip の入力になります。 コネクション動作が不要で、同じ LAN 上にある場合相手を指定するだけで キー入力できます。 またはシリアルケーブルや赤外線でも同じように キー入力入力することができます。
ただ PocketPC 2003 では NetKeySip は動くものの、ppckeyClient は きちんと動作しないようです。同じように WindowsCE 4 ( .NET ) 系の H/PC でも動作しないかもしれません。
入力パネルからシステム側に、押したキーを通知する手段は二通りあります。 仮想キーコードを直接渡す方法と、 仮想キーコードに加えてキーが押されたときに発する文字そのものを 渡すやり方です。
IIMCallback::SendVirtualKey( VKey, dwFlags );
IIMCallback::SendCharEvent( VKey, uKeyFlags, uChars, puShift, puChars );
仮想キーコードは物理的なキー1つ1つに割り振られた識別名で、 実際に押されたときにどの文字になるのかはまた別ものです。 なので日本語配列のキーボードを作ったり、 手書き認識などさまざまな文字入力手段を実装する場合は 文字コードを直接渡した方が便利です。
文字コードで送る場合でも、一緒に仮想キーコードを渡す必要があります。 これは、キー自体を仮想キーコードで識別するアプリケーションに対応するためです。 実際の文字入力には不要なので、無くてもたいていの場合困りません。
実は PocketPC 標準の入力パネル「ローマ字/かな」がこの値を省略しており、 「英数+半角」状態では 文字キーがすべて同じ仮想キーコードを返してきます。
以前 こちら のページに書きましたが、 PocketPC 用 Terminal Services Client のログイン時にキー入力できなかったのはこれが原因のようです。 かな モードにすると入力できるようになるのは、 その場合だけ仮想キーコードがきちんと実装されているのでしょう。
ちなみに ppckeyClient も 仮想キーコードを必要とします。 今回作成した NetKeySip は Terminal Services Client で使えるよう キーコードの再現と互換性を重視してみました。
なお日本語版 PocketPC 2002/2003 には Terminal Services Client
が付属していませんが、
2002 にアップグレードした iPAQ 用に
Microsoft のこちらからダウンロードできるようです。
Pocket PC Downloads - Terminal Services
http://www.microsoft.com/technet/prodtechnol/wce/downloads/ppctsrv.mspx
PocketPC 用プログラム開発環境は OS のバージョンがあがり SDK の種類も増えて 少々複雑になりました。
WindowsCE の開発に使用する eMbedded Visual Tools/eMbedded Visual C++ は、
Microsoft のサイトからダウンロードすることができます。
Mobile Device - Download
http://www.microsoft.com/japan/windowsmobile/downloads/default.asp
ダウンロードできるこれらのツールは、 Visual C++ 6.0 と使い勝手やインターフェースが全く同じです。 PC の開発に慣れている方ならすぐ使いこなせると思います。
ただし最新の eMbedded Visual C++ 4.0 は WindowsCE 3.0 以前の SDK に 対応していないので、PocketPC 2002 用の バイナリも作る場合は古い eMbedded Visual Tools 3.0 も必要になります。
eMbedded Visual Tools 3.0
WindowsCE 2.11 H/PC Pro 3.0
WindowsCE 3.0 H/PC 2000
WindowsCE 3.0 PocketPC(2000), PocketPC 2002 など
eMbedded Visual C++ 4.0 (sp2/3)
WindowsCE 4.2 PocketPC 2003/2003 SE など
PC 用に Visual Studio も入れてあるため、互換性を保ちながら開発するには 3つツールが混在することになってしまいます。
ちなみに SDK には PocketPC はエミュレータがついてくるので、 ターゲット機器が無くても動作確認できるのは便利です。 とはいっても ARM 用バイナリが動くわけではありません。 PC 上で動作させるため CPU Type が x86 になります。 x86 用のバイナリは普段作成していないしまず見当たらないので、 エミュレータにツールをインストールしたり 他のソフトとの相性を調べたりするのは厄介です。
WindowsCE 用のインストール用パッケージに使われる .CAB ファイルは、 Cabwiz というコマンドを使って作成します。 あらかじめ必要なファイルや転送先などのルールを .ini ファイルに記述しておけば、指定した CAB ファイルを生成してくれます。 CPU タイプ別、環境別などの条件を一緒に記述しておくこともできます。 この辺は、オンラインヘルプで Cabwiz を検索するといろいろとでてきます。
SIP の場合、インストールと同時にレジストリへの DLL 登録が必要になります。 もともと DLL の関数 DllRegisterServer() でレジストリ登録を行っているので、 インストール時に呼び出してもらう必要があります。 これは DefaultInstall へ CESelfRegister を追加することで実現できるようです。
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/setcommstate.asp
[DefaultInstall.ARM]
CopyFiles = Files.Common, Files.ARM
CESelfRegister = netkeysip.dll
アンインストール時も同様に DllUnregisterServer() が呼び出されるため、 こちらでは不要になったレジストリエントリを削除しておきます。 SIP のサンプル dvoraksip は DllUnregisterServer() の記述が無いので、 自分で追加しておく必要があります。
DLL ファイルの転送先は \Windows ですが、2002 では動くものの PocketPC 2003 でファイルが転送されない現象に悩みました。 コピー時にフラグ 0x80000000 を記述することでコピhttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/setcommstate.aspーされるようになりました。
[Files.ARM] netkeysip.dll,,,0x80000000
設定の「個人用」から「入力」を開くと 各 SIP のオプション画面を開くことができます。 このオプション画面選択時は IInputMethod の UserOptionsDlg() が呼び出されます。
注意点は、オプション画面が呼び出されたときのインスタンスは 実際にキー入力している SIP 本体と別であることです。 そのため実際に設定した内容は、レジストリなどを使って 受け渡しする必要があります。
NetKeySip をシリアル対応にするために、 久しぶりに RS-232C ケーブルなどを触りました。 買っておいた h3630 用シリアルケーブルが役に立ちました。
Windows ではシリアルデバイスに COM1: 〜 などの名前がつけられており、
ファイルとして Open して読み書きするだけで通信できます。
通信速度などの細かい条件は
SetCommState()
で設定できます。同様に Comm 系の API を使って
Timeout 条件や現在のエラー状況取得など細かい操作もできるようです。
赤外線ポートも同じように、 IrCOMM によってシリアルポートの一種として扱うことができます。 iPAQ h3630 では赤外線ポートが COM2: に割り当てられていました。
初期状態では、システムが赤外線ポートを占有しています。 設定画面の「接続」タブから「ビーム」を選び「ビームを受信する」 部分のチェックをあらかじめはずしておく必要があります。
赤外線ポートを使って通信する場合もシリアルケーブルと全く同じ条件で 実行できます。 ただ通信途中に電源を切ってしまうと、 電源を入れてサスペンドから復帰しても通信状態が回復しません。 せめて API がエラーを返してくれれば再接続できるのですが、 なぜかエラーも返ってこないようです。
外部キーボードとして使う場合はできる限りコネクションレスにしたいし、 こまめに電源を ON/OFF しながら使うであろうことが考えられます。 なので電源 OFF を監視して、一度電源が切れたと思われるときは 自分から再接続しなおすようにします。
ところが今度は、電源 OFF の監視方法がわかりません。 適当にイベントを監視して、 ウィンドウに初期化がかかったら再接続するようにしてみました。 PocketPC 2003 では まだきちんと再接続できていません。残念ながら SIP の選択しなおしなど、自分でリセットする必要があります。 PocketPC 2002 の ppckeyClient ではうまくいっているようです。
[メニューに戻る] | [ZAURUS総合] | [Direct3D] | [Ko-Window] | [Win32] | [WinCE] | [携帯電話] | [その他] |
フルパワー全開 | Hyperでんち |