⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 感悟visualbasic(3).txt

📁 学习(编程技巧_编程知识_程序代码),是学习编程不可多得的学习精验
💻 TXT
字号:
感悟VisualBasic(3)
 

--------------------------------------------------------------------------------
 
第八军团 时间:2003-11-28 10:03:57 
   
第二话字符串
上一期我们已经对API有了大概了解,并学习了第一个API。为了方便以后的学习,我就先讲一点字符串知识和一个相关的API。
用过VB5.0或者更早版本的读者应该知道VB有一个测试字符串长度的函数:Len。但当你升级到VB6时,会发现这里的Len并没有以前那么好用了——它变成了测试字符个数而不是字符串长度。就是说,当你用以前版本的VB执行Len("字符abc")时,返回值是7,因为中文字符每个有2个字节,所以总共有7个字节;而在VB6中执行,返回值是5。VB6不再有一个直接计算出字符串总字节数的函数了,因为VB6内部已经把字符串转换成了Unicode——一种比ANSI更新的字符编码方式。
Unicode把每一个字,无论是中文还是其他文字都当成两个字节,如果是英文,则这两个字节中第二个字节保留着不使用,如果是双字节字符(如中文,双字节日文以及韩文),而由这两个字节的组合表示一个字符。所以Len可以方便地知道一共有多少个双字节字符,多少个单字节字符,也就出现了上面所说的情况。不过既然VB内部把ANSI字符转换成Unicode,那么它一定有对应方法转换回来。所以这里提供一个比较方便的方法来得到总字节数:LenB(StrConv("字符abc",vbFromUnicode))。
这里用到了一个LenB()函数,你可以自己试试它,比如LenB("字符")、LenB("abc")、LenB("字符abc"),会发现返回值分别是4、6和10。为什么是4、6和10呢?我说过VB内部把ANSI字符转换为Unicode,每个Unicode字符用2个字节来表示,所以,LenB()的作用是返回字符串的实际字节数。但是,这个实际字节数已经不是我所输入的字符串的,而是被VB转换过的(我们无法让VB函数在转换之前先算好长度),所以我们需要先把字符串转换回来,使用的是StrConv()函数。对于这个函数我不想太过详细解释它(一般应用中比较少用),你可以参考MSDN,我只提一提它的第二个参数:vbFromUnicode。
StrConv()函数的第二个函数指定转换的类型,vbFromUnicode指定把字符串从Unicode转换回来,如果是vbUnicode,则把字符串转换为Unicode。注意,虽然你的程序中写的是ANSI的字符而不是Unicode字符,但当这个函数执行时,它得到的却是已经被转换成为Unicode的字符串了。
现在问题可以算解决了,但我们还需要另一个解决方法,因为这种方法太费时。想想看,每一次算长度都要进行Unicode->ANSI的转换,这将会花费太多时间。对少量字符还可以,对长字符串,时间就变得更长了。所以我们再讲一个API:lstrlen。
PublicDeclareFunctionlstrlenLib"kernel32"Alias"lstrlenA"(ByVallpStringAsString)AsLong以上是lstrlen的声明。lstrlen的作用只有一个:得到字符串的字节数。所以执行lstrlen("字符abc")将返回7。我们不需要知道它内部是如何工作的,但它总是返回该字符串是ANSI时的长度,并且速度很快。
第三话定长字符串的使用
上一话讲lstrlen时我们传递字符串给API时是直接传递的,相当一部分API也是这样。当然在VB中这里面是有秘密的,我们现在还不对其进行讨论,现在我要讲另一个API,它用的是定长字符串。
看上图,这是一个显示Windows的Temp目录、Windows安装目录以及System目录的路径的程序。这里用到了三个API分别得到这三个目录的路径。
Private Declare Function GetSystemDirectory Lib"kernel32"Alias"GetSystemDirectoryA"(ByVal lpBuffer As String,ByValnSize As Long)As Long
Private Declare Function GetTempPath Lib"kernel32"Alias"GetTempPathA"(ByValnBufferLength As Long,ByVallpBuffer As String)As Long
Private Declare Function GetWindowsDirectory Lib"kernel32"Alias"GetWindowsDirectoryA"(ByVal lpBuffer As String,ByVal nSize As Long)As Long
比较一下,可以看到这三个API都用到两个参数,一个是字符串缓存,用来保存得到的路径,另一个是指定该缓存的大小。为什么这里要指定大小呢?我把我的代码贴下来,你看一看。
Private Sub Form_Load()
    DimsPathAsString*260,lLenAsLong
    lLen=GetTempPath(260,sPath)
    Text1=Left(sPath,lLen)
    lLen=GetWindowsDirectory(sPath,260)
    Text2=Left(sPath,lLen)
    lLen=GetSystemDirectory(sPath,260)
    Text3=Left(sPath,lLen)
End Sub
我的sPath是让API去赋值的,因此必须指定大小,以避免当缓存比API要填充的字符串还小时出现错误。它们的返回值都是API已经填充了的字符个数。因为定长字符串长度是一定的,所以没被填充的空间仍留着,所以要用left来取出有用的部分。
我在现在讲这个例子除了它实用简单,还因为我想让你知道定义长字符串在API中的应用,而且这里有个VB的知识要跟大家讲。当我们定义一个变长的字符串变量时,VB并不会像其他变量一样马上为它分配内存,而是当赋值给它时才分配合适大小的内存来存放。但是API并不会像VB一样为你的变量分配内存并赋值,它只是知道你想要得到一个字符串,那么它就给你,至于你的变量装不装得下,那是你的事。定长的字符在定义时,由于已经指定了大小,所以VB就同时分配了内存给它,所以在使用API填充一个字符串变量时就要用定长字符串并指定字符的大小了。
但是,是不是定义时是变长的字符串变量就无法用来让API填充呢?其实是有办法的,就是事先让VB为它分配好足够的内存。看下面:
Dim sPath As String
sPath=Space(260)
或者
sPath=String(260,0)
用这段代码来代替前面定长字符串变量的声明,得到的结果是一样的。
Space(260)把260个空格赋给了sPath变长字符串变量,因此VB此时为它分配了可容纳260个空格的内存,而String(260,0)则把260个NULL字符(ASCII码为0的字符,在API中多数代表字符串的结尾)赋给sPath,它同样因此而得到260个字节的内存空间。当然你也可以用String(260,""),让空格来填充这个空间,效果是一样的。
好了,这一期的内容已经讲完,记得复习,我们下期再继续。
源程序下载地址:http://www.cfan.net.cn/qikan/cxg/0203gwv.zip
 
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -