SHBrowseForFolder是一个可以用于获取文件夹路径的Windows API。使用起来可以方便很多,近来在写程序时用到了,现在总结一下。

  首先当然要有一些基本认识才行。所以先看一下下面所列的MSDN。

http://msdn.microsoft.com/en-us/library/bb762115%28VS.85%29.aspx

http://msdn.microsoft.com/en-us/library/bb773205%28VS.85%29.aspx

 

SHBrowseForFolder是一个可以用于获取文件夹路径的Windows API。使用起来可以方便很多,近来在写程序时用到了,现在总结一下。
  首先当然要有一些基本认识才行。所以先看一下下面所列的MSDN。
http://msdn.microsoft.com/en-us/library/bb762115%28VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/bb773205%28VS.85%29.aspx
看完了上面的再往下看吧。
1. // The following code to get a folder path which you //select.  
2.  BOOL ShellGetOutPath( HANDLE hDlg,  LPTSTR lpszRoot,  LPTSTR lpszPath,  LPCTSTR lpszDesc/* = 0*/)  
3. {  
4.      BOOL bRet;  
5.     //TCHAR szPath[MAX_PATH];  
6.     LPITEMIDLIST lpil;  
7.     //HGLOBAL hgMem;  
8.       
9.     // the following segment define and initialize the BROWSEINFO, prepareing for the SHBrowseForFolder API  
10.    BROWSEINFO bi;  
11.    bi.hwndOwner=( HWND) hDlg;  
12.    IShellFolder *ppshf;  
13.    SHGetDesktopFolder(&ppshf);  
14.     if(!ppshf)  
15.         return FALSE;  
16.    LPITEMIDLIST pidlRoot = NULL;  
17.    ppshf->ParseDisplayName(( HWND)hDlg, NULL, lpszRoot, NULL, &pidlRoot, NULL);  
18.     if(!pidlRoot)  
19.         return FALSE;  
20.    bi.pidlRoot = pidlRoot;  
21.    bi.pszDisplayName = lpszPath;//szPath;  
22.    //strMsg.LoadString(IDS_STR_FOLDER_OUTPUT);  
23.    bi.lpszTitle = lpszDesc;  
24.    bi.ulFlags = /*BIF_DONTGOBELOWDOMAIN |*/BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE ;  
25.    bi.lpfn =  BFFCALLBACK(BrowseCallbackProcInit);  
26.    bi.lParam = ( LPARAM)lpszPath;  
27.    lpil = SHBrowseForFolder(&bi);  
28.     if(lpil == NULL)  
29.         return FALSE;  
30.    bRet = SHGetPathFromIDList(lpil, lpszPath);  
31.    CoTaskMemFree(lpil);  
32.    //CString strPath = lpszPath;  
33.     TCHAR szDrive[_MAX_DRIVE];  
34.    _tsplitpath(lpszPath, szDrive, NULL, NULL, NULL);  
35.     return bRet;  
36.}  
1. // the callback function for the BROWSEINFO, to implement your own function  
2. // here I try to do that:  
3. //  1, when the user slelect CD/DVD drives, the OK and Make New Folder button  
4. //     will be disable.  
5. //  2, Change the title of the dialogbox.  
6.  int CALLBACK BrowseCallbackProcInit( HWND hwnd,  UINT uMsg,  LPARAM lParam,  LPARAM lpData)  
7. {  
8.      TCHAR szPath[MAX_PATH];  
9.     //  TCHAR szTargetPath[MAX_PATH];  
10.     TCHAR szDrive[MAX_PATH], szDir[MAX_PATH], szFile[MAX_PATH], szExt[MAX_PATH];  
11.    LPCITEMIDLIST pidl;  
12.    //  WIN32_FIND_DATA FileData;   
13.    //  HANDLE hSearch;   
14.     static  HWND hMakeNewFolder=NULL;  
15.      
16.     TCHAR szWindosText[MAX_PATH+1];  
17.     switch(uMsg)  
18.    {  
19.     case BFFM_SELCHANGED:  
20.        {  
21.            pidl = LPCITEMIDLIST(lParam);  
22.            SHGetPathFromIDList(pidl, szPath);            
23.             if (szPath[0] == '\0')  
24.                SendMessage(hwnd, BFFM_ENABLEOK, lParam, 0);  
25.            _tsplitpath(szPath, szDrive, szDir, szFile, szExt);       
26.             TCHAR szRoot[MAX_PATH+1];  
27.            lstrcpyn(szRoot,szPath, MAX_PATH);  
28.            ::PathStripToRoot(szRoot);  
29.            // disable when select CD/DVD drive, otherwise enables  
30.             if(GetDriveType(szRoot)==DRIVE_CDROM)  
31.            {  
32.                 HWND btnHwnd=GetDlgItem(hwnd,IDOK);  
33.                ::EnableWindow( btnHwnd, FALSE);  
34.                 if(hMakeNewFolder)  
35.                    ::EnableWindow(hMakeNewFolder,FALSE);  
36.                //SendMessage(hwnd,BFFM_SETSELECTION ,TRUE ,(LPARAM)(_T("C:\\")));  
37.            }  
38.             else  
39.            {  
40.               HWND btnHwnd=GetDlgItem(hwnd,IDOK);  
41.             ::EnableWindow( btnHwnd, TRUE);  
42.              if(hMakeNewFolder)  
43.                 ::EnableWindow(hMakeNewFolder,TRUE);  
44.            }  
45.       
46.        }  
47.         break;  
48.     case BFFM_INITIALIZED:  
49.        {  
50.            SendMessage(hwnd, BFFM_SETSELECTION, TRUE, ( LPARAM)( LPCTSTR)lpData);  
51.            //if (szLastPath[0] == '\0')  
52.            //  SendMessage(hwnd, BFFM_ENABLEOK, lParam, 0);  
53.            //Change the caption of the Browse for Folder caption  
54.            CString szCaption(( LPCTSTR)lpData);  
55.             if(szCaption.GetLength()>2)  
56.            {  
57.                szCaption.LoadString(IDS_SAVE_AGENT_INSTALLER);  
58.                SetWindowText(hwnd,szCaption);  
59.            }  
60.             HWND   hChild=GetWindow(hwnd, GW_CHILD);  
61.            //Get the tree view handle  
62.            //while(hChild)  
63.            //{  
64.            //  TCHAR szClass[256];  
65.            //  GetClassName(hChild, szClass, 255);  
66.            //  //   
67.            //  if (strcmp(szClass, _T("SHBrowseForFolder ShellNameSpace Control")) == 0)  
68.            //  {  
69.   //                     hTree=hChild;  
70.            //          break;  
71.            //  }  
72.            //  hChild = GetNextWindow(hChild, GW_HWNDNEXT);  
73.            //}  
74.          while(hChild)  
75.          {  
76.                GetWindowText(hChild,szWindosText,MAX_PATH);  
77.                 TCHAR szText[]=_T("&Make New Folder");  
78.                 if(lstrcmp(szWindosText,szText)==0)  
79.                {        
80.                                        //find and keep the make new folder button handle  
81.                    hMakeNewFolder=hChild;     
82.                    //::OutputDebugString(_T("find the control"));  
83.                    //::OutputDebugString(szWindosText);  
84.                     break;  
85.                }  
86.                hChild = GetNextWindow(hChild, GW_HWNDNEXT);  
87.            }  
88.              
89.        }  
90.         break;  
91.    }  
92.     return 0;  
93.}  
上面就完成了一个使用SHBrowseForFolder的基本例子。另外也对基本的例子有了一些扩充。