ウィザード

ウィザード1
ウィザード2

今回は、ウィザードを作成します。プロパティシートとほぼ同じです。

プロパティシート1 - インコのWindowsSDK で作成したソースを修正します。

流れ

1.PROPSHEETHEADER構造体のdwFlagsメンバに、PSH_WIZARDを追加。
これにより、プロパティシートは、ウィザードになります。

プロパティシートのコールバック関数

コールバック関数とは、プログラム中で、呼び出し先の関数の実行中に実行されるように、あらかじめ指定しておく関数のことです。

1.ユーザーが「次へ(N)>」ボタンを押すと、ダイアログプロシージャに WM_NOTIFY メッセージが送信されます。 この通知コードは PSN_WIZNEXTになります。

WM_NOTIFYメッセージは、コモンコントロールでイベントが起こった場合、およびコモンコントロールが情報を親ウィンドウに要求する場合に、コモンコントロールの親ウィンドウに送信されます。

WM_NOTIFYメッセージ発生時の lParam [コールバック関数の第4引数]の値が、NMHDR構造体のアドレスです。
NMHDR構造体のcodeメンバが「通知コード」です。

「戻る」ボタンを押すとPSN_WIZBACK通知コードが、 「完了」ボタンを押すとPSN_WIZFINISH通知コードが送られます。

2.PropSheet_SetFinishText() で、「完了」ボタンが表示され、「次へ(N)>」と「<戻る(B)」ボタンが非表示になります

void PropSheet_SetFinishText(
    HWND hPropSheetDlg, // プロパティシートのハンドル
    LPTSTR lpszText     // 「完了」ボタンの新しいテキストへのポインタ
);

ソースコードの入力

ソースコードは下記のように入れてください。

test.cpp
#include <windows.h>
#include <commctrl.h> 
#include "resource.h"

#pragma comment(lib, "comctl32.lib")

// グローバル変数:
TCHAR szBuf_edit1[64], szBuf_edit2[64];

// このコード モジュールに含まれる関数の宣言を転送します:
BOOL CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DialogProc1(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DialogProc2(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DialogProc3(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
          PSTR lpCmdLine, int nCmdShow ) {
    DialogBox(hInstance, TEXT("DIALOG_BOX"), NULL, DialogProc);
    return 0;
}

BOOL CALLBACK DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    UINT wmId;
    PROPSHEETPAGE psp;
    PROPSHEETHEADER psh;
    HPROPSHEETPAGE hPsp[3];
    switch (msg)
    {
        case WM_INITDIALOG:
            InitCommonControls(); 
            break;
        case WM_CLOSE:
            EndDialog(hWnd, IDOK);
            break;
        case WM_COMMAND:
            wmId = LOWORD(wParam);
            switch (wmId)
            {
                case IDM_EXIT:
                    EndDialog(hWnd, IDOK);
                    break;
                case IDM_PROP:
                    psp.dwSize = sizeof(PROPSHEETPAGE);
                    psp.dwFlags = PSP_DEFAULT | PSP_USEICONID;
                    psp.pszIcon = TEXT("IDI_TEST");
                    psp.hInstance = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);

                    psp.pszTemplate = TEXT("DIALOG1");
                    psp.pfnDlgProc = (DLGPROC)DialogProc1;
                    hPsp[0] = CreatePropertySheetPage(&psp);

                    psp.pszTemplate = TEXT("DIALOG2");
                    psp.pfnDlgProc = (DLGPROC)DialogProc2;
                    hPsp[1] = CreatePropertySheetPage(&psp);

                    psp.pszTemplate = TEXT("DIALOG3");
                    psp.pfnDlgProc = (DLGPROC)DialogProc3;
                    hPsp[2] = CreatePropertySheetPage(&psp);

                    psh.dwSize = sizeof (PROPSHEETHEADER);
                    psh.dwFlags = PSH_DEFAULT | PSH_USEHICON | PSH_WIZARD;
                    psh.hwndParent = hWnd;
                    psh.hIcon = LoadIcon(NULL, IDI_ASTERISK);
                    psh.pszCaption = TEXT("設定");
                    psh.nPages = 3;
                    psh.phpage = hPsp;
                    PropertySheet(&psh);
                    break;
                default:
                    break;
            }
        default:
            break;
    }
    return FALSE;
}

BOOL CALLBACK DialogProc1(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    NMHDR *nmhdr;

    switch(msg)
    {
        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                case IDC_EDIT1:
                    if (HIWORD(wParam) == EN_CHANGE)
                    {
                        PropSheet_Changed(GetParent(hWnd), hWnd);
                    }
                break;
            }
            break;
        case WM_INITDIALOG:
            SetWindowText(GetDlgItem(hWnd, IDC_EDIT1), szBuf_edit1);
            break;
        case WM_NOTIFY:
            nmhdr = (NMHDR *)lParam;
            switch(nmhdr->code)
            {
                case PSN_WIZNEXT:
                    GetWindowText(GetDlgItem(hWnd, IDC_EDIT1), szBuf_edit1, sizeof(szBuf_edit1));
                    break;
                default:
                    break;
            }
            break;
    }
    return FALSE;
}

BOOL CALLBACK DialogProc2(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    NMHDR *nmhdr;

    switch(msg)
    {
        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                case IDC_EDIT2:
                    if (HIWORD(wParam) == EN_CHANGE)
                    {
                        PropSheet_Changed(GetParent(hWnd), hWnd);
                    }
                break;
            }
            break;
        case WM_INITDIALOG:
            SetWindowText(GetDlgItem(hWnd, IDC_EDIT2), szBuf_edit2);
            break;
        case WM_NOTIFY:
            nmhdr = (NMHDR *)lParam;
            switch(nmhdr->code)
            {
                case PSN_WIZNEXT:
                    GetWindowText(GetDlgItem(hWnd, IDC_EDIT2), szBuf_edit2, sizeof(szBuf_edit2));
                    break;
                default:
                    break;
            }
            break;
    }
    return FALSE;
}

BOOL CALLBACK DialogProc3(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    PropSheet_SetFinishText(GetParent(hWnd) , TEXT("完了(&F)"));
    return FALSE;
}

上記の太線で示している箇所のみ追加です。

resource.h(変更なし)
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDM_PROP 106
#define IDC_HP 109
#define IDC_EDIT1 1001
#define IDC_EDIT2 1002
#ifndef IDC_STATIC
#define IDC_STATIC -1
#endif

Reseditで作成した場合は、これとは異なるソースコードになります。

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

/////////////////////////////////////////////////////////////////////////////
//
// アイコン
//

IDI_TEST ICON "test.ico"

/////////////////////////////////////////////////////////////////////////////
//
// メニュー
//

IDC_HP MENU
BEGIN
    POPUP "ファイル(&F)"
    BEGIN
        MENUITEM "アプリケーションの終了(&X)", IDM_EXIT
        MENUITEM "プロパティ(&P)", IDM_PROP
    END
    POPUP "ヘルプ(&H)"
    BEGIN
        MENUITEM "バージョン情報(&A)...", IDM_ABOUT
    END
END

/////////////////////////////////////////////////////////////////////////////
//
// ダイアログ
//

DIALOG_BOX DIALOG 0, 0, 170, 62
FONT 9, "MS UI Gothic"
CAPTION "ダイアログ"
MENU IDC_HP
BEGIN
    LTEXT           "Copyright (C) 2008",IDC_STATIC,42,26,114,8
END

DIALOG1 DIALOG 0, 0, 170, 62
FONT 9, "MS UI Gothic"
CAPTION "設定1"
BEGIN
    EDITTEXT        IDC_EDIT1, 2, 2, 166, 13, ES_AUTOHSCROLL
END

DIALOG2 DIALOG 0, 0, 170, 62
FONT 9, "MS UI Gothic"
CAPTION "設定2"
BEGIN
    EDITTEXT        IDC_EDIT2, 2, 2, 166, 13, ES_AUTOHSCROLL
END

DIALOG3 DIALOG 0, 0, 170, 62
FONT 9, "MS UI Gothic"
CAPTION "設定完了"
BEGIN
    LTEXT           "設定が完了しました",IDC_STATIC,42,26,114,8
END

上記の太線で示している箇所のみ追加です。
Reseditで作成した場合は、これとは異なるソースコードになります。