C++のスピンコントロールの使い方

エディットボックスの隣に矢印ボタンがくっついて値を調整できるスピンコントロール (アップダウンコントロール)というものがあります。

 

Viual Studio を使って MFC アプリケーションへスピンコントロールを組み込んでいく方法を解説していきます。


エディットとスピンをそれそれ配置

リソースの編集画面からエディットコントロールスピンコントロールをそれぞれ配置していきます。

一見1つのコントロールに見えますが、2つのコントロールを組み合わせたものになります。


エディットとスピンを関連付ける

スピンコントロールには自動で関連付ける仕組みがありますが、それを利用するにはコントロールのZオーダーを意識する必要があります。

スピンコントロールはZオーダーで自身の直前にあるコントロールと関連付けされます。

 

コントロールのZオーダー

Zオーダーは基本的にはコントロールを配置した順番になります。

スピンコントロールは直前のコントロールと関連付くので、まずエディットコントロールを配置してからスピンコントロールを配置するとよいでしょう。

タブオーダーを変更する事でZオーダーを変更する事も可能です。

タブオーダーの変更はメニューから[書式(O)]→[タブオーダー(O)]から行えます。

 

タブオーダーを実行すると右の図のようにコントロールに番号が表示されます。

この状態でコントロールをクリックしていくと順番に番号が振り直されていきます。

スピンコントロールのプロパティ

続いてスピンコントロールのプロパティを設定していきます。

 

重要なのは「Auto Buddy」と「Set Buddy Integer」でいずれも「True」に設定します。

 

Auto Buddy を True にする事で直前のコントロールと関連付けされます。

Set Buddy Integer を True にすると関連付けされたコントロールにスピンの値が表示されるようになります。

1つのコントロールっぽい見た目にする

スピンコントロールのプロパティ「Alignment」を変更する事でエディットとスピンを一体化させたような見た目に変更する事が出来ます。

Alignment = アタッチしない


Alignment = Left


Alignment = Right Align



スピンコントロールの値の範囲や初期値を設定

スピンコントロールは整数型の値を持つことが出来ます。

値は上限と下限を設定する事が可能で、矢印ボタンの操作でその範囲外にならないようにする事が出来ます。

 

初期設定はダイアログクラスの OnInitDialog メソッド内で行うのが良さそうです。

上限と下限は SetRange32 メソッドで設定します。

初期値の設定は SetPos32 メソッドを使用します。

 

BOOL CSpinTestDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();


    CSpinButtonCtrl* pSpin = (CSpinButtonCtrl*)GetDlgItem(IDC_SPIN1);
    pSpin->SetRange32(-10, 10);
    pSpin->SetPos32(5);

    return TRUE;
}

矢印ボタンを押した時の増減量を設定

SetAccel メソッドを使う事でスピンコントロールの矢印ボタンを押した時の値の変化量を設定する事が出来ます。

 

変化量の指定は「UDACCEL」という構造体の配列を使用します。

この構造体は変化量とそれが適用され始める秒数を指定する仕組みになっていて、矢印ボタンを押しっぱなしにした時に、始めは1づつ増えていき5秒後からは10づつ増やすといった指定が可能になっています。

BOOL CSpinTestDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();


    CSpinButtonCtrl* pSpin = (CSpinButtonCtrl*)GetDlgItem(IDC_SPIN1);
    pSpin->SetRange32(-10000, 10000);
    pSpin->SetPos32(5);

    accelList[0].nInc =   1;     //最初は1づつ増やす
    accelList[0].nSec =   0;
    accelList[1].nInc =  10;     //5秒後からは10づつ増やす
    accelList[1].nSec =   5;
    accelList[2].nInc = 100;     //10秒後からは100づつ増やす
    accelList[2].nSec =  10;
    pSpin->SetAccel(3, accelList);

    return TRUE;
}