ホーム ATL/WTL
Wizard97
ドキュメント種別 ATL/WTL に関する文書
最終更新日 2005/05/08
PR
 前回は明示的にSetHeader()やSetWatermark()を呼び出してWizard97スタイルのウィザードモードプロパティシートを作成しましたが、 WTL7.5.5002ではWizard97スタイル専用のクラステンプレート群が追加されました。

Wizard97スタイルプロパティシート
 WTL7.5.5002ではWizard97スタイルのウィザードモードプロパティシートを作成するために CWizard97SheetImplクラスが追加されました。 このクラスはCPropertySheetImplクラスから派生しています。

  • CWizard97SheetImpl
    Wizard97スタイルプロパティシートを作成するための基底クラス。

WTL7.5.5002では一般的なWizard97スタイルプロパティシートを作成するために、 CWizard97SheetImplクラスの派生クラスであるCWizard97Sheetクラスを用意しています。

次に示すのは、CWizard97Sheetクラスに通常のプロパティページを追加してWizard97スタイルプロパティシートを表示する例です。


// コンストラクタの引数は順に
// タイトル文字列、ヘッダBitmapリソースID、ウォーターマークBitmapリソースID
CWizard97Sheet sheet(_T("サンプル"), IDB_BITMAP_HEADER, IDB_BITMAP_WATERMARK);

// 通常のプロパティページを追加
CPropertyPage<IDD_PROPPAGE_VERSION> page;
sheet.AddPage(page);

sheet.DoModal();
			

ヘッダやウォーターマークのBitmapリソース(IDB_BITMAP_HEADER、IDB_BITMAP_WATERMARK)、 およびプロパティページに指定するダイアログリソース(IDD_PROPPAGE_VERSION)は前回作成したものです。

このように、CWizard97Sheetクラスを使用すると、 通常のプロパティページを追加しても自動的にWizard97スタイルになります。 また、CWizard97SheetImplクラスのコンストラクタでは PSH_HASHELPフラグやPSH_WIZARDCONTEXTHELPフラグがセットされるため、 自動的にヘルプボタンも追加されます。

Wizard97スタイルのプロパティシートをカスタマイズするには、 CWizard97SheetImplクラスから独自の派生クラスを作成します。 次に示すのは、ヘルプボタンの無いWizard97スタイルのプロパティシートクラスを作成する例です。


class CCustomWizard97 : public CWizard97SheetImpl<CCustomWizard97>
{
public:
    // コンストラクタ
    CCustomWizard97(ATL::_U_STRINGorID title, ATL::_U_STRINGorID headerBitmap,
        ATL::_U_STRINGorID watermarkBitmap, UINT uStartPage = 0,
        HWND hWndParent = NULL) :
        CWizard97SheetImpl<CCustomWizard97>(title, headerBitmap,
        watermarkBitmap, uStartPage, hWndParent)
    {
        // ヘルプボタンを非表示
        m_psh.dwFlags &= ~(PSH_HASHELP | PSH_WIZARDCONTEXTHELP);
    }

    BEGIN_MSG_MAP_EX(CCustomWizard97)
        CHAIN_MSG_MAP(CWizard97SheetImpl<CCustomWizard97>)
    END_MSG_MAP()
};
			

このクラスはCWizard97Sheetクラスと同じように使用できます。

// コンストラクタの引数は順に
// タイトル文字列、ヘッダBitmapリソースID、ウォーターマークBitmapリソースID
CCustomWizard97 sheet(_T("サンプル"), IDB_BITMAP_HEADER, IDB_BITMAP_WATERMARK);

// 通常のプロパティページを追加
CPropertyPage<IDD_PROPPAGE_VERSION> page;
sheet.AddPage(page);

sheet.DoModal();
			

Wizard97スタイルプロパティページ
 WTL7.5.5002ではWizard97スタイルのプロパティページを作成するために 以下の3種類のクラスが追加されました。 これらのクラスはCPropertyPageImplクラスから派生しています。

  • CWizard97PageImpl
    一般的なWizard97スタイルプロパティページを作成するための基底クラス。

  • CWizard97InteriorPageImpl
    ヘッダ付きWizard97スタイルプロパティページを作成するための基底クラス。

  • CWizard97ExteriorPageImpl
    ウォーターマーク付きWizard97スタイルプロパティページを作成するための基底クラス。

これらのクラスを使用するためには派生クラスを作成する必要があります。

次に示すのは、上記3種類のプロパティページクラスから派生クラスを作成し、 Wizard97スタイルプロパティシートに追加して表示する例です。




// stdafx.h内
#include <atlbase.h>
#include <atlapp.h>
extern CAppModule _Module;
#include <atlwin.h>

#include <atlcrack.h>
#include <atlmisc.h>

#include <atldlgs.h>  // Wizard97スタイルのウィザードモードプロパティシートを使用するため
			

// CustomWizard97.h内
class CCustomPage97 : public CWizard97PageImpl<CCustomPage97>
{
public:
    enum { IDD = IDD_PROPPAGE_WIZARD97 };

    // コンストラクタ
    CCustomPage97(ATL::_U_STRINGorID title = (LPCTSTR)NULL)
        : CWizard97PageImpl<CCustomPage97>(title)
    {}

    BEGIN_MSG_MAP_EX(CCustomPage97)
        CHAIN_MSG_MAP(CWizard97PageImpl<CCustomPage97>)
    END_MSG_MAP()

    BOOL OnSetActive(){
        SetWizardButtons(PSWIZB_NEXT);
        return TRUE;
    }
};

class CCustomInteriorPage : public CWizard97InteriorPageImpl<CCustomInteriorPage>
{
public:
    enum { IDD = IDD_PROPPAGE_INTERIOR };

    // コンストラクタ
    CCustomInteriorPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL)
        : CWizard97InteriorPageImpl<CCustomInteriorPage>(title)
    {}

    BEGIN_MSG_MAP_EX(CCustomInteriorPage)
        CHAIN_MSG_MAP(CWizard97InteriorPageImpl<CCustomInteriorPage>)
    END_MSG_MAP()

    BOOL OnSetActive(){
        SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
        return TRUE;
    }
};

class CCustomExteriorPage : public CWizard97ExteriorPageImpl<CCustomExteriorPage>
{
public:
    enum { IDD = IDD_PROPPAGE_EXTERIOR };

    // コンストラクタ
    CCustomExteriorPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL)
        : CWizard97ExteriorPageImpl<CCustomExteriorPage>(title)
    {}

    BEGIN_MSG_MAP_EX(CCustomExteriorPage)
        CHAIN_MSG_MAP(CWizard97ExteriorPageImpl<CCustomExteriorPage>)
    END_MSG_MAP()

    BOOL OnSetActive(){
        SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH);
        return TRUE;
    }
};
			

// maindlg.h内
class CMainDlg : public CDialogImpl<CMainDlg>
{
public:
    enum { IDD = IDD_MAINDLG };

    // メッセージマップ
    BEGIN_MSG_MAP_EX(CMainDlg)
        MSG_WM_INITDIALOG(OnInitDialog)
        COMMAND_ID_HANDLER_EX(IDC_BUTTON_OPENDLG, OnButtonOpenDlg)
        COMMAND_ID_HANDLER_EX(IDOK, OnOK)
        COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
    END_MSG_MAP()

    LRESULT OnInitDialog(HWND hWnd, LPARAM lParam){
        // スクリーンの中央に配置
        CenterWindow();

        // 大きいアイコン設定
        HICON hIcon = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR,
            ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));
        SetIcon(hIcon, TRUE);
        
        // 小さいアイコン設定
        HICON hIconSmall = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR,
            ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON));
        SetIcon(hIconSmall, FALSE);

        return TRUE;
    }

    void OnButtonOpenDlg(UINT uNotifyCode, int nID, HWND hWndCtl){
        CWizard97Sheet sheet(_T("サンプル"), IDB_BITMAP_HEADER, IDB_BITMAP_WATERMARK);

        // プロパティページを追加
        CCustomPage97 page97;
        sheet.AddPage(page97);
        CCustomInteriorPage pageInterior;
        sheet.AddPage(pageInterior);
        CCustomExteriorPage pageExterior;
        sheet.AddPage(pageExterior);

        if(sheet.DoModal() == IDOK){
            // [完了]ボタンを押して閉じた時の処理
        }
    }

    void OnOK(UINT uNotifyCode, int nID, HWND hWndCtl){
        EndDialog(nID);
    }

    void OnCancel(UINT uNotifyCode, int nID, HWND hWndCtl){
        EndDialog(nID);
    }
};
			

// CommDlg.cpp内
#include "stdafx.h"

#include "resource.h"

#include "CustomWizard97.h"
#include "maindlg.h"

CAppModule _Module;

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpCmdLine, int nCmdShow)
{
    HRESULT hRes = ::CoInitialize(NULL);
    ATLASSERT(SUCCEEDED(hRes));

    ::DefWindowProc(NULL, 0, 0, 0L);

    AtlInitCommonControls(ICC_COOL_CLASSES | ICC_WIN95_CLASSES);

    hRes = _Module.Init(NULL, hInstance);
    ATLASSERT(SUCCEEDED(hRes));

    int nRet = 0;
    // BLOCK: アプリケーション実行
    {
        CMainDlg dlgMain;
        nRet = dlgMain.DoModal();
    }

    _Module.Term();
    ::CoUninitialize();

    return nRet;
}
			

 まず、リソースを作成します。 プロジェクトにプロパティページ用のダイアログリソースとビットマップリソースを追加し、 リソースIDを次のように指定します。

リソース名 リソースID
ダイアログ(1番目のプロパティページ用) IDD_PROPPAGE_WIZARD97
ダイアログ(2番目のプロパティページ用) IDD_PROPPAGE_INTERIOR
ダイアログ(3番目のプロパティページ用) IDD_PROPPAGE_EXTERIOR
ビットマップ(ヘッダアイコン用) IDB_BITMAP_HEADER
ビットマップ(ウォーターマーク用) IDB_BITMAP_WATERMARK

なお、Wizard97スタイルのプロパティページ用にダイアログリソースのサイズを変更します。 atldlgs.hファイルでは、Wizard97スタイルのプロパティページの幅と高さが次のように定義されています。

#define WIZARD97_EXTERIOR_CXDLG 317
#define WIZARD97_EXTERIOR_CYDLG 193

#define WIZARD97_INTERIOR_CXDLG 317
#define WIZARD97_INTERIOR_CYDLG 143
			

ヘッダがある分、WIZARD97_INTERIOR_CYDLGの方がWIZARD97_EXTERIOR_CYDLGよりも小さな値になっています。 この値を参考に、リソースファイルをテキストモードで編集します。(赤い部分が変更した値です)

// CommDlg.rc内
IDD_PROPPAGE_WIZARD97 DIALOG DISCARDABLE  0, 0, 317, 143
STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "ウィザード 1/3"
FONT 9, "MS Pゴシック"
BEGIN
    LTEXT           "CWizard97PageImplベースのページ",IDC_STATIC,50,50,132,8
END

IDD_PROPPAGE_INTERIOR DIALOG DISCARDABLE  0, 0, 317, 143
STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "ウィザード 2/3"
FONT 9, "MS Pゴシック"
BEGIN
    LTEXT           "CWizard97InteriorPageImplベースのページ",IDC_STATIC,50,
                    50,132,8
END

IDD_PROPPAGE_EXTERIOR DIALOG DISCARDABLE  0, 0, 317, 193
STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "ウィザード 3/3"
FONT 9, "MS Pゴシック"
BEGIN
    LTEXT           "CWizard97ExteriorPageImplベースのページ",IDC_STATIC,120,
                    75,132,8
END
			

 次に、プロジェクトにCustomWizard97.hというヘッダファイルを追加し、 そこに3種類のプロパティページクラスを定義します。 今回の例では各クラスのメッセージマップで基底クラスへのチェーンを追加し、 OnSetActive()でウィザードのボタンを設定しているだけです。

 CMainDlgクラスではボタン用のコマンドメッセージハンドラ OnButtonOpenDlg()を追加します。 そこでCWizard97Sheetクラスのインスタンスを作成し、 3種類のプロパティページを追加します。

 最後に、CommDlg.cpp内でmaindlg.hヘッダの前にCustomWizard97.hヘッダをインクルードします。

 なお、CWizard97InteriorPageImplクラスの派生クラスでは、 デフォルトでヘッダタイトルとヘッダサブタイトルを設定するように促すメッセージ文字列が表示されます (今回の例では2番目のプロパティページ)。 このため、コンストラクタでそれらを設定すると良いでしょう。

class CCustomInteriorPage : public CWizard97InteriorPageImpl<CCustomInteriorPage>
{
public:
    enum { IDD = IDD_PROPPAGE_INTERIOR };

    // コンストラクタ
    CCustomInteriorPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL)
        : CWizard97InteriorPageImpl<CCustomInteriorPage>(title)
    {
        // ヘッダ文字列を設定
        SetHeaderTitle(_T("2番目のページ"));
        SetHeaderSubTitle(_T("CWizard97InteriorPageImplベースのページ"));
    }

    BEGIN_MSG_MAP_EX(CCustomInteriorPage)
        CHAIN_MSG_MAP(CWizard97InteriorPageImpl<CCustomInteriorPage>)
    END_MSG_MAP()

    BOOL OnSetActive(){
        SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
        return TRUE;
    }
};