最近做了个小软件,其中要使用用户指定的文件夹中的文件,后来发现要实现文件夹的选择还挺费劲,我把查的资料整理了一下,供大家参考,省得大家在这些小问题上耽误时间,哈。提供了两种方法,(哈,起个名吧,仅为了区分,要不叫猫猫、狗狗也行,哈)第一种为类封装法; 第二种为成员函数法。 一、 类封装法 (1)增加文件夹选择类声明文件 //保留人的版权吧,劳动光荣 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // GETFLDER.H文件 /************************************************************************ GETFLDER.H Defines the interface to a for a MFC DDX_ routine to get a directory/folder Using the file open/save as common dialogs. Copyright 1997-2001 TechSmith Corporation. All rights reserved. *************************************************************************/ #ifndef __GETFLDER_H__ #define __GETFLDER_H__ class CBrowseForFolder : public CObject { public: CBrowseForFolder( CWnd * pWnd, UINT uEditID, UINT uCaptionID ); int DoBrowseForFolder( void ); protected: static int CALLBACK SetSelProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData); CWnd * m_pWnd; // CWnd of the calling dialog box UINT m_uCaptionID; // String ID for browse caption text UINT m_uEditID; // ID of the edit control to receive folder text public: CString m_sInitialDir; // String of the initial path the dialog should display }; #endif //__GETFLDER_H__ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// (2)增加文件夹选择类执行文件 // GetFlder.CPP文件 /************************************************************************ GetFlder.CPP Copyright 1997-2001 TechSmith Corporation. All rights reserved. *************************************************************************/ ///////////////////////////////// Includes ////////////////////////////////// #include "stdafx.h" #include "GetFlder.h" CBrowseForFolder::CBrowseForFolder( CWnd * pWnd, UINT uEditID, UINT uCaptionID ) { m_pWnd = pWnd; m_uEditID = uEditID; m_uCaptionID = uCaptionID; // String ID for browse caption text m_sInitialDir = ""; m_pWnd->GetDlgItemText( uEditID, m_sInitialDir ); } int CBrowseForFolder::DoBrowseForFolder() { CString sTitle; int nRet = IDCANCEL; // Initialize dialog caption if (!sTitle.LoadString( m_uCaptionID )) { TRACE1("Error: failed to load message box prompt string 0x%04x.n", m_uCaptionID ); ASSERT(FALSE); } // SHBrowseForFolder only available with the Win95 shell interface TCHAR sDisplayName[_MAX_PATH]; BROWSEINFO bi; // strip off any trailing blanks and '' because SHBrowseForFolder doesn't like them m_sInitialDir.TrimRight(); if ( ! m_sInitialDir.IsEmpty() && m_sInitialDir.GetAt( m_sInitialDir.GetLength()-1 ) == '' ) { m_sInitialDir = m_sInitialDir.Left( m_sInitialDir.GetLength()-1 ); } bi.hwndOwner = m_pWnd->m_hWnd; bi.pidlRoot = NULL; bi.lpszTitle = sTitle; bi.pszDisplayName = sDisplayName; bi.ulFlags = BIF_RETURNONLYFSDIRS; bi.lpfn = SetSelProc; bi.lParam = (LPARAM)(LPCSTR)m_sInitialDir; LPITEMIDLIST pItemIDList = SHBrowseForFolder(&bi); if (pItemIDList) { TCHAR sPath[_MAX_PATH]; if (SHGetPathFromIDList(pItemIDList, sPath)) { m_pWnd->SetDlgItemText( m_uEditID, sPath); m_sInitialDir = sPath; nRet = IDOK; } //avoid memory leaks by deleting the PIDL //using the shells task allocator IMalloc* pMalloc; if ( SHGetMalloc(&pMalloc) != NOERROR ) { TRACE("Failed to get pointer to shells task allocator"); return( nRet ); } pMalloc->Free( pItemIDList ); if (pMalloc) pMalloc->Release(); } return( nRet ); } int CALLBACK CBrowseForFolder::SetSelProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { // Set the initial directory to directory found in the current edit box if ( uMsg == BFFM_INITIALIZED ) { ::SendMessage( hWnd, BFFM_SETSELECTION, TRUE, lpData ); } return 0; } //////////////////////////////////////////////////////////////////////////////////////////////////////// (3)增加文件夹选择类调用函数 /* *函数功能:类封装法实现文件夹选择,具有路径记忆功能 */ void CBrowseDlg::OnButtonSelectpathA() { CBrowseForFolder MyBrowseDlg( this, IDC_EDIT_PATH_A, IDS_BROWSE_FOLDER ); MyBrowseDlg.DoBrowseForFolder(); } IDC_EDIT_PATH_A:输入框ID IDS_BROWSE_FOLDER:选择提示文字 二、 成员函数法 将SelectPath函数加入到你的文件中即可 IDC_EDIT_PATH_B:输入框ID /* *函数功能:函数法实现文件夹选择,比较简洁 */ void CBrowseDlg::OnButtonSelectpathB() { CString str = SelectPath(); if (!str.IsEmpty()) { GetDlgItem(IDC_EDIT_PATH_B)->SetWindowText(str); UpdateData(false); } } /* *函数功能:路径选择函数 *输入参数:无 *输出参数:无 *返回值 :所选择路径 */ CString CBrowseDlg::SelectPath() { CString strPath = ""; int iImageIndex = 0; LPMALLOC pMalloc; if (SHGetMalloc (&pMalloc)!= NOERROR) { return ""; } BROWSEINFO bInfo; LPITEMIDLIST pidl; ZeroMemory ( (PVOID) &bInfo,sizeof (BROWSEINFO)); bInfo.hwndOwner = this->GetSafeHwnd(); bInfo.pszDisplayName = strPath.GetBuffer (MAX_PATH); bInfo.lpszTitle = "请选择新的文件夹:"; bInfo.ulFlags = BIF_RETURNFSANCESTORS| BIF_RETURNONLYFSDIRS; // |BIF_NEWDIALOGSTYLE // |BIF_SHAREABLE // |0x0010 ; if ((pidl = ::SHBrowseForFolder (&bInfo)) == NULL) { return ""; } strPath.ReleaseBuffer (); iImageIndex = bInfo.iImage; if (::SHGetPathFromIDList(pidl,strPath.GetBuffer (MAX_PATH)) == FALSE) { pMalloc ->Free (pidl); pMalloc ->Release (); return ""; } strPath.ReleaseBuffer (); pMalloc ->Free (pidl); pMalloc ->Release (); return strPath; }//end SelectPath()
最近做了个小软件,其中要使用用户指定的文件夹中的文件,后来发现要实现文件夹的选择还挺费劲,我把查的资料整理了一下,供大家参考,省得大家在这些小问题上耽误时间,哈。提供了两种方法,(哈,起个名吧,仅为了区分,要不叫猫猫、狗狗也行,哈)第一种为类封装法; 第二种为成员函数法。