Jason-Yuan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

  MFC提供了CFileDialog 对话框,可以方便地打开打开和保存文件,但是在应用中往往需要选择一个路径而不是固定的文件,MFC并没有提供现成的工具。

void CMyDialog::OnBtnClickedBrowseFile()
{
	CFileDialog FileDialog(
		TRUE,
		(LPCSTR)"txt",
		(LPCSTR)m_TextFile,
		OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
		"TXT file(*.txt)|*.txt|All files(*.*)|*||",
		this
	);

	FileDialog.m_ofn.lpstrInitialDir	= m_TextFile;
	if( FileDialog.DoModal() == IDOK )
	{
		UpdateData( TRUE );
		m_TextFile = FileDialog.GetPathName();
		UpdateData( FALSE );
	}
}

   我们可以利用 SHBrowseForFolderW 选择目录函数,并结合一个回调函数来实现这个功能,并确保如下几点:

  1. 能够传递一个初始路径
  2. 用户可以在整个磁盘区域内浏览
  3. 目录不存在时可以新建
// 回调函数:用于初始化选中路径
int CALLBACK BrowseCallbackProc(
    HWND hwnd,      // 对话框句柄
    UINT uMsg,      // 消息
    LPARAM lParam,  // 消息参数
    LPARAM lpData   // 自定义数据(传递初始路径)
)
{
    switch (uMsg)
    {
        case BFFM_INITIALIZED:  // 对话框初始化完成
        {
            // 发送消息设置初始选中路径(lpData为初始路径的宽字符指针)
            if (lpData != NULL) {
                ::SendMessageW(hwnd, BFFM_SETSELECTIONW, TRUE, lpData);
            }
            break;
        }
        default:
            break;
    }
    return 0;
}

void CMyDialog::OnBtnClickedBrowsePath()
{
    BROWSEINFOW bi = { 0 };
    bi.hwndOwner = this->m_hWnd;
    bi.lpszTitle = L"请选择要保存的目录";
    bi.ulFlags = BIF_RETURNONLYFSDIRS   // 只允许选择文件系统目录
               | BIF_USENEWUI           // 使用带编辑框的新界面
               | BIF_EDITBOX;           // 显示编辑框(可手动输入路径)
               // 移除了 BIF_NONEWFOLDERBUTTON 以显示新建文件夹按钮

    UpdateData(TRUE);

    // 将 CString 转换为宽字符字符串
    CStringW strWInitialPath = CStringW(m_Path);
    
    // 注册回调,用于设置初始路径
    bi.lpfn = BrowseCallbackProc;
    bi.lParam = (LPARAM)(LPCWSTR)strWInitialPath;

    // 不限制根目录(允许浏览所有路径)
    bi.pidlRoot = NULL;

    // 显示目录选择对话框
    LPITEMIDLIST pidlSelected = SHBrowseForFolderW(&bi);
    if (pidlSelected != NULL) {
        WCHAR szPath[MAX_PATH] = { 0 };
        if (SHGetPathFromIDListW(pidlSelected, szPath)) {
            // 将宽字符路径转换回 CString
            m_Path = CString(szPath);
        }
        CoTaskMemFree(pidlSelected);  // 释放内存
    }
    UpdateData(FALSE);
}
posted on 2025-09-15 12:50  12yuan  阅读(46)  评论(0)    收藏  举报