【VC++】ファイル選択ダイアログを表示する
<機能>
(1)2種類のファイル選択ダイアログを表示します
・単一ファイルを選択
・複数ファイルを選択
(2)初期フォルダを設定します
(3)2回目以降は前回選択したフォルダを初期表示します
(4)ファイルフィルターを3つ(.bmp/.dat/.*)から選択できます
(5)単一ファイル選択時は選択ファイルパスを表示します
(6)複数ファイル選択時は選択フォルダパスと選択ファイル一覧を表示します
<動作検証&開発環境>
Visual Studio Community 2015
<イメージ>
[ファイル選択1]ボタンで単一ファイルを選択できます
[ファイル選択2]ボタンで複数ファイルを同時選択できます
<使い方>
(1)ダイアログベースでプロジェクト(FileSelect)を作成
(2)ダイアログにコントロールを配置
(3)エディットボックス、リストボックスにメンバ変数を追加
・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
//メンバ変数を追加(自動で追加されるものを含む)
{
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);
{
CDialogEx::OnInitDialog();
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);
}
関数名 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);
if (iMode == 1) {
ofn.lpstrTitle = L"ファイル選択1 単一ファイルを選択してください...";
//存在するファイル名のみ指定できる
ofn.Flags |= OFN_FILEMUSTEXIST;
}
else {
ofn.lpstrTitle = L"ファイル選択2 複数ファイルを選択してください...";
//複数選択ができるようにする、存在するファイル名のみ指定できる
ofn.Flags |= (OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST);
}
//サンプルとして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));
}
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;
}
よろしければポチッと押してください