【VC++】ファイル選択ダイアログを表示する

0

    <機能>

    (1)2種類のファイル選択ダイアログを表示します

     ・単一ファイルを選択

     ・複数ファイルを選択

    (2)初期フォルダを設定します

    (3)2回目以降は前回選択したフォルダを初期表示します

    (4)ファイルフィルターを3つ(.bmp/.dat/.*)から選択できます

    VC++,MFC,ファイル選択,初期フォルダ,複数ファイル,ファイルフィルター,前回選択,OPENFILENAME,CFileDialog,

    (5)単一ファイル選択時は選択ファイルパスを表示します

    (6)複数ファイル選択時は選択フォルダパスと選択ファイル一覧を表示します

     

    <動作検証&開発環境>

    Visual Studio Community 2015

     

    <イメージ>

    [ファイル選択1]ボタンで単一ファイルを選択できます

    [ファイル選択2]ボタンで複数ファイルを同時選択できます

    VC++,MFC,ファイル選択,初期フォルダ,複数ファイル,ファイルフィルター,前回選択,OPENFILENAME,CFileDialog,

     

    <使い方>

    (1)ダイアログベースでプロジェクト(FileSelect)を作成

    (2)ダイアログにコントロールを配置

    VC++,MFC,ファイル選択,初期フォルダ,複数ファイル,ファイルフィルター,前回選択,OPENFILENAME,CFileDialog,

    (3)エディットボックス、リストボックスにメンバ変数を追加

    VC++,MFC,ファイル選択,初期フォルダ,複数ファイル,ファイルフィルター,前回選択,OPENFILENAME,CFileDialog,

    ・IDC_EDIT1

     変数名:m_Edt1

     アクセス:private

     変数の種類:CString

     コントロール変数:チェックOn

     カテゴリ:Value

    ・IDC_EDIT2

     変数名:m_Edt2

     アクセス:private

     変数の種類:CString

     コントロール変数:チェックOn

     カテゴリ:Value

    ・IDC_LIST1

     変数名:m_List1

     アクセス:private

     変数の種類:CListBox

     コントロール変数:チェックOn

     カテゴリ:Control

     

    (4)ボタンクリックイベントを追加

    (5)コードを記述

     

    //FileSelectDlg.h

    //メンバ変数を追加(自動で追加されるものを含む)

    class CFileSelectDlg : public CDialogEx
    {
        //〜〜省略〜〜
    private:
        CString m_Edt1;
        CString m_Edt2;
        CListBox m_List1;
        //初回選択時は実行ファイル格納フォルダを初期表示する
        CString m_ModuleFol;
        //複数選択用にファイルパスは配列に格納する
        CStringArray csa;
    public:
        afx_msg void OnBnClickedBtnsel1();
        afx_msg void OnBnClickedBtnsel2();
    };

     

    //FileSelectDlg.cpp

    //プロトタイプ宣言
    BOOL GetFilePath(CStringArray& csaPath, CString csCurrent, int iMode);
    CString SplitFilePath(CString csPath, int kbn);
    int isExistFile(CString csPath);
    BOOL CFileSelectDlg::OnInitDialog()
    {
        CDialogEx::OnInitDialog();
        //〜〜省略〜〜
        //ファイル選択1の結果を初期化
        m_Edt1 = "";
        m_Edt2 = "";
        UpdateData(FALSE);
        //ファイル選択2の結果を初期化
        m_List1.ResetContent();
        //ファイルダイアログを初回表示する際は実行ファイルのパスを表示する
        char cbuf[2048];
        CStringW cwk;
        ZeroMemory(&cbuf, sizeof(cbuf));
        GetModuleFileName(NULL, (LPWSTR)cbuf, sizeof(cbuf));
        cwk.Format(L"%s",cbuf);
        m_ModuleFol = SplitFilePath(cwk, 1);
        return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
    }

     

    /*************************************************
    関数名 OnBnClickedBtnsel1
    機能   ファイル選択1(単一選択)ボタン押下イベント
    *************************************************/

    void CFileSelectDlg::OnBnClickedBtnsel1()
    {
        CString csCur;
        int iwk;
        UpdateData(TRUE);
       
        //選択中のファイルがあればその格納フォルダを初期表示フォルダとする
        iwk = isExistFile(m_Edt1);
        if (iwk == 1) {
            //前回の選択フォルダを取得
            csCur = SplitFilePath(m_Edt1, 1);
        }
        else {
            //パスが存在しない
            csCur = m_ModuleFol;
        }

     

        //単一ファイル選択
        if (GetFilePath(csa, csCur, 1)) {
            if (csa.GetSize() > 0) {
                m_Edt1 = csa.GetAt(0);
            }else{
                //何もしない(前回選択ファイルをそのまま表示)
            }
        }
        UpdateData(FALSE);
    }

     

    /*************************************************
    関数名 OnBnClickedBtnsel2
    機能   ファイル選択2(複数選択)ボタン押下イベント
    *************************************************/

    void CFileSelectDlg::OnBnClickedBtnsel2()
    {
        CString csCur;
        int iwk;
        UpdateData(TRUE);

     

        //選択中のファイルがあればその格納フォルダを初期表示フォルダとする
        iwk = isExistFile(m_Edt2);
        if (iwk == 2) {
            //前回の選択フォルダ
            csCur = m_Edt2;
        }
        else {
            //パスが存在しない
            csCur = m_ModuleFol;
        }
        //複数ファイル選択
        if (GetFilePath(csa, csCur, 2)) {
            if (csa.GetSize() > 0) {
                m_List1.ResetContent();
                for (int i = 0; i < csa.GetSize(); i++) {
                    m_List1.AddString(SplitFilePath(csa.GetAt(i), 2));
                }
                //選択フォルダを保持
                m_Edt2 = SplitFilePath(csa.GetAt(0),1);
            }else{
                //何もしない(前回選択ファイルをそのまま表示)
            }
        }
        UpdateData(FALSE);
    }

    /*************************************************
    関数名 GetFilePath
    機能   ファイル選択ダイアログよりファイルを選択する
    csaPath  : 取得ファイルリスト
    csCurrent: 初期表示するフォルダ
    iMode    : 1(単一ファイル選択) 1以外(複数ファイル選択)
    *************************************************/

    BOOL GetFilePath(CStringArray& csaPath, CString csCurrent, int iMode)
    {
        CString csBuf;
        //ファイルリストを初期化
        csaPath.RemoveAll();
        //ファイルダイアログを用意
        //[ファイルを開く]ダイアログ:TRUE
        //[ファイルを保存]ダイアログ:FALSE
        CFileDialog fdl(TRUE);
        //OPENFILENAME構造体に値をセット
        //OPENFILENAME構造体についてはmsdn参照(英語のみ)
        OPENFILENAME& ofn = fdl.GetOFN();
        //ダイアログのタイトルとフラグをセット
        if (iMode == 1) {
            ofn.lpstrTitle = L"ファイル選択1 単一ファイルを選択してください...";
            //存在するファイル名のみ指定できる
            ofn.Flags |= OFN_FILEMUSTEXIST;
        }
        else {
            ofn.lpstrTitle = L"ファイル選択2 複数ファイルを選択してください...";
            //複数選択ができるようにする、存在するファイル名のみ指定できる
            ofn.Flags |= (OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST);
        }
        //ファイルのフィルター(ビットマップあるいはdatあるいは全てのファイル)
        //サンプルとして3つのフィルターを記載
        ofn.lpstrFilter = _T("ビットマップファイル (*.bmp)¥0*.bmp¥0")
            _T("バイナリファイル (*.dat)¥0*.dat¥0")
            _T("すべて (*.*)¥0*.*¥0¥0");
        //最初に一番上のフィルターを初期表示する
        ofn.nFilterIndex = 0;
        //パスが格納されるバッファサイズ
        //複数ファイル選択用に大きめに用意
        ofn.lpstrFile = csBuf.GetBuffer(MAX_PATH * 100);
        ofn.nMaxFile = MAX_PATH * 100;
        //初期表示フォルダ
        ofn.lpstrInitialDir = csCurrent;
        //ダイアログ表示
        if (fdl.DoModal() != IDOK){
            csBuf.ReleaseBuffer();
            return FALSE;
        }
        //ファイル名を取得
        POSITION pos = fdl.GetStartPosition();
        while (pos)
        {
            csaPath.Add(fdl.GetNextPathName(pos));
        }
        csBuf.ReleaseBuffer();
        return TRUE;
    }


    /*************************************************
    関数名 SplitFilePath
    機能   最後の'¥'から分割した文字列を返す
    csPath    : 対象のファイルパス
    kbn      : 1('¥'より前) 1以外('¥'より後)
    *************************************************/

    CString SplitFilePath(CString csPath, int kbn)
    {
        return kbn == 1 ? csPath.Left(csPath.ReverseFind('¥¥')) : csPath.Mid(csPath.ReverseFind('¥¥') + 1);
    }

     

    /*************************************************
    関数名 isExistFile
    機能   ファイル(フォルダ)が存在するかチェックする
    戻り値 0(存在しない) 1(ファイルパス) 2(フォルダパス)
    csPath   : 対象のパス
    *************************************************/

    int isExistFile(CString csPath)
    {
        //存在チェックとフォルダ判定を実施
        CFileFind   fFind;
        int            iRtn = 0;
        if (fFind.FindFile(csPath)) {
            fFind.FindNextFile();
            if (fFind.IsDirectory()) {
                //フォルダパス
                iRtn = 2;
            }
            else {
                //ファイルパス
                iRtn = 1;
            }
        }else {
            //実在しないパス
            iRtn = 0;
        }
        fFind.Close();
        return iRtn;
    }

    よろしければポチッと押してください


    プログラマー ブログランキングへ



    selected entries

    categories

    calendar

    S M T W T F S
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
    << November 2018 >>

    profile

    others

    archives