本資料はClie用Palmwareを開発する方へのPowerJOGに関する情報です。本資料内の情報、ソースコード、プロジェクトは開発者が自由に対価なく利用することができますが、その内容及び品質、合目的性に関しては無保証です。
(1)PowerJOGによる変化
ユーザーがPowerJOGを利用しており、かつ「一時停止」していない場合、ジョグダイヤルに関するイベントについて以下の変化が起こります。
・vchrJogPressRepeatがアプリケーションには渡されない。
PowerJOGが本イベントを契機に動作を開始しますので、ユーザーアプリケーションには本イベントは渡されません.
・vchrJogPressの渡されるタイミングが変化する。
ユーザーがジョグダイヤルを押したときにvchrJogPressがユーザーアプリケーションに渡されません。これはユーザーがPowerJOGのメニューを出そうとおもってジョグダイヤルを長押しした場合に、 vchrJogPressRepeatが発生する前にvchrJogPressがアプリケーションに渡ってしまうと、ユーザーが期待しない動作(カテゴリーの変化、画面の変更等)をしてしまうのを防ぐためです。
PowerJOG動作時はvchrJogPressは以下のタイミングでユーザーアプリケーションに渡されます。
・ジョグダイヤルが離された場合:vchrJogPressとvchrJogReleaseがほぼ同時に、この順で発生します。
・ジョグダイヤルが押し回しされた場合:vchrJogPressとvchrJogPageUp/vchrJogPageDownがほぼ同時に、この順で発生します。
・PowerUP時
ユーザーがPowerUPを指定した場合、PowerJOGはEvtGetEventの内部でvchrJogUp/vchrJogDownをvchrPageUp/vchrPageDownに変換してイベントキューに登録します。そのため、ユーザーアプリケーションにはvchrJogUp/vchrJogDownの2イベントは通知されません。
(2)PowerJOG Friendlyなソフトを作るには
PowerJOGでは、FrmDispatchEvent実行後にジョグダイヤルに関するイベントが処理されていない場合(handled=false)に、処理を行います。(現バージョンではvchrPageUp/vchrPageDownをPOSTしますが、この処理は変更される可能性があります。)
したがって、以下のようなソフトでは問題が起きます。
・ジョグダイヤルに関するイベントを処理していないのにHandled=trueにするアプリケーション
ジョグダイヤルを上下に回しても画面のスクロールが行われません。たとえば、keyDownEventを受信した場合必ずhandled=trueとしてしまうアプリケーションはこれに該当します。
この場合、ユーザーが「PowerUP」をすると、EvtGetEvent内でイベントの変更が行われますので、画面のスクロールが行われることになります。
・ジョグダイヤルに関するイベントを処理したのにHandled=falseにするアプリケーション
この場合、アプリケーションとPowerJOGが重なってジョグダイヤルの処理を行ってしまうことになります。具体的にはジョグダイヤルを1回動かすだけで画面が2回スクロールするなどの症状が起こります。
・FrmDispatchEventの後でSysHandleEventを呼ぶアプリケーション
本来SysHandleEventで処理されるべきジョグダイヤル関係のイベントがPowerJOGによって処理されてしまいます。このため、たとえば、ATOKをジョグダイヤルで操作できなくなったりします。
・vchrJogPressとvchrJogPageUp/Down、vchrJogPressとvchrJogReleaseが間隔を空けて発行されることを想定しているアプリケーション
PowerJOGはシステムが発行したvchrJogPressをいったん取得し、異なるタイミングでアプリケーションに渡します。従って、上記前提を置いているアプリケーションは動作が変わります。
PowerJOG Friendlyなソフトを作るには、以下の3点を守ってください。(3点目は推奨であり、必須ではありません)
・SysHandleEventの後でFrmDispatchEventを呼ぶ。
・Fromのイベントハンドラーでは、ジョグダイヤルの処理をしたときのみhandled=trueとする。
・vchrJogPressではなく、vchrJogReleaseを契機に処理を行う。
(3)PowerJOGに関するAPI
以下の情報を利用することにより、Palmwareから以下のことが可能になります。
・PowerJOGを一時的に停止する。動作を再開する。
・PowerJOGの動作状況を取得する。
一般的にPowerJOGはほぼ全てのPalmware上で問題なく動作しますが、ジョグダイヤルの押しつづけを用いるPalmware(PowerJOGはジョグダイヤルを押しつづけたときに発生するvchrJogPressRepeatにより起動しますので、Palmware自身はvchrJogPressRepeatを受け取ることができません。)及びvchrJogPressと他のイベントが連続して発生することを許容しないPalmware(PowerJOG動作時はvchrJogPressが発生するタイミングが変わります)はPowerJOGとの間で問題が発生します。これを避けるには以下2つの方法があります。
・ユーザがPowerJOGのメニューから「一時停止」を実行する
・PalmwareがPowerJOGを停止させる。
以下の関数によりPalmwareはPowerJOGの動作状況を変化させ、状態を取得できます。
関数仕様
-----------
void
PowerJOGChangeState(Boolean enabled)
入力:
enabled: false...PowerJOGを一時的に停止させる
true....PowerJOGの動作を再開させる
返却する値:なし
動作:
PowerJOGの動作状況を変化させます。enabledとしてfalseを渡した場合、ユーザーがPowerJOGのメニューから「一時停止」を選択したときと同じ動作を行います。ただし、ユーザーが行った場合に表示されるメッセージ(「PowerJOGを一時的に停止します......」)は表示されません。
この関数によりPowerJOGを停止した場合も、「一時停止」の時と同様他のアプリケーションが起動するとPowerJOGは自動的に動作を再開します。したがって、Palmwareの動作開始時にPowerJOGを停止させた場合も、動作終了時にPowerJOGの動作を再開させる必要はありません。ただし、DA内で本関数を使う場合のみ注意が必要です。DA内でPowerJOGの動作を停止した場合、DAが動作を終了した後のアプリケーションにおいてもその状況が持続します。したがって、DA内で本関数を利用する場合、PowerJOGGetStateによりPowerJOGの状態を取得し、DA終了時にその状態を復帰するようにしてください.
-----------
Boolean
PowerJOGGetState(void)
入力:なし
返却する値:
false....PowerJOGがONになっていない、もしくは一時的に停止されている
true....PowerJOGは動作中である。
動作:
PowerJOGの動作状況を返却します。
DA内でPowerJOGの動作を停止させる場合、本関数により状態を取得し、返却値が1だった場合、DA終了前にPowerJOGの動作を再開させてください。
-----------
参考:
'JOGD'というCreator IDは私がPalm Incに登録しています。ただし、このCreator
IDを持ったPalmwareは作らないことを保証します。PowerJOG及び類似ソフトウェアの状態変更をFeatureManagerを用いて行う用途のみに用います。
#define JogStopAll 1
// Change the status of PowerJOG
// enabled:
// false : Stop PowerJOG
// true : Start PowerJOG
void
PowerJOGChangeState(Boolean enabled)
{
if (enabled)
FtrUnregister( 'JOGD', 1000);
else
FtrSet( 'JOGD', 1000,JogStopAll );
return;
}
// Get the current state of PowerJOG
// return:
// false : PowerJOG is not running or canceled
// true : PowerJOG is running
Boolean
PowerJOGGetState(void)
{
UInt32 result;
s
if ( FtrGet( 'JOGD',1000, &result) == ftrErrNoSuchFeature)
return true;
else
return false;
}
本関数を用いたサンプルプログラムのプロジェクト(CW R6向け)をここからダウンロードできます。
// Change the status of PowerJOG. This status is reset when another
application launch
// enabled:
// false : Stop PowerJOG
// true : Start PowerJOG
void
PowerJOGChangeState(Boolean enabled)
{
Err err;
UInt16 card;
LocalID dbId;
DmSearchStateType
search;
UInt32 result;
err = DmGetNextDatabaseByTypeCreator
( true, &search,
'appl','PJog' ,true,&card,&dbId);
if (err == errNone
){
SysAppLaunch(card,dbId, 0, (enabled==true)?0x7001:0x7000
,0, &result);
}
}
// Get the current state of PowerJOG
// return:
// -1 : PowerJOG is not installed
// 0 : PowerJOG is not running or canceled
// 1 : PowerJOG is running
int
PowerJOGGetState(void)
{
Err err;
UInt16 card;
LocalID dbId;
DmSearchStateType search;
UInt32 result;
UInt8 state=255;
err = DmGetNextDatabaseByTypeCreator
( true, &search,'appl','PJog' ,true,&card,&dbId);
if (err == errNone ){
SysAppLaunch(card,dbId,
0, 0x7002 ,&state, &result);
state &= 0x01; // Mask Upper bits
}
return state ;
}