#include "shlobj.h" //包含头文件
函数介绍
1、WINSHELLAPI HRESULT WINAPI SHGetSpecialFolderLocation (HWND hwndOwner, int nFolder,LPITEMIDLIST * ppidl); //函数声明
hwndOwner: 指定了"所有者窗口",在调用这个函数是可能出現的对话框或信息框.
nFolder: 是一个整数id,決定哪个目录是待查找目录,它的取值可能是
CSIDL_BITBUCKET 回收站
CSIDL_CONTROLS 控制面板
CSIDL_DESKTOP Windows桌面desktop;
CSIDL_DESKTOPDIRECTORY desktop的目录;
CSIDL_DRIVES 我的电脑
CSIDL_FONTS 字体目录
CSIDL_NETHOOD 网上邻居
CSIDL_NETWORK 网上邻居virtual folder
CSIDL_PERSONAL 我的文档
CSIDL_PRINTERS 打印机
CSIDL_RECENT 最近打开文档
CSIDL_SENDTO 发送到菜单项
CSIDL_STARTMENU 快启菜单
CSIDL_STARTUP 启动目录
CSIDL_TEMPLATES 临时文档
ppidl: pidl地址. SHGetSpecialFolderLocation把地址写到pidl.
2、SHGetFileInfo
包含在文件#include"shellapi.h"
DWORD SHGetFileInfo( LPCTSTR pszPath,
DWORD dwFileAttributes,
SHFILEINFO FAR* psfi,
UINT cbFileInfo,
UINT uFlags);
SHGetFileInfo()函数提供关于文件系统对象的信息。这个对象可以是文件,文件夹,目录或驱动器根。DWORD的返回是指可能有相当多的返回状态,这与uFlags变量的设置有关。简单地说,使用这个函数,你可以期望:
确定可执行文件的目标平台(Win32,Win16,MS-DOS)
获取各种有特色的文件图标(小的,大的,有关联重叠的,选中的,打开的)
读出其它显示属性,如文件类型(显示在探测器类型列上的简短描述)和显示名(出现在名字列上)
读出任何其它属性,可以是文件特有的,如,是否可以拷贝,移动,删除或重命名,是否它可以形成一个快捷方式,它是否有子文件夹,是否是共享的,是拖拽目标,或有附加的属性页,等等。
3、SHGetPathFromIDList
从LPITEMIDLIST中获取文件路径
//这里给出的是项目中自己写的CDlgOpenSave类,显示我的桌面
void CDlgOpenSave::SetDeskTopList()
{
LPITEMIDLIST lpItemIDList;
SHFILEINFO shinfo;
ListItem LI;
LPWSTR szPath = new TCHAR[MAX_PATH];
DWORD dwType[4] = {CSIDL_RECENT, CSIDL_PERSONAL, CSIDL_DRIVES, CSIDL_DESKTOPDIRECTORY};
FILETYPE FT[4] = {F_RECENT, F_PERSONAL, F_COMPUTER, F_DESKTOP};
CString strDisplayName,strPath;
for (int i=0; i < 4; i++)
{
::SHGetSpecialFolderLocation(m_hWnd, dwType[i], &lpItemIDList);
::SHGetFileInfo((LPCTSTR)lpItemIDList,NULL, &shinfo, sizeof(shinfo),
SHGFI_SYSICONINDEX | SHGFI_DISPLAYNAME | SHGFI_ICON | SHGFI_SMALLICON | SHGFI_PIDL);
::SHGetPathFromIDList(lpItemIDList,szPath);
strDisplayName.Format(_T("%s"),shinfo.szDisplayName);
strPath.Format(_T("%s"), szPath);
if ( i == 3 )
{
m_strDesktop = strPath + _T("\");
m_nCurFolder = 0;
m_vFilePath.clear();
m_vFilePath.push_back(make_pair(m_strDesktop, F_DESKTOP));
ShowListContent(m_strDesktop,i);//显示桌面上的文件
delete[] szPath;
return;
}
if ( i== 2 )
{
strDisplayName = _T("我的电脑");
}
LI.strFileName = strDisplayName;
LI.strFilePath = strPath;
LI.dwFileType = FT[i];
OnNotifyShowListContent(strDisplayName, shinfo, i, LI);
}
delete[] szPath;
}
void CDlgOpenSave::ShowListContent(CString strPath, int nStartIndex)
{
int nFileType = m_pComFileType->GetCurSel();
CString strTypeName = _T("*.*");
if (nFileType > 0 && nFileType < (int)m_vFileType.size())
{
strTypeName = m_vFileType[nFileType];
}
CString strFullPath = strPath + strTypeName;
WIN32_FIND_DATA FindFileData;
int nlength = nStartIndex;
HANDLE hListFile = ::FindFirstFile((LPTSTR)(LPCTSTR)strFullPath, &FindFileData);
if (hListFile != INVALID_HANDLE_VALUE)
{
do
{
CString strFilePathName;
strFilePathName = strPath;
CString strFileName;
strFileName.Format(_T("%s"), FindFileData.cFileName);
strFilePathName += strFileName;
int nHide = (FindFileData.dwFileAttributes) & FILE_ATTRIBUTE_HIDDEN;//过滤隐藏属性
if (!nHide)
{
ShowFileToList(strPath, strFileName,nlength); //ShowFileToList接口
}
}while( ::FindNextFile(hListFile, &FindFileData) );
::FindClose(hListFile);
}
UpdateGobackBtnState();
}
//根据路径将打开的文件显示在对话框列表中
void CDlgOpenSave::ShowFileToList(CString strFilePath, CString strFileName, int &length)
{
if ( strFileName.Compare(_T(".")) ==0 || strFileName.Compare(_T("..") ) ==0 )
return;
CString strPathName = strFilePath + strFileName;
SHFILEINFOW fileInfo;
DWORD_PTR dwPtr = ::SHGetFileInfoW(strPathName,FILE_ATTRIBUTE_HIDDEN, &fileInfo, sizeof(SHFILEINFO), SHGFI_DISPLAYNAME | SHGFI_ICON | SHGFI_TYPENAME);
if (IsShowFile(strPathName))
{
ListItem itList;//这个是自定义的结构体,来存储文件信息
itList.strFileName = strFileName;
itList.strFilePath = strFilePath;
itList.dwFileType = F_NORMAL;
OnNotifyShowListContent(strFileName, fileInfo,length, itList);//添加到界面列表中
length++;
}
else if(::PathIsDirectory(strPathName + _T("\")))
{
ListItem itList;
itList.strFileName = strFileName; //文件名
itList.strFilePath = strFilePath;
itList.dwFileType = F_NORMAL;
OnNotifyShowListContent(strFileName, fileInfo, length, itList);
length++;
}
}
例如:
// The following code to get a folder path which you //select.
BOOL ShellGetOutPath(HANDLE hDlg, LPTSTR lpszRoot, LPTSTR lpszPath, LPCTSTR lpszDesc/* = 0*/)
{
BOOL bRet;
//TCHAR szPath[MAX_PATH];
LPITEMIDLIST lpil;
//HGLOBAL hgMem;
// the following segment define and initialize the BROWSEINFO, prepareing for the SHBrowseForFolder API
BROWSEINFO bi;
bi.hwndOwner=(HWND) hDlg;
IShellFolder *ppshf;
SHGetDesktopFolder(&ppshf);
if(!ppshf)
return FALSE;
LPITEMIDLIST pidlRoot = NULL;
ppshf->ParseDisplayName((HWND)hDlg, NULL, lpszRoot, NULL, &pidlRoot, NULL);
if(!pidlRoot)
return FALSE;
bi.pidlRoot = pidlRoot;
bi.pszDisplayName = lpszPath;//szPath;
//strMsg.LoadString(IDS_STR_FOLDER_OUTPUT);
bi.lpszTitle = lpszDesc;
bi.ulFlags = /*BIF_DONTGOBELOWDOMAIN |*/BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE ;
bi.lpfn = BFFCALLBACK(BrowseCallbackProcInit);
bi.lParam = (LPARAM)lpszPath;
lpil = SHBrowseForFolder(&bi);
if(lpil == NULL)
return FALSE;
bRet = SHGetPathFromIDList(lpil, lpszPath);
CoTaskMemFree(lpil);
//CString strPath = lpszPath;
TCHAR szDrive[_MAX_DRIVE];
_tsplitpath(lpszPath, szDrive, NULL, NULL, NULL);
return bRet;
}
[cpp] view plaincopy
// the callback function for the BROWSEINFO, to implement your own function
// here I try to do that:
// 1, when the user slelect CD/DVD drives, the OK and Make New Folder button
// will be disable.
// 2, Change the title of the dialogbox.
int CALLBACK BrowseCallbackProcInit(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
TCHAR szPath[MAX_PATH];
// TCHAR szTargetPath[MAX_PATH];
TCHAR szDrive[MAX_PATH], szDir[MAX_PATH], szFile[MAX_PATH], szExt[MAX_PATH];
LPCITEMIDLIST pidl;
// WIN32_FIND_DATA FileData;
// HANDLE hSearch;
static HWND hMakeNewFolder=NULL;
TCHAR szWindosText[MAX_PATH+1];
switch(uMsg)
{
case BFFM_SELCHANGED:
{
pidl = LPCITEMIDLIST(lParam);
SHGetPathFromIDList(pidl, szPath);
if (szPath[0] == '/0')
SendMessage(hwnd, BFFM_ENABLEOK, lParam, 0);
_tsplitpath(szPath, szDrive, szDir, szFile, szExt);
TCHAR szRoot[MAX_PATH+1];
lstrcpyn(szRoot,szPath, MAX_PATH);
::PathStripToRoot(szRoot);
// disable when select CD/DVD drive, otherwise enables
if(GetDriveType(szRoot)==DRIVE_CDROM)
{
HWND btnHwnd=GetDlgItem(hwnd,IDOK);
::EnableWindow( btnHwnd, FALSE);
if(hMakeNewFolder)
::EnableWindow(hMakeNewFolder,FALSE);
//SendMessage(hwnd,BFFM_SETSELECTION ,TRUE ,(LPARAM)(_T("C://")));
}
else
{
HWND btnHwnd=GetDlgItem(hwnd,IDOK);
::EnableWindow( btnHwnd, TRUE);
if(hMakeNewFolder)
::EnableWindow(hMakeNewFolder,TRUE);
}
}
break;
case BFFM_INITIALIZED:
{
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)(LPCTSTR)lpData);
//if (szLastPath[0] == '/0')
// SendMessage(hwnd, BFFM_ENABLEOK, lParam, 0);
//Change the caption of the Browse for Folder caption
CString szCaption((LPCTSTR)lpData);
if(szCaption.GetLength()>2)
{
szCaption.LoadString(IDS_SAVE_AGENT_INSTALLER);
SetWindowText(hwnd,szCaption);
}
HWND hChild=GetWindow(hwnd, GW_CHILD);
//Get the tree view handle
//while(hChild)
//{
// TCHAR szClass[256];
// GetClassName(hChild, szClass, 255);
// //
// if (strcmp(szClass, _T("SHBrowseForFolder ShellNameSpace Control")) == 0)
// {
// hTree=hChild;
// break;
// }
// hChild = GetNextWindow(hChild, GW_HWNDNEXT);
//}
while(hChild)
{
GetWindowText(hChild,szWindosText,MAX_PATH);
TCHAR szText[]=_T("&Make New Folder");
if(lstrcmp(szWindosText,szText)==0)
{
//find and keep the make new folder button handle
hMakeNewFolder=hChild;
//::OutputDebugString(_T("find the control"));
//::OutputDebugString(szWindosText);
break;
}
hChild = GetNextWindow(hChild, GW_HWNDNEXT);
}
}
break;
}
return 0;
}