SHBrowseForFolder 的一些使用

 

  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

 

看完了上面的再往下看吧。

 

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

 

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

 

上面就完成了一个使用SHBrowseForFolder的基本例子。另外也对基本的例子有了一些扩充。

 

你可能感兴趣的:(C/C++)