MFC选择目录SHBrowseForFolder选择文件CFileDialog对话框设置默认路径

简介:
CFileDialog会自动记住上一次路径,
SHBrowseForFolder需要写个回调函数,
传值给BROWSEINFO
BaseFunc.h
复制代码
#include < string>

using  namespace std;
namespace BaseFunc
{
     //  选择文件,可设置定位到默认目录
    unsigned selFile( string &strFile, const  string &strExt, bool bOpen);

     //  选择目录,可设置定位初始目录
    unsigned selDir( string &strDir, void *hwnd = NULL);
}
复制代码
BaseFunc.cpp
复制代码
#include  " stdafx.h "
#include <Windows.h>
#include  " BaseFunc.h "

using  namespace std;
using  namespace BaseFunc;

unsigned BaseFunc::selFile(  string &strFile, const  string &strExt, bool bOpen )
{
     string strDir =  " D:\\Downloads "; // 这里通过strFile解析目录,CFileDialog会自动记住
     string filename =  " hi.txt ";   // 通过strFile解析文件名
     string filter = strExt +  " 文件 (*. " + strExt +  " )|*. " + strExt +  " || ";
     string ext =  " . " + strExt;

    CFileDialog dlg(bOpen,ext.c_str(),filename.c_str(),OFN_READONLY|OFN_OVERWRITEPROMPT,filter.c_str(),NULL);
    dlg.GetOFN().lpstrInitialDir = strFile.c_str(); //  默认目录

     if (dlg.DoModal())
    {
        strFile = dlg.GetPathName();
         return IDOK;
    }

     return IDCANCEL;
}

int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData)
{
     switch(uMsg)
    {
     case BFFM_INITIALIZED:
        ::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,lpData);
         break;
    }

     return  0;
}

unsigned BaseFunc::selDir(  string &strDir, void *hwnd /*  = NULL */ )
{
     char szDir[MAX_PATH];
    BROWSEINFO bi; 
    bi.hwndOwner = (HWND)hwnd;
    bi.pidlRoot = NULL;
    bi.pszDisplayName = szDir;
    bi.lpszTitle =  " 选择位置: ";
    bi.iImage =  0;

    bi.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS;
    bi.lpfn = BrowseCallbackProc;
    bi.lParam = (LPARAM)(LPCTSTR)strDir.c_str();

    LPITEMIDLIST lp = SHBrowseForFolder(&bi);
     if (lp && SHGetPathFromIDList(lp,szDir))
    {
        strDir = szDir;
         return IDOK;
    }

     return IDCANCEL;
}
复制代码
selDirDlg.cpp
复制代码
void CselDirDlg::OnBnClickedButtonFile()
{
    CString sFile;
    GetDlgItemText(IDC_EDIT_FILE,sFile);

    std:: string strFile = sFile;
     if (IDOK == BaseFunc::selFile(strFile, " mp3 ", true))
    {
        SetDlgItemText(IDC_EDIT_FILE,strFile.c_str());
    }
}


void CselDirDlg::OnBnClickedButtonDir()
{
    CString sDir;
    GetDlgItemText(IDC_EDIT_DIR,sDir); // 可扩展个返回string

    std:: string strDir = sDir;
     if (IDOK == BaseFunc::selDir(strDir,GetSafeHwnd()))
    {
        SetDlgItemText(IDC_EDIT_DIR,strDir.c_str());
    }
}
复制代码
需要源码的留下邮箱。
url: http://greatverve.cnblogs.com/archive/2012/12/16/SHBrowseForFolder-CFileDialog.html  

注意:目录浏览函数不仅可以选择目录,也可以用来选择一个文件。

下例是一个既可以选择目录也可以选择文件的代码范例。该范例中详细说明了相关消息的含义及使用方法。

 

//目录浏览对话框可能会像回调函数发送3种消息:

//BFFM_INITIALIZED --   通知对话框已经初始化结束。

//                   回调函数响应此消息时通常是做初始选择

//BFFM_SELCHANGED -- 目录浏览对话框当前选择项发生变化时调用此消息。

//                   回调函数响应此消息时通常是显示所选项的相关信息

//BFFM_VALIDATEFAILED -- 表示用户按确认按钮时却发现浏览对话框的编辑框内输入了一个非法名称

//                   回调函数响应此消息时通常是提示客户选择项非法,并确定是否继续显示该对话框

//回调函数可以发送如下几个消息给目录浏览对话框,从而改变目录浏览对话框的面目

//BFFM_SETSELECTION  -- 改变当前选择项目

//BFFM_ENABLEOK      -- 改变“确认”按钮的状态

//BFFM_SETSTATUSTEXT-- 改变目录浏览对话框中状态行消息,当然前提是目录浏览对话框中有状态行

int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData)

{

      switch (uMsg)

      {

      case BFFM_INITIALIZED:

           {

                 //BFFM_INITIALIZED表示浏览对话框已经初化结束,参数lParam为NULL

 

                 //设置初始选项

                 ::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,lpData);

 

                 //关于BFFM_SETSELECTION消息的说明

                 //wParam :标记lParam参数包含一个ITEMIDLIST结构(PIDL)还是一个目录路径名

                 //          如果为TRUE,lParam内容为路径名;否则lParam包含一个路径PIDL。

                 //lParam :内容为浏览对话框所选的路径。如果wParam为TRUE,lParam内容为一个

                 //         以NULL结尾的字符串的指针,否则为PIDL

 

                 break;

           }

      case BFFM_SELCHANGED:

           {

                 //BFFM_SELCHANGED表示选择项已经发生变化,参数lParam包含列表中最新选中项的条目ID

                

                 ITEMIDLIST * pidl; 

                 char path[MAX_PATH]; 

 

                 //根据条目ID取路径信息

                 pidl = (ITEMIDLIST*) lParam;

                 if (SHGetPathFromIDList(pidl, path))

                 {

                      //使得“确认”按钮生效

                      //关于BFFM_ENABLEOK消息的说明

                      //wParam :无意义,可设置为0

                      //lParam :如果为非0,则使能确认按钮;否则失效“确认”按钮

                      ::SendMessage(hwnd,BFFM_ENABLEOK,0,TRUE);

 

                      //读属性

                      DWORD attributes = ::GetFileAttributes(path);

 

                      //命令状态行显示当前所选项的全路径名及其文件属性

                      //关于BFFM_SETSTATUSTEXT消息的说明

                      //wParam :无意义,可设置为0

                      //lParam :指向一个内含状态行提示信息的字符串

                      CString strText;

                      strText.Format("%s%s%s%s",

                            path,

                            attributes & FILE_ATTRIBUTE_HIDDEN ? ",H":"",

                            attributes & FILE_ATTRIBUTE_READONLY ? ",R":"",

                            attributes & FILE_ATTRIBUTE_SYSTEM ? ",S":""

                            );

                      ::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)(LPTSTR)(LPCTSTR)strText);

                 }

                 else

                 {

                      //使得“确认”按钮失效

                      ::SendMessage(hwnd,BFFM_ENABLEOK,0,FALSE);

                      //清状态行信息

                      ::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)(LPTSTR)(LPCTSTR)"");

                 }

 

                 break;

           }

      case BFFM_VALIDATEFAILED:

           {

                 //BFFM_VALIDATEFAILED表示用户在浏览对话框的编辑框内输入了一个非法名称

                 //该消息在用户按“确认”时送出——当然前提是编辑框内输入的名称非法

                 //lParam参数包含了非法输入内容的地址,应用程序可以使用这个消息提示用户输入非法。

                 //另外,此消息的回调函数返回0表示目录浏览对话框旋即关闭,返回其他值则允许对话框继续显示。

 

                 //仅当目录浏览对话框中含有编辑框并且设置了BIF_VALIDATE标记才可能出现此消息

                 //即BROWSEINFO结构中ulFlags含有BIF_EDITBOX|BIF_VALIDATE标志

                 CString strTip;

                 strTip.Format("目录%s非法!",lParam);

 

                 //返回0允许对话框提前关闭,SHBrowseForFolder()返回NULL

                 AfxMessageBox(strTip);

                 return 0;

 

                 //返回1对话框继续显示,因为对话框仍继续显示,可以在状态行显示出错消息

                 //注意:如果此时仍用AfxMessageBox来显示提示信息,提示信息框关闭后,要使焦点重返目录

                 //浏览对话框,需要客户手工移动鼠标激活该对话框才行,这样会使得后继操作不是很方便,所以在状态行显示提示信息比较好

                 //::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)(LPTSTR)(LPCTSTR)strTip);

                 //return 1;

 

                 break;

           }

      default:

           {

                 ASSERT(FALSE);

           }

      }

      return 0;

}

 

void CModifyFileAttributeDlg::OnSelectpath()

{文件目录选择函数SHBrowseForFolder()及其回调函数

      UpdateData(TRUE);

 

      BROWSEINFO bi; 

      char dispname[MAX_PATH], path[MAX_PATH]; 

      ITEMIDLIST * pidl; 

     

      //定义目录浏览对话框的属主

      bi.hwndOwner = 0;

      //确定浏览范围(根目录)

      //只有根目录及其子目录下可以浏览

      //定义为NULL表示名字空间下皆可用

      bi.pidlRoot = NULL;

      //用于接收用户所选目录的显示名

      //经测试,该项并不包含全路径名

      bi.pszDisplayName = dispname; 

      //设置目录浏览对话框的对话框标题

      bi.lpszTitle = "请选择路径:"; 

      //设置状态

      //BIF_BROWSEINCLUDEFILES

      //BIF_RETURNONLYFSDIRS表示只返回目录,

      //BIF_STATUSTEXT表示对话框中有状态行

      //BIF_EDITBOX表示对话框中有编辑框

      //BIF_VALIDATE表示客户按“确认”按钮时检查编辑框内容的合法性

      bi.ulFlags = BIF_BROWSEINCLUDEFILES|BIF_RETURNONLYFSDIRS|BIF_STATUSTEXT|BIF_EDITBOX|BIF_VALIDATE;

      //设置回调函数

      //如果需要设置初始选择项、显示所选项的相关信息、让系统自动校验用户输入

      //的合法性,那么应该使用回调函数;否则可将该项设置为NULL

      bi.lpfn = BrowseCallbackProc; 

      //设置回调函数的lParam参数

      //此处用来传递目录浏览对话框的初始选项

      bi.lParam = (LPARAM)(LPCTSTR)m_strFilePath; 

      //用来接收所选目录的图标(系统图像列表中的序号)

      bi.iImage = 0; 

     

      //显示目录浏览对话框

      if (pidl = SHBrowseForFolder(&bi))

      { 

           //将PIDL转换为字符串

           if (SHGetPathFromIDList(pidl, path))

           {

                 //更新对话框显示,以显示用户的最新选择

                 m_strFilePath = path;

                 TRACE("%s",bi.pszDisplayName);

                 UpdateData(FALSE);

           }

      }






    本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/greatverve/archive/2012/12/16/SHBrowseForFolder-CFileDialog.html,如需转载请自行联系原作者




相关文章
|
安全 网络协议 Ubuntu
【常见开源库的二次开发】HTTP之libcurl库——libcurl使用(二)
【常见开源库的二次开发】HTTP之libcurl库——libcurl使用(二)
1928 2
源文件与模块生成时的文件不同,是否希望调试器使用它?如何解决
源文件与模块生成时的文件不同,是否希望调试器使用它?如何解决
python基础14题(入门必看)
python基础14题(入门必看)
python基础14题(入门必看)
|
缓存 算法 NoSQL
【分布式详解】一致性算法、全局唯一ID、分布式锁、分布式事务、 分布式缓存、分布式任务、分布式会话
分布式系统通过副本控制协议,使得从系统外部读取系统内部各个副本的数据在一定的约束条件下相同,称之为副本一致性(consistency)。副本一致性是针对分布式系统而言的,不是针对某一个副本而言。强一致性(strong consistency):任何时刻任何用户或节点都可以读到最近一次成功更新的副本数据。强一致性是程度最高的一致性要求,也是实践中最难以实现的一致性。单调一致性(monotonic consistency):任何时刻,任何用户一旦读到某个数据在某次更新后的值,这个用户不会再读到比这个值更旧的值。
901 0
|
10月前
Eigen::Matrix4f 是先旋转还是先平移的顺序
Eigen::Matrix4f 是先旋转还是先平移的顺序
361 0
|
10月前
|
传感器 算法 C++
C++ PCL 设置法向量的方向
C++ PCL 设置法向量的方向
176 0
|
10月前
|
数据采集 C++
curl使用小记(二)——远程下载一张图片
curl使用小记(二)——远程下载一张图片
574 0
|
11月前
|
JSON API 数据安全/隐私保护
PyMuPDF 1.24.4 中文文档(十三)(5)
PyMuPDF 1.24.4 中文文档(十三)
342 0
|
存储 Linux 网络安全
在 Linux 中通过 SSH 执行远程命令时,无法自动加载环境变量(已解决)
SSH远程执行命令时遇到“命令未找到”问题,原因是Linux登录方式不同导致环境变量加载差异。解决方案:将环境变量写入`/etc/profile.d/`下的文件,或手动在命令前加载环境变量,如`source /etc/profile`。
994 0
|
安全 Unix Linux
探秘Linux特殊设备文件:(/dev/null,/dev/zero,/dev/random,/dev/urandom等)
探秘Linux特殊设备文件:(/dev/null,/dev/zero,/dev/random,/dev/urandom等)
1006 1