接下来就到了本次的核心内容:
winmain.c (接上)
......
int open_filename(void)
{
//INIT OPENFILENAME
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(OPENFILENAME));
//MODE
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWinMain;
//FILTER
ofn.lpstrFilter = strFilter;
ofn.nFilterIndex = 1;
//FILE AND FILETITLE
ofn.lpstrFile = strFilename;
ofn.nMaxFile = 399;
ofn.lpstrFileTitle = strFiletitle;
ofn.nMaxFileTitle = 143;
//STYLE
ofn.lpstrTitle = "iNotepad OpenFile";
ofn.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
return GetOpenFileName(&ofn);
}
......
首先对之前的知识进行"扫盲".
Filter, 可以翻译为"过滤器", 是一种特殊格式的字符串, 它可以确定在对话框之内出现的文件特性, 如只允许后缀名为txt的文件出现等.
Filename, 是对话框在选定文件之后, 输出文件名及文件路径的字符串. Filetitle与之类似, 只不过字符串里只包含文件名.
解释完毕之后, 我们来回到代码. OPENFILENAME, 是一个结构体, 里面包含着与这个对话框相关的属性.
lStructSize, 是结构体的大小(似乎许多Windows结构体都要求提供大小, WNDCLASSEX也是)
hwndOnwer, 是对话框的父窗口, 一般情况下我们可以赋值为hWinMain.
lpstrFilter, 是过滤器字符串地址.
在这里, 我们再详细谈谈Filter字符串的格式. 比如之前的Notepad的截图:
它的Filter字符串结构可能是如下构成
"Text Documents (*.txt)\0*.txt\0\0"
在这里, 前面的"Text Documents (.txt)"是可以显示在对话框中的文件类别下拉列表中的, 而后面的".txt", 则主要用于过滤, 让对话框中只显示*.txt这样的文件.
如果文件类别下拉列表想要写多一点, 比如添上"All Files"这样的内容呢? 那么就可以多谢这样的Filter格式, 但是必须要以2个\0结尾. 比如说本次的strFilter:
const char strFilter[] = "Text File(*.txt)\0*.txt\0All Files\0*.*\0\0";
nFilterIndex其实我也没看懂是个什么东西(笑), 但是我看的参考程序的惯例一般都是写1.
lpstrFile, lpstrFileTitle, 分别是输出的Filename和Filetitle的地址. 而nMaxFile和nMaxFileTitle, 则是输出字符串的最大长度. 在这里设定为字符串数组大小-1.
lpstrTitle是对话框的标题.
Flags是对话框的属性, 在这里我选择的属性是OFN_ALLOWMULTISELECT(可以使用下拉列表在文件名框内选择文件), OFN_EXPLORER(Explorer式对话框样式, 在这里如果没有选择本属性而选择前属性的话 显示出的对话框将会类似于Windows 3.1的样式), OFN_FILEMUSTEXIST(文件必须存在), OFN_HIDEREADONLY(选择此属性可以隐藏原先对话框中的"以只读形式打开文件"复选框).
最后, 调用GetOpenFileName函数, 显示对话框, 并返回函数返回值. 如果函数返回值为0, 则说明点击了对话框中的"取消"按钮或者关闭了对话框. 返回值为1则代表已经选择了一个文件并且输出了Filename和Filetitle信息.