由于各种应用,我们需要调用系统的打开文件对话框或者打开文件夹对话框,或两者兼有。今遇到这个情况已经解决,特写下这篇博文。

1.打开文件对话框常用的方法是使用系统的CFileDialog。这里介绍另外一种方法就是使用OPENFILENAME这个结构体和GetOpenFileName()这个函数,可以实现单选文件或者多选文件,代码如下:

需引入头文件#include "CommDlg.h"

  1. TCHAR szBuffer[MAX_PATH] = {0};
  2. OPENFILENAME ofn= {0};
  3. ofn.lStructSize = sizeof(ofn);
  4. ofn.hwndOwner = m_hWnd;
  5. ofn.lpstrFilter = _T("Exe文件(*.exe)\0*.exe\0所有文件(*.*)\0*.*\0");//要选择的文件后缀
  6. ofn.lpstrInitialDir = _T("D:\\Program Files");//默认的文件路径
  7. ofn.lpstrFile = szBuffer;//存放文件的缓冲区
  8. ofn.nMaxFile = sizeof(szBuffer)/sizeof(*szBuffer);
  9. ofn.nFilterIndex = 0;
  10. ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER ;//标志如果是多选要加上OFN_ALLOWMULTISELECT
  11. BOOL bSel = GetOpenFileName(&ofn);

这样就可以打开选择文件对话框了。可以选择需要的文件。szBuffer是存放的选择的文件路径。

1.1 多选

下面的代码演示了如何得到GetOpenFileName允许多选的情况下选择的文件名
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
 OPENFILENAME ofn;
 TCHAR szOpenFileNames[80*MAX_PATH];
 TCHAR szPath[MAX_PATH];
 TCHAR szFileName[80*MAX_PATH];
 TCHAR* p;
 int nLen = 0;
 ZeroMemory( &ofn, sizeof(ofn) );
 ofn.Flags = OFN_EXPLORER | OFN_ALLOWMULTISELECT;
 ofn.lStructSize = sizeof(ofn);
 ofn.lpstrFile = szOpenFileNames;
 ofn.nMaxFile = sizeof(szOpenFileNames);
 ofn.lpstrFile[0] = '/0';
 ofn.lpstrFilter = TEXT("All Files(*.*)/0*.*/0");
 if( GetOpenFileName( &ofn ) )
 {  
  //把第一个文件名前的复制到szPath,即:
  //如果只选了一个文件,就复制到最后一个'/'
  //如果选了多个文件,就复制到第一个NULL字符
  lstrcpyn(szPath, szOpenFileNames, ofn.nFileOffset );
  //当只选了一个文件时,下面这个NULL字符是必需的.
  //这里不区别对待选了一个和多个文件的情况
  szPath[ ofn.nFileOffset ] = '/0';
  nLen = lstrlen(szPath);
  
  if( szPath[nLen-1] != '//' )   //如果选了多个文件,则必须加上'//'
  {
   lstrcat(szPath, TEXT("//"));
  }
  
  p = szOpenFileNames + ofn.nFileOffset; //把指针移到第一个文件
  
  ZeroMemory(szFileName, sizeof(szFileName));
  while( *p )
  {   
   lstrcat(szFileName, szPath);  //给文件名加上路径  
   lstrcat(szFileName, p);    //加上文件名  
   lstrcat(szFileName, TEXT("/n")); //换行   
   p += lstrlen(p) +1;     //移至下一个文件
  }
  MessageBox(NULL, szFileName, TEXT("MultiSelect"), MB_OK);
 }

2.打开文件夹对话框方法:

需引入头文件:#include "Shlobj.h"

  1. TCHAR szBuffer[MAX_PATH] = {0};
  2. BROWSEINFO bi;
  3. ZeroMemory(&bi,sizeof(BROWSEINFO));
  4. bi.hwndOwner = NULL;
  5. bi.pszDisplayName = szBuffer;
  6. bi.lpszTitle = _T("从下面选文件夹目录:");
  7. bi.ulFlags = BIF_RETURNFSANCESTORS;
  8. LPITEMIDLIST idl = SHBrowseForFolder(&bi);
  9. if (NULL == idl)
  10. {
  11. return;
  12. }
  13. SHGetPathFromIDList(idl,szBuffer);

上面的代码就可以打开一个选择文件夹对话框了。

3.选择文件或文件夹对话框的调用:

  1. TCHAR szBuffer[MAX_PATH] = {0};
  2. BROWSEINFO bi;
  3. ZeroMemory(&bi,sizeof(BROWSEINFO));
  4. bi.hwndOwner = NULL;
  5. bi.pszDisplayName = szBuffer;
  6. bi.lpszTitle = _T("从下面选择文件或文件夹:");
  7. bi.ulFlags = BIF_BROWSEINCLUDEFILES;
  8. LPITEMIDLIST idl = SHBrowseForFolder(&bi);
  9. if (NULL == idl)
  10. {
  11. return;
  12. }
  13. SHGetPathFromIDList(idl,szBuffer);

使用了上面的代码就可以根据需要选择文件或者文件夹了。

4. 创建一个可以新建文件夹且指定选中初始路径的浏览文件夹对话框

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

// Browsing for directory.

#define BIF_RETURNONLYFSDIRS   0x0001  // For finding a folder to start document searching

#define BIF_DONTGOBELOWDOMAIN  0x0002  // For starting the Find Computer

#define BIF_STATUSTEXT         0x0004

#define BIF_RETURNFSANCESTORS  0x0008

#define BIF_EDITBOX            0x0010

#define BIF_VALIDATE           0x0020   // insist on valid result (or CANCEL)

#define BIF_BROWSEFORCOMPUTER  0x1000  // Browsing for Computers.

#define BIF_BROWSEFORPRINTER   0x2000  // Browsing for Printers

#define BIF_BROWSEINCLUDEFILES 0x4000  // Browsing for Everything

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

#define BIF_NEWDIALOGSTYLE   0x40

#define BIF_USENEWUI (BIF_NEWDIALOGSTYLE|BIF_EDITBOX)

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

下面给出这个简单扩展的代码

#define BIF_NEWDIALOGSTYLE   0x40

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

{

if(uMsg == BFFM_INITIALIZED)

{

SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);

}

return 0;

}

void CSisAppendMidDlg::OnButtonSisdes()

{

// TODO: Add your control notification handler code here

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|BIF_NEWDIALOGSTYLE;

CFileFind   finder;

if(finder.FindFile(m_cSisDes)==FALSE)

{

bi.lParam =0;

bi.lpfn = NULL;

}

else

{

bi.lParam = (long)(m_cSisDes.GetBuffer(m_cSisDes.GetLength()));//初始化路径,形如(_T("c:\\Symbian"));

bi.lpfn = BrowseCallbackProc;

}

finder.Close();

bi.iImage=IDR_MAINFRAME;

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

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

if(pIDList)

{

SHGetPathFromIDList(pIDList, Buffer);

//取得文件夹路径到Buffer里

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

}

UpdateData(FALSE);

// free memory used

IMalloc * imalloc = 0;

if ( SUCCEEDED(SHGetMalloc( &imalloc)))

{

imalloc->Free (pIDList);

imalloc->Release();

}

}

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

C++文件(夹)选择对话框的更多相关文章

  1. [VB.NET]调用系统的文件夹选择对话框

    以下示例代码展示如何调用系统的文件夹选择对话框: Private Function SelectFolder(ByVal Describe As String, Optional ByVal Show ...

  2. c# 打开、保存文件对话框 和 文件夹选择对话框

    1. OpenFileDialog openImageDialog = new OpenFileDialog(); openImageDialog.Filter = "Image Files ...

  3. 【转】python qt(pyqt)的文件打开、文件保存、文件夹选择对话框

    import PyQt4.QtCore,PyQt4.QtGui # 获取文件路径对话框 file_name = QFileDialog.getOpenFileName(self,"open ...

  4. WPF:自定义Metro样式文件夹选择对话框FolderBrowserDialog

    1.前言 WPF并没有文件选择对话框,要用也就只有使用Winform版的控件.至今我也没有寻找到一个WPF版本的文件选择对话框. 可能是我眼浊,如果各位知道有功能比较健全的WPF版文件选择对话框.文件 ...

  5. 在WPF中使用文件夹选择对话框

    开发中有时会想实现"选择某个文件夹"的效果: 在WPF中,使用Microsoft.Win32.OpenFileDialog只能选择文件,FolderBrowserDialog只能用 ...

  6. (WPF) 文件和文件夹选择对话框。

    点击button,选择一个excel文件,并将文件名显示在textbox上. private void btnSelectErrorTableFile_Click(object sender, Rou ...

  7. MFC 文件夹选择对话框

    CString setSavePath() { CString strPath = _T(""); HRESULT hr; LPITEMIDLIST pItemList; BROW ...

  8. Asp.net点击按钮弹出文件夹选择框的实现(网页)

    本文地址:http://www.cnblogs.com/PiaoMiaoGongZi/p/4092112.html 在Asp.net网站实际的开发中,比如:需要实现点击一个类似于FileUpload的 ...

  9. javascript文件夹选择框的两种解决方案

    javascript文件夹选择框的两种解决方案 解决方案1:调用windows 的shell,但会有安全问题. * browseFolder.js * 该文件定义了BrowseFolder()函数,它 ...

随机推荐

  1. 把SmartForm转换成PDF

    摘要:将SmartForm转换为PDF的过程包括3个简单步骤. 调用智能窗体,然后返回OTF数据. 使用“转换”功能模块将OTF数据转换为所需格式. 下载文件 呈现宏“code”时出错:为参数“lan ...

  2. 剑指offer题目练习一

    看见了一道二维数组找数的题,已排好序的数组(从左至右从上到下,都是由小变大的)让找数,瞬间就出思路了,并没有必要去看他的解释,两次二分就搞定了. #include<cstdio> #inc ...

  3. WPF系列教程——(二)使用Prism实现MVVM设计模式 - 简书

    原文:WPF系列教程--(二)使用Prism实现MVVM设计模式 - 简书 本文假设你已经知道MVVM设计模式是什么,所以直接进入正题,今天我们就用Prism来实现WPF的MVVM设计模式,百度上关于 ...

  4. echarts 地图的背景色和各省颜色配置以及地图饼图联动

    myChart.on(ecConfig.EVENT.MAP_SELECTED, function (param) { var selected = param.selected; var str = ...

  5. Freemarker 语法详解

    Freemarker 在线中文官方参考手册 Freemarker是一款模板引擎,是一种基于模版生成静态文件的通用工具,它是使用纯java编写的,一般用来生成HTML页面. Freemarker 生成静 ...

  6. Jmeter微信小程序接口测试

    最近公司新项目组开发一款微信小程序电商平台,为了更好保证产品质量,因此提出了需要进行接口测试. 从接口本身来讲,对其测试与其他项目应该是一样的.所以不难理解,我们要对小程序的接口测试需要准备的 材料有 ...

  7. python-isinstance,issubclass

    1 #当存在继承关系时,两个类中存在相同的方法,如何执行父类的方法,通过super 2 class C1: 3 def f1(self): 4 print('c1.f1') 5 6 7 class C ...

  8. Linux认知之旅【04 进一步了解目录】!

    一.目录是什么? 二.不得不提的文件系统! 三.绝对路经,相对路径

  9. 孤荷凌寒自学python第十八天python变量的作用范围

    孤荷凌寒自学python第十八天python函数的形参与变量的范围 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.在python的函数中各种不同的形式参数在定义的先后顺序上有规定: 必须 ...

  10. 转: jsp之c标签

    http://www.gbsou.com/2009/10/12/1028.htmljsp标签之c标签 核心标签库 它是JSTL中的核心库,为日常任务提供通用支持,如显示和设置变量.重复使用一组项目.测 ...