跟我一起玩Win32开发(19):浏览和打开文件
在应用程序中,我们很经常要实现的功能,是Open文件或保存文件对话框,让用户来选择一个或N个文件。本文我将介绍两种思路,第一种方法较为复杂,第二种方法较为简单。
方法一:老规矩
这是一种传统方法,使用GetOpenFileName或者GetSaveFileName函数,看名字就知道,前者用来打开文件,后者是保存文件,这两个函数的用法是一样的,因此,我只演示其中一个。
无论你使用哪个函数,都要涉及一个结构体——OPENFILENAME。关于它的成员,我就不一一来说了,挑几个有用的扯一扯。
lStructSize:结构的大小,弄个sizeof就行了。
lpstrFilter:设置过滤器。注意啊,这个过滤器字符串和.NET中的写法不同,.NET的写法是从VB6继承过来,可以写成“垃圾文件 | *.rbs | 老鼠文件 | *.mos”,我们这里不是用“|”来分隔的,而是用“\0”分隔,而结尾是两个NULL,即两个“\0”。
nFilterIndex:过滤器索引,设置了N个滤过的后缀,设置默认选择哪个,第一个为1,第二个为2,第三个为3,依此类推,是从1开始的,不是0。
lpstrFile:文件名,包含完整路径,当对话框关闭后,我们就是从这个成员把用户选择的文件名取出。
nMaxFile:文件名的长度,一定要足够大,不然就装不下了,对路径长度,系统是有限定的,用MAX_PATH宏就可以了,WCHAR myFilename[MAX_PATH]。
Flags:标志位。主要决定对话框应具备哪些特征和行为,如是否检查目标文件已存在。
哦,这个可能看了没感觉,看看例子代码,一目了然。
- OPENFILENAME opfn;
- WCHAR strFilename[MAX_PATH];//存放文件名
- //初始化
- ZeroMemory(&opfn, sizeof(OPENFILENAME));
- opfn.lStructSize = sizeof(OPENFILENAME);//结构体大小
- //设置过滤
- opfn.lpstrFilter = L"所有文件\0*.*\0文本文件\0*.txt\0MP3文件\0*.mp3\0";
- //默认过滤器索引设为1
- opfn.nFilterIndex = 1;
- //文件名的字段必须先把第一个字符设为 \0
- opfn.lpstrFile = strFilename;
- opfn.lpstrFile[0] = '\0';
- opfn.nMaxFile = sizeof(strFilename);
- //设置标志位,检查目录或文件是否存在
- opfn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
- //opfn.lpstrInitialDir = NULL;
- // 显示对话框让用户选择文件
- if(GetOpenFileName(&opfn))
- {
- //在文本框中显示文件路径
- HWND hEdt = GetDlgItem(hDlg, IDC_EDTFILENAME);
- SendMessage(hEdt, WM_SETTEXT, NULL, (LPARAM)strFilename);
- }
ZeroMemory函数前面说过了,你就当作它用来初始化结构就行了。
你可能会疑问,不是说lpstrFilter的字符串是两个NULL结尾的吗,为什么代码中只有一个?因为你输入的字符串会在后面自动加了个‘\0’,所以我们加一个就OK,后面自动加上一个,就两个了。
下图是执行结果:
GetSaveFileName的用法也一样,有兴趣的朋友可以回家自己玩一下。
方法二:新规矩
这个新规矩是谁定的?哈哈,我定的。
都说知识是可以综合运用的,所以,下面的方法是灵活运用知识了。为啥?记得吧,.NET类库其实也为我们封装了,大家玩过Windows Forms开发肯定知道,在System.Windows.Forms下面的。是啊,既然有了现成的,我们干吗不拿来用呢。
首先,打开项目属性,按下图的方法,让项目支持 /clr ,然后点击“应用”。
引用需要用到的程序集。
在代码文件中引入命名空间。
- using namespace System;
- using namespace System::Windows::Forms;
然后实现打开文件的功能。
- if(LOWORD(wParam) == IDC_BTNOPWTCLR)
- {
- OpenFileDialog ^dlg = gcnew OpenFileDialog;
- dlg ->Filter = L"所有文件|*.*|图片文件|*.jpg";
- dlg->FilterIndex = 1;
- dlg->CheckFileExists = true;
- if (dlg ->ShowDialog() == DialogResult::OK)
- {
- //取得文件名
- }
- }
但是,当获取文件名的时候,遇到了一个严重问题了,在CLR中,我们取到的文件名是System::String ^类型的,可是我们这里的Win32程序需要wchar_t类型的字符串,这怎么办?能进行转换吗?
微软早就想到这个问题,所以,它给我们写了一个vcclr.h头文件,里面有一个PtrToStringChars函数,使用它就可以将托管的字符串转为标准字符串了。
- if (dlg ->ShowDialog() == DialogResult::OK)
- {
- //取得文件名
- pin_ptr<const WCHAR> strFileName = PtrToStringChars(dlg->FileName);
- HWND hEdt = GetDlgItem(hDlg, IDC_EDTFILENAME);
- SendMessage(hEdt, WM_SETTEXT, NULL, (LPARAM)strFileName);
- }
但是,问题仍未解决,运行之后你会很惊喜地收到一个异常信息。
运气真的太好了,那么这个怎么解决呢?再次打开项目属性窗口,找到“链接器”-“高级”,把CLR线程模型改为STA就可以了。
现在运行应用程序,估计没有问题了。
代码我随后上传。
好了,好了,现在大功告成了。拜拜。
跟我一起玩Win32开发(19):浏览和打开文件的更多相关文章
- 跟我一起玩Win32开发(转自CSDN-东邪独孤)
跟我一起玩Win32开发(1):关于C++的几个要点 跟我一起玩Win32开发(2):完整的开发流程 跟我一起玩Win32开发(3):窗口的重绘 跟我一起玩Win32开发(4):创建菜单 跟我一起玩W ...
- 跟我一起玩Win32开发(17):启动和结束进程
这里我再次说明一下,我不知道为什么,现在的人那么喜欢走极端,估计是价值观都“升级”了的缘故吧. 我撰写这一系列Win32相关的文章,并不是叫大家一定要用Win32去开发项目,仅仅是给大家了解一下,Wi ...
- 跟我一起玩Win32开发(18):使用对话框的两个技巧
相信大家知道对话框怎么用了,就是先用“资源编辑器”设计一个对话框,然后在代码中加载处理.今天,我向大家分享两个使用对话框的技巧,还是比较实用的.不用担心,先喝杯茶,很简单的,一点也不复杂,总之,看俺写 ...
- 跟我一起玩Win32开发(20):浏览文件夹
最近忙于一些相当无聊的事情,还没忙完,不过,博客还是要写的,不然我头顶上会多了几块砖头. 在上一篇博文中,我们浏览了文件,今天我们也浏览一下目录,如何? 浏览目录我们同样有两个规矩,用托管类库的我就不 ...
- 跟我一起玩Win32开发(12):使用控件——单选按钮
今天,咱们还是接着玩“控件斗地主”,这是我原创的超级游戏,有益身心健康,玩一朝,十年少. 哦,对,脑细胞极速运动了一下,想起了一个问题,这个破问题虽然网上有很多种解决方案,但是,并没有让所有人都解决问 ...
- 跟我一起玩Win32开发(21):复制&粘贴&剪贴板操作
我要提醒一下大家,看了我的博文学到的知识,千万不要用于实际开发,不然你会被你的上司骂:“妈的,这些东西哪来的,从来没有人这样做过.”不信你试试,脑细胞被冻结的经理或者技术总监们肯定会这样说的. 如果是 ...
- 跟我一起玩Win32开发(4):创建菜单
也不知道发生什么事情,CSDN把我的文章弄到首页,结果有不少说我在误人子弟,是啊,我去年就说过了,如果你要成为砖家级人物,请远离我的博客,我这个人没什么特长,唯一厉害的一点就是不相信权威,鄙视砖家,所 ...
- 跟我一起玩Win32开发(2):完整的开发流程
上一篇中我给各位说了一般人认为C++中较为难的东西——指针.其实对于C++,难点当然不局限在指针这玩意儿上,还有一些有趣的概念,如模板类.虚基类.纯虚函数等,这些都是概念性的东西,几乎每一本C++书上 ...
- 跟我一起玩Win32开发(25):监视剪贴板
自从郭大侠和蓉儿离开桃花岛后,最近岛比较寂静,有一种“门前冷落鞍马稀”的感觉.于是,老邪就拿出<九阴真经>认真阅读,同时用迅雷下载经典大剧<汉武大帝>晚上睡觉前看上几集,老邪一 ...
随机推荐
- 12.怎样自学Struts2发送邮件和验证补充[视频]
12.怎样自学Struts2发送邮件和验证补充[视频] 之前写了一篇"打算做一个视频教程探讨怎样自学计算机相关的技术",优酷上传不了,仅仅好传到百度云上: http://pan.b ...
- linux以及git和maven常用命令
maven常用命令: clean install -Dmaven.test.skip -Ptest-lx (注意:test-lx是pom文件名) 其他 https://www.cnblogs.co ...
- 解决Javascript md5 和 Java md5 中文加密后不同问题
Javascript md5 和 Java md5 带中文字符加密结果不一致,可以通过编码进行转化. javascript可以使用encodeURLComponent将中文先转化一次再进行MD5加密. ...
- JVM Safepoint 安全点
一.什么是安全点: 在可达性分析算法中查找存活的对象,首先要找到哪些是GC Roots: 有两种查找GC Roots的方法: 一种是遍历方法区和栈区来查找(保守式GC): 一种是通过OopMap的数据 ...
- CodeChef:Little Elephant and Colored Coins
类似墨墨的等式 设f[2][j][k]表示a[i].c是否和当前颜色相同,到当前枚举到的颜色为止,颜色数为j,对mnv取模为k的最小数 这是个无限循环背包,用spfa优化 #include<cs ...
- 一步一步学Silverlight 2系列(26):基本图形
概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...
- g00 网站说明
最近在做dns tunnel检测,发现了一堆类似这样的域名:c-6rtwjumjzx7877x24uwjkjwjshjx78x2eywzx78yjx2ehtr.g00.medicinenet.com ...
- 四叉树 bnuoj
点击打开题目链接 建树+广搜一棵树:最下面有更短代码(很巧妙). #include<iostream> #include<stdio.h> #include<queue& ...
- RxJava RxBinding 按钮(Button) 点击(click)
/********************************************************************* * RxJava RxBinding 按钮(Button) ...
- [Selenium] Android 中旋转屏幕,触摸,滚动
package com.learingselenium.android; import junit.framework.TestCase import org.openqa.selenium.Rota ...