Palm Programmer's Laboratory

トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

Palm OS Programmer's Companion Volume I/9-4

← 3 節に戻る ↑9 章トップへ 5 節に進む →


9-4 フォームのリサイズ

 
ペン入力マネージャが入力エリアやコントロールバーの開閉、あるいはディスプレイの表示方向の変更をした場合、sysNotifyDisplayResizedEvent ノティフィケーションが受信登録をしたアプリケーション全てに対してブロードキャストされます。

sysNotifyDisplayResizedEvent を受信したアプリケーションは、(EvtAddUniqueEventToQueue を使って)winDisplayChangedEvent をポストしなければなりません。このイベントにより、フォームがリサイズ処理を自身で処理できます。

リスト 9.3 winDisplayChangedEvent のポスト

case sysAppLaunchCmdNotify:
if(((SysNotifyParamType*)cmdPBP)->notifyType == sysNotifyDisplayResizedEvent)
{
    EventType resizedEvent;
    MemSet(&resizedEvent, sizeof(EventType), 0);
    //add winDisplayChangedEvent to the event queue
    resizedEvent.eType = winDisplayChangedEvent;
    EvtAddUniqueEventToQueue(&resizedEvent, 0, true);
}
break;

入力エリアはメニューがオープンしていても状態を変更できます。そのような状況では、winEnterEvent を受信した場合にも( リスト 9.3 と同じようなコードで )winDisplayChangedEvent をキューに追加すべきです。

ノティフィケーションには現在のフォームの新しい領域を示す矩形情報が含まれています。一般的に、フォームは入力エリアのクローズに応答してボタンを新しい矩形領域の下部に移動したり、データ領域をリサイズする必要があります。

リスト 9.4 に winDisplayChangedEvent の処理例を示します。

リスト 9.4 winDisplayChangedEvent の処理

// Input area was opened or was closed. Must resize form.
case winDisplayChangedEvent:
    // get the current bounds for the form
    frmP = FrmGetActiveForm();
    WinGetBounds (FrmGetWindowHandle(frmP), &curBounds);

    // get the new display window bounds
    WinGetBounds(WinGetDisplayWindow(), &displayBounds);

    EditFormResizeForm(frmP, &curBounds, &displayBounds);
    WinSetBounds(FrmGetWindowHandle(frmP), &displayBounds);
    FrmDrawForm(frmP);
    handled = true;
    break;

この例では、フォームには複数行のテキストフィールド、スクロールバー、および最下部にいくつかのボタンがあります。このフォームは winDisplayChangedEvent に応答して EditFormResizeForm という関数にフォームの現在の領域と新しい領域を渡します。この関数をリスト 9.5 に示します。この関数は新旧の幅と高さの違いを調べ、フォーム内のオブジェクトにその違いを適用します。コマンドボタンについては、常に画面の下部に配置されるように位置を変更します。テキストフィールドとスクロールバーについては、より多くのテキスト行がスクリーン上に表示されるようにリサイズを行ないます。

テキストフィールドのあるフォームをリサイズしたら、FldRecalculateField をコールしてフィールドの新しいサイズでワードラップを更新した方が良いでしょう。

リスト 9.5 フォームのリサイズ

void EditFormResizeForm(FormType *frmP,
                        RectangleType* fromBoundsP,
                        RectangleType* toBoundsP)
{
    Int16 heightDelta, widthDelta;
    UInt16 numObjects, i;
    Coord x, y;
    RectangleType objBounds;

    heightDelta = widthDelta = 0;
    numObjects = 0;
    x = y = 0;
    FieldType* fldP;

    // Determine the amount of the change
    heightDelta=(toBoundsP->extent.y - toBoundsP->topLeft.y) -
                (fromBoundsP->extent.y - fromBoundsP->topLeft.y);
    widthDelta=(toBoundsP->extent.x - toBoundsP->topLeft.x) -
                (fromBoundsP->extent.x - fromBoundsP->topLeft.x);

    // Iterate through objects and re-position them.
    // This form consists of a big text field and
    // command buttons. We move the command buttons to the
    // bottom and resize the text field to display more data.
    numObjects = FrmGetNumberOfObjects(frmP);
    for (i = 0; i < numObjects; i++) {
        switch (FrmGetObjectType(frmP, i)) {
        case frmControlObj:
            FrmGetObjectPosition(frmP, i, &x, &y);
            FrmSetObjectPosition(frmP, i, x + widthDelta, y + heightDelta);
            break;
        case frmFieldObj:
        case frmScrollBarObj:
            FrmGetObjectBounds(frmP, i, &objBounds);
            objBounds.extent.x += widthDelta;
            objBounds.extent.y += heightDelta;
            FrmSetObjectBounds(frmP, i, &objBounds);
            fldP = (FieldType*) FrmGetObjectPtr(frmP, i);
            FldRecalculateField(fldP, false);
            break;
        }
    }
}

 


← 3 節に戻る ↑9 章トップへ 5 節に進む →