数値入力フィールドにリピートボタンを付ける
Top > Tips > Repeatbutton

 ちょっとした数値などの入力をさせたい場合には、 Graffitiよりもテンキーの方が簡単で良いですが画面スペースを多く使ってしまいます。

 少スペースで簡単に入力させるにはリピートボタンが有効です。
 リピートボタンは普通のボタンと見た目は同じですが、 フレームを非表示にして表示文字列を上下の三角文字にすれば、 おなじみの上下ボタンになります。

 リピートボタンはボタンをタップしている間は、 一定間隔でctlRepeatEventが通知され続けます。
 スクロールバーと違いリピートボタン自体は値の管理はしないので、 もし入力値の範囲が決まっている場合は、 イベントを受信した時に値の更新処理と上限値下限値になった時に、 それぞれのボタンを無効表示にする必要があります。

 無効表示にしても表示上だけでボタンは有効なままなので、 値の更新処理では上限値下限値を越えないようにチェックする必要があります。
 上限値下限値になった場合にボタンを非表示にしてしまうという方法もあります。

サンプル画面

ヘッダファイル
#define MainForm        1000
#define NumField        1001
#define UpButton        1002
#define DownButton      1003

リソースファイル
FORM ID MainForm AT (0 0 160 160)
NOFRAME
BEGIN
    TITLE "Repeatbutton"
    FIELD ID NumField AT (54 51 20 12) FONT 0 RIGHTALIGN UNDERLINED MAXCHARS 1 NUMERIC
    REPEATBUTTON "\x01" ID UpButton AT (76 48 12 AUTO) FONT 5 LEFTANCHOR NOFRAME
    REPEATBUTTON "\x02" ID DownButton AT (76 57 12 AUTO) FONT 5 LEFTANCHOR NOFRAME
END

イベントハンドラ
/* フィールドの数値を増減する */
static void NoModify(
    FormPtr pForm,  /* I:フォームハンドルポインタ */
    Int16 iAdd)     /* I:加算値 */
{
    FieldPtr    pField;     /* フィールドハンドルポインタ */
    MemHandle   hMem;       /* メモリハンドル */

    pField = (FieldPtr)FrmGetObjectPtr(pForm, FrmGetObjectIndex(pForm, NumField));
    hMem = FldGetTextHandle(pField);
    if (NULL != hMem)       /* 有効なテキストハンドル? */
    {
        Int16       i;          /* 表示数値 */
        Char        buff[6];    /* 表示用バッファ */

        i = StrAToI((CharPtr)MemHandleLock(hMem));
        MemHandleUnlock(hMem);
        i += iAdd;
        if (1 >= i)         /* 設定値が1以下? */
        {
            i = 1;
            CtlSetLabel((ControlPtr)FrmGetObjectPtr(pForm, FrmGetObjectIndex(pForm, DownButton)), "\x04");
        }
        else if (9 <= i)    /* 設定値が9以上? */
        {
            i = 9;
            CtlSetLabel((ControlPtr)FrmGetObjectPtr(pForm, FrmGetObjectIndex(pForm, UpButton)), "\x03");
        }
        else
        {
            CtlSetLabel((ControlPtr)FrmGetObjectPtr(pForm, FrmGetObjectIndex(pForm, UpButton)), "\x01");
            CtlSetLabel((ControlPtr)FrmGetObjectPtr(pForm, FrmGetObjectIndex(pForm, DownButton)), "\x02");
        }
        StrIToA(buff, i);
        SetStrToFieldText(pField, buff);
    }
}

static Boolean MainFormHandleEvent(EventPtr pEvent)
{
    Boolean handled = false;
    FormPtr pForm;

    switch (pEvent->eType)
    {
    case frmOpenEvent:      /* フォームオープンイベント */
        pForm = FrmGetActiveForm();
        FrmDrawForm(pForm);
        handled = true;
        break;

    case ctlRepeatEvent:    /* リピートボタンイベント */
        pForm = FrmGetActiveForm();
        if (UpButton == pEvent->data.ctlRepeat.controlID)           /* ▲押下? */
        {
            NoModify(pForm, +1);
        }
        else if (DownButton == pEvent->data.ctlRepeat.controlID)    /* ▼押下? */
        {
            NoModify(pForm, -1);
        }
        break;

    default:
        break;
    }

    return handled;
}

'04/12/5 新規作成