当前位置:文档之家› 浅谈VB文件对话框

浅谈VB文件对话框

浅谈visual basic文件对话窗微软提供了通用对话框接口Microsoft Common Dialog Control,为编程带来了很大方便,利用它可以轻松调用字体、颜色、打印、帮助等对话框,其中最常用的莫过于打开文件对话框,很多朋友都会用,但是未必每个人都能真正掌控它。

在此假定程序里有CommonDialog的一个实例,命名为cd1,对于单个文件的选择,只需令cd1.Action = 1即可,通常不会遇到问题,返回值cd1.FileName 是选定文件的全路径,但是如果要实现多选,还是有一些问题需要解决的,下面来分析两种方法。

操作:从对话框选定多个文件,把文件路径添加到列表List1方法一:cd1.Flags = 512 '常量cdlOFNAllowMultiselect 的值'示例代码Dim i As Integer, j As IntegerDim temp() As String '接收文件名cd1.Flags = 512cd1.MaxFileSize = 2048cd1.FileName = ""cd1.Filter = "歌曲文件|*.MP3|" '查找类型过滤cd1.Action = 1If cd1.FileName = "" Then Exit SubIf InStr(cd1.FileName, " ") = 0 ThenList1.AddItem cd1.FileNameElsetemp = Split(cd1.FileName, " ")For i = 1 To UBound(temp)List1.AddItem temp(0) & temp(i)Next iEnd If以上代码的每一行都有其特定作用,有些朋友从网上找了类似的代码,但是改动后总是出错,找不到解决的办法,下面逐行分析。

第一行:Dim i As Integer, j As Integer,变量声明坚持“先声明后引用,尽可能避免隐式声明”的使用变量原则,养成好的习惯,出错的几率就小很多。

此外在VB6.0中如Dim a,b as Integer的声明语句仅仅把第一项a声明为整形变量,后边的均为变体Variant型,可用MsgBox TypeName(b)语句测试。

所以尽量对于每个变量在声明时都指明其类型,不过在中,声明方面已被合理修改。

第二行:Dim temp() As String,数组声明temp()数组用于存放cd1返回的单个文件名。

对于cd1.Flags = cdlOFNAllowMultiselect的情况返回值稍复杂些。

如果选中的是单个文件,自不必说,直接用返回值cd1.FileName即可,其值等于目录加文件名,即InitDir + FileTitle(注:此处InitDir代替文件的位置,并非指cd1的InitDir属性,因为在不设置ce1 的InitDir属性的情况下,打开的是当前目录,但cd1.InitDir="")如果选择了多个文件,那么返回值cd1.FileName的格式类似为:"D:\多媒体\许巍\ 爱.mp3 彩虹.mp3",在此选定了两个文件,返回值里有两个个空格,分别把目录、文件名1、文件名2隔开,这里的空格等于字符串" ",区别于下边要说的Chr(0)。

那么temp()的作用自然就是存放单个的文件名。

第三行:cdlOFNAllowMultiselect =512,以下是MSDN关于此常量的介绍:the FileName property returns a string containing the names of all selected files. The names in the string are delimited by spaces.含义在上边第二行已经做了示例和解释,在此不必赘述。

第四行:cd1.MaxFileSize = 2048关于cd1.MaxFileSize 的设置,来看MSDN:object.MaxFileSize [=value]The MaxFileSize property syntax has these parts:省略此行代码的后果是:一次选择文件过多的情况下会出错,提示“FileName缓冲区过小,不能存储选定的文件名。

(增加到MaxFileSize)”。

因为“The default is 256”,在程序里测试是260,这个大小通常能包含10个以下的文件名,显然太小了。

当然也并非越大越好,因为浪费计算机内存。

它的范围既然是1 — 32K,显然cd1.MaxFileSize的单位为B,256B 只能存储256个英文字母,根据单位换算推出合适的数值赋给cd1.MaxFileSize 即可,如果设置较大数值(不能大于2^32),建议在过程结束时释放空间,即在End Sub之前加上cd1.FileName="",32K对于单个进程来说是个不小的数字,而且此句代码能避免后续的过程出错,将在下面提及。

第五行:还是cd1.FileName="",即使单个过程的首尾都加上此举也并非多此一举。

因为作为cd1的属性,FileName是一个字符串型变量,它的作用范围是全局的,在内存中开辟一段固定地址,如果某过程调用cd1打开了一文件对话框,并选择了一些文件,在过程末尾没有清理缓冲区,cd1.FileName会一直存放着本次的返回值,并在cd1下次启动文件对话框时,直接把数据填入对话框界面文件名对应的文本框,也达到了记录上次打开位置的效果,同样也带来了麻烦。

(也可理解为对话框是一直存在的)这里有一个误区:即并非在cd1每次启动前自动清除cd1.FileName的内容,有些朋友喜欢用诸如:If cd1.FileName = "" ThenExit SubElse……'非空操作End If的代码来判断用户是否没有选择文件就关闭了对话框,相当于放弃操作。

对于cd1.FileName本来就为空的情况,显然是行得通的。

但是如上面所说,只要cd1返回过非空的cd1.FileName,在没有手动释放的情况下,这样的代码逻辑上就有了问题,产生误判断,会执行Else语句。

此外,这句代码的重要性还在于它能避免另一重要错误。

如果手动设置过cd1.MaxFileSize的大小,cd1.FileName的长度比较长的情况下,当文件对话启动并给文件名文本框赋cd1.FileName的值时,就会引发“文件名无效”的错误,代号为20477.Invalid filename (Error 20477)The specified filename may not exist or may contain illegal characters.因为引用的cd1.FileName这个值是上次返回遗留下来的,它太长了。

这样导致的结果是本过程只能运行一次,下次运行必然出错。

第六行:cd1.Filter = "歌曲文件|*.MP3|" ,过滤文件类型,不必说第七行:cd1.Action = 1,调用文件窗口,此句可用cd1.ShowOpen替代。

需要注意的是:所有对于cd1属性的赋值都应放在此句之前,否则赋值语句的效果只能在本过程下次启动时显现出来,结果可能导致本次运行出错或不能达到预期结果。

第八行:If cd1.FileName = "" Then Exit Sub ,用户放弃操作,则退出过程第九行:前边已经说过,对于选择单个文件的情况,返回值里是没有空格的,操作系统对于含有空格的目录和文件名都已用等价的无空格格式代替,如果InStr(cd1.FileName, " ") = 0,那么表明只选择了一个文件,直接用返回值cd1.FileName即可;否则,肯定有多个文件,那么需要把单个文件名分离出来。

第十行:List1.AddItem cd1.FileName,列表加载第十一行:Else语句,选中多个文件情况第十二行:temp = Split(cd1.FileName, " "),分离各段Split(),很有用的一个函数,根据分隔符,把各段分离出存入数组,返回值是一数组;对于字符串"D:\多媒体\许巍\ 爱.mp3 彩虹.mp3"执行Split()操作:Dim temp() As Stringtemp = Split("D:\多媒体\许巍\ 爱.mp3 彩虹.mp3", " ")那么得到的数组temp()中,元素依次为"D:\多媒体\许巍\","爱.mp3","彩虹.mp3"本站有多个改进的取段函数,及其详细算法介绍。

第十三行-第十五行:For i = 1 To UBound(temp)List1.AddItem temp(0) & temp(i)Next i把文件名依次加入列表我们已经知道了多个文件名的返回值格式:如"D:\多媒体\许巍\ 爱.mp3 彩虹.mp3",显然所得数组第一个元素为文件位置,其后元素为FileTitle。

所以没个文件全名FileName为数组首元素+该文件对应元素。

第十六行:End If,判断结束以上是基本代码,可以根据实际需要做适当修改。

用过cd1.Flags =512对话框的朋友差不多都会感叹,界面太难看了!的确,微软做出的这款界面真的让人不敢恭维,太丑了,而且操作很不方便,还是来看我们完美的方法二吧!方法二:cd1.Flags = cdlOFNAllowMultiselect Or cdlOFNExplorer'示例代码cd1.Flags = cdlOFNAllowMultiselect Or cdlOFNExplorercd1.MaxFileSize = 2048cd1.FileName = ""cd1.Filter = "歌曲文件|*.MP3|" '查找类型过滤cd1.ShowOpenIf cd1.FileName = "" Then Exit SubIf InStr(1, cd1.FileName, Chr(0)) = 0 ThenList1.AddItem cd1.FileNameElsetemp = Split(cd1.FileName, Chr(0))For i = 1 To UBound(temp)List1.AddItem temp(0) & "\" & temp(i) Next iEnd Ifcd1.FileName = "" '二次清除前边方法一已经做了详细介绍,这里主要对不同的地方略作说明。

相关主题