日別アーカイブ: 2007年11月17日

続 キーボードの作り方 / WindowsMobile (SIP)

DBZ でもペンタッチは可能でしたが、あくまで手書きメモ専用と割り切った
ものでした。PV-F1 はこれを一気にメインの入力手段へと変えてしまいます。

あまりに高価だった PV-F1 を普及帯へ押し上げたのが PI-ZAURUS です。
初代 PI-3000 はまだ電源スイッチが付いていたものの、PI-6000 など
次々登場する後継機種ではついに電源スイッチすら廃止されます。

液晶画面のタップだけで電源が入るので、本体にはタッチパネル兼液晶画面
しかない、ある意味究極の形となりました。

そんな中ハードボタンが注目を浴びるようになった、Palm 等ほかの
PDA の人気によるものです。

・スクロールキー+アプリキーなどハードウエアボタン搭載
・縦型(縦長)のスタイル

どちらも Zaurus が築いてきたスタイルとは正反対であったものの、
MI-P1 以降、代を重ねるごとにその影響は強くなります。

これ以後 PDA の進化の方向は、
ペンオペレーションへ一気に傾倒しすぎた反動か
それとも使いづらく神経を使う操作性からの反動か、
QWERTY キーまで搭載して完全にハードウエアキー全盛となります。
手書き文字認識もほとんど忘れられた存在となってしまいました。

そして手本は Palm から携帯電話へと代わります。

PocketPC は世代ごとに、ハードウエアキー等の標準が変化しています。
・ゲームパッドのような CASSIOPEIA スタイル
・センターカーソルキー+左右にアプリケーションボタンの iPAQ スタイル

そして WindowsMobile では、左右のソフトキーが追加されました。
モードや画面、アプリケーションごとに自由に機能を割り当てられる
ソフトキーの存在は携帯電話と同じものです。

カーソルキー+ソフトキーだけでほぼ全部の操作が可能で、旧 PocketPC
用に作られたアプリ以外はほぼペン操作無しに扱えるようになりました。

PDA の操作が徐々に携帯電話化していく中、突如再びタッチパネルの
時代が訪れました。

その第一段階は DS の登場です。PDA では使い古されたはずのペン
オペレーションが、ゲームでは斬新なものとして大きく脚光を浴びました。

そして iPhone & iPod touch の登場が大きな事件であったことは
いうまでもありません。

WindowsMobile にもソフトウエア入力パネル (SIP) があります。
QWERTY キーボードやら、携帯電話風のテンキーやら備えた端末が多数
出ていてすっかり邪魔者扱いされがちな SIP ですが、
ここであらためて注目してみました。

かつて SIP を作ったときの記録は下記の通りです。
キーボードの作り方(1)
キーボードの作り方(2)
キーボードの作り方(3)

● WindowsMobile の SIP

WindowsMobile でも SIP の基本構造は全く代わっていないようです。
Dvoraksip のサンプルもほとんど同じものでした。
基本的には新しい SDK で Build するだけでよく、修正点はそれほど
多くありません。

唯一違う点があるとすれば、画面解像度のバリエーションが大幅に
増えたことです。
PocketPC2002/2003 の時代は QVGA 240×320 解像度しかなく、
画面の縦横切り替えすらありませんでした。

QVGA 用に作った SIP をそのまま VGA 機種に組み込むと、RealVGA 化
していなくても等倍の解像度で表示されます。
非常に小さく、針の先でつつくようなこじんまりとしたパネルになって
しまいます。

ハイレゾに対応した座標系の補正や、表示するリソースの拡大は SIP 側の
プログラム側で対応しておく必要があるようです。

デバイスの画面解像度は下記の API で取得できます。

int width= GetSystemMetrics( SM_SXSCREEN );
int height= GetSystemMetrics( SM_SYSCREEN );

画面を回転させたときも、きちんと移転後の縦横サイズを受け取る
ことができます。この値から縦横の判断もできるようです。

この画面解像度を元に、表示リソースの拡大縮小変換、ペンタッチ座標の
スケール変換を行えば、きちんと意図した座標で表示可能となります。

● ハイレゾ対応方法

VGA 機種で SIP を表示してもパネルのサイズが 240×80 のまま表示
されます。ウィンドウ領域や描画サイズを拡大しても変わりません。
これはパネルエリアの親ウィンドウのサイズが固定されているからです。

この辺もいろいろ試しましたが、やはり自分でリサイズする必要がある
ようです。パネル選択時に呼ばれる IInputMethod2::Select() には
親ウィンドウが渡されます。

IInputMethod2::Select( HWND hwndSip )

このハンドルを元にパネル領域のサイズ変更が可能です。
例えば VGA に対応した 480x160dot 等に拡大することができます。
また

IInputMethod2::GetInfo( IMINFO* info )

でも正しいパネルサイズを返す必要があります。

IInputMethod2::ReceiveSipInfo( SIPINFO* psi )

こちらの ReceiveSipInfo() は特に変更する必要はありません。

画面回転時は画面の幅が広くなりますが、このときは指定したサイズを
元に勝手にセンタリングされるようです。
縦横に応じてサイズを可変にすれば、横画面でも左右端まで使った
大きなキーボードを作ることができます。

iPod touch のように、本格的に指で使いやすい SIP を作ることも
可能だと思います。

ちなみに WindowsMobile5.0 の SDK で作成しておけば、そのまま
WindowsMobile6.0 でも動作します。

● IME の制御

キーボードの作り方(1) でも書いていますが、日本語入力モードの
切り替えは基本的にキーストロークのシミュレートでできます。
[ALT]+[漢字] や [全/半] など。
より安全に切り替えたり、現在の状態を参照する場合は Imm 系 API
を使います。

下記のコードは em1key 等で使用しているものの抜粋で WindowsCE
専用です。未確定バッファがあるときは IME を CLOSE できないように
なっています。em1key ではフック内では使わずに、一旦 Window に
ポストして代わりに呼び出してもらっています。

enum {
    IMECTRL_OPEN  = (1<<0),
    IMECTRL_CLOSE = (1<<1),
};

// 0= QUERY, 1= OPEN, 2= CLOSE, 3= 切り替え
int ControlEngine::ImeControl( int mode )
{
    HIMC    himc= NULL;
    int     openstat= ImmGetOpenStatus( himc );
    if( openstat ){
        if( mode & IMECTRL_CLOSE ){
            int	size= ImmGetCompositionString( himc, GCS_COMPSTR, NULL, 0 );
            if( !size ){
                ImmSetOpenStatus( himc, FALSE );
            }
        }
    }else{
        if( mode & IMECTRL_OPEN ){
            ImmSetOpenStatus( himc, TRUE );
        }
    }
    return  openstat;
}

参考
歴代ザウルス
歴代ポケットPC
※ DBZ は SHARP の電子手帳 PA-9500 シリーズ