Visual Basic 作为一个集应用程序开发、测试、查错功能于一 体的集成式开发环境,越来越受到程序员的青睐。笔者在开发某数据 库维护系统的过程中,选择了VB5.0作为开发平台,Unix作为服务器端 操作系统,Informix 作为服务器数据库。
问题的出现
在开发该维护系统的过程中,注意到Informix 数据库的字段 类型CLOB 填入数据时需要函数FILETOCLOB("FILENAME","SERVER") , 其中的"FILENAME"需要指出文件路径和文件名称。然而,在维护过程 中此文件是在客户端执行的,这样就要求即时将文件传输到服务器端 。
解决办法
1. FTP传输工具
我们首先使用FTP传输工具,用VB5.0中SHELL 命令调用DOS批处理 文件来实现传输的需要。
Shell调用格式:
Shell(pathname[,windowstyle])
例子:Shell("c:\windows\upload.bat")
批处理文件upload.bat 的内容:
c:\windows\ftp hostname
username
password
send c:\zrh\upload.txt upload.txt
bye
该命令实现了文件"upload.txt"的传输要求。在使用完毕之后, 再调用命令把该文件删除。
例子:Shell("c:\windows\del_up.bat")
批处理文件del_up.bat 的内容:
c:\windows\ftp hostname
username
password
dele upload.txt
bye
这样,文件"upload.txt"被删除。
但是,另一个问题出现了。由于Shell 函数的运行机制是与其它 程序同步执行,也就是说,当调用Shell 函数的子程序还没有执行完毕 之前,Shell函数后面的语句已经执行。在大批量添加数据的过程中, 就会出现某个记录的文件还没有传到,而下一个插入语句(I nsert)已 经开始调用。这样,ODBC调用就会出现错误。
2. INET 控件
Internet Transfer控件提供了Internet 上最常使用的两种协议 :HTTP 和FTP。使用HTTP 协议可以连接到WWW服务器上来下载文件;使 用FTP协议则可以登录到FTP 服务器。一般的FTP命令,例如CD、GET 都可以通过Execute 方法实现。
下面是一个设置INET控件属性的例子。
inet1.URL=ftp://username:password@hostname/document
inet1.Protocol=2-icFTP
inet1.RemoteHost=hostname
inet1.RemotePort=21
inet1.Username=username
inet1. Password=password
执行文件传输:
Inet1.Execute "ftp://username:password@hostname";, _
"PUT" &local_filename & " UPLOAD1.TXT"
right1 = Inet1.StillExecuting
Do While right1
right1 = Inet1.StillExecuting
DoEvents
Loop
这样便实现了文件的上载。
*SINET 控件的优点
INET控件与Shell()函数的不同之处在于INET控件通过调用语句
right1 = Inet1.StillExecuting
Do While right1
right1 = Inet1.StillExecuting
DoEvents
Loop来控制语句执行的顺序。在文件传输工作未完成之前,程序 不会执行其它语句,自然也就不会出现调用Shell 函数所出现的问题 。变量right1用来测试inet1 的执行状态,如果进程中仍在进行文件 传输的工作,则调用过程DoEvents给系统空闲时间来做文件传输工作, 这样便成功地执行了文件上载的功能。该文件使用完毕之后将被删除 。
Inet1.Execute "ftp://informix:informix@rd";, _
"Delete UPLOAD1.TXT"
right1 = Inet1.StillExecuting
Do While right1
right1 = Inet1.StillExecuting
DoEvents
Loop
将上载的文件删除是为了避免占用服务器端磁盘空间。
*S利用StateChanged事件提示信息
服务器在执行inet1.execute 的同时也激活了Inet1_StateChang ed事件,进程可以根据捕获到的状态进行动作。
object_StateChanged(ByVal State As Integer)
State:整数类型Integer
下面是状态的说明。
常数值 描述icNone
0 未报告状态icHostResolvingHost
1 控件正在寻找指定主机的IP地址icHostResolved
2 控件已成功找到指定主机的IP地址icConnecting
3 控件正在与指定主机进行连接icConnected
4 控件已成功与指定主机连接icRequesting
5 控件正在向主机发出请求icRequestSent
6 控件已成功向主机发出请求icReceivingResponse
7 控件正在从主机接收反馈信息icResponseReceived
8 控件已成功从主机接受反馈信息icDisconnecting
9 控件正在与主机断开icDisconnected
10 控件已与主机断开icError
11 在与主机通信的过程中发生了错误icResponseComp leted
12 请求结束且数据已经接收到
下面是一个例子。
Private Sub Inet1_StateChanged(ByVal State As Integer)
' Retrieve server response using the GetChunk
' method when State = 12. This example assumes the
' data is text.
Select Case State
' … Other cases not shown.
Case icResponseReceived ' 12
Dim vtData As Variant ' Data variable.
Dim strData As String: strData = ""
Dim bDone As Boolean: bDone = False
' Get first chunk.
vtData = Inet1.GetChunk(1024, icString)
Do While Not bDone
strData = Data & vtData
' Get next chunk.
vtData = Inet1.GetChunk(1024, icString)
If Len(vtData) = 0 Then
bDone = True
End If
Loop
txtData.Text = strData
End Select
End Sub
Tags: VB编程
UDP协议基础:
UDP(User Datagram Protocol)是一种无连接协议,与TCP操作不同,计算机间并不需要建立一个连接,同时,一个UDP应用可同时作为应用的客户或服务器方。
由于UDP协议并不需要建立一个明确的连接,因此建立UDP应用要比建立TCP应用简单得多。在TCP应用中,一个Winsock控制必须明确地设置成“监听”,而其它Winsock控制则必须使用Connect方法来初始一个连接。
使用UDP协议,在两个Winsock控制间进行数据的发送,在连接的两端必须完成以下三步:
1.设置RemoteHost属性为其它计算机的名称;
2.设置RemotePort属性为第二个Winsock控制的LocalPort属性的值;
3.申请Bind方法。
通过使用方法Bind,则可将该Winsock控制捆绑到一个本地端口,以便该Winsock控制使用该端口来进行类似TCP的“监听”功能,并防止其它应用使用该端口。
使用该协议传送数据,首先设置客户计算机的LocalPort属性。而作为服务器的计算机仅需要设置RemoteHost属性为客户计算机的IP地址或域名即可,并将其RemotePort属性设置成客户计算机上的LocalPort属性即可,然后就可通过申请SendData方法来开始信息发送,客户计算机则可在其DataArrial事件中使用方法GetData来获取发送的信息。
下例具体演示了一个“谈话”应用,以允许相互间进行实时的交谈。
UDP应用一:
建立一个新标准EXE工程文件,拖放一个Winsock控制到表单上,添加两个文本框到表单上,然后进行以下属性的设置:
表单(Form):Name=“frmPeerA” Caption=“UDP Application(1)”
Winsock控制:Name=“udpPeerA” Protocol=“sckUDPProtocol”
文本框1(TextBox): Name“txtSend”
文本框2(TcxtBox): Name=“txtOutput” MultiLine-True ScrollBars=2
然后打开代码窗口,分别在相应的事件下输入以下代码:
Private Sub Form_Load()
With udpPeerA
.RemoteHost=“197.1.1.2” '要连接到的计算机名
.RemotePort=1010 '要连接到的端口号
.LocalPort=1011 '该Winsock控制将要使用的本地端口号,便于其它端与该Winsock通讯
.Bind 1011 '将该Winsock控制绑定到该本地端口
EndWith
End Sub
Private Sub txtSend_Change()
udpPeerA.SendData txtSend.Text'发送文本
End Sub
Private Sub udpPeerA_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
udpPeerA.GetData strData,vbString
txtOutput.Text = strData
End Sub
UDP应用二:
类似建立UDP Server的方法,在表单上添加一个Winsock控制及两个文本框,然后进行以下属性的设置:
表单(Form):Name=“frmPeerB” Caption=“UDP Application(2)”
Winsock控制:Name=“udpPeerB” Protocol=“sckUDPProtoclool”
文本框1(TextBox):Name=“txtSend”
文本框2(TextBox):Name=“txtOutput” MultiLine=True ScrollBars=2
然后输入以下代码:
Private Sub Form_Load()
With udpPeerB
.RemoteHost=“197.1.1.2” '要连接到计算机的IP地址
.RemotePort=1011 '要连接到的端口号
.LocalPort=1010 '该Winsock控制将使用的本地端口号,便于其它方与之通讯
.Bind 1010 '将该Winsock控制绑定到该本地端口
End With
End Sub
Private Sub txtSend_Change()
udpPeerB.SendData txtSend.Text '发送文本
End Sub
Private Sub udpPeerB_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
udpPeerB.GetData strData,vbString
txtOutput.Text=strData
End Sub
要运行该实例,打开两个Visual Basic的事例,然后分别运行这两个工程文件即可。若要在不同的机器上运行此两例,只需要将两个工程文件中的RemoteHost改变成相应的计算机的IP地址或域名即可。
Tags: VB编程
VB6.0全称为VisualBasic 6.0,是微软公司推出的可视化编程工具MSDN之一,是目前世界上使用最广泛的程序开发工具。如果你是一个对编程一无所知,而又迫切希望掌握一种快捷实用的编程语言的初学者,那选择VB 6.0没错的。即使考虑到VB程序本身编译和运行效率较低的不足(嘻嘻速度现在不是问题吧),单是它的快捷的开发速度,简单易学的语法,体贴便利的开发环境,它仍不失一款优秀的编程工具,是初学者的首选。
也许你会问,我以前没学过任何一种语言,我能快速上手吗?别担心,没问题VB的语法的和QBASIB语言是基本相同的,也就是说它的语法是最容易被初学者所接受的。另外VB提供的是可视化的开发环境,我们可以象搭积木一样构建出程序的界面,而且VB提供了丰富的控件组,省去了我们自己写代码实现这些效果的麻烦,这样我们就能把更多的精力放在程序功能的实现上,所以VB学起来简单,用起来方便。
接着看看VB语言的前景,在目前各种编程语言共存的时代,VB会不会落伍呢?当然不会了,在我写这篇文章的同时,微软已经透露了VB7.0将完全面向对象的消息,可以肯定下一代VB的功能一定会强大很多,我们这些所谓的 VB 程序员总算可以放心了,VB不会落后于时代,毕竟它是使用人数最多的优秀的开发工具。
好了,侃了这么多关于VB的台前幕后,总之是为想学编程的你树立信心,编程一点都不难,只要你决定了开始,就让我们一起踏上愉快的编程之旅吧。
接下来谈谈怎样学习VB,先说说“看实例学VB6.0”系列教程,它是面向编程初学者的VB入门教程,这个教程的特点是抛开晦涩难懂的概念和语法,不做内容上的堆积和罗列,而是采用了每节一个生动有趣的小例子的形式,每个小例子中会涉及到一个或几个VB编程的知识点(可能是控件,也许会是某个函数或编程小技巧),使你快速入门。
从对编程一窍不通或从未接触过编程的状态,通过学习能够对VB6.0的编程环境比较熟悉,掌握VB开发界面的使用方法;对VB语言的基本语法大致了解,知道常见的语句的意义;学习VB常用控件的使用方法,并能将它们灵活运用到应用程序中;能开发简单的VB程序。到那时你已经能够继续深入的学习VB编程,可以继续参与到程序设计栏目其他版块的学习中去,嘻嘻,目标就是这样啦。
然后谈谈学习编程的方法,万事开头难,刚刚开始,遇到些困难没关系,慢慢来。编程是一个不断学习,不断积累的过程,编程的乐趣也正是存在于学习的过程中。我们每学一点,就赶快把它用到实际的程序中去,自己多学多用多实践,水平才能不断提高,这就是“学以致用”。
另外,编程涉及到很多的知识,象操作系统的、软件工程的、硬件系统的以及编程思想等各个方面,这就需要我们多看看这方面的资料,扩充自己的知识面。
还有如果学习过程中遇到了什么问题,或者有什么好的心得,你可以到洪恩的“网上交流”的“编程技术”版去提问求助或是发表文章,那里有许多编程高手可以为你答疑,还有许多同样的初学者一起交流。
“求知无限”是网上学习的特点,如果你觉得自己能够更深的学习VB或是其他编程的知识时,“程序设计”栏目的其他版块将是理想的去处,希望我们能在这样的学习环境中不断进步。
教程分为三个大的部分,它们是由浅入深的一个系列,分别是:
一、熟悉一下VB6.0的编程环境
二、学习VB常用控件的使用方法
三、试着开发简单的VB应用程序
好了,下面就一起来开始我们的学习吧
Tags: VB编程
本文题目所说的系统菜单不是指应用程序系统的菜单,而是指当用户用鼠标左键单击应用程序窗体左上角的图标时弹出的菜单。同样,当用户用鼠标右键单击应用程序窗体的标题栏,或系统任务栏中的应用程序标题时,弹出的也是这个菜单。系统菜单与应用程序菜单不一样,系统菜单不受应用程序控制,它是由Windows系统直接控制的。因此,在系统菜单上添加自定义菜单项,就显得比较困难。以下便是本人利用VB实现在系统菜单上添加自定义菜单项的方法。
—- 首先需要知道一点是系统菜单的工作过程。当我们单击系统菜单中某一项时,应用程序窗口会收到一条WM_SYSCOMMAND消息,该消息包含了系统菜单中所单击那一项的标识符ID。此时,应用程序窗口的默认窗口函数会根据WM_SYSCOMMAND消息以及菜单标识符ID执行相应的操作,完成菜单命令。如果我们能拦截到达窗口的WM_SYSCOMMAND消息,并且识别出菜单的标识符ID,我们就能够在系统菜单上添加自己的菜单项,并且执行指定的动作。下面的例子就是在系统菜单上添加一条分隔符和"关于…"菜单项。
—- 启动Visual Basic,新建标准EXE工程,在工程中添加一标准模块,名称可以是默认的。在标准模块的声明部分加入下列代码:
'菜单API函数声明
Public Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) As Long
Public Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long '菜单API函数常数声明
Public Const MF_BYCOMMAND = "H0"
Public Const MF_SEPARATOR ="H800"
Public Const MF_STRING = "H0" '有关窗口函数的API函数声明
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long,ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long '消息
Public Const GWL_WNDPROC = (-4)
Public Const WM_NCLBUTTONDOWN = "HA1"
Public Const WM_NCRBUTTONDOWN = "HA4"
Public Const WM_USER = "H400"
Public Const WM_SYSCOMMAND = "H112"
Public Const HTSYSMENU = 3
Public Const HTCAPTION = 2 '自定义菜单项的标识号偏移量
Public Const IDM_SEPARATOR = 1
Public Const IDM_MYABOUT = 2 '其他变量
Dim sHwnd As Long
Dim OldProc As Long
接着可向标准模块添加下面两个过程: Public Sub AddMenu(frm As Form) '置换窗口函数过程
sHwnd = frm.hwnd
OldProc = SetWindowLong(frm.hwnd, GWL_WNDPROC, AddressOf AddCallBack)
End Sub
Public Sub Release() '释放自定义窗口函数过程
SetWindowLong sHwnd,GWL_WNDPROC, OldProc
End Sub
最后向标准模块中添加一自定义窗口函数过程:
Public Function AddCallBack(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Select Case wMsg Case WM_SYSCOMMAND
'系统消息
Select Case wParam '测试
Case WM_USER + IDM_MYABOUT
'"关于…"菜单项
'此处可加入用户需要自己处理"关于…" 菜单项的代码
MsgBox "单击了添加的菜单条目",vbOKOnly
Case Else '其它菜单项交换系统处理
AddCallBack =DefWindowProc(hwnd, wMsg, wParam, lParam)
End Select
Exit Function
Case Else
AddCallBack = CallWindowProc(OldProc, hwnd, wMsg, wParam, lParam) End
Select End
Function 关闭标准模块的代码窗口,打开窗体的代码窗口, 在Form_Load()过程中加入下列代码:
'加载自定义窗口过程 AddMenu Me '获得系统菜单的句柄 Dim
hMenu As Long hMenu = GetSystemMenu(Me.hwnd, 0) '在系统菜单中添加自定义2条菜单项
AppendMenu hMenu, MF_SEPARATOR or MF_BYCOMMAND, IDM_SEPARATOR,
vbNullString '分隔符 AppendMenu hMenu, MF_BYCOMMAND or MF_STRING,
WM_USER + IDM_MYABOUT, "关于…" ' "关于…"菜单项
在Form_Unload过程中加入下列代码: Release '释放自定义窗口过程
—- 到此,代码的输入工作完成,接下来的是进行测试。单击启动按钮或按F5,启动工程,用鼠标单击窗体左上角的图标弹出系统菜单,看看是否如愿。千万要注意的一点是,在结束工程时,一定要用窗体右上角的关闭按钮或者系统菜单中的关闭菜单项,否则的话,会造成Visual Basic系统崩溃,出现非法操作的错误,所以在测试工程前,最好对工程进行保存。
—- 以上程序在Windows95,Visual Basic6.0环境下调试通过。
Tags: VB编程
的对象进行操作访问。本文介绍了VB中的内部集合和自定义集合的应用,以及它与数组的异同。
关键词:Visual Basic 6.0 集合对象 应用
Visual Basic提供一种很有用的数据集合对象(Collection),它是由相关数据所构成的有序集,它可以使编程者对一组对象进行操作。Visual Basic本身含有一些内部集合,如Forms、Controls和Printers等,它们给出了工程中所有窗体、具体窗体中的所有控件以及Windows环境中的所有打印机的信息。如果要建立自己的集合,则需要使用Collection类。
对象变量的集合
对于对象变量可以理解为属于某种类型对象的集合,这个集合可以有很多对象,也可以只有一个,甚至可以是空集。在VB中可以用Set语句使一个对象变量指向一个具体的控件。
对于集合对象,其Count属性是一个非常重要的属性,利用这个属性可以对同一类对象的某一共同的属性进行访问和操作。如可以用以下的代码实现将项目中所有窗体上控件的字体的大小都设置成统一的格式,所有载入的窗体中的控件的字体都被指定为宋体,字号为16。
(1) 在项目中定义一标准模块[code]‘定义两个全局变量
Global CtrFont As Control, Aform As Form
‘定义一FontAllSame子过程
Sub FontAllSame()
Dim i, j As Integer
For i = 0 To Forms.Count – 1 ‘Count属性是从0开始的整数
Set Aform = Forms(i)
For j = 0 To Aform.Controls.Count – 1
Set Font1 = Aform.Controls(j)
CtrFont.FontName = "宋体"
CtrFont.FontSize = 16
Next j
Next i
End Sub[/code]
(2) 在项目中的所有窗体的Activate事件中加入以下语句
FontAllSame
2 数据库中的集合对象
在VB的数据库编程中,所有的数据库均看作是一个结构良好一致的对象所组成。可以使用对象的属性及方法对这些对象进行操作、创建和删除。
在VB数据库管理中数据的集合对象存在两类:一类是用于数据库结构的维护和管理,有三种集合:如,表集(TableDefs)、字段集(Fields)和索引集(Indexes);一类是数据存取对象的记录集:Recordset。每个集合对象都可以看作是一个数组,并按数组的方法来调用。一旦数据库建立以后,就可以用这些集合来对数据库的结构进行修改和数据处理。
在这些集合中同样具有属性Count,利用它可对集合中的元素进行操作,如下面是打开一个数据库,并取得其内各表(Table)的具体特征的应用程序实例。可以得到各表:表名,字段名,字段的个数,字段的类型,表中记录的条数。[code]Sub TableInfo()
Dim i, j As Integer, Fname As String
Dim db1 As Database, Td1 As TableDefs
Dim fld1 As Fields
Dim FieldNum, RecNum As Integer
Fname$ = "d:/mdb/xx.mdb" ‘XX为Access数据库文件
Set db1 = OpenDataBase(Fname$) '打开一数据库文件
Set Td1 = db1.TableDefs
For i = 1 To Td1.Count - 1
Debug.Print Td1(i).Name ‘输出表名
Set fld1 = Td1(i).Fields
FieldNum = fld1.Count
RecNum = Td1(i).RecordCount
Debug.Print "当前表共有"; FieldNum; "个字段" ‘输出字段的个数
Debug.Print "当前表有:"; RecNum; "记录" ‘输出记录的个数
For j = 0 To fld1.Count - 1
Debug.Print "字段名", fld1(j).Name ‘输出字段名
Debug.Print "类型", fld1(j).Type ‘输出字段类型
Next j
Next i
End Sub[/code]
从以上的程序中可以清楚地看出:数据库、表、字段存在着层次关系。在VB中层次结构的顶部是Jet数据引擎(DBEngine对象),它是惟一不被其它对象所包含的数据访问对象。DBEngine对象拥有一个Workspaces集合,该集合含有一个或多个Workspace对象。每个Workspace对象有一个Database集合,该集合又有一个或多个Database对象。每个Database对象含有一个TableDfes集合,该集合又含有一个或多个TableDef对象,依次类推。集合的对象都是基于0的索引来访问的。
如:DBEngine.Workspaces(0).Databases(0).TableDefs(0).Fields(“CustName”)
建立自己的集合
VB中Collection类用于建立自己的集合。它的工作原理类似于C语言的链表,在使用时可以很方便地在其中进行数据的插入、删除,并且在使用了关键字以后,查询操作也变得简单了。建立集合后可以用Add方法添加项到集合,Remove方法从集合中删除项,Item方法检索集合中的特定项,Count属性反应集合中项的数目。
VB中旧的内部集合的索引大多是基于0的,即集合中元素的下标是从现0开始的,如上面所述的Forms、Controls和数据库上的集合等;Collection类建立的集合对象都是基于1的。
1、手工创建
用Add方法向中添加项:
Add(Item As Variant,[,Key As Variant][,Before As Variant][,After As Variant])
其中的Key为关键字,是一个字符串的表达式,如果以整数为关键字则必须用CStr函数将其转换为字符串。Before和After用于指定添加项所放的相对位置。
如建立一数据结构,用保存学生学号,姓名和成绩。[code]Public m_colData As New Collection ‘m_ColDta用于保存记录
‘自定义一数据类型
Type Mytype
ID as Strng
Name as String
End Type
‘建立一类Class1,如下
Public ID As String
Public Name As String
Public Score As Integer
‘定义插入函数用来接受数据到数据结构中
Public Function Insert2col(pData As Mytype)
Dim Myclass As New Class1
Set Myclass = Nothing
Myclass.ID = pData.ID
Myclass.Name = pData.Name
Myclass.Score = pData.Score
m_colData.Add Item:=Myclass, Key:=pData.ID ‘以ID作为关键字
End Function[/code]
这样这建立了数据结构,通过编写处理函数代码就可以对其中的数据进行处理输出,如成绩的排序、统计不及格人数等。
2、使用向导
同样建立上例中建立的自定义类型MyTpye和类Class1。在“项目(Project)”菜单中选取“增加类模块(Add Class Module)”,选择“VB类构造(VB Class Builder)”,在Cass Builder对话框中,选取栏中的“Add New Collection”按钮,选已存在的类clsData形成集合对象Collection1 类。
此时系统会自动生成Add,Remove,Item属性和Count方法。
通过定义:Public m_colData As New Collection1 ‘用于保存记录
调用Collecton1类中的Add方法,即可生成数据结构。
3、集合与数组的比较
集合和数组都可用下标来调用,但它们之间存在着区别和联系。
(1)相同点。它们都是数据元素的有序集,数组可以看作为限制了数据元素个数的集合。
(2)不同点。①元素的个数不同。数组的大小由创建时决定;集合的大小在创建时并不确定。
②访问元素的效率不同:。集合相当于链表,查找元素时从集合的头一个开始,顺序向下,访问m_coData(99)要比访问_colData(1)慢得多;而数组元素在内存中是顺序存放的,访问m_coData(99)和访问m_coData(1)的时间是一样的。
结束语
集合是面向对象编程的一个很重要的特点,对于多个具有相同特征的对象可以用集合对象来处理,从而提高编程效率和界面的统一。
Tags: VB编程
[code]
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal
hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
As Long
Public Const CB_FINDSTRING = &H14C
Private Sub Combo1_Change()
Dim iStart As Integer
Dim sString As String
Static iLeftOff As Integer
iStart = 1
iStart = Combo1.SelStart
If iLeftOff <> 0 Then
Combo1.SelStart = iLeftOff
iStart = iLeftOff
End If
sString = CStr(Left(Combo1.Text, iStart))
Combo1.ListIndex = SendMessage(Combo1.hwnd,B_FINDSTRING, -1, ByVal CStr(
Left( ombo1.Text, iStart)))
If Combo1.ListIndex = -1 Then
iLeftOff = Len(sString)
combo1.Text = sString
End If
Combo1.SelStart = iStart
iLeftOff = 0
End Sub
[/code]
静态变量 iLeftOff 指定了字符长度
Tags: VB编程