一、打开一个文件目录
实现这个功能要调用
Windows API
函数
SHBrowseForFolder
,入参为
BROWSEINFO
结构的指针,返回一个
ITEMIDLIST
类型的指针,通过这个指针调用函数
SHGetPathFromIDList
可以确定所选择的目录的全名称。
首先要包含头文件
shlobj.h
创建一个如图所示的对话框,调用函数:
LPITEMIDLIST SHBrowseForFolder(
LPBROWSEINFO
lpbi
);
如果用户选择了“取消”,此函数返回
NULL
。
参数:(用来传递和接收函数的信息)
typedef struct _browseinfo {
HWND hwndOwner; //
对话框所有者窗口的句柄
LPCITEMIDLIST pidlRoot; //
表示在哪个路径下选择,通常设为NULL
LPTSTR pszDisplayName; //[
返回]所选目录的名称(不包含父级目录)被拷贝到这个指针指向的位置
LPCTSTR lpszTitle; //
窗口上显示的提示语句
UINT ulFlags; //
组合此对话框的元素标记
BFFCALLBACK lpfn; //
事件产生时对话框调用的函数地址,一般不用,设置为NULL
LPARAM lParam; //
传递给回调函数的参数
int iImage; //
与所选目录相关联的图标在系统图标集合中的索引
} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO;
一般可以不用设计回调函数(将
lpfn
赋值
NULL
),除非有特殊的处理时,如:,将“确定”按钮不可用;
回调函数
:
int CALLBACK BrowseCallbackProc(
HWND hwnd, //
浏览对话框的窗体句柄,用这句柄给上图对话框发消息改变其状态(SendMessage)
UINT uMsg,//
浏览对话框返回的消息
LPARAM lParam, //
消息参数
LPARAM lpData //BROWSEINFO
结构传递的参数
);
把项目标示符表(
LPITEMIDLIST
类型,
SHBrowseForFolder
函数的返回值)转换为文件路径:
BOOL SHGetPathFromIDList(
LPCITEMIDLIST pidl, //
项目标示符表
LPTSTR pszPath //
返回的文件路径
);
总结:
使用这个对话框来获得文件夹路径的步骤是:
1
、声明
BROWSEINFO
结构体对象,填充其各字段;
2
、把上面的结构体作参数,调用
SHBrowseForFolder
函数,获取其返回值为
LPITEMIDLIST
类型对象;
3
、以上个函数的返回值(
LPITEMIDLIST
类型)作为
SHGetPathFromIDList
函数的第一个参数,其第二个参数传出获取的文件夹路径;
4
、另外,可以设计回调函数,给对话框发送消息,和接受对话框的消息来进行响应。
举个例子(控制台程序):
/*
打开一个文件夹,在窗口打印文件路径
*/
#include <iostream>
using namespace std;
#include <windows.h>
#include <tchar.h>
#include <shlobj.h>
int CALLBACK BrowseCallbackProc(HWND hwnd,
UINT uMsg,
LPARAM lParam,
LPARAM lpData
)
{//
浏览导出目录的回调函数。目的是为了可以让上次选择的导出目录直接被选中。
if (BFFM_SELCHANGED == uMsg)
{
TCHAR tchPath[MAX_PATH];
memset(tchPath , 0 ,MAX_PATH );
SHGetPathFromIDList((LPCITEMIDLIST )lParam, tchPath);
if (!tchPath[0] || ':' != tchPath[1])
{
SendMessage(hwnd , BFFM_ENABLEOK , 0 , 0);
}
else
{
SendMessage(hwnd , BFFM_ENABLEOK , 0 , 1);
}
}
return 0;
}
void main()
{
//
从对话框中选择一个目录,返回路径
_TCHAR szDisplayName[_MAX_PATH];
BROWSEINFO browse_info;
browse_info.hwndOwner = NULL;
browse_info.pidlRoot = NULL;
browse_info.lpszTitle = _T("Please select a folder:");
browse_info.pszDisplayName = szDisplayName;
browse_info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_EDITBOX | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE;
browse_info.lpfn = BrowseCallbackProc; //SetSelProc;
browse_info.lParam = (LPARAM)(LPCTSTR)NULL;
LPITEMIDLIST pItemIDList = SHBrowseForFolder(&browse_info);
//
调用函数,打开目录选择对话框
if (pItemIDList==NULL)
{
cout << _T("You selected cancel export.");
}
else
{
_TCHAR tchPath[_MAX_PATH];
SHGetPathFromIDList(pItemIDList, tchPath);
//
获取所选目录的全名
GlobalFree(pItemIDList); //
返回的
pItemIDList
占用了系统资源,不要忘了释放
cout << tchPath;
}
}
二、复制,移动,重命名或删除文件或文件夹
有如下图所示的文件飞行动画:
要包含头文件
shellapi.h
进行拷贝,移动,重命名或删除文件或文件夹
(
包含其子文件、子文件夹
)
的函数:
int SHFileOperation(
LPSHFILEOPSTRUCT lpFileOp
);
其参数是一个
SHFILEOPSTRUCT
结构体对象的地址,此结构体为函数提供操作的信息:
typedef struct _SHFILEOPSTRUCT{
HWND hwnd; //
窗口句柄
UINT wFunc; //
操作:FO_COPY,FO_DELETE,FO_MOVE,FO_RENAME
LPCTSTR pFrom; //
注意是以“/0/0”结尾,“/0”用来分隔两个文件路径
LPCTSTR pTo; //
若From是两个路径,这个参数必须文件夹
FILEOP_FLAGS fFlags; //
控制操作的标志
BOOL fAnyOperationsAborted; //[
返回]如果用户在结束前忽略任何操作,返回TURE
LPVOID hNameMappings;
LPCTSTR lpszProgressTitle;
} SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT;
#include <shellapi.h>
// 复制 SOURCE.TXT 到 DEST.TXT;
char *From = "C://SOURCE.TXT/0";
char *To = "C://DEST.TXT/0";
SHFILEOPSTRUCT op;
ZeroMemory(&op, sizeof(op));
op.hwnd = NULL; // 主窗体或应用程序的句柄
op.wFunc = FO_COPY;
op.pFrom = From;
op.pTo = To;
op.fFlags= 0;
SHFileOperation( &op);
// 移动 SOURCE.TXT 到 windows 的临时目录
char *From = "C://SOURCE.TXT/0";
char *To = "C://WINDOWS//TEMP/0";
SHFILEOPSTRUCT op;
ZeroMemory(&op, sizeof(op));
op.hwnd = NULL;
op.wFunc = FO_MOVE;
op.pFrom = From;
op.pTo = To;
op.fFlags= 0;
SHFileOperation( &op);
// 把所有的临时文件删除到回收站
char *File = "C://windows//temp//*.TMP/0";
SHFILEOPSTRUCT op;
ZeroMemory(&op, sizeof(op));
op.hwnd = NULL;
op.wFunc = FO_DELETE;
op.pFrom = File;
op.fFlags= FOF_ALLOWUNDO;
SHFileOperation( &op);
// 复制 SOURCE.TXT 到 DEST.TXT;
char *From = "C://SOURCE.TXT/0";
char *To = "C://DEST.TXT/0";
SHFILEOPSTRUCT op;
ZeroMemory(&op, sizeof(op));
op.hwnd = NULL; // 主窗体或应用程序的句柄
op.wFunc = FO_COPY;
op.pFrom = From;
op.pTo = To;
op.fFlags= 0;
SHFileOperation( &op);
// 移动 SOURCE.TXT 到 windows 的临时目录
char *From = "C://SOURCE.TXT/0";
char *To = "C://WINDOWS//TEMP/0";
SHFILEOPSTRUCT op;
ZeroMemory(&op, sizeof(op));
op.hwnd = NULL;
op.wFunc = FO_MOVE;
op.pFrom = From;
op.pTo = To;
op.fFlags= 0;
SHFileOperation( &op);
// 把所有的临时文件删除到回收站
char *File = "C://windows//temp//*.TMP/0";
SHFILEOPSTRUCT op;
ZeroMemory(&op, sizeof(op));
op.hwnd = NULL;
op.wFunc = FO_DELETE;
op.pFrom = File;
op.fFlags= FOF_ALLOWUNDO;
SHFileOperation( &op);