ProbressBar を貼り付けた DialogBox を表示する

VC++ を使ってメニューの選択で ProbressBar を貼り付けた DialogBox を表示します。
空のプロジェクトから始めてリソースも全て自前で作成します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの作成

  1. 空の新規プロジェクト(PmbBar)を作成します。
    空のプロジェクトの作成方法は Dialog Box のプログラム を参照して下さい。
  2. 次のファイルをフォルダーに格納して[プロジェクト][既存項目の追加]からプロジェクトに追加して下さい。
    メニューや Dialog Box は、全て自前で作成したものを使用します。
    ファイルの詳細は、この後の説明を参照して下さい。
    ファイル名 説明
    PmbBar.cpp ソースプログラム
    PmbBar.rc リソース定義ファイル
    resource.h リソースヘッダーファイル
  3. 自前で作成したリソースを使うと警告のメッセージが表示されますが無視して下さい。
    リソースのソースコードを調べれば原因がつかめると思うのですが暇なときの課題です。 (^_^;
    この後のリソースの修正もテキストエディッタなどを使って自前で修正しなければなりません。
  4. ビルドに続いて実行を行います。
    メニューから「オプション」「ダイアログ」を選択すると Probress Bar(ページ先頭の画像) が表示されます。

プログラムの説明

  1. リソース定義ファイル(PmbBar.rc) の説明です。
    VC++ でリソースを定義すると非常に多くのソースコードが生成されますが、実際に必要なものは数行だけです。
    これを機会に、リソースの定義に関する理解を深めて下さい。
    メニューのリソース定義です。
    リソースファイルの先頭で windows.h を #include します。
    また、リソースで使われている ID が定義されているヘッダファイルも #include して下さい。
        MYMENU MENU DISCARDABLE 
        BEGIN
            POPUP "ファイル(&F)"
            BEGIN
                MENUITEM "終了(&X)",                    IDM_END
            END
            POPUP "オプション(&O)"
            BEGIN
                MENUITEM "ダイアログ(&D)",              IDM_DLG
            END
        END
        
  2. Dialog Box のリソース定義です。
    書かれている内容を見れば、大体理解できるでしょう。
        MYDLG DIALOG DISCARDABLE  0, 0, 187, 81
        STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
        CAPTION "プログレスバー"
        FONT 9, "MS Pゴシック"
        BEGIN
            DEFPUSHBUTTON   "OK",IDOK,7,60,50,14
            PUSHBUTTON      "キャンセル",IDCANCEL,130,60,50,14
            CONTROL         "Progress1",IDC_PROGRESS1,"msctls_progress32",WS_BORDER,
                            26,16,137,15
            LTEXT           "0%",IDC_STATIC,22,7,12,8
            LTEXT           "100%",IDC_STATIC,150,7,22,8
            LTEXT           "現在",IDC_STATIC,56,42,15,8
            LTEXT           "0",IDC_MYSTATIC,83,41,12,8
            LTEXT           "%です",IDC_STATIC,108,42,21,8
        END
        
  3. リソースのヘッダーファイル(resource.h) の説明です。
    ID で定義する値は、重複しないように適当な値を設定します。
    何を設定しても大抵うまく行くのですが、あまり変な値を設定すると思わぬことが起こるかも知れません。 (^_^;
    IDC_STATIC はプログラムからは参照しないことを意味する値「-1」に設定します。
        #define MYDLG                           101
        #define MYMENU                          102
        #define IDC_EDIT1                       1001
        #define IDC_DISP                        1002
        #define IDC_PROGRESS1                   1007
        #define IDC_MYSTATIC                    1008
        #define IDM_END                         40001
        #define IDM_DLG                         40002
        #define IDC_STATIC                      -1
        
  4. Main Program(PmbBar.cpp) の説明です。
    commctrl.h をインクルードして下さい。
    ID_MYTIMER はタイマのIDです。
    PB_MIN, PB_MAX, PB_STEP は Probress Bar の最小値、最大値、ステップ幅で、iProg は現在の値です。
    /********************************************/
    /*★ Progress Bar を表示する      前田 稔 ★*/
    /********************************************/
    #define     NAME    "Progress Bar"
    #define     TITLE   "Mode Less Dialog"
    #include    <windows.h>
    #include    <commctrl.h>
    #include    "resource.h"
    
    #define     ID_MYTIMER 32767
    #define     PB_MIN     0
    #define     PB_MAX     100
    #define     PB_STEP    10
    
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK    MyDlgProc(HWND, UINT, WPARAM, LPARAM);
    void                SetProgBar(HWND);
    int     iProg;      // 現在のプログレスバーの位置
        
  5. Windows Main 関数 の CALLBACK 関数です。
    IDM_DLG: で Probress Bar を貼り付けた Dialog Box を表示します。
    id は MessageBox() で終了を確認するための領域です。
    HINSTANCE は WinMain() でグローバル領域に保存しておくのが良いのですが、GetWindowLong() で hWnd から取得することもできます。
        LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
        {   int         id;
            HINSTANCE   hInst;
            switch(msg)
            {
                case WM_COMMAND:
                    switch(LOWORD(wp))
                    {   case IDM_END:
                            SendMessage(hWnd,WM_CLOSE,0,0L);
                            break;
                        case IDM_DLG:
                            hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);
                            DialogBox(hInst,MAKEINTRESOURCE(MYDLG),hWnd,(DLGPROC)MyDlgProc);
                            break;
                    }
                    break;
                      :
                      :
        
  6. Dialog Box の CALLBACK 関数です。
    WM_INITDIALOG: で Probress Bar を初期化してタイマを設定します。
        LRESULT CALLBACK MyDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
        {   char    str[16];
            switch(msg)
            {   case WM_INITDIALOG:
                    SetProgBar(hDlg);
                    SetTimer(hDlg,ID_MYTIMER,1000,NULL);
                    return TRUE;
        
  7. IDOK でタイマを停止して Dialog Box を終了します。
    IDCANCEL で Probress Bar を先頭に戻します。
            case WM_COMMAND:
                switch(LOWORD(wp))
                {   case IDOK:
                        iProg = 0;
                        KillTimer(hDlg,ID_MYTIMER);
                        EndDialog(hDlg,IDOK);
                        return TRUE;
                    case IDCANCEL:
                        iProg = 0;
                        SendMessage(GetDlgItem(hDlg,IDC_PROGRESS1),PBM_SETPOS,(WPARAM)0,0);
                        return TRUE;
                }
                return FALSE;
        
  8. WM_TIMER: でタイマ割り込みが起こる度に Probress Bar を進めます。
    SendMessage(GetDlgItem(hDlg,IDC_PROGRESS1),PBM_STEPIT,0,0); でステップ数を設定します。
    SendMessage(GetDlgItem(hDlg,IDC_PROGRESS1),PBM_SETPOS,0,0); で現在の位置を設定します。
            case WM_TIMER:
                SendMessage(GetDlgItem(hDlg,IDC_PROGRESS1),PBM_STEPIT,0,0);
                iProg += PB_STEP;
                if (iProg > 100)
                {   iProg = 0;
                    SendMessage(GetDlgItem(hDlg,IDC_PROGRESS1),PBM_SETPOS,0,0);
                }
                _itoa(iProg, str, 10);
                SetWindowText(GetDlgItem(hDlg,IDC_MYSTATIC),(LPCTSTR)str);
                return TRUE;
        
  9. Probress Bar を初期化して、最大・最小を設定します。
        void SetProgBar(HWND hDlg)
        {   HWND    hProg;
            hProg = GetDlgItem(hDlg, IDC_PROGRESS1);
            SendMessage(hProg,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(PB_MIN,PB_MAX));
            SendMessage(hProg,PBM_SETSTEP,(WPARAM)PB_STEP,0);
            return;
        }
        

【補足】

  1. PmbBar.rc で使われているIDは、必ず resource.h で定義して下さい。
  2. 定義されていないIDがあると、リソースタブを選択してもリソースが表示されません。
    またはリソースを開こうとするとエラー(赤いマークが表示)になります。
  3. resource.h の最後の行にも改行コードをタイプして下さい。
  4. プロジェクトに組み込んだリソースファイルは、そのプロジェクトに関連付けられる場合があります。
    これをそのまま他のプロジェクトにコピーすると「他で使用中」の警告が表示されます。
    別のプロジェクトで使うときは Editor で作成し直して下さい。

【メモ】

リソースを自前で作成したときは、追加のリソースも自前で作成して下さい。
自前のリソースにプロジェクトからリソースを追加しようとすると、意味不明のエラーが発生することがあります。
直接の原因はリソースファイル(.rc) の先頭で Windows.h を取り込むと解決したのですが、これ以外にも色々あるようです。

全ソースコード

超初心者の方のために全ソースコードを掲載します。 (^_^;)

ファイル名 ファイルの説明
PbmBar.cpp ソースプログラム
PmbBar.rc リソース定義ファイル
resource.h リソースヘッダーファイル

超初心者のプログラム入門(Win32API C++)