目录处理的Shell函数

一、打开一个文件目录
实现这个功能要调用 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);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值