巧用Visual Basic的TIMER控件
Visual Basic提供一个Timer控件,其本质上是一个具有间隔时间设置所触发的
时间程序,使我们可以将其隐藏在系统中,以某一时间间隔触发相关程序。灵活地运
用它可以取得很巧妙的效果。
下面,我们举一个例子。
我们可以在界面设计中设计出这样一种效果:一行文字在窗体中自左向右逐渐滚动,
从右边“滚”出窗体的文字,又在左边逐渐出现。如此循环下去。类似电视上的滚动信
息。这样可使你设计的软件显得很生动,极易引起用户的兴趣 。其实,使用Visual
Basic的Timer控件就可很容易地实现它。
首先,我们在窗体中设置两个Label控件Label1、Label2。这两个控件中除Left
属性外,其他属性设置成完全一样。这主要是为了实现循环滚动的效果。它们的Caption
属性设置为要滚动显示的文字。另外再调整好其字体、大小和颜色等。在Form-Load过
程中设置Label2.Left=-6240(窗体宽度),Label1.Left=0。这样可保证La?bel1
的一部分“滚”出窗体,则Label2的一部分就进入窗体。而形成循环滚动在窗体中设置?/FONT>Timer控件。Timer控件的Interval属性决定滚动的速度,单位是毫秒。例如,
我们设置成300,则每隔0.3秒滚动一次。然后,在Timer1-Timer()过程中加入如下
程序:
Private Sub Timer1-Timer()
Label1.Left=Label1.Left+50
Label2.Left=Label2.Left+50
If Label1.Left>=6240 Then
Label1.Left=-6240
End If
If Label2.Left>=6240 Then
Label2.Left=6240
End If
End Sub
滚动效果就形成了,感兴趣的读者可以试试看。只要灵活运用Timer控件,我们
还可以设计出更有趣的效果。如用Timer控件控制按钮控件的Visible属性,形成闪烁
按钮。用Timer控件控制显示不同的图象,形成简单的动画。
在 RichTextBox 之中, 如何将被选取的内容(包含文字及图片) 复制到剪贴簿?
如果不是写程序, 那么就是按下键盘 Ctrl+C。
当使用者按下 Ctrl+C 时, RichTextBox 会对自己送出 WM_COPY 的信息, 而接着 RichTextBox 的窗口程序收到此一信息时, 便会将被选取的内容(包含文字及图片)复制到剪贴簿&127;。
所以如果想要将 RichTextBox 中被选取的内容复制到剪贴簿, 只要对 RichTextBox 送出 WM_COPY 信息即可, 以下是程序撰写上的细节:
1. API 函数的声明式:
Const WM_PASTE = &H302
Const WM_CUT = &H300
Const WM_COPY = &H301
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
注:如果以上的声明放在「一般模块」底下, 应在 Const 之前加上 Public 保留字, 并且将 Private 保留字去掉。
2. 调用例:
SendMessage RichTextBox1.hWnd, WM_COPY, 0, ByVal 0&
在 ListBox 之中, 如何检测鼠标所在位置的选项?
我们可以利用 ListIndex 属性得知 ListBox 的选项, 但是当鼠标移到某一个选项上面(但还没有选取),如何得知此一选项呢?方法是对 ListBox 送出 LB_ITEMFROMPOINT 信息, 细节如下:
1. API 的声明:
Const LB_ITEMFROMPOINT = &H1A9
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
注:如果以上的声明放在「一般模块」底下, 应在 Const 之前加上 Public 保留字, 并且将 Private 保留字去掉。
2. 调用例:(在表单上布置一个 TextBox 及一个 ListBox, 然后利用 MouseMove 事件程序来检测鼠标所在位置的选项)
Private Sub List1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim pos As Long, idx As Long
pos = X / Screen.TwipsPerPixelX + Y / Screen.TwipsPerPixelY * 65536
idx = SendMessage(List1.hwnd, LB_ITEMFROMPOINT, 0, ByVal pos)
' idx 即等于鼠标所在位置的选项
If Idx <65536 Then Text1.Text="List1.List(idx)<Br"> End Sub
在VB6.0中使用数据窗体设计器插件
一个插件实际上是一个OLE服务器,用于扩展VB开发环境,增强VB的功能。我们可以使用插件为VB菜单增加定制项,可管理当前激活窗体及控件,并响应多种文件控制事件。VB在SAMPLES目录的ALIGN、DATAWIZ和SPY子目录下就包含了三个这样的插件应用程序。
这里我们着重讨论DATAWIZ下的数据窗体设计器插件。
1.数据窗体设计器插件的引入
通常,我们在使用VB数据控件设计数据窗体时,大量的时间都花在窗体的可视化设计过程上,如标签和数据装订控件的建立和对齐定位。我们设想要是能根据数据库结构自动生成数据窗体,那将是一件非常令人愉快的事情。随着VB4的推出,我们将会惊喜地发现,它不仅提供了实现插件的功能,而且包含了一个实用的数据窗体设计器(Data Form Designer)插件。利用该插件瞬间即可生成使用数据控件的简单数据窗体。但是由于该窗体设计器只是一个随VB发行的示例应用程序,我们必须首先载入该文件,生成VB的一个插件,再安装该插件才能使用。所以VB的数据窗体设计器可能还不广为人知,下面将它介绍给VB的使用者,希望能为设计数据窗体提供帮助。
2.载入数据窗体设计器示例文件
如果数据窗体设计器没有出现在可用插件的列表中,则必须载入它,其步骤是:
*选择File|Open Project菜单命令,打开\Vb\Samples\Datawiz\Dfd.Vbp项目文件
*选择File|Make EXE File命令创建一个可执行文件
*运行该程序,数据窗体设计器自动加入到下一步中要使用的可用插件到列表中
3.安装数据窗体设计器插件
安装数据窗体设计器插件是通过插件管理器完成的,其过程是:
*选择Add-Ins|Add-In Manager菜单命令
*选取Data Form Designer,即数据窗体设计器
*单击OK,则数据窗体设计器出现在Add-Ins菜单中
4.使用数据窗体设计器
通过几个简单的步骤就可创建一个查看并编辑库的示例应用程序:
*选择Add-Ins|Data Form De?signer菜单命令,弹出一个数据窗体设计器窗口
*输入窗体名称
*选取一个数据库类型
*单击Open Database打开一个数据库
*从RecordSource列表中选取相应表
*从Available Columns中选取部分或全部字段至Included Columns中
*单击Build the Form按钮,产生所需要的数据窗体
*数据窗体建立完毕,单击Close按钮
*选择Tools|Options命令将该窗体设置为启动窗体
*运行该应用程序
5.数据窗体设计器完成的工作
数据窗体设计器为程序开发者创建的可视窗体包括以下的工作:
*在窗体上增加一个数据控件,并为其设置Connect,DatabaseName和RecordSource属性
*对于表中所选的数据库字段,增加一个有字段名的标签和相应的装订控件,装订控件的类型取决于字段的数据类型:
字段数据类型
装订控件类型
字符串、日期和数值
文本框
布尔
检查框
Memo域
多行文本框
二进制数据
OLE包容器
*增加四个命令按钮:增加、删除、刷新、更新和关闭,以执行不同的数据访问功能
为命令按钮和数据控件增加简单的程序代码和注释说明
当然,使用数据窗体设计器产生的数据访问窗体是非常简单的,但这个简单的窗体可以作为在应用程序中建立更复杂的数据访问功能的框架结构。
如何在输入光标进入TextBox时,将整个TextBox的内容变成反白?
利用 GetFocus 事件(发生于输入游标进入 TextBox时 )、 SelStart属性 (表示被选 取区的起始位置 )、及 SelLength 属性 (表示被选取区的长度 ),程序 如 下 :
Private Sub Text1_GotFocus()
Text1.SelStart = 0
Text1.SelLength = Len(Text1.Text)
End Sub
利用 EM_LINESCROLL 信息控制 TextBox 的卷动。
在含有卷动轴的 TextBox 中, 如何以程序控制 TextBox 的卷动?
传送 EM_LINESCROLL 信息给 TextBox 控制文件,方法是调用 SendMessage API 函数,细节如下:
1. API 的声明:
Const EM_LINESCROLL = &HB6
Private Declare Function SendMessageBynum Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
注:如果以上的声明放在「一般模块」底下, 应在 Const 之前加上 Public 保留字, 并且将 Declare 之前的 Private 保留字去掉。
2. 调用范例:
ret = SendMessageBynum(Text1.hwnd, EM_LINESCROLL, 0, 1 ) ' 下卷一行
ret = SendMessageBynum(Text1.hwnd, EM_LINESCROLL, 0, -1 ) ' 上卷一行
ret = SendMessageBynum(Text1.hwnd, EM_LINESCROLL, 1, 0) ' 右卷一列
ret = SendMessageBynum(Text1.hwnd, EM_LINESCROLL, -1, 0) ' 左卷一列
ret = SendMessageBynum(Text1.hwnd, EM_LINESCROLL, 1, 1 ) ' 下卷一行且右卷一列
注:以上的 Text1 为 TextBox 的名称。
利用 timeGetTime 更精准地计算时间差。
我想每 0.005 秒做某一件工作, 所以撰写了以下程序:
Dim tm1 As Single
Do
tm1 = Timer
While Timer - tm1 <0.005 ' 等于 0.005 秒
DoEvents
Wend
...做某一件工作
Loop
但实际上, 在 While 循环里面, Timer 函数几乎每次都得到相同的时间,只有大约隔了 0.05秒才会得到不同的时间, 也就是说 Timer 的准确性只有 0.05 秒, 但我希望进行的工作却是每 0.005 秒一次, 该怎么办呢?
可以改用 Windows API 的 timeGetTime 函数, 此一函数会传回 Windows 开机以来所经过的时间,时间单位是 1/1000 秒, 举例来说, 开机经过 2 分钟, 则传回值等于 2*60*1000, timeGetTime 的优点是时间可以精确到 1/1000 秒, 所以可以用来解决上述的问题,细节如下:
1. API 的声明:
Private Declare Function timeGetTime Lib "winmm.dll" Alias "timeGetTime" () As Long
注:如果以上的声明放在「一般模块」底下, 应将 Declare 之前的 Private 保留字去掉。
2. 程序范例:
Dim tm1 As Long
Do
tm1 = timeGetTime
While timeGetTime - tm1 <5 ' 等于 5/1000="0.005" 秒
DoEvents
Wend
...做某一件工作
Loop