プログラム悪戦苦闘日記

はてなダイアリーからの移行(遺物)

いまさら、フォルダダイアログの出し方 (MFC)

 
いまさらだが、フォルダダイアログはコモンコントロールにないので自分で作る必要がある。やり方は2つあって、

  • SHBrowseForFolderをつかったエクスプローラ
  • CFileDialogでフォルダも選択できるようにしたもの

だ。前者は有名だが、後者はマイナーだ。CFileDialog::OnFolderChange()をオーバーライドする。
 
後者のサンプルをのせておく。
FileFolderDlg.h

#pragma once

// CFileFolderDlg
class CFileFolderDlg : public CFileDialog
{
	DECLARE_DYNAMIC(CFileFolderDlg)

public:
	CFileFolderDlg(BOOL bOpenFileDialog, // FileOpen に TRUE を、FileSaveAs に FALSE を指定します。
		LPCTSTR lpszDefExt = NULL,
		LPCTSTR lpszFileName = NULL,
		DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		LPCTSTR lpszFilter = NULL,
		CWnd* pParentWnd = NULL);
	virtual ~CFileFolderDlg();

protected:
	virtual void OnFolderChange();

	DECLARE_MESSAGE_MAP()

private:
	CString m_oldFolder;
};

FileFolderDlg.cpp

#include "stdafx.h"
#include "FileFolderDlg.h"

// CFileFolderDlg
IMPLEMENT_DYNAMIC(CFileFolderDlg, CFileDialog)
CFileFolderDlg::CFileFolderDlg(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
		DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :
		CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd)
			, m_oldFolder(_T("C:\\"))
{
}

CFileFolderDlg::~CFileFolderDlg()
{
}

BEGIN_MESSAGE_MAP(CFileFolderDlg, CFileDialog)
END_MESSAGE_MAP()

// CFileFolderDlg メッセージ ハンドラ
void CFileFolderDlg::OnFolderChange()
{
    CString strFolderPath = GetFolderPath();
	TRACE("%s\n", static_cast<const char*>(strFolderPath));
    if (m_oldFolder != strFolderPath)
        m_oldFolder = strFolderPath;
    else {
        CPoint point;
        GetCursorPos(&point);
        CRect rect;
        GetParent()->GetDlgItem(IDOK)->GetWindowRect(&rect);
		
        // マウスポインタが「開く」ボタンの上にある
		if (rect.PtInRect(point)) {
            // フォルダ名をセット
			strncpy(m_ofn.lpstrFile, (LPCTSTR)strFolderPath, m_ofn.nMaxFile);
            if (OnFileNameOK() == FALSE) {
                // ダイアログを閉じる
                CDialog *pParent = (CDialog *)GetParent();
                if (pParent != NULL)
                    pParent->EndDialog(IDOK);
            }
        }
    }

    CFileDialog::OnFolderChange();
}