MFC選擇目錄SHBrowseForFolder選擇文件CFileDialog對話框設置默認路徑


CFileDialog會自動記住上一次路徑,
SHBrowseForFolder需要寫個回調函數,
傳值給BROWSEINFO
BaseFunc.h
#include < string>

using  namespace std;
namespace BaseFunc
{
     //  選擇文件,可設置定位到默認目錄
    unsigned selFile( string &strFile, const  string &strExt, bool bOpen);

     //  選擇目錄,可設置定位初始目錄
    unsigned selDir( string &strDir, void *hwnd = NULL);
}
BaseFunc.cpp
#include  " stdafx.h "
#include <Windows.h>
#include  " BaseFunc.h "

using  namespace std;
using  namespace BaseFunc;

unsigned BaseFunc::selFile(  string &strFile, const  string &strExt, bool bOpen )
{
     string strDir =  " D:\\Downloads "; // 這里通過strFile解析目錄,CFileDialog會自動記住
     string filename =  " hi.txt ";   // 通過strFile解析文件名
     string filter = strExt +  " 文件 (*. " + strExt +  " )|*. " + strExt +  " || ";
     string ext =  " . " + strExt;

    CFileDialog dlg(bOpen,ext.c_str(),filename.c_str(),OFN_READONLY|OFN_OVERWRITEPROMPT,filter.c_str(),NULL);
    dlg.GetOFN().lpstrInitialDir = strFile.c_str(); //  默認目錄

     if (dlg.DoModal())
    {
        strFile = dlg.GetPathName();
         return IDOK;
    }

     return IDCANCEL;
}

int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData)
{
     switch(uMsg)
    {
     case BFFM_INITIALIZED:
        ::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,lpData);
         break;
    }

     return  0;
}

unsigned BaseFunc::selDir(  string &strDir, void *hwnd /*  = NULL */ )
{
     char szDir[MAX_PATH];
    BROWSEINFO bi; 
    bi.hwndOwner = (HWND)hwnd;
    bi.pidlRoot = NULL;
    bi.pszDisplayName = szDir;
    bi.lpszTitle =  " 選擇位置: ";
    bi.iImage =  0;

    bi.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS;
    bi.lpfn = BrowseCallbackProc;
    bi.lParam = (LPARAM)(LPCTSTR)strDir.c_str();

    LPITEMIDLIST lp = SHBrowseForFolder(&bi);
     if (lp && SHGetPathFromIDList(lp,szDir))
    {
        strDir = szDir;
         return IDOK;
    }

     return IDCANCEL;
}
selDirDlg.cpp
void CselDirDlg::OnBnClickedButtonFile()
{
    CString sFile;
    GetDlgItemText(IDC_EDIT_FILE,sFile);

    std:: string strFile = sFile;
     if (IDOK == BaseFunc::selFile(strFile, " mp3 ", true))
    {
        SetDlgItemText(IDC_EDIT_FILE,strFile.c_str());
    }
}


void CselDirDlg::OnBnClickedButtonDir()
{
    CString sDir;
    GetDlgItemText(IDC_EDIT_DIR,sDir); // 可擴展個返回string

    std:: string strDir = sDir;
     if (IDOK == BaseFunc::selDir(strDir,GetSafeHwnd()))
    {
        SetDlgItemText(IDC_EDIT_DIR,strDir.c_str());
    }
}
需要源碼的留下郵箱。
url: http://greatverve.cnblogs.com/archive/2012/12/16/SHBrowseForFolder-CFileDialog.html 

注意:目錄瀏覽函數不僅可以選擇目錄,也可以用來選擇一個文件。

下例是一個既可以選擇目錄也可以選擇文件的代碼范例。該范例中詳細說明了相關消息的含義及使用方法。

 

//目錄瀏覽對話框可能會像回調函數發送3種消息:

//BFFM_INITIALIZED --   通知對話框已經初始化結束。

//                   回調函數響應此消息時通常是做初始選擇

//BFFM_SELCHANGED -- 目錄瀏覽對話框當前選擇項發生變化時調用此消息。

//                   回調函數響應此消息時通常是顯示所選項的相關信息

//BFFM_VALIDATEFAILED -- 表示用戶按確認按鈕時卻發現瀏覽對話框的編輯框內輸入了一個非法名稱

//                   回調函數響應此消息時通常是提示客戶選擇項非法,並確定是否繼續顯示該對話框

//回調函數可以發送如下幾個消息給目錄瀏覽對話框,從而改變目錄瀏覽對話框的面目

//BFFM_SETSELECTION  -- 改變當前選擇項目

//BFFM_ENABLEOK      -- 改變“確認”按鈕的狀態

//BFFM_SETSTATUSTEXT-- 改變目錄瀏覽對話框中狀態行消息,當然前提是目錄瀏覽對話框中有狀態行

int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData)

{

      switch (uMsg)

      {

      case BFFM_INITIALIZED:

           {

                 //BFFM_INITIALIZED表示瀏覽對話框已經初化結束,參數lParam為NULL

 

                 //設置初始選項

                 ::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,lpData);

 

                 //關於BFFM_SETSELECTION消息的說明

                 //wParam :標記lParam參數包含一個ITEMIDLIST結構(PIDL)還是一個目錄路徑名

                 //          如果為TRUE,lParam內容為路徑名;否則lParam包含一個路徑PIDL。

                 //lParam :內容為瀏覽對話框所選的路徑。如果wParam為TRUE,lParam內容為一個

                 //         以NULL結尾的字符串的指針,否則為PIDL

 

                 break;

           }

      case BFFM_SELCHANGED:

           {

                 //BFFM_SELCHANGED表示選擇項已經發生變化,參數lParam包含列表中最新選中項的條目ID

                

                 ITEMIDLIST * pidl; 

                 char path[MAX_PATH]; 

 

                 //根據條目ID取路徑信息

                 pidl = (ITEMIDLIST*) lParam;

                 if (SHGetPathFromIDList(pidl, path))

                 {

                      //使得“確認”按鈕生效

                      //關於BFFM_ENABLEOK消息的說明

                      //wParam :無意義,可設置為0

                      //lParam :如果為非0,則使能確認按鈕;否則失效“確認”按鈕

                      ::SendMessage(hwnd,BFFM_ENABLEOK,0,TRUE);

 

                      //讀屬性

                      DWORD attributes = ::GetFileAttributes(path);

 

                      //命令狀態行顯示當前所選項的全路徑名及其文件屬性

                      //關於BFFM_SETSTATUSTEXT消息的說明

                      //wParam :無意義,可設置為0

                      //lParam :指向一個內含狀態行提示信息的字符串

                      CString strText;

                      strText.Format("%s%s%s%s",

                            path,

                            attributes & FILE_ATTRIBUTE_HIDDEN ? ",H":"",

                            attributes & FILE_ATTRIBUTE_READONLY ? ",R":"",

                            attributes & FILE_ATTRIBUTE_SYSTEM ? ",S":""

                            );

                      ::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)(LPTSTR)(LPCTSTR)strText);

                 }

                 else

                 {

                      //使得“確認”按鈕失效

                      ::SendMessage(hwnd,BFFM_ENABLEOK,0,FALSE);

                      //清狀態行信息

                      ::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)(LPTSTR)(LPCTSTR)"");

                 }

 

                 break;

           }

      case BFFM_VALIDATEFAILED:

           {

                 //BFFM_VALIDATEFAILED表示用戶在瀏覽對話框的編輯框內輸入了一個非法名稱

                 //該消息在用戶按“確認”時送出——當然前提是編輯框內輸入的名稱非法

                 //lParam參數包含了非法輸入內容的地址,應用程序可以使用這個消息提示用戶輸入非法。

                 //另外,此消息的回調函數返回0表示目錄瀏覽對話框旋即關閉,返回其他值則允許對話框繼續顯示。

 

                 //僅當目錄瀏覽對話框中含有編輯框並且設置了BIF_VALIDATE標記才可能出現此消息

                 //即BROWSEINFO結構中ulFlags含有BIF_EDITBOX|BIF_VALIDATE標志

                 CString strTip;

                 strTip.Format("目錄%s非法!",lParam);

 

                 //返回0允許對話框提前關閉,SHBrowseForFolder()返回NULL

                 AfxMessageBox(strTip);

                 return 0;

 

                 //返回1對話框繼續顯示,因為對話框仍繼續顯示,可以在狀態行顯示出錯消息

                 //注意:如果此時仍用AfxMessageBox來顯示提示信息,提示信息框關閉后,要使焦點重返目錄

                 //瀏覽對話框,需要客戶手工移動鼠標激活該對話框才行,這樣會使得后繼操作不是很方便,所以在狀態行顯示提示信息比較好

                 //::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)(LPTSTR)(LPCTSTR)strTip);

                 //return 1;

 

                 break;

           }

      default:

           {

                 ASSERT(FALSE);

           }

      }

      return 0;

}

 

void CModifyFileAttributeDlg::OnSelectpath()

{文件目錄選擇函數SHBrowseForFolder()及其回調函數

      UpdateData(TRUE);

 

      BROWSEINFO bi; 

      char dispname[MAX_PATH], path[MAX_PATH]; 

      ITEMIDLIST * pidl; 

     

      //定義目錄瀏覽對話框的屬主

      bi.hwndOwner = 0;

      //確定瀏覽范圍(根目錄)

      //只有根目錄及其子目錄下可以瀏覽

      //定義為NULL表示名字空間下皆可用

      bi.pidlRoot = NULL;

      //用於接收用戶所選目錄的顯示名

      //經測試,該項並不包含全路徑名

      bi.pszDisplayName = dispname; 

      //設置目錄瀏覽對話框的對話框標題

      bi.lpszTitle = "請選擇路徑:"; 

      //設置狀態

      //BIF_BROWSEINCLUDEFILES

      //BIF_RETURNONLYFSDIRS表示只返回目錄,

      //BIF_STATUSTEXT表示對話框中有狀態行

      //BIF_EDITBOX表示對話框中有編輯框

      //BIF_VALIDATE表示客戶按“確認”按鈕時檢查編輯框內容的合法性

      bi.ulFlags = BIF_BROWSEINCLUDEFILES|BIF_RETURNONLYFSDIRS|BIF_STATUSTEXT|BIF_EDITBOX|BIF_VALIDATE;

      //設置回調函數

      //如果需要設置初始選擇項、顯示所選項的相關信息、讓系統自動校驗用戶輸入

      //的合法性,那么應該使用回調函數;否則可將該項設置為NULL

      bi.lpfn = BrowseCallbackProc; 

      //設置回調函數的lParam參數

      //此處用來傳遞目錄瀏覽對話框的初始選項

      bi.lParam = (LPARAM)(LPCTSTR)m_strFilePath; 

      //用來接收所選目錄的圖標(系統圖像列表中的序號)

      bi.iImage = 0; 

     

      //顯示目錄瀏覽對話框

      if (pidl = SHBrowseForFolder(&bi))

      { 

           //將PIDL轉換為字符串

           if (SHGetPathFromIDList(pidl, path))

           {

                 //更新對話框顯示,以顯示用戶的最新選擇

                 m_strFilePath = path;

                 TRACE("%s",bi.pszDisplayName);

                 UpdateData(FALSE);

           }

      }

 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM