ホーム ATL/WTL
複数ファイル選択ダイアログ
ドキュメント種別 ATL/WTL に関する文書
最終更新日 2007/04/29
PR
 WTLでは複数ファイル選択に対応したファイル選択ダイアログを CMultiFileDialogImplというクラステンプレートでカプセル化しています。 これはATLのCDialogImplクラステンプレートのように基底クラスとしてのみ使用します。 atldlgs.hヘッダではCMultiFileDialogImplから派生したCMultiFileDialogクラスが定義されています。

// atldlgs.h
class CMultiFileDialog : public CMultiFileDialogImpl<CMultiFileDialog>
{
    ...
    ...
			

以下に示すのは、CMultiFileDialogクラスを使用する例です。


CMultiFileDialog dlg(_T("txt"), NULL, OFN_HIDEREADONLY,
    _T("テキスト ファイル (*.txt)\0*.txt\0すべてのファイル (*.*)\0*.*\0\0"));

if(dlg.DoModal() == IDOK){
    CString strMsg;
    bool find = dlg.GetFirstPathName(strMsg);
    while(find){
        MessageBox(strMsg);
        find = dlg.GetNextPathName(strMsg);
    }
}
			

CMultiFileDialogクラスのコンストラクタ引数はすべて省略できます。 引数は順に、デフォルト拡張子、デフォルトファイル名、フラグ、フィルタ、 親ウィンドウのハンドルです。

複数ファイル選択ダイアログを表示するためにはCMultiFileDialogクラスのメンバ関数であるDoModal()を呼び出します。 [開く]ボタンを押して複数ファイル選択ダイアログを閉じた場合は、 戻り値としてIDOKが、 [キャンセル]ボタンを押して閉じた場合はIDCANCELが返ります。

戻り値がIDOKの場合は、CMultiFileDialogクラスのメンバ関数である GetFirstPathName()GetNextPathName()を呼び出して、 選択されたファイルパスを取得できます。

CMultiFileDialogクラスの基底クラスであるCMultiFileDialogImplは、 CFileDialogImplから派生しています。 このため、CMultiFileDialogImplの派生クラスは、 通常のファイル選択ダイアログと同様に特定のメンバ関数をオーバーライドすることによって、 複数ファイル選択ダイアログの動作をカスタマイズすることができます。

次に示すのは、OnInitDone()OnHelp()をオーバーライドして、 独自の複数ファイル選択ダイアログを作成する例です。 プロジェクトにCustomDlg.hというヘッダファイルを追加し、 そこにCCustomDlgというクラスを定義します。 この複数ファイル選択ダイアログには[ヘルプ]ボタンが追加され、親ウィンドウの中央に表示されます。


// CustomDlg.h
#pragma once

class CCustomDlg : public CMultiFileDialogImpl<CCustomDlg>
{
public:
    // コンストラクタ
    CCustomDlg(
        LPCTSTR lpszDefExt = NULL,
        LPCTSTR lpszFileName = NULL,
        DWORD dwFlags = OFN_HIDEREADONLY,
        LPCTSTR lpszFilter = NULL,
        HWND hWndParent = NULL)
        : CMultiFileDialogImpl<CCustomDlg>(
            lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent)
    {
        // [ヘルプ]ボタンを表示するためにOFN_SHOWHELPフラグ追加
        m_ofn.Flags |= OFN_SHOWHELP;
    }

    void OnInitDone(LPOFNOTIFY lpon){
        // 複数ファイル選択ダイアログを親ウィンドウの中心に表示
        GetFileDialogWindow().CenterWindow();
    }

    void OnHelp(LPOFNOTIFY lpon){
        // 現在開いているフォルダパスを取得
        TCHAR szPath[_MAX_PATH];
        GetFolderPath(szPath, sizeof(szPath)/sizeof(TCHAR));

        CString strMsg;
        strMsg.Format(_T("現在のフォルダは %s です。"), szPath);

        MessageBox(strMsg);
    }
};
			

CCustomDlgクラスのコンストラクタ引数は、 CMultiFileDialogクラスのコンストラクタ引数を参考にしています。 コンストラクタでは、複数ファイル選択ダイアログに[ヘルプ]ボタンを追加するために OFN_SHOWHELPフラグを追加します。 OnInitDone()ではGetFileDialogWindow()を呼び出して複数ファイル選択ダイアログのウィンドウオブジェクトを取得し、 CenterWindow()を呼び出してダイアログを中央に表示します。 OnHelp()は[ヘルプ]ボタンを押した時に呼び出されます。 今回の例では現在開いているフォルダパスをメッセージボックスで表示します。

 次に示すのは、CCustomDlgクラスを使用する例です。

プロジェクトファイル ダウンロード
// stdafx.h
#pragma once

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

#include <atlcrack.h>
#include <atlmisc.h>
#include <atldlgs.h>  // コモンダイアログ用クラスを使用するため
			

// MainDlg.h
#pragma once

class CMainDlg : public CDialogImpl<CMainDlg>
{
public:
    enum { IDD = IDD_MAINDLG };

    BEGIN_MSG_MAP(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()

    BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam){
        // スクリーンの中央に配置
        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, CWindow wndCtl){
        CCustomDlg dlg(_T("txt"), NULL, OFN_HIDEREADONLY,
            _T("テキスト ファイル (*.txt)\0*.txt\0すべてのファイル (*.*)\0*.*\0\0"));

        if(dlg.DoModal() == IDOK){
            CString strMsg;
            bool find = dlg.GetFirstPathName(strMsg);
            while(find){
                MessageBox(strMsg);
                find = dlg.GetNextPathName(strMsg);
            }
        }
    }

    void OnOK(UINT uNotifyCode, int nID, CWindow wndCtl){
        EndDialog(nID);
    }

    void OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl){
        EndDialog(nID);
    }
};
			

// SampleProject.cpp
#include "stdafx.h"
#include "resource.h"
#include "CustomDlg.h"
#include "MainDlg.h"

CAppModule _Module;

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

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

    AtlInitCommonControls(ICC_BAR_CLASSES);

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

    CMainDlg dlg;
    int nRet = (int) dlg.DoModal();

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

    return nRet;
}
			

 まず、リソースを作成します。ダイアログにボタンコントロールを配置し、 [ID]と[Caption]を次のように設定します。

コントロール名 ID Caption
ボタン IDC_BUTTON_OPENDLG ダイアログを開く

 次に、stdafx.hヘッダでは、コモンダイアログを使用するためにatldlgs.hヘッダをインクルードします。

 CMainDlgクラスでは、リソースIDがIDC_BUTTON_OPENDLGWM_COMMANDメッセージハンドラとして OnButtonOpenDlg()を追加します。 このハンドラ関数ではCCustomDlgクラスのインスタンスを作成し、 DoModal()を呼び出して独自の複数ファイル選択ダイアログを表示します。

 最後に、SampleProject.cppファイルでMainDlg.hヘッダの前にCustomDlg.hヘッダをインクルードします。