概要

スピン(アップダウン)のサンプルです。
スピンコントロールとエディットボックスを組み合わせたサンプルです。
エディットボックス右の上下の三角をクリックすると連動してエディットボックスとその下のラベルの数値が変化します。
エディットボックスの数値を編集するとスピンコントロールの内部値とその下のレベルの数値が変化します。
エディットボックスに数字以外を入力した場合は無視されます。
スピンコントロールで設定した範囲外の数値を入力した場合は、ビープ音を発し、ラベル及びスピンコントロールの内部値に反映されません。 OKボタンをクリックするとプログラムが終了します。
キャンセルボタンをクリックするとプログラムが終了します。
スピンコントロール等はリソースファイル(resource.rc)で定義しています。
エディットボックスで数字外の入力を受け付けないようにリソースファイルでES_NUMBER属性を付加しています。 スピンコントロール等は、ダイアログボックスの子ウィンドウです。

テスト環境

コンパイラ

Visual C++ 2008 Standard 32/64bit
Visual C++ 2013 Express 32/64bit

実行環境

Windows 8.1 Enterprise 64bit
Windows 7 EnterPrise Service Pack 1 64bit
Windows Vista Ultimate Service Pack 2 32bit
Windows XP Professional Service Pack 3 32bit

プログラムソースの概要

updown.cpp

_tWinMain

DialogBox APIを呼び出してモーダルダイアログボックスを表示します。

UpDownDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)

ダイアログボックスプロシージャーです。
必要な時にWindowsから呼び出されます。
第2引数にメッセージの種類が格納されていますので、switchステートメントによりメッセージごとの処理を振り分けます。
ダイアログボックスに張り付けられているエディットボックス・アップダウンコントロールを操作するには、コントロールのハンドルが必要です。 ダイアログボックスのコントロール(子ウィンドウ)のハンドルを取得するには、 GetDlgItem APIを呼び出し、ダイアログボックスのハンドルとコントロールのID番号よりハンドルを取得します。
自分で処理しないメッセージは、ダイアログボックスプロシージャー終了時にFALSEを渡せば、Windowsが標準的な処理を行ってくれます。
case WM_INITDIALOG:
ダイアログボックスの初期化時に発生するメッセージです。
ここでは、エディットボックスとスピンコントロールの連動及びスピンコントロールの値の範囲と初期値を設定しあます。
コントロールのハンドルは他のメッセージでも使用するのでGetDlgItem APIにより取得しスタティック変数に保存します。
SendMessage APIによりUDM_SETBUDDYメッセージを発生させ、スピンボックスにエディットボックスを連動させます。
SendMessage APIによりUDM_SETRANGEメッセージを発生させ、スピンコントロールがとりうる範囲を設定します。MAKELONGマクロの第1引数が最大値、第2引数が最少値です。
SendMessage APIによりUDM_SETPOSによりスピンコントロールの初期値を設定します。
SetWindowTextによりラベルに現在値を表示させます。
case WM_COMMAND:
ダイアログボックスの子ウィンドウ(ダイアログボックスに張り付けられているエディットボックスやプッシュボタン等)から発生したメッセージが届きます。
ダイアログボックスプロシージャーの第3引数であるWPARAMの下位16bitがコントロールのID番号、その上位16bitには通知内容が格納されています。
LOWORDマクロによりWPARAMの下位16bitを取り出し、switchステートメントによりコントロールごとに処理を振り分けます。
case IDC_EDIT1:
エディットボックスのID番号がIDC_EDIT1です。
エディットボックスからのメッセージが届きます。
ここではエディットボックスの入力内容に変化が生じたときに発生するEN_UPDATEメッセージを処理します。
他に以下のようなメッセージがあります。

EN_SETFOCUS フォーカスを取得
EN_KILLFOCUS フォーカスを失った時 
EN_UPDATE 内部のテキストが変更
EN_CHANGE 内部のテキストが変更
EN_HSCROLL 横スクロールバーをクリック
EN_VSCROLL 縦スクロールバーをクリック
EN_MAXTEXT 入力文字制限数に達した時 
HIWORDマクロによりWPARAMの31~16bitの値を取り出し、ifステートメントによりEN_UPDATEの時 SendMessage APIによりを呼び出し、エディットボックスの文字列を取得します。
SetWindowText APIによりUDM_GETPOS32メッセージを発生させ、スピンコントロールの現在値を取得します。
戻り値が正常な時は、取得された現在値をSetWindowText APIによりラベルに表示します。
正常でないときは、ビープ音を発生させます。
case IDOK:
case IDCANCEL:
OKプッシュボタンのID番号がIDOKです。
リソースファイルでBS_DEFPUSHBUTTONと定義していますのでディフォルトプッシュボタンとなります。 ENTERキーを押した場合もこのメッセージが発生します。
ダイアログボックスの閉じるボタンまたはESCキーを押した場合もこのメッセージが発生します EndDialog APIを呼び出し、ダイアログボックスを終了させます。 このAPIの第2引数は、ダイアログボックスが終了し、DialogBox APIが返す値となります。

resource.h

ダイアログボックスで使用する各コントロールのID値をマクロで定義しています。

resource.rc

ダイアログボックスやコントロールの定義をしています。

プログラムソース

updown.cpp


//      スピン(アップダウン)コントロールサンプル
//      Visual C++ 2013 32/64bit

#include <windows.h>
#include <commctrl.h>
#include <tchar.h>
#include "resource.h"

//ダイアログボックスのプロシージャ
LRESULT CALLBACK UpDownDlgProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI _tWinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
                   TCHAR* lpsCmdLine, int nCmdShow){
    DialogBox(0, TEXT("updown"), 0, (DLGPROC)UpDownDlgProc);
    return 0;
}

//ダイアログボックスのプロシージャ

LRESULT CALLBACK UpDownDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp){
    static HWND hUpdown, hEdit, hLabel1;
    static int num;
    TCHAR buf[8];
        BOOL err;

    switch (msg) {
        case WM_INITDIALOG:
            hUpdown = GetDlgItem(hDlg, IDC_SPIN1);
            hEdit = GetDlgItem(hDlg, IDC_EDIT1);
            hLabel1 = GetDlgItem(hDlg, IDC_LABEL1);
                // エディットコントロールを連動させる。
                        SendMessage(hUpdown, UDM_SETBUDDY, (WPARAM)hEdit, 0);
                                // Up Down の範囲を設定する。 100~200
                        SendMessage(hUpdown, UDM_SETRANGE, (WPARAM)0, (LPARAM)MAKELONG(200,100));
                                // 初期値の設定 150
                        num = 150;
                        SendMessage(hUpdown, UDM_SETPOS, 0, (LPARAM)num);
            _stprintf_s(buf,sizeof(buf)/sizeof(TCHAR), TEXT("%d"), num);
            SetWindowText(hLabel1, buf);
            return TRUE;
        case WM_COMMAND:
            switch (LOWORD(wp)) {
                        case IDC_EDIT1:
                                if (HIWORD(wp) == EN_CHANGE) {
                                        //      現在の値を取得する。
                                        num = (int)SendMessage(hUpdown, UDM_GETPOS32, 0, (LPARAM)&err);
                                        if (err == 0){  //      エディットボックスの値が正常な範囲
                                                wsprintf(buf, TEXT("%d"), num);
                                                SetWindowText(hLabel1, buf);
                                        }
                                        else{   //      エディットボックスの値が正常でない場合
                                                Beep(1000, 200);
                                        }
                                        return TRUE;
                                }
                                break;
                        case IDOK:
            case IDCANCEL:
                    EndDialog(hDlg, IDOK);
                    return TRUE;
                        }
            return FALSE;
    }
    return FALSE;
}

resource.h


#define IDC_SPIN1 100
#define IDC_EDIT1 110
#define IDC_LABEL1 120

resource.rc


#include <windows.h>
#include "resource.h"

UPDOWN DIALOG DISCARDABLE  0, 0, 71, 76
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "スピンコントロール"
FONT 9, "MS Shell Dlg"
{
    DEFPUSHBUTTON   "OK",IDOK,8,51,50,14
    EDITTEXT        IDC_EDIT1,9,7,31,18,ES_AUTOHSCROLL | ES_NUMBER
    CONTROL         "Spin1",IDC_SPIN1,"msctls_updown32",UDS_WRAP | 
                    UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | 
                    UDS_NOTHOUSANDS,39,6,10,18
    LTEXT           "現在の位置=",-1,7,35,42,8
    LTEXT           "",IDC_LABEL1,50,35,21,8
}

ソースファイルと実行ファイルのダウンロード

ダウンロード updown.zip(37.4kByte)

ZIPファイルに含まれるファイル

updown.cpp
updown.exe
resource.h
resource.rc