SPDL: SHGetSpecialFolderLocation()、SHGetFileInfo()、SHGetPathFromIDList()函数

6 篇文章 0 订阅

#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;  
}  

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值