Palm Programmer's Laboratory
Palm OS Programmer's Companion Volume I/3-3
3-3 カスタムイベントの作成と処理
Palm OS はいくつもの標準イベントを定義しています。完全な一覧は eventsEnum を参照して下さい。最後の2つのエントリ ── firstUserEvent と lastUserEvent ── は、システムイベントではありません。これらは、アプリケーション定義の「カスタムイベント」を確保するための範囲を定義しています。
カスタムイベントはその他のイベントと同じように処理されます。EvtAddEventToQueue( ) や EvtAddUniqueEventToQueue( ) を使ってカスタムイベントをポストし、EvtGetEvent( ) をコールして受け取ります。ただし、Palm OS がイベントを処理する方法により、Palm OS の標準イベントキューにポストされたイベントは常にアプリケーションに届くとは限りません。詳細は「カスタムイベントと Palm OS イベントキュー」を参照して下さい。
カスタムイベントを作成するためには以下の作業が必要です。
- イベントタイプを決めます。firstUserEvent 〜 lastUserEvent の範囲の値でなければなりません。
- 「一般的な」イベント構造体を使うか、独自のイベント構造体を定義します。カスタムイベント構造体の最初から data 共用体までの部分(ただし data 共用体は含みません)はEventType 構造体と一致している必要があります。構造体の残りの部分はそのイベントに必要なデータを含むように定義します。ただし、オペレーティングシステムは全てのイベントが同一のサイズであると仮定していることに注意してください。そのため、作成するカスタムイベント構造体のサイズは Palm OS の EventType 構造体のそれと一致している必要があります。おそらく最も簡単な方法は、構造体のイベント固有データ部分を共用体として宣言し、そのメンバとして _GenericEventType 構造体を加えることです。
訳注:上のパラグラフの最後の文の原文は以下のとおりです。 Perhaps the easiest way to do this is to declare the event-specific data portion of your structure as an enum, and add a _GenericEventType structure to your enum: この文に2回登場する enum という単語は、union の誤りではないかと 考えられます。そうでないと意味が通りませんし、そうすることによって 下記サンプルコードととも符合します。訳出にあたっては union と読み かえてあります。
typedef struct { eventsEnum eType; Boolean penDown; UInt8 tapCount; Int16 screenX; Int16 screenY; union { struct _GenericEventType generic; // sets size of union struct { // define your event-specific data here // Must not exceed 16 bytes in length! } myEventData; } data; } MyCustomEventType;
- WARNING!
- イベント固有データのサイズは16バイトを越えてはなりません。
- イベント構造体を初期化する時は、カスタムイベントのイベントタイプを eType フィールドにセットします。
- イベントキューにポストする際、カスタムイベント構造体のポインタを EventPtr 型にキャストします。EvtGetEvent( ) でイベントを受け取った時は、ポインタをカスタムイベント構造体のポインタ型にキャストします。
カスタムイベントと Palm OS イベントキュー
アプリケーションの UI スレッドは Palm OS により、時として長時間サスペンドされます。ある Palm OS コンポーネントが処理を引き継いだ時点でキューに入っていたイベントは『消費』されてしまうため、アプリケーションには届かないことがあります。
もしアプリケーションがカスタムイベントを即座に処理されるUI関連機能で使用しているのであれば、カスタムイベントの“喪失”問題に出くわすことはないかもしれません。それでも、時として発生するイベントの喪失は再現困難な問題の原因になりえます。
この種の問題を発生させない方法の1つとして、カスタムイベントのための独自のイベントハンドラの作成があります。単純にキュー(先頭と末尾のポインタを伴う固定配列)とイベント送受信のために必要な関数を作成するのです。カスタムイベントハンドラはいくつかのかなり大きな利点があります。
- カスタムイベントが Palm OS によって『消費』されてしまうことがありません。
- カスタムイベントキューは Palm OS のキューよりも深くすることができます。
- Palm OS の イベント構造体に合わせる必要がなく、よりニーズに合わせたものを作ることができます。