首先介绍一个兼容Unicode和多字节的方法,定义如下头文件:

 // TString.h;
#pragma once
#include <string> #ifdef UNICODE
typedef std::wstring TString;
#ifndef _T
#define _T(x) L ## x
#endif /* END _T */
#else
typedef std::string TString;
#ifndef _T
#define _T(x) x
#endif /* END _T */
#endif

下面贴出两种方式的代码。

一般使用方法:

 bool SelectFilePath( TString& strFilePath )
{
TCHAR szPathName[MAX_PATH] = {};
BROWSEINFO bInfo = {};
bInfo.hwndOwner = GetForegroundWindow(); // 父窗口;
bInfo.lpszTitle = _T("选择目录");
bInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI /*包含一个编辑框 用户可以手动填写路径 对话框可以调整大小之类的..;*/
| BIF_UAHINT /*带TIPS提示*/ /*| BIF_NONEWFOLDERBUTTON 不带新建文件夹按钮*/;
// 关于更多的 ulFlags 参考 http://msdn.microsoft.com/en-us/library/bb773205(v=vs.85).aspx; LPITEMIDLIST lpDlist;
lpDlist = SHBrowseForFolder(&bInfo);
if ( nullptr == lpDlist ) // 单击了确定按钮;
{
strFilePath.clear();
return false;
}
SHGetPathFromIDList(lpDlist, szPathName);
strFilePath = szPathName;
return true;
}

这样打开的是根目录,每次都定位到根目录中, 很是麻烦。

下面介绍可以设置打开时的默认目录。

 // 此回调函数为全局函数或静态函数;
int CALLBACK BrowseCallbackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData )
{
switch(uMsg)
{
case BFFM_INITIALIZED:
{
::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpData);
}
break;
default:
break;
}
return ;
} bool SelectFilePath( TString& strFilePath )
{
TCHAR szPathName[MAX_PATH] = {};
BROWSEINFO bInfo = {};
TString strDefaultPath = _T("E:\\"); // 注意路径中不要带'\..\'或'\.\'符号,否则设置默认路径失败;
bInfo.hwndOwner = GetForegroundWindow(); // 父窗口;
bInfo.lpszTitle = _T("选择目录");
bInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI /*包含一个编辑框 用户可以手动填写路径 对话框可以调整大小之类的..;*/
| BIF_UAHINT /*带TIPS提示*/ /*| BIF_NONEWFOLDERBUTTON 不带新建文件夹按钮*/;
// 关于更多的 ulFlags 参考 http://msdn.microsoft.com/en-us/library/bb773205(v=vs.85).aspx;
bInfo.lpfn = (CDataBackupDlg::BrowseCallbackProc);
bInfo.lParam = (LPARAM)(LPCTSTR)(strDefaultPath.c_str()); LPITEMIDLIST lpDlist;
lpDlist = SHBrowseForFolder(&bInfo);
if ( nullptr == lpDlist ) // 单击了确定按钮;
{
strFilePath.clear();
return false;
}
SHGetPathFromIDList(lpDlist, szPathName);
strFilePath = szPathName;
return true;
}

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

详细介绍一下回调函数的相关知识。

//目录浏览对话框可能会像回调函数发送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,,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,,(LPARAM)(LPTSTR)(LPCTSTR)strText);
}
else
{
//使得“确认”按钮失效
::SendMessage(hwnd,BFFM_ENABLEOK,,FALSE); //清状态行信息
::SendMessage(hwnd,BFFM_SETSTATUSTEXT,,(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 ; //返回1对话框继续显示,因为对话框仍继续显示,可以在状态行显示出错消息
//注意:如果此时仍用AfxMessageBox来显示提示信息,提示信息框关闭后,要使焦点重返目录
//浏览对话框,需要客户手工移动鼠标激活该对话框才行,这样会使得后继操作不是很方便,所以在状态行显示提示信息比较好
//::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)(LPTSTR)(LPCTSTR)strTip);
//return 1;
break;
}
default:
{
ASSERT(FALSE);
}
}
return ;
}

WINDOWS选择目录SHBrowseForFolder使用方法介绍的更多相关文章

  1. 在Linux下访问Windows共享目录的配置方法

    在Linux下访问Windows共享目录的配置方法 1.在Windows上设置一个共享目录 如:将d:\RedHat_disk设置为共享目录 2.在Windows上创建一个用户,如tommy,密码11 ...

  2. Linux访问Windows共享目录的方法——smbclient

    之前写过Ubuntu访问Windows共享目录,里面主要介绍如何在GUI上访问windows共享目录. 本文侧重于整理通过命令行访问的方法. 先确保smbclient.ubuntu下可以直接运行下面命 ...

  3. 如何在VBS脚本中显示“选择文件对话框”或“选择目录对话框”

    .选择文件[XP操作系统,不能用于Win2000或98],使用“UserAccounts.CommonDialog”对象向用户显示一个标准的“文件打开”对话框 Set objDialog = Crea ...

  4. Windows下获取本机IP地址方法介绍

    Windows下获取本机IP地址方法介绍 if((hostinfo = gethostbyname(name)) != NULL) { #if 1 ; printf("IP COUNT: % ...

  5. windows下重置mysql的root密码方法介绍(转)

    自己在内网操作的,遇到了一些的问题,其中一个是需要重置密码的,所以网上找了两篇文章,都有一些借鉴的地方. 版本mysql5.7.2,linux系统 除了参考文章还有几点说明: service mysq ...

  6. ubuntu 挂载windows共享目录的方法

    建立windows共享目录 右击要共享的文件夹-->属性-->高级共享-->添加用户-->添加完全控制权限 假设建立的共享地址为\\192.168.1.100\Linux 获取 ...

  7. winFrom 常用控件属性及方法介绍

    目录 1.窗体(Form) 2.Label (标签)控件 3.TextBox(文本框)控件 4.RichTextBox控件 5.NumericUpDown控件 6.Button(按钮)控件 7.Gro ...

  8. Cassandra在Windows上安装及使用方法

    http://archive.apache.org/dist/cassandra/2.1.2/ http://docs.datastax.com/en/landing_page/doc/landing ...

  9. C# 常用控件属性及方法介绍

      C#常用控件属性及方法介绍                                               目录 1.窗体(Form) 2.Label (标签)控件 3.TextBox ...

随机推荐

  1. mysql数据库优化思路

    1.设置合适的主键和索引. (1).设置主键和索引的字段尽量不要选取经常修改的字段,同时索引的个数一般不宜超过6个: (2).sql语句中like  “%str%” 不支持索引, "str% ...

  2. react 实现类似vue中的<keep-alive>的功能,并解决antd-mobile切换回来时的空白

    在移动端的spa页面中,只要使用到了路由就很有必要使用到状态保存的功能,这样才能保证在页面进行切换的时候,让用户可以看到刚才滑动的地方,让用户的体验更加友好.这儿我找到了react-router-ca ...

  3. NOI2016

    luoguP1712 [NOI2016]区间 这是一道送分题. 对于我这种每天抄题解不动脑子思维僵化得厉害的智障选手就是送命题. 一直在想端点排序各种Treap搞... 正解: 已知一些区间,如何判断 ...

  4. 运用shtml类型文件,实现项目页面的分割。

    学过动态网页,如asp.php的人知道如何去引用网站头部.底部文件包含.例如在php中有一个方法:include();这个方法能在当前文档中引入外部文件,从而方便网站的开发和维护,然而html静态文件 ...

  5. Linux课程---12、linux中内存指令(top命令的作用是什么)

    Linux课程---12.linux中内存指令(top命令的作用是什么) 一.总结 一句话总结: top实时观察进程.内存和CPU情况 1.电脑出现反应慢情况,最先想到的是什么? 内存 2.linux ...

  6. (一)通过JAVA连接SAP (sapjco3.jar在Windows和MacOS上的配置)

    (一)通过JAVA连接SAP调用接口 (sapjco3.jar在Windows和MacOS上的配置) 一.sapjoc3.jar获取 由于sap官网提供的链接需要合作公司提供账号密码,如果商用请索要正 ...

  7. mui 上拉加载 实现分页加载功能

    mui 上拉加载 实现分页加载功能,效果图: 分页功能(上拉加载): 1.引入需要的css.js文件 <link href="static/css/mui.css" rel= ...

  8. Python中好用的模块们

    目录 Python中好用的模块们 datetime模块 subprocess模块 matplotlib折线图 importlib模块 Python中好用的模块们 datetime模块 ​ 相信我们都使 ...

  9. selenium基础(获取验证信息-断言)

    获取验证信息 实际结果与预期结果进行比较称之为断言 通过获取title.URL.text等信息进行断言 text方法用于获取标签对之间的文本信息 from selenium import webdri ...

  10. centos zabbix4.0编译安装

    zabbix的部署原理 zabbix server需要把监控数据入sql数据库,所以得Mysql环境 zabbix的web是基于php开发的,所以得LNMP环境 部署zabbix server和zab ...