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,如需转载请自行联系原作者




相关文章
|
4月前
|
安全 Windows
Windows 10 用户变量、系统变量等环境变量新建、编辑修改与删除方法
Windows 10 用户变量、系统变量等环境变量新建、编辑修改与删除方法
|
Java Android开发
eclipse修改文件打开的默认样式
1.在当前jsp页面里面,右击——open with——jsp Edit。这样只是设置当前的页面的打开类型,为jsp编辑类型。
67 0
PyQt5 技术篇-调用文件对话框获取文件、文件夹路径。文件对话框返回选中的多个文件路径
PyQt5 技术篇-调用文件对话框获取文件、文件夹路径。文件对话框返回选中的多个文件路径
2352 0
PyQt5 技术篇-调用文件对话框获取文件、文件夹路径。文件对话框返回选中的多个文件路径
win7,如何把文件夹和文件,视图改成平铺,默认是列表
win7,如何把文件夹和文件,视图改成平铺,默认是列表
154 0
|
Windows
MFC中修改默认启动对话框方法
// CMyAppEApp 初始化BOOL CMyAppEApp::InitInstance(){// 如果一个运行在 Windows XP 上的应用程序清单指定要// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,//则需要 InitCommonControls()。
1365 0
|
Windows
win7下将dll文件的打开方式改回系统默认
打开注册表,定位到HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.dll把除OpenWithProgids外的键全部删除,重启电脑,OK,dll文件又恢复系统默认的技术改变世界! ...
986 0
|
Shell Windows
右键添加复制路径选项
原文:右键添加复制路径选项 右键添加复制路径选项 周银辉     效果:   注册表导入(保存为xxx.reg, 双击导入): Windows Registry Editor Version 5.
930 0
MFC更改菜单名称后进行编译还是原来的名称
问题: 用vc2010 随便弄一个有菜单的程序 然后使用资源管理器(在Menu那个树目录中)添加一个菜单,并加入对应的ID,编译运行,新添加的菜单正常显示 这个时候,我想更改一下新添加的菜单的名字 双击后打开属性,在cap...
1549 0