Palm Programmer's Laboratory
Palm OS Programmer's Companion Volume I/4-3
4-3 フォーム、ウィンドウ、ダイアログ
フォームとは、アプリケーションのそれぞれのビューにおける GUI エリアです。例えばアドレス帳は、アドレス一覧ビュー、アドレス編集ビューなどを提供します。各アプリケーションは1つのフォームを持たなければなりませんし、ほとんどのアプリケーションは1つ以上持っています。実際にビューを作成するには、フォームにUI要素をいくつか追加する必要があります。UI要素のカタログからフォーム上にドラッグするか、フォームのフィールドの値として UI 要素の ID を入力します。
図 4.5 にフォームの例を示します。見てのとおり、典型的なフォームはスクリーンと同じ大きさになります。その他のフォームはモーダルダイアログで、幅はスクリーンと同じですが背がより低いものがあります。
図 4.5 フォーム
ウィンドウは描画領域を定義します。この領域はディスプレイかもしれませんし、メモリ上のバッファ(オフスクリーンウィンドウ)かもしれません。オフスクリーンウィンドウは、他の UI オブジェクトによって見えないようなディスプレイ上の領域を保存したり再表示したりするのに適しています。全てのフォームはウィンドウですが、全てのウィンドウがフォームなわけではありません。
ウィンドウオブジェクトは、フォームの外観と振舞いを決めるフォームオブジェクトの一部です。ウィンドウオブジェクトにはウィンドウビューの座標とクリッピング領域が含まれています。
フォームが開かれると、フォーム ID が保存された frmOpenEvent が発行されます。フォームが閉じられると winExitEvent が発行され、フォームが描画されるたびに winEnterEvent が発行されます。
以下のセクションでは、特殊なフォームについて説明します。
- アラートダイアログ
- プログレスダイアログ
- キーボードダイアログ
アラートダイアログ
アラートダイアログ(図 4.6 参照)を表示したり、質問に対するユーザーの回答を求めたいのであれば、アラートマネージャを使用します。アラートマネージャは以下の関数を定義します。
- FrmAlert
- FrmCustomAlert
図 4.6 アラートダイアログ
アラートを定義するリソース ID を与えると、アラートマネージャはモーダルダイアログを作成して表示します。ユーザーがダイアログ上のボタンの1つをタップすると、アラートマネージャはダイアログボックスを破棄してタップされたボタンの要素番号を呼出元に返却します。
システム定義のアラートには4種類があります。
- 質問
- 警告
- 通知
- エラー
アラートの種類によって、アラートウィンドウに表示されるアイコンと、アラート表示時に鳴らされるサウンドが決まります。
アラートマネージャが呼び出される際、以下の情報を含むアラートリソースが渡されます。
- アラートウィンドウのサイズと位置を示す矩形
- アラートのタイプ(質問、警告、通知、エラー)
- アラートが表示するメッセージとしての NULL 終端文字列
- 1つ以上のボタンに表示されるテキストラベル
プログレスダイアログ
通信セッションにおけるデータ転送など、アプリケーションが長時間に及ぶ処理を行う場合、ユーザーに処理状況を通知するプログレスダイアログの表示を検討して下さい。プログレスマネージャはプログレスダイアログを表示するためのメカニズムを提供します。
PrgStartDialog をコールすることでプログレスダイアログを表示します。処理の進み具合に応じて、PrgUpdateDialog をコールしてユーザーのために新しい情報でダイアログを更新します。イベントループ内で PrgHandleEvent をコールし、PrgUpdateDialog によってイベントキューに追加されたプログレスダイアログ更新イベントを処理します。PrgHandleEvent 関数は、最新の進行状況を取得するためにユーザーが提供した textCallback 関数を使用してコールバックを行ないます。
長時間かかる処理であれば何であれ、必ずイベントループ内で処理を行ない、コールバック関数内では行なわないようにして下さい。つまり、EvtGetEvent をコールし、nilEvent を取得した場合に処理を行ないます。nilEvent を取得するたびにひとまとまりの処理を行ないますが、ペンタップなどの他のイベントに十分素早く対応できるよう、EvtGetEvent の呼び出しは頻繁( 0.5 秒ごとなど )に行うようにして下さい。
プログレスダイアログは、自動的にセンタリングとフォーマットされた数行のテキストを表示できます。また、進行中の処理を示すアイコンを指定することもできます。オプションとして、キャンセルボタンか OK ボタンを1つ表示することもできます。ボタンの種類はプログレスマネージャによって自動的ににコントロールされ、処理状況(エラーなし、エラー、ユーザーキャンセル)によって変更されます。
textCallback 関数
新しい情報でプログレスダイアログを更新したい場合、PrgUpdateDialog 関数をコールします。プログレスダイアログに表示する進行状況を取得するために、PrgHandleEvent は textCallback 関数をコールバックします。これは、PrgStartDialog をコールした時にユーザーが指定する関数です。
システムは textCallback 関数にパラメータとして、PrgCallbackData 構造体のポインタを1つ渡します。この構造体で渡される情報については、「Palm OS Programmer's API Reference 」 の“プログレスマネージャ”を参照して下さい。
textCallback 関数は Boolean 値を返します。PrgCallbackData 構造体に設定した値を使用してプログレスダイアログを更新する必要がある場合、true を返します。false を返却してもダイアログは更新されますが、デフォルトの状態メッセージが使用されます(false の返却は推奨されません)。
textCallback 関数では、更新の際にプログレスダイアログに表示したいテキスト文字列を textP バッファに設定します。文字列リソースのメッセージを探すのに stage フィールドの値を使用できます。ベースとなる文字列に message フィールドのテキストを連結したい場合もあるかもしれません。通常、message フィールドには電話番号やデバイス名、あるいはネットワーク識別名など、ユーザーの選択に依存する動的な情報が含まれています。
例えば、PrgUpdateDialog 関数が stage に1、messageP に電話番号文字列 "555-1212" を指定されて呼び出されたとします。stage の値に従って文字列リソースから "Dialing" を探し出し、それに電話番号を連結して textP バッファに設定する最終的なテキスト "Dialing 555-1212" を作成します。
さまざまなステージに対応するスタティックな文字列をリソースに保持することは、アプリケーションのローカライズを容易にします。さらに動的な情報は PrgUpdateDialog に渡すパラメータ messageP を介して渡すことができます。
- NOTE
- textCallback 関数は、PrgUpdateDialog関数に渡されたパラメータの値が前回と異なる場合にのみ呼び出されます。PrgUpdateDialog が2回呼び出された場合でも、パラメータがまったく同じであれば textCallback 関数が呼び出されるのは1回だけになります。
キーボードダイアログ
キーボードダイアログはユーザーがタップしてテキストフィールドに情報を入力するための画面上のキーボードです。テキストフィールドにカーソルがある状態で入力エリアの下隅にあるシルクスクリーンの文字列( "abc" か "123" )をタップすることでオンスクリーンキーボードを表示できます。キーボードダイアログは以下のような外観を持っています。
図 4.7 キーボードダイアログ
キーボードダイアログのテキストフィールドには、元のフィールドのテキストが全て含まれ、カーソルの位置も元のフィールドと同じになっています。ユーザーはただちに文字の入力や削除を行なえますし、上下にスクロールしてから挿入・削除をすることもできます。画面上のキーがタップされると、対応する文字がキーボードダイアログ上のテキストフィールドに挿入されます。
ユーザーがタップをすると、キーボードダイアログのコードはペンイベントをキャプチャして文字にマッピングし、keyDownEvent をポストします。キーボードダイアログのテキストフィールドはそれぞれの keyDownEvent を処理し、画面上に文字を表示してフィールドに関連づけられたメモリチャンクに文字を挿入します。キーボードダイアログは独自のイベントループを持っているため、アプリケーションはキーイベントを処理できません。キーイベントをキャプチャしたいのであれば、カスタムバージョンのオンスクリーンキーボードの作成を検討する必要があります。その概要については「カスタムキーボードレイアウトの作成」を参照して下さい。
キーボードのコードは元のフィールド上のテキスト文字列を編集します。それぞれのフィールドは、そのフィールドのテキスト文字列を含むメモリチャンクを指すテキストハンドルを保有しています。キーボードダイアログがオープンされると、元のフィールドとそのテキストハンドルの関連が切り離されます。テキストハンドルはキーボードダイアログのテキストフィールドと関連づけられ、ユーザー入力に従って編集されます。キーボードダイアログがクローズされると、テキストハンドルは再び元のフィールドに関連づけられます。
FldHandleEvent がフィールドのテキスト文字列を保有するメモリチャンクをどのように操作するかについての詳細は、「Palm OS Programmer's API Reference」 の 「9章 フィールド」 を参照して下さい。FldGetTextHandle 関数と FldSetText 関数のところで説明されています。
プログラムからキーボードダイアログを表示する。
ほとんどのアプリケーションでは、キーボードダイアログはユーザーの操作によって表示されます。しかし、時にはユーザーに対してオンスクリーンキーボードを介しての文字入力を強制したい場合もあるかもしれません。例えば、全ての Palm VII デバイスに同梱されるサービス有効化アプリケーションは、自動的にキーボードダイアログを表示します。Palm 社は、Graffiti の入力方法やキーボードダイアログを表示させる方法を知らない完全な Palm 初心者でも有効化アプリケーションを扱えなければならないという理由でこの選択をしました。キーボードダイアログを強制する他の理由としては、パスワードやアカウント番号を正確に入力させる場合などがあります。
プログラムからキーボードダイアログを表示するには、以下の関数のいずれかを使用します。
- SysKeyboardDialog
- SysKeyboardDialogV10
通常、SysKeyboardDialog だけを使用します。SysKeyboardDialogV10 は Palm OS 1.0 との互換性のためにあります。
関数のプロトタイプとそれらが使用する KeyboardType については、Keyboard.h を参照して下さい。Keyboard.h 内の他の関数については、システムが使用するものであり、Palm OS API には含まれていないことに注意して下さい。
キーボードレイアウト
キーボードダイアログは、それぞれレイアウトが定義済みの3つのビューを持っています。英文字、数字と句読点、およびラテン文字と付加記号です。デフォルトは英文字です。特定のレイアウトを表示するには、SysKeyboardDialog をコールして KeyboardType という名前の列挙値として定義されている以下の定数のいずれかを渡します。
表 4.4 KeyboardType の定数定義
定数 | 文字セット |
---|---|
kbdAlpha | 英語の文字セット |
kbdNumbersAndPunc | 数字とさまざまな句読記号を含むセット |
kbdAccent | ラテン文字と付加記号で構成される国際文字セット |
kbdDefault | kdbAlpha と同値であり、変更不可 |
カスタムキーボードレイアウトの作成
新しいキーボードレイアウトを追加したり、既存のレイアウトを変更することはできません。しかし、以下に概要を示す機能を実装するキーボードダイアログモジュールを独自に作成することができます。
まず、ユーザーが入力エリア内の "abc" や "123" をタップした際に生成される keyDownEvent をアプリケーションで横取りしなければなりません。そしてそれを処理するカスタムキーボードダイアログのロードルーチンを作成します。作成するキーボードのコードは以下のことをする必要があります。
- 対象フィールドのテキストハンドルを取得し、変数に保存する。これには FldGetTextHandle 関数を使用します。
- 対象フィールドと取得したテキストハンドルの関連を切り離します。FldSetTextHandle 関数か FldSetText 関数を使用、2番目の引数に NULL を指定します。
- キーボードダイアログのテキストフィールドに取得したテキストハンドルを関連づけます。
- 以下のことを行うキーボードイベントハンドラを設定します。
- 画面上のキーボード領域 ── これはキーボードのビットマップかもしれませんし、独立したプッシュボタンで構成されているかもしれません ── でのペンイベントをキャプチャします。
- ペンイベントを文字に対応付けます。
- keyDownEvent を作成し、イベントキューにポストします。キーボードダイアログのテキストフィールドはそれを自動的に処理してテキストチャンクに文字を追加します。
- ダイアログがクローズされたら、テキストハンドルとキーボードダイアログのフィールド間の関連を取り除き、テキストハンドルを元のフィールドに再び関連付けます。
最後に、もし複数のレイアウトが必要な場合、カスタムキーボードダイアログにはそれぞれのレイアウトをオープンするためのボタンが必要になります。
オフスクリーンウィンドウ
オフスクリーンウィンドウは、一般に2つの理由のうちいずれかのために使用されます。オフスクリーン描画( ダブルバッファリング、スムーズなアニメーション、ちらつき防止 )のためか、あるいはアプリケーションがグラフィックのキャプチャやインポートをできるようにするためです。
WinCreateOffscreenWindow はオフスクリーンウィンドウのためのビットマップをアロケートします。フォーマットに nativeFormat を指定しない限り、オフスクリーンウィンドウのビットマップは常に低解像度になります。これにより、低解像度ビットマップを想定しているアプリケーションや、ビットマップデータを直接操作するアプリケーションに対しても関数は期待どおりに動作します。WinCreateOffscreenWindow を nativeFormat を指定してコールする場合、オフスクリーンウィンドウのビットマップを直接操作してはなりません。Palm OS が作成するビットマップのフォーマットはリリースやデバイスごとに異なる可能性があり、さらに同じデバイスでもスクリーンの深度や互換モードによって異なる場合はあるからです。
ウィンドウの寸法を返すような関数 ── WinScreenMode や WinGetBounds、WinGetDrawWindowBounds など ── は、アクティブな座標系の文脈で座標を返すためにウィンドウのスケーリングファクタを使用します。これにより、ウィンドウが期待される寸法を持ち、それを構成するグラフィックがアプリケーションの期待する座標を持つことが確実になります。
WinCreateBitmapWindow を使えば、オフスクリーンウィンドウ用に高解像度ビットマップをアロケートできます。BmpCreate と BmpSetDensity を使って高解像度ビットマップを作成し、次に WinCreateBitmapWindow をコールしてウィンドウに関連付けます。