vc中如何获取打开文件名

来源:互联网 发布:mac air如何切换输入法 编辑:程序博客网 时间:2024/05/22 17:35

在编制程序的过程中,很多时候我们需要从外部存储器中获取文件名。如果你知道文件路径,那很容易解决,但是不知道文件路径的话,怎么办呢?其实答案地球人都知道,那就是vc提供的“打开文件对话方块”。怎么使用它呢?请看代码:

#include <windows.h>//包含windows.h头文件
#include <commdlg.h>//包含通用对话框头文件.
static OPENFILENAME ofn ;//定义打开文件结构

TCHAR openName[100][MAX_PATH]={'\0'},//定义二个储存打开文件名字符数组.
      openBuffer[100][MAX_PATH]={'\0'};

void PopFileInitialize (HWND) ; //声明打开文件名结构初始化函数

BOOL PopFileOpenDlg (HWND, PTSTR) ; //声明打开文件对话框函数

BOOL GetOpenName(HWND hwnd) ;//声明获取打开文件名函数

void PopFileInitialize (HWND hwnd)//打开文件结构初始化函数
{
static TCHAR szFilter[] = TEXT ("WAVE音频文件(*.WAV)\0*.WAV\0所有文件 (*.*)\0*.*\0\0") ;//定义过滤字符数组
ofn.lStructSize = sizeof (OPENFILENAME) ;//定义结构大小(DWORD类型)
ofn.hwndOwner = hwnd ;//定义窗口所有者句柄(HWND类型)
ofn.hInstance = NULL ;//定义指向对话框模板(HINSTANCE类型)
ofn.lpstrFilter = szFilter ;//定义过滤字符缓冲(LPCTSTR类型)
ofn.lpstrCustomFilter = NULL ;//自定义过滤字符缓冲(LPTSTR类型)
ofn.nMaxCustFilter = 0 ;//定义缓冲大小(DWORD类型)
ofn.nFilterIndex = 0 ;//定义过滤字符索引(DWORD类型)
ofn.lpstrFile = NULL ; //定义保存打开文件全名的缓冲(LPTSTR类型)
ofn.nMaxFile =100 * MAX_PATH ;//定义缓冲的大小(DWORD类型)
ofn.lpstrFileTitle = NULL ; //定义保存打开文件名的缓冲(LPTSTR类型)
ofn.nMaxFileTitle = 0 ;//定义缓冲的大小(DWORD类型)
ofn.lpstrInitialDir = NULL ;//定义初始化目录的缓冲(LPCTSTR类型)
ofn.lpstrTitle = NULL ;//定义打开对话框的标题(LPCTSTR类型)
ofn.Flags = 0 ; //定义打开对话框的旗标(DWORD类型)
ofn.nFileOffset = 0 ;//保存从lpstrfile起始位置到第一个文件名的偏移值,从0开始计算(WORD类型)
ofn.nFileExtension = 0 ;//保存到扩展名的偏移值,以TCHAR为单位,即字节或字符.(WORD类型)
ofn.lpstrDefExt = TEXT ("wav") ;//定义默认扩展名.(LPCTSTR类型)
ofn.lCustData = 0L ;//自定义数据(LPARAM类型)
ofn.lpfnHook = NULL ;//指向打开文件钩子函数(LPOFNHOOKPROC类型)
ofn.lpTemplateName = NULL ;//指向用户自定义模板(LPCTSTR类型)
}
BOOL PopFileOpenDlg (HWND hwnd, PTSTR pstrFileName)//打开文件对话框函数
{
ofn.hwndOwner = hwnd ;
ofn.lpstrFile = pstrFileName ;
ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_ALLOWMULTISELECT |
            OFN_EXPLORER | OFN_NOVALIDATE ;
return GetOpenFileName (&ofn) ;//返回GetOpenFileName函数打开对话方块.
}

//定义获取打开文件名函数
BOOL GetOpenName(HWND hwnd)
{
    int i = 0 ,j = 0 ,iCount = 0 ;//定义几个整型计数器变量

    HANDLE hFile = NULL ;//定义一个文件句柄
    static TCHAR szFileName[100 * MAX_PATH]={'\0'};//定义一个接受打开文件名的临时字符数组
 if (PopFileOpenDlg (hwnd, szFileName))//判断是否选中文件;
 {
         
      while(szFileName[i])//从szFileName中读出文件名
      {
               j=0;
       //将文件名保存到openBuffer;
               while(openBuffer[iCount][j]=szFileName[i])
               {
                  i++;
                  j++;
               }
               i++;
               iCount++;
      }
     
 }
 else
   return FALSE ;//如果没选中文件则返回假
  
 if(INVALID_HANDLE_VALUE==
                (hFile =CreateFile(openBuffer[0],GENERIC_READ,
       0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0)))
 {
    for(i=0;i<iCount-1;i++)//保存旧文件路径.
    {
                  lstrcpy(openName[i],openBuffer[0]);
      if(openBuffer[0][3] != '\0')
                    lstrcat(openName[i],"\\");
    }
    j=1;
    for(i=0;i<iCount-1;i++)//加上文件名.
    {
                  lstrcat(openName[i],openBuffer[j]);
                  j++;
    }
    CloseHandle(hFile);//关闭文件句柄.
               
    Count = iCount - 1 ;//保存打开文件的数量
 }
 else
 {
      Count = iCount ;//保存打开文件的数量
                  CloseHandle(hFile);//关闭文件句柄.
                  lstrcpy(openName[0],openBuffer[0]);//保存文件名
                  lstrcat(openName[0],'\0');//字符数组加上结束字符
 }
 return TRUE ;
}

这是我写的函数,专门用于获取文件名,其中蓝色的代码是照抄《windows程序设计》一书的。对于这个函数来说,最复杂的应是OPENFILENAME结构,很多初学者见到它都像见到鬼一样,其实不用怕,只有你有“朱古力”就行了(打鬼用“朱古力”嘛,星爷说的)。看看上面的红色代码,填入你需要的,其余的照抄就行了。其实很多东西都没有它外表那么可怕,用过一两次后,你就会慢慢掌握它的。这一招真是百试百灵,比“万金油”还好用,元芳你怎么看?

我们再来看看上面的绿色代码,它定义了一个字符数组szFileName,这是专门储存从打开文件方块返回文件名用的。文件名的格式是这样的,如果是单个文件,则是文件名全路径;如果是多个文件,则开头是文件路径,然后是文件名,中间用'\0'隔开,而且两种情况末尾都是加上两个'\0'。我这里用了两个互相嵌套的while循环将文件名析出,分个存入二维数组openBuffer,然后再区分单个与多个文件名的情况分别处理。

循环是一个初学者比较头痛的问题,其实不必太在意,只要弄清楚内在的逻辑,慢慢地你就能掌握它。循环的例子在现实中也是司空见惯的,你看大街小巷的“反串男”,说穿了也是“循环”惹的祸!

最后总结一下,这个函数最难处其实就在于循环的设计,其它的都没什么,都是些api的调用罢了。谢谢你阅读这篇文章,祝你好运!

原创粉丝点击