vc文件夹选择对话框

 

正文
1、API概述
    使用Windows的SHBrowseForFolder可以实现目录选择功能。
    该函数的参数也实现如下:见MSDN
    Displays a dialog box that enables the user to select a shell folder.
    LPITEMIDLIST SHBrowseForFolder(LPBROWSEINFO lpbi);
  Returns a pointer to an ITEMIDLIST structure (PIDL) that specifies the location of the selected folder relative to the root of the namespace. If the user chooses the Cancel button in the dialog box, the return value is NULL.


2、使用
     #define REMOVE_HEIGHT 28
     //  回调函数的声明
     int CALLBACK _SHBrowseForFolderCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData);

#ifndef BIF_NEWDIALOGSTYLE
#define  BIF_NEWDIALOGSTYLE  0x0040
#endif

#ifndef BIF_USENEWUI
#define  BIF_USENEWUI   0x0050
#endif

    BOOL SelectFolder(CString& lpstrFolderPos, CString strInitPosition)
    {
        BOOL          bRes = FALSE;

 

         char          lpszPath[MAX_PATH];
         LPMALLOC      lpMalloc;
         BROWSEINFO    sInfo;
         LPITEMIDLIST lpidlBrowse;

         if (::SHGetMalloc(&lpMalloc) != NOERROR)
             return FALSE;

         if (strInitFolder != _T(""))
         {
             if(strInitFolder.Right(1) == _T("//"))                           // 删除尾部的"//"
             strInitFolder = strInitFolder.Left(strInitFolder.GetLength() - 1);
         }

         ::ZeroMemory(&sInfo, sizeof(BROWSEINFO));
         sInfo.pidlRoot   = 0;
         sInfo.pszDisplayName = lpszPath;
         sInfo.lpszTitle   = _T("请选择您需要的目的文件夹:");
         sInfo.ulFlags   = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_USENEWUI;

         sInfo.lpfn     = _SHBrowseForFolderCallbackProc;
         sInfo.lParam   = (LPARAM)strInitFolder.GetBuffer(0);

         // 显示文件夹选择对话框
         lpidlBrowse = ::SHBrowseForFolder(&sInfo); 

         if (lpidlBrowse != NULL)
         {
             // 取得文件夹名
             if (::SHGetPathFromIDList(lpidlBrowse,lpszPath))  
             {
                 lpstrFolder = _T("");
                 lpstrFolder = lpszPath;
  
                 if(lpstrFolder != "")
                 {
                     if(lpstrFolder.Right(1) != _T("//"))
                         lpstrFolder += _T("//");               //在末尾时附加"//"
                 }
             }
 
             bRes = TRUE;
         }

         if(lpidlBrowse != NULL)
         {
             ::CoTaskMemFree(lpidlBrowse);
         }

         lpMalloc->Release();

         return bRes;
    }


    下面是回调函数,以及函数的处理
    int CALLBACK _SHBrowseForFolderCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
    {
        static HWND hWndEdit = NULL;
         CString strDir;

         switch (uMsg)
         {
         case BFFM_INITIALIZED:
             {
                 ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
  
                 CRect rect;  
                 HWND  hChild = GetWindow(hwnd, GW_CHILD);
                 while (hChild)
                 {
                     TCHAR szClass[256];
                     GetClassName(hChild, szClass, 255);
                   //  如果是中间的树目录控件,使可以随窗口移动大小
                     if (strcmp(szClass, "SHBrowseForFolder ShellNameSpace Control") == 0)
                     {
                         GetWindowRect(hChild, rect);
                         rect.top -= REMOVE_HEIGHT;

                         CPoint pt = rect.TopLeft();
                         ScreenToClient(hwnd, &pt);
                         MoveWindow(hChild, pt.x, pt.y, rect.Width(), rect.Height(), TRUE);
                     }

                     if (strcmp(szClass, "Edit") == 0)
                     {
                         hWndEdit = hChild;
                     }
   
                     hChild = GetNextWindow(hChild, GW_HWNDNEXT);
                 }

                 SetWindowText(hwnd, "alinx文件浏览...");
             }
            break;
 
        case BFFM_SELCHANGED:
             if(hWndEdit)
             {
                 if(::SHGetPathFromIDList((LPITEMIDLIST)lParam, strDir.GetBufferSetLength(MAX_PATH)))
                 {
                     SetWindowText(hWndEdit, strDir);
                 }
                 else
                 {
                     SetWindowText(hWndEdit, NULL);
                     SendMessage(hwnd, BFFM_VALIDATEFAILED, 0, 0);
                 }
               strDir.ReleaseBuffer();
            }
            break;
 
        default:
            break;
 
        }

        return 0;
    }

3、效果
   


另一应用实例
#ifndef GLOBAL_H
#define GLOBAL_H

#ifndef BIF_NEWDIALOGSTYLE
#define  BIF_NEWDIALOGSTYLE  0x0040
#endif

#ifndef BIF_USENEWUI
#define  BIF_USENEWUI   0x0050
#endif

// 初始化文件夹设定用的回调函数
int CALLBACK _SHBrowseForFolderCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
 if(uMsg == BFFM_INITIALIZED)
  ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
 
 return 0;
}


bool g_fSelectFolderDlg(CString* lpstrFolder,CString strIniFolder,bool bAvailNewFolder)
{
 bool   ret;
 char   lpszPath[MAX_PATH];
 LPMALLOC  lpMalloc;
 BROWSEINFO  sInfo;
 LPITEMIDLIST lpidlRoot;
 LPITEMIDLIST lpidlBrowse;
 
 if(lpstrFolder == NULL)
  return false;
 
 if(::SHGetMalloc(&lpMalloc) != NOERROR)
  return false;
 
 ret = false;
 
 if(strIniFolder != "")
 {
  if(strIniFolder.Right(1) == "//")
   strIniFolder = strIniFolder.Left(strIniFolder.GetLength() - 1);   //删除末尾的"//"
 
 }
 
 ::SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &lpidlRoot); //取得选定的文件夹名
 
 
 ::ZeroMemory(&sInfo, sizeof(BROWSEINFO));
 sInfo.pidlRoot  = lpidlRoot;
 sInfo.pszDisplayName = lpszPath;
 sInfo.lpszTitle  = _T("Please Select Work Directory:");
 sInfo.ulFlags  = BIF_RETURNONLYFSDIRS;
 if(bAvailNewFolder == true)
  sInfo.ulFlags |= BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_USENEWUI;
 sInfo.lpfn   = _SHBrowseForFolderCallbackProc;
 sInfo.lParam  = (LPARAM)strIniFolder.GetBuffer(0);
 
 lpidlBrowse = ::SHBrowseForFolder(&sInfo);   //显示文件夹选择对话框
 
 if(lpidlBrowse != NULL)
 {
  if(::SHGetPathFromIDList(lpidlBrowse,lpszPath)) //取得文件夹名 
  {
   *lpstrFolder = "";
   *lpstrFolder = lpszPath;
  
   if(*lpstrFolder != "")
   {
    if(lpstrFolder->Right(1) != "//")
     *lpstrFolder += "//";    //在末尾时附加"//"
   }
  }
 
  ret = true;
 }
 
 if(lpidlBrowse != NULL)
  ::CoTaskMemFree(lpidlBrowse);
 if(lpidlRoot != NULL)
  ::CoTaskMemFree(lpidlRoot);
 
 lpMalloc->Release();
 
 return ret;
}

#endif

调用:

void CSelectDir::OnButton1()
{
 // TODO: Add your control notification handler code here
 if(g_fSelectFolderDlg(&m_strFolder,m_strFolder,false))
 {
  UpdateData(false);
 }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值