打开目录文件夹怎么设置(打开目录文件的函数)

打开目录文件夹怎么设置(打开目录文件的函数)p style TEXT INDENT 21pt MARGIN 0cm 0cm 0pt mso char indent count 2 0 class MsoNormal span lang EN US o p nbsp o p span p

大家好,我是讯享网,很高兴认识大家。



<p style="TEXT-INDENT: 21pt; MARGIN: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p> 

讯享网

自从第一份工作辞职后,差不多三年多没有再搞MFC了,对于微软的Windows桌面开发真的淡忘了,这次接到一个任务,需要开发个小工具,虽然任务很小,但是在一个如何打开文件目录对话框的小问题上卡了下,虽然通过网络找到了解决方法,但是网上七拼八凑的文章太多,看的有点费时,所以就抽时间小结一下,虽然也是简单使用,没有太多扩展,就当给自己Mark一下吧。

打开文件目录对话框,我找到的方法就是使用SHBrowseForFolder函数,这个函数的原型是LPITEMIDLIST SHBrowseForFolder(LPBROWSEINFO lpbi)。函数很简单,就一个返回值和一个参数。参数简单罗列如下

typedef struct _browseinfo {

     HWND hwndOwner;            // 父窗口句柄

     LPCITEMIDLIST pidlRoot;    // 要显示的文件目录对话框的根(Root)

     LPTSTR pszDisplayName;     // 保存被选取的文件夹路径的缓冲区

     LPCTSTR lpszTitle;         // 显示位于对话框左上部的标题

     UINT ulFlags;              // 指定对话框的外观和功能的标志

     BFFCALLBACK lpfn;          // 处理事件的回调函数

     LPARAM lParam;             // 应用程序传给回调函数的参数

     int iImage;                // 文件夹对话框的图片索引

} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO

一般而言父窗口句柄(hwndOwner)和根(pidlRoot)设置为Null就可以了,pszDisplayName设定一块MAX_PATH大小的缓冲区,跟显示相关的参数就是对话框提示标题(lpszTitle)、对话框样式(ulFlags)、设定对话框的缺省路径的操作(lpfnlParam)以及对话框任务栏上显示的图标(iImage)。

由于返回值LPITEMIDLIST是一个指向ITEMIDLIST的指针,这个ITEMIDLIST涉及到Windows Shell中关于管理诸如文件、网络上的计算机、控制面板程序、回收站等等对象的知识点,Windows Shell为了识别具体的每一个对象,就使用了ITEMID来唯一识别和区分,而ITEMIDLIST就是一个完整的对象路径。显然这个函数可以用来浏览非文件对象,比如局域网内的电脑等等,在这里这个LPITEMIDLIST返回的对象路径是一个文件夹的路径,Windows提供了一个函数BOOL SHGetPathFromIDList(LPCITEMIDLIST pidl, LPSTR pszPath)来实现从对象路径转化为文件夹路径。

在这里需要注意的是,这个返回值是通过调用IMalloc Interface来分配内存的,函数并不负责释放内存操作,所以我们在使用完这个返回值之后,必须通过IMalloc Interface来释放内存。

下面给出一段最简单的使用代码

       BROWSEINFO bi;

       char Buffer[MAX_PATH];

       //初始化入口参数bi开始

       bi.hwndOwner = NULL;

       bi.pidlRoot =NULL;//初始化制定的root目录很不容易

       bi.pszDisplayName = Buffer;//此参数如为NULL则不能显示对话框

       bi.lpszTitle = "选择Sis目标文件路径";

       bi.ulFlags = BIF_EDITBOX;//带编辑框的风格

       bi.lpfn = NULL;

       bi.lParam = 0;

       bi.iImage=IDR_MAINFRAME;

       //初始化入口参数bi结束

       LPITEMIDLIST pIDList = SHBrowseForFolder(&bi);//调用显示选择对话框

       if(pIDList)

       {

          SHGetPathFromIDList(pIDList, Buffer);

          //取得文件夹路径到Buffer

          CString m_cSisDes = Buffer;//将路径保存在一个CString对象里

       }

       UpdateData(FALSE);

       // free memory used     

   IMalloc * imalloc = 0;

       if (SUCCEEDED(SHGetMalloc(&imalloc)))

       {

              imalloc->Free (pIDList);

              imalloc->Release();

       }

如上代码可以显示一个最简单的带编辑框的其实选中对象为我的电脑的浏览文件夹对话框。

由于我在实际工作中需要的就是一个有新建文件夹功能且指定初始选中路径的浏览文件夹对话框,就把这个需求当做扩展应用吧,由于对话框样式由ulFlags标记确定,而在系统头文件SHLOBJ.h头文件中给出的对话框样式只有如下几种 /o:p

// Browsing for directory. /o:p

#define BIF_RETURNONLYFSDIRS&nbsp;&nbsp; 0x0001&nbsp; // For finding a folder to start document searching /o:p

#define BIF_DONTGOBELOWDOMAIN&nbsp; 0x0002&nbsp; // For starting the Find Computer /o:p

#define BIF_STATUSTEXT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0004 /o:p

#define BIF_RETURNFSANCESTORS&nbsp; 0x0008 /o:p

#define BIF_EDITBOX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0010 /o:p

#define BIF_VALIDATE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0020&nbsp;&nbsp; // insist on valid result (or CANCEL) /o:p

&nbsp; /o:p

#define BIF_BROWSEFORCOMPUTER&nbsp; 0x1000&nbsp; // Browsing for Computers. /o:p

#define BIF_BROWSEFORPRINTER&nbsp;&nbsp; 0x2000&nbsp; // Browsing for Printers /o:p

#define BIF_BROWSEINCLUDEFILES 0x4000&nbsp; // Browsing for Everything /o:p

没有满足我需求的样式,通过csdn查到其实有一个支持新建文件夹功能的样式值0x40,通常网络上给出宏为BIF_NEWDIALOGSTYLEBIF_USENEWUI,由于不知道在具体哪个头文件中,所以我们可以在代码中自己定义一下这两个宏,具体如下 /o:p

#define BIF_NEWDIALOGSTYLE&nbsp;&nbsp; 0x40 /o:p


讯享网

#define BIF_USENEWUI (BIF_NEWDIALOGSTYLE|BIF_EDITBOX) /o:p

这样一来第一个问题解决了,那么如何让对话框有初始选中的文件夹路径呢,我起初想着通过pidlRoot,结果撞了一鼻子灰,原来设定初始选中文件夹路径,是通过那个神奇的回调函数来实现,换句话来说你调用SHBrowseForFolder也就好比你调用了CDialog:: DoModal()函数,具体这个对话框里面的类似初始化,选择等操作的不同实现就通过lpfn这个回调函数来实现了。 /o:p

下面给出这个简单扩展的代码 /o:p

#define BIF_NEWDIALOGSTYLE&nbsp;&nbsp; 0x40 /o:p

&nbsp; /o:p

int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData)&nbsp;&nbsp; /o:p

{ /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(uMsg == BFFM_INITIALIZED) /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData); /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;&nbsp;&nbsp; /o:p

} /o:p

&nbsp; /o:p

void CSisAppendMidDlg::OnButtonSisdes() /o:p

{ /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // TODO: Add your control notification handler code here /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BROWSEINFO bi; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char Buffer[MAX_PATH]; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //初始化入口参数bi开始 /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bi.hwndOwner = NULL; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bi.pidlRoot =NULL;//初始化制定的root目录很不容易 /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bi.pszDisplayName = Buffer;//此参数如为NULL则不能显示对话框 /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bi.lpszTitle = “选择Sis目标文件路径”; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bi.ulFlags = BIF_EDITBOX|BIF_NEWDIALOGSTYLE;&nbsp;&nbsp; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CFileFind&nbsp;&nbsp; finder; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(finder.FindFile(m_cSisDes)==FALSE) /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bi.lParam =0; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bi.lpfn = NULL; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bi.lParam = (long)(m_cSisDes.GetBuffer(m_cSisDes.GetLength()));//初始化路径,形如(_T(“c:\Symbian”)); /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bi.lpfn = BrowseCallbackProc; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finder.Close(); /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bi.iImage=IDR_MAINFRAME; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //初始化入口参数bi结束 /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPITEMIDLIST pIDList = SHBrowseForFolder(&bi);//调用显示选择对话框 /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(pIDList) /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; SHGetPathFromIDList(pIDList, Buffer); /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; //取得文件夹路径到Buffer /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; m_cSisDes = Buffer;//将路径保存在一个CString对象里 /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UpdateData(FALSE); /o:p

&nbsp; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // free memory used&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /o:p

&nbsp;&nbsp;&nbsp; IMalloc * imalloc = 0; /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( SUCCEEDED(SHGetMalloc( &imalloc))) /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; imalloc-&gt;Free (pIDList); /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; imalloc-&gt;Release(); /o:p

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } /o:p

&nbsp; /o:p

} /o:p

好了,简单扩展就到这里为止,至于很多大神需要再做更深一步的扩展,那就沿着这个思路走下去就可以了。毕竟我目前也就走到这一步了,呵呵。 /o:p

&nbsp; /o:p

小讯
上一篇 2025-05-14 18:52
下一篇 2025-05-05 13:51

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/180962.html