文件夹选择对话框,SHBrowseForFolder,文件夹选择,目录选择 z


正文
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);

     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、效果
    pic my.jpg

另一应用实例

#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);
}
}


<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值