最近在做Windows 开发过程中遇到一个问题,需要打开文件对话框和另存为对话框,获取所选文件的路径信息,这部分很容易就实现了,可当另存为文件时如何获得格式不同文件的扩展名却遇到了一点问题,经过一番资料搜索和官方文档查阅,遂解决。先说心得,windows API 相关的问题还是要直接查询微软官方文档来的快,上面解释的很清楚,不要被英文和那些奇奇怪怪的定义吓到,自己动手实现几次就明白是怎么回事了。东拉西扯,进入正题,
Windows 打开和另存为对话框如下所示,
(1) 打开对话框
(2)另存为对话框
这里用一个例子说明几个概念,文件目录,文件路径,文件名,如下图所示,在F盘Demo文件夹下有一个名为"Test"的txt文件
文件Test.txt的文件名是“Test”
文件目录是 “F:\Demo";
文件路径是:“F:\Demo\Test.txt";
文件扩展名是:“.txt”
这打开“打开”对话框以及打开“另存为对话框”这两个两个窗口涉及到的API分别为
GetOpenFileName()
GetSaveFileName()
微软官方的文档的建议是这两个API已经过时了,建议使用 IFileOpenDialog 或者IFileSaveDialog,这个不是本文的主题,有兴趣的朋友可以去官网查询新方法的用法,此处暂且不表。
以GetOpenFileName() 为例,做以解释。官方文档给出的函数定义是
BOOL GetOpenFileNameA(
LPOPENFILENAMEA Arg1
);
参数 Arg1 类型 LPOPENFILENAME
(小提示,如果觉得官方文档大段的英文看起来很费劲,可以用chrome浏览器自带的翻译功能,鼠标右键有翻译选项,翻译的结果也八九不离十)关于类型LPOPENFILENAME 文档给出的解释是:
A pointer to an OPENFILENAME structure that contains information used to initialize the dialog box. When GetSaveFileName returns, this structure contains information about the user’s file selection.(一个指向OPENFILENAME结构的指针,该结构包含用于初始化对话框的信息。当GetSaveFileName返回时,此结构包含有关用户文件选择的信息。)
因此我们知道GetOpenFileNameA的参数我们需要传入的是一个指向 OPENFILENAME 结构的指针,马不停蹄的我们要立即看看这个OPENFILENAME 结构的内容是什么,因为只有知道他的结构我们才能知道如何初始化我们的结构体指针。如果经常使用Windows API 你就会发现这是很常见的模式。 不同的开发人员有不同的需要,Windows 把框架丢给你,让你自己定义,比如我们打开的窗口的标题,窗口的模态,保存文件类型的数目,是否允许多选,等等。这也是我们初始化这个结构体的意义所在。
点进OPENFILENAME 的链接,我们看到如下结构体定义
typedef struct tagOFNA {
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCSTR lpstrFilter;
LPSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPSTR lpstrFile;
DWORD nMaxFile;
LPSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCSTR lpstrInitialDir;
LPCSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCSTR lpstrDefExt;
LPARAM lCustData;
LPOFNHOOKPROC lpfnHook;
LPCSTR lpTemplateName;
LPEDITMENU lpEditInfo;
LPCSTR lpstrPrompt;
void *pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
} OPENFILENAMEA, *LPOPENFILENAMEA;
文档里面每一项都解释的很清楚,这里就不做一一解读了。挑其中几个用的比较多的解释一下。
lStructSize:结构的长度,以字节为单位。此参数使用 sizeof (OPENFILENAME)。
hwndOwner:拥有该对话框的窗口的句柄。这个成员可以是任何有效的窗口句柄。如果对话框里有没有所有者,它可以为 NULL。
lpstrFilter:筛选器,这个关键字很常用,他决定着对话框的文件类型。这个关键字通常由两对字符串构成,每一对中的第一个字符串是一个显示字符串,描述了该筛选器 (例如,“文本文件”),和第二个字符串指定筛选器模式 (例如,"*.TXT")。例如
ofn.lpstrFiler = TEXT