CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

关于CFileDialog和SHBrowseForFolder浏览限制问题

楼主huziwu(虎子)2006-03-03 14:59:48 在 VC/MFC / 基础类 提问

如题,1:我如何将CFileDialog和SHBrowseForFolder的对话框浏览的路径限制在E盘?即其它盘屏蔽掉。  
  如果不能屏蔽的话,当选择别的盘符自动跳回到E盘。 问题点数:60、回复次数:26Top

1 楼billy145533($_$)回复于 2006-03-03 15:26:07 得分 0

晕,看来不行  
  关注Top

2 楼striking(庸人自扰)回复于 2006-03-03 15:37:54 得分 30

我如何将CFileDialog和SHBrowseForFolder的对话框浏览的路径限制在E盘?即其它盘屏蔽掉。  
  ===这个似乎不行.  
  如果不能屏蔽的话,当选择别的盘符自动跳回到E盘。    
  ====这个可以实现..  
  #include   <shlobj.h>  
   
  INT   CALLBACK   BrowseCallbackProc(HWND   hwnd,    
                                                                  UINT   uMsg,  
                                                                  LPARAM   lp,    
                                                                  LPARAM   pData)    
  {  
  TCHAR   szDir[MAX_PATH];  
  pData;  
  switch(uMsg)    
  {  
  case   BFFM_INITIALIZED:    
  SendMessage(hwnd,   BFFM_SETSELECTION,   TRUE,   (LPARAM)(LPCTSTR)pData);//默认的路径  
  break;  
   
  case   BFFM_SELCHANGED:    
  //   Set   the   status   window   to   the   currently   selected   path.  
  if   (SHGetPathFromIDList((LPITEMIDLIST)   lp   ,szDir))  
  {  
  //这边是用户选择目录后发出的消息.   你可以在这边判断szDir是否在e盘,不是的话,继续发送  
  //BFFM_INITIALIZED消息..  
  //否则  
  SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);  
  }  
  break;  
  }  
  return   0;  
  }  
   
  BROWSEINFO   bi;  
  TCHAR   szDir[MAX_PATH];  
  LPITEMIDLIST   pidl;  
  LPMALLOC   pMalloc;  
   
  if   (SUCCEEDED(SHGetMalloc(&pMalloc)))  
  {  
  ZeroMemory(&bi,sizeof(bi));  
  bi.hwndOwner   =   NULL;  
  bi.pszDisplayName   =   0;  
  bi.pidlRoot   =   0;  
  bi.ulFlags   =   BIF_RETURNONLYFSDIRS   |   BIF_STATUSTEXT;  
  bi.lpfn   =   BrowseCallbackProc;  
  bi.lParam   =   (LPARAM)defaultPath;             //   pass   address   of   object   to   callback   function  
   
  pidl   =   SHBrowseForFolder(&bi);  
  if   (pidl)  
  {  
  if   (SHGetPathFromIDList(pidl,szDir))  
  {  
  UpdateData(FALSE);  
  }  
  pMalloc->Free(pidl);  
  pMalloc->Release();  
  }  
  }  
   
   
  Top

3 楼huziwu(虎子)回复于 2006-03-03 17:17:49 得分 0

To   striking:  
          你给的代码是重载SHBrowseForFolder吗?该怎么重载呢?头一次用不是很懂啊。  
  还有在CFileDialog怎么实现呢  
  我的代码:  
  void   CMyFileDlg::OnFolderChange()  
  {  
  CString   GetFileName;  
  GetFileName=CMyFileDlg::GetFolderPath();  
  if(GetFileName.Left(1)!="E")  
  {  
                            //该怎么处理呢?  
  }  
  }  
   
  或有什么别的办法呢?Top

4 楼striking(庸人自扰)回复于 2006-03-03 22:45:59 得分 0

BROWSEINFO   bi;  
  TCHAR   szDir[MAX_PATH];  
  LPITEMIDLIST   pidl;  
  LPMALLOC   pMalloc;  
   
  if   (SUCCEEDED(SHGetMalloc(&pMalloc)))  
  {  
  ZeroMemory(&bi,sizeof(bi));  
  bi.hwndOwner   =   NULL;  
  bi.pszDisplayName   =   0;  
  bi.pidlRoot   =   0;  
  bi.ulFlags   =   BIF_RETURNONLYFSDIRS   |   BIF_STATUSTEXT;  
  bi.lpfn   =   BrowseCallbackProc;  
  bi.lParam   =   (LPARAM)defaultPath;             //   pass   address   of   object   to   callback   function  
   
  pidl   =   SHBrowseForFolder(&bi);  
  if   (pidl)  
  {  
  if   (SHGetPathFromIDList(pidl,szDir))  
  {  
  UpdateData(FALSE);  
  }  
  pMalloc->Free(pidl);  
  pMalloc->Release();  
  }  
  }  
   
  这段添加到要浏览目录的地方Top

5 楼striking(庸人自扰)回复于 2006-03-03 22:46:23 得分 0

#include   <shlobj.h>  
   
  INT   CALLBACK   BrowseCallbackProc(HWND   hwnd,    
                                                                  UINT   uMsg,  
                                                                  LPARAM   lp,    
                                                                  LPARAM   pData)    
  {  
  TCHAR   szDir[MAX_PATH];  
  pData;  
  switch(uMsg)    
  {  
  case   BFFM_INITIALIZED:    
  SendMessage(hwnd,   BFFM_SETSELECTION,   TRUE,   (LPARAM)(LPCTSTR)pData);//默认的路径  
  break;  
   
  case   BFFM_SELCHANGED:    
  //   Set   the   status   window   to   the   currently   selected   path.  
  if   (SHGetPathFromIDList((LPITEMIDLIST)   lp   ,szDir))  
  {  
  //这边是用户选择目录后发出的消息.   你可以在这边判断szDir是否在e盘,不是的话,继续发送  
  //BFFM_INITIALIZED消息..  
  //否则  
  SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);  
  }  
  break;  
  }  
  return   0;  
  }  
  这段添加到cpp前面Top

6 楼jiangsheng(蒋晟.Net[MVP])回复于 2006-03-04 06:58:48 得分 30

CFileDialog   不行,不过你可以在DoModal之后提示路径不符并且重新显示一个CFileDialog    
  用SHBrowseForFolder的话可以直接设置BROWSEINFO的pidlRoot成员为E:的pidl。Top

7 楼huziwu(虎子)回复于 2006-03-06 11:24:29 得分 0

To   striking:我用你的方法还是不行,以下是我对你的代码进行的修改。  
  INT   CALLBACK   BrowseCallbackProc(HWND   hwnd,   UINT   uMsg,LPARAM   lp,LPARAM   pData)    
  {  
  TCHAR   szDir[MAX_PATH];  
  pData;  
  switch(uMsg)    
  {  
  case   BFFM_INITIALIZED:    
  SendMessage(hwnd,   BFFM_SETSELECTION,   TRUE,   (LPARAM)(LPCTSTR)"e:\\");//默认的路径  
  break;  
   
  case   BFFM_SELCHANGED:    
  //   Set   the   status   window   to   the   currently   selected   path.  
  if   (SHGetPathFromIDList((LPITEMIDLIST)   lp   ,szDir))  
  {  
  //这边是用户选择目录后发出的消息.   你可以在这边判断szDir是否在e盘,不是的话,继续发送  
  //BFFM_INITIALIZED消息..  
  CString   path;  
  path.Format(szDir);  
  if(path.Left(1)=='e'   ||   path.Left(1)=='E')  
  {  
  SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);//否则:  
  }  
  else  
  {  
  SendMessage(hwnd,BFFM_INITIALIZED,0,(LPARAM)"e:\\");  
  }  
  }  
  break;  
  }  
  return   0;  
  }  
   
  虽然选中别的盘符时浏览框上面显示的是E盘,但还是不能跳到E盘目录下Top

8 楼striking(庸人自扰)回复于 2006-03-06 11:30:04 得分 0

jiangsheng(蒋晟.Net[MVP])     厉害,   我怎么没有想到呢,   唉.   lz参考jiangsheng(蒋晟.Net[MVP])   的方法.Top

9 楼huziwu(虎子)回复于 2006-03-06 11:43:54 得分 0

怎么改呢?  
  我有试过  
  bi.pidlRoot="e:\\";  
  说类型不匹配。  
  还有我觉得我在修改的地方也不对,我是在浏览目录的地方改的。  
  Top

10 楼huziwu(虎子)回复于 2006-03-06 11:59:27 得分 0

bi.pidlRoot的元素有:  
  USHORT   cb;    
  BYTE       abID[1];  
  现在不知怎么给这两个元素赋值。  
  我的代码是这样的:  
  bi.pidlRoot->mkid.abID[0]=(BYTE)'e';  
  编译时提示错误为:error   C2166:   l-value   specifies   const   object  
  这是为什么呢?Top

11 楼striking(庸人自扰)回复于 2006-03-06 15:04:02 得分 0

if   (SHGetPathFromIDList((LPITEMIDLIST)   lp   ,szDir))  
  {  
  //这边是用户选择目录后发出的消息.   你可以在这边判断szDir是否在e盘,不是的话,继续发送  
  //BFFM_INITIALIZED消息..  
  CString   path;  
  path.Format(szDir);  
  if(path.Left(1)=='e'   ||   path.Left(1)=='E')  
  {  
  SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);//否则:  
  }  
  else  
  {  
  SendMessage(hwnd,BFFM_INITIALIZED,0,(LPARAM)"e:\\");//改成  
  SendMessage(hwnd,   BFFM_SETSELECTION,   TRUE,   (LPARAM)(LPCTSTR)"e:\\");//默认的路径  
   
  }  
  }  
  break;  
  Top

12 楼huziwu(虎子)回复于 2006-03-06 16:18:58 得分 0

To   striking:  
  按你的方法解决自动跳到E盘,但是D盘(或其它被双击的盘)同时也会展开目录树。  
  能不能实现我双击D盘时自动跳到E盘,且D盘不会展开目录树呢?  
   
  先谢谢大家了!特别感谢striking一路帮忙!解决问题后外开帖加分!!!!!!  
  Top

13 楼striking(庸人自扰)回复于 2006-03-06 17:07:48 得分 0

最终解决方案:  
  第一步:   将E盘转化为pidl  
  LPITEMIDLIST     pidl;  
  LPSHELLFOLDER   pDesktopFolder;  
  char                     szPath[MAX_PATH];  
  OLECHAR               olePath[MAX_PATH];  
  ULONG                   chEaten;  
  ULONG                   dwAttributes;  
  HRESULT               hr;  
   
  strcpy(szPath,   "E:\\"   );  
   
  //    
  //   Get   a   pointer   to   the   Desktop's   IShellFolder   interface.  
  //    
  if   (SUCCEEDED(SHGetDesktopFolder(&pDesktopFolder)))  
  {  
  //    
  //   IShellFolder::ParseDisplayName   requires   the   file   name   be   in  
  //   Unicode.  
  //    
  MultiByteToWideChar(CP_ACP,   MB_PRECOMPOSED,   szPath,   -1,  
  olePath,   MAX_PATH);  
   
  //    
  //   Convert   the   path   to   an   ITEMIDLIST.  
  //    
  hr   =   pDesktopFolder->ParseDisplayName(NULL,NULL,  
  olePath,  
  &chEaten,  
  &pidl,  
  &dwAttributes);  
  if   (FAILED(hr))  
  {  
  //   Handle   error.  
  return   ;  
  }  
   
  //    
  //   pidl   now   contains   a   pointer   to   an   ITEMIDLIST   for   .\readme.txt.  
  //   This   ITEMIDLIST   needs   to   be   freed   using   the   IMalloc   allocator  
  //   returned   from   SHGetMalloc().  
  //    
   
  //release   the   desktop   folder   object  
  pDesktopFolder->Release();  
  }    
   
  第二步:   设置BROWSEINFO  
  #include   <shlobj.h>  
   
  INT   CALLBACK   BrowseCallbackProc(HWND   hwnd,    
                                                                  UINT   uMsg,  
                                                                  LPARAM   lp,    
                                                                  LPARAM   pData)    
  {  
  TCHAR   szDir[MAX_PATH];  
  pData;  
  switch(uMsg)    
  {  
  case   BFFM_INITIALIZED:    
  SendMessage(hwnd,   BFFM_SETSELECTION,   0,   pData   );//   默认的路径,,   这边有修改  
  break;  
   
  case   BFFM_SELCHANGED:    
  //   Set   the   status   window   to   the   currently   selected   path.  
  if   (SHGetPathFromIDList((LPITEMIDLIST)   lp   ,szDir))  
  {  
  SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);  
  }  
  break;  
  }  
  return   0;  
  }  
   
  BROWSEINFO   bi;  
  TCHAR   szDir[MAX_PATH];  
  LPITEMIDLIST   pidl;//这个为第一步的结果  
  LPMALLOC   pMalloc;  
   
  if   (SUCCEEDED(SHGetMalloc(&pMalloc)))  
  {  
  ZeroMemory(&bi,sizeof(bi));  
  bi.hwndOwner   =   NULL;  
  bi.pszDisplayName   =   0;  
  bi.pidlRoot   =   pidl;  
  bi.ulFlags   =   BIF_RETURNONLYFSDIRS   |   BIF_STATUSTEXT;  
  bi.lpfn   =   BrowseCallbackProc;  
  bi.lParam   =   (LPARAM)pidl;             //   pass   address   of   object   to   callback   function  
   
  pidl   =   SHBrowseForFolder(&bi);  
  if   (pidl)  
  {  
  if   (SHGetPathFromIDList(pidl,szDir))  
  {  
  UpdateData(FALSE);  
  }  
  pMalloc->Free(pidl);  
  pMalloc->Release();  
  }  
  }  
   
  Top

14 楼huziwu(虎子)回复于 2006-03-07 16:36:57 得分 0

To   striking:  
          非常感谢硬撑者,浏览目录的问题解决了。  
  还有一个问题是CFileDialog有没有办法也限制在e盘啊。  
  另开帖给striking:加60分,贴题为striking兄弟请进来.Top

15 楼striking(庸人自扰)回复于 2006-03-07 16:54:36 得分 0

呵呵.   得到蒋大人的提示.   也一并谢谢蒋大人吧.  
   
  引用:  
    jiangsheng(蒋晟.Net[MVP])   (   )   信誉:290     2006-03-04   06:58:00     得分:   0      
   
  CFileDialog   不行,不过你可以在DoModal之后提示路径不符并且重新显示一个CFileDialog    
  用SHBrowseForFolder的话可以直接设置BROWSEINFO的pidlRoot成员为E:的pidl。  
   
  ////////////  
  我帮你写了实现而已.  
  Top

16 楼huziwu(虎子)回复于 2006-03-07 17:11:45 得分 0

呵呵,帮忙的都要谢啊。  
  我是菜鸟,有时只讲方法领会不了,郁闷啊。  
  感谢jiangsheng(蒋晟.Net[MVP])大哥,striking(硬撑者)大哥。  
  先在此谢谢看贴的顶的兄弟姐妹们。  
  还有一问题没解决先不结贴。Top

17 楼huziwu(虎子)回复于 2006-03-07 17:15:18 得分 0

重载CFileDialog也不行吗?  
  我就不是想让操作者看到别的盘上的东西啊。  
  不行有别的办法吗?不用CFileDialog也行。这个不只是显示目录,还要显示文件。  
  Top

18 楼jiangsheng(蒋晟.Net[MVP])回复于 2006-03-07 23:35:01 得分 0

SHBrowseForFolder可以用来选择单个文件(BROWSEINFO.ulFlags|=BIF_BROWSEINCLUDEFILES)  
  你也可以考虑重载BOOL   CFileDialog::OnFileNameOKTop

19 楼huziwu(虎子)回复于 2006-03-08 09:00:43 得分 0

TO:jiangsheng(蒋晟.Net[MVP])  
          大哥你太牛了,用你的方法问题解决了。用SHBrowseForFolder解决的。  
  再次谢谢各位大哥帮忙,另开帖加分了!!!!!!!!标题:jiangsheng大哥请进  
  怎样才能拦载CFileDialog的消息呢,CFileDialog类里怎么ClassWizard里没有像PreTranslateMessage或Oncommand之类的事件呢?Top

20 楼huziwu(虎子)回复于 2006-03-08 09:16:16 得分 0

一时高兴过头,忘了一件事。用SHBrowseForFolder能不能过滤文件呢,例如我只要显示*.bmp文件其它类型文件不显示。Top

21 楼jiangsheng(蒋晟.Net[MVP])回复于 2006-03-08 10:43:20 得分 0

http://msdn.microsoft.com/msdnmag/issues/05/06/CAtWork/default.aspxTop

22 楼jiangsheng(蒋晟.Net[MVP])回复于 2006-03-08 11:26:03 得分 0

I   suspect   the   nub   of   the   probem   lies   in   the   fact   that   your   class   is   not   the    
  hierarchical   parent   of   the   dialog   that   you   see   on   the   screen.   To   put   it    
  another   way,   your   class   actually   becomes   a   child   of   the   file   open   dialog    
  window.   Use   Spy++   to   look   at   the   hierarchy   and   you'll   see   what   I   mean.   It    
  appears   that   the   real   dialog   window   (which   I   assume   does   get   the   message)    
  examines   the   various   messages   and   decides   to   whom   it   should   pass   on    
  messages.Top

23 楼huziwu(虎子)回复于 2006-03-08 11:57:07 得分 0

bi.ulFlags   =   BIF_RETURNONLYFSDIRS   |   BIF_STATUSTEXT   |   BIF_BROWSEINCLUDEFILES   ;  
  我用SHGetPathFromIDList(pidl,szDir),返回结果szDir不带扩展名,怎么获得扩展名?Top

24 楼jiangsheng(蒋晟.Net[MVP])回复于 2006-03-08 13:07:16 得分 0

IShellFolder::GetAttributesOf   ?Top

25 楼huziwu(虎子)回复于 2006-03-10 10:02:23 得分 0

仿造CFileDialog我自己做了一个打开文件的对话框,可是在CListBox里显示文件太单调了,就只显示了文件名,没有图标。例如文件夹的显示:[新建文件夹],多了[]。如何像CFileDialog里显示那样加图标呢?Top

26 楼huziwu(虎子)回复于 2006-03-10 16:35:29 得分 0

结贴了谢谢   硬撑者   和   蒋晟   两位大哥的帮忙!!!!!!!!!!!Top

相关问题

  • 请问怎么限制IE浏览器打开的窗口数?
  • 如何实现限制每个浏览者的下载数量?
  • 怎样限制客户端浏览网页?
  • 怎样用程序限制用户只能用浏览器来下载东西
  • IIS 是不是真的限制浏览网页的用户数量
  • 梅花雨的日历在不同的浏览器中有限制吗?
  • 请问"<!-- #include file='a.html' -->"是什么命令,有浏览器限制吗
  • 有谁知道,那些限制上网浏览网页相关内容的软件的主要思想??
  • 解决ActiveX在浏览器中被提示安全限制的问题,本周结账!
  • 求一思路:如何纪录/或限制浏览器登陆那一些网站?

关键词

  • .net
  • bi
  • bffm
  • szdir
  • cfiledialog
  • pidl
  • shbrowseforfolder
  • browsecallbackproc
  • lparam
  • bif

得分解答快速导航

  • 帖主:huziwu
  • striking
  • jiangsheng

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo