分享
 
 
 

从钟表的制作兼谈数学在编程中的应用

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

VB设计有语音报时和报警功能的闹钟

2004-05-18■作者:潇潇■出处: Yesky开发者网络

从钟表的制作兼谈数学在编程中的应用

经常在论坛上看到很多刚刚想要步入编码领域的爱好者问道:我数学学的不好,能学好编程吗?当然回答的人也各自有不同的答案。但我要说,随着编程工具功能的日臻完善,工具所能做的越来越多,大大提高了程序员的开发速度,因此如果只是玩玩编程的话,对于数学不许要太多的专业知识,单是各个工具中提供的控件,就足以让你编写出一个让你感到自豪的软件了;而对于逻辑方面的问题,只要没有智力问题,说话不颠三倒四的,应该也不会有什么问题。但是对于一个计算机专业的工作者,或者想要成为一名计算机专业领域工作者的爱好者,数学就是必须学习的知识了,而且越是和图形打交道多的领域,对数学的运用越多。

所以这里我们就以一个很小的程序来看一看数学在编程中的应用。

先来看一看,我们想要实现的功能吧。作为一个有实在意义的时钟,除了显示时间,还要能够定时、报时等等。所以我们在这个例子中,就要实现以下几种功能:

1、 显示时间 2、定时报警 3、语音报时 4、定时关机

(一)显示时间

让我们先来看看怎样实现显示时间吧。在windows中给我们提供了一系列通用控件,而且各种编程工具又在这个基础上,给我们提供了更多的选择。不同的控件,有不同的作用,但就显示信息来说,主要有textbox,Lable等控件。在这里我们选择Lable控件来显示时间。

那么怎样获取时间呢?vb中给我们提供了以下函数:

函数名

函数功能

语法结构

Date 函数

返回包含系统日期的Variant( Date ) 。

Date

DateAdd函数

返回包含一个日期的Variant( Date ) ,这个日期还加上了一段时间间隔。

DateAdd ( interval ,number ,date )

DateDiff函数

返回Variant( Long )的值,表示两个指定日期间的时间间隔数目。

DateDiff ( interval ,date1 ,date2,firstdayofweek [,firstweekofyear ] )

DatePart函数

返回一个包含已知日期的指定时间部分的Variant( Integer )

DatePart( interval ,date

[ , firstdayofweek ]

[ , firstweekofyear ] )

DateSerial函数

返回包含指定的年月日的Variant( Date )

DateSerial( year ,month ,day )

DateValue函数

返回一个Variant( Date )

DateValue( date )

Day函数

返回一个Variant( Integer ) ,其值为1到31之间的整数,表示一个月中的某一日

Day( date )

Hour函数

返回一个Variant ( integer ) ,其值为0到23之间的整数,表示一天之中的某一个钟点

Hour ( time )

Minute函数

返回一个Variant ( Integer ) ,其值为0到59之间的整数,表示一个小时中的某一分钟

Minute ( time )

Now函数

返回一个Variant ( Date ) ,根据计算机系统设置的日期和时间来指定日期和时间

Now

Second函数

返回一个Variant( Integer ) ,其值为0到59之间的整数,表示一分钟之内的某一秒钟

Second( time )

Time函数

返回一个指明当前系统时间的Variant( Date )

Time

Time语句

设置系统时间

Time = time

Timer函数

返回一个Single,代表从午夜开始到现在所经过的秒数

Timer

TimeSerial函数

返回一个Variant( Date ) ,包含具有现在时、分、秒的时间。

TimeSerial(hour,minute,second)

TimeValue函数

返回一个包含时间的Variant( Date )

TimeValue( time )

Weekday函数

返回一个Variant ( Integer ) ,包含一个整数,代表某个日期是星期几

Weekday( date

[ ,firstdayofweek ] )

Year函数

返回一个Variant( Integer ) ,包含表示年份的整数

Year( date )

多丰富的资源,vb真是体贴。下面然我们来以一个实例看看怎样显示时间吧。

程序中所用到的控件的作用和相关属性设置如下表:

控件

属性

作用

Form1

Caption

时钟

显示窗体

Label1

Caption

显示时间

Label2

Caption

显示分钟

Label3

Caption

显示秒钟

Label4

Caption

显示年份

Label5

Caption

显示月份

Label6

Caption

显示日期

Label7

Caption

显示星期几

Timer1

Interval

1000

每秒钟触发一次事件

下面是代码:

Private Sub Timer1 _ Timer ( )

hou = Hour ( Time )

miu = Minute ( Time )

sec = Second ( Time )

yea = Year ( Date )

mon = Month ( Date )

da = Day ( Date )

Label1 . Caption = hou & "小时 "

Label2 . Caption = miu & "分钟"

Label3 . Caption = sec & "秒钟"

Label4 . Caption = yea & "年"

Label5 . Caption = mon & "月"

Label6 . Caption = da & "日"

Label7 . Caption = "星期" & Weekday ( Date )

End Sub

下图是运行的结果:

很简单吧!下面我们看看不使用控件,我们用绘图函数自己来画出一个运行着的时钟。

现来补充一些v b中的绘图知识:

1、Line方法

Line方法用于画出一条直线或矩形,其语法格式如下:

格式:[对象] . Line [ [ Step ] ( x1 , y1 ) ] -( x2 ,y2 )[ ,颜色 ] [ ,B [ F ] ]

说明:

(1)对象指的是Line在何处产生结果,它可以是窗体或图形框,默认为当前窗体;

(2)( x1 ,y1 )为线段的起点坐标或矩形的左上角坐标;

(3)(x2,y2)为线段的终点坐标或矩形的右下叫坐标;

(4)关键字Step表示采用当前作图位置的相对值;

(5)关键字B表示画矩形;

(6) 关键字F表示用画矩形的的颜色来填充矩形。缺省F时,矩形的填充由FillColor和FillStyle属性决定。

举个例子:我们在窗体上随机画20条颜色不同得直线.可以这样写:

Private Sub Form _ Click ( )

Dim i As Integer

Dim x As Integer

Dim y As Integer

For i = 1 To 20

x = Form1 . ScaleWidth * Rnd

y = Form1 . ScaleHeight * Rnd

Clr = 15 * Rnd

Line ( Form1 . Width / 2 , Form1 . Height / 2 ) - ( x , y ) , QBColor ( Clr )

Next i

End Sub

下面是运行结果:

2、Circle方法

Circle方法用于画圆、椭圆、圆弧和扇形,其语法格式如下:

格式: [对象.] Circle [ [ Step ] ( x , y ) ,半径 [ ,颜色 ] [ ,起始角度 ] [ ,终止角度 ] [ ,长短轴比率 ] ]

说明:

(1) 对象指的是Circle方法将在何处产生结果,它可以是窗体或图形框或打印机,缺省时为当前窗体。

(2)(x,y)为圆心坐标,关键字Step表示采用当前作图位置的相对值。

(3)圆弧和扇形通过参数的起始角度和终止角度控制。当起始角度和终止角度取值为0~360度时,画出来的是圆弧;当在起始角度和终止角度取值前加一个负号时,画出的是扇形,负号表示要画圆心到圆弧的径向线。

(4)椭圆通过长短轴比率控制,默认值为1,所以画出来的是圆。

下面我们用Circle方法分别画出圆形,椭圆,圆弧和扇形。下面是代码和图示:

Private Sub Form _ Click ( )

Circle (1500, 1500), 1000

End Sub

下图为画出的圆形:

Private Sub Form _ Click ( )

Circle ( 1500, 1500 ) , 1000 , , 0.7 , 2.1 ‘注意1000和0.7,中间是两个逗号

End Sub

下图为画出的圆弧:

Private Sub Form _ Click ( )

Circle (1500 , 1500 ) , 1000 , , - 0.7 , - 2.1

End Sub

下图为画出的圆形:

Private Sub Form _ Click ( )

Circle ( 1500 , 1500 ) , 1000 , , , , 0.5

End Sub

下图为画出的椭圆形:

3、Pset方法

Pset方法用于画点,其语法格式如下:

格式: [对象 . ] Pset [ Step ] ( x , y ) [ ,颜色 ]

说明:

(1)参数(x,y)为所画点的坐标

(2)关键字Step表示采用当前作图位置的相对值

(3)采用背景颜色可清除某个位置上的点,利用Pset方法可画出任意的曲线

下面我们来看一个例子.我们用Pset方法在窗体上面绘制阿基米德螺线.下面是代码和运行结果:

Private Sub Form _ Activate ( )

Dim x As Single

Dim y As Single

Dim z As Single

Scale ( - 20 , 20 ) - ( 20 , - 20 )

Line ( 0 , 17 ) - ( 0 , - 17 )

Line ( 18 , 0 ) - ( - 18 , 0 )

For z = 0 To 15 Step 0.01

y = z * Sin ( z )

x = z * Cos ( z )

PSet ( x , y )

Next z

End Sub

运行结果如下:

到现在为止,应该说我们关于编程方面的知识已经足够了.但应该怎样画出一个钟表的准确位置呢?也就是说我们怎样在窗体中确定每一个刻度呢?

肯定得用到三角函数了.让我们一起简单的回顾以下,在高中时所学的三角函数的知识吧.

我们知道,三角函数主要有这样几个公式:

sin ( a ) = 对边a / 斜边c

cos ( a ) = 底边b / 斜边c (其中角度a,可以是任意角度)

如下图所示:

由图可知,在一周之内,角度a可以在从0度到360度取值而对于钟表来说,每个刻度之间的度数差别为360度除以60个刻度,等于6度,也就是说公式里的角度a已经知道了.而且可知边a实际上就是圆上任意一点在y轴上的坐标,而边b是加上就是圆上任意一点在x轴上的坐标,半径r由我们所要画出的圆形的大小决定的,所以我们可以得到圆上任意一点在坐标系中的x , y轴上的取值.公式如下:

x = sin ( a ) * r

y = cos ( a ) * r

而且在vb中,也有这样的函数可供使用.

1、cos函数

作用:返回一个Double,指定一个角度的余弦值

格式: Cos(number)

2、sin函数

作用:返回一个Double,指定一个角度的正弦值

格式: Sin(number)

下面我们通过示例来看看具体的用法。

首先,我们将用这些知识来画出一个正弦:

下面是代码:

'=======================

'说明,x从0到form1的最右面

'y值中,因为i是从0变到form1的最右面

'所以i/form1.scalewidth 就从0 变到1

'所以,i/form1.scalewidth*2*3.1415926既是o*2pi 到1* 2pi

'所以,cos(i/form1.scalewidth*2*3.1415926),就从1到-1,在变到1

'所以,1-cos(i/form1.scalewidth*2*3.1415926),就从0到2,在变到0

'所以y 就从0到form1.scaleheight,在变到0

'即可画出cos曲线

'=======================

Private Sub huacos ( ) ‘自定义了一个名为huacos的过程

Dim x As Double

Dim y As Double

For i = 0 To Form1 . ScaleWidth ‘设定周期为Form1 . ScaleWidth

x = i

y = ( 1 – Cos ( i / Form1 . ScaleWidth * 2 * 3.1415926 ) ) * Form1 . ScaleHeight / 2

‘ 因为三角函数中的角度的增长方向,和计算机中相反,所以要用1减去cos值

PSet ( x , y )

Next i

End Sub

Private Sub Form _ Activate ( )

Huacos ‘调用huacos 过程

End Sub

下图为运行结果:

余弦和它相似,代码如下:

Private Sub huasin ( ) ‘自定义了一个名为huasin的过程

Dim x As Double

Dim y As Double

For i = 0 To Form1 . ScaleWidth ‘设定周期为Form1 . ScaleWidth

x = i

y = (1 – Sin ( i / Form1 . ScaleWidth * 2 * 3.1415926 ) ) * Form1 . ScaleHeight / 2

‘ 因为三角函数中的角度的增长方向,和计算机中相反,所以要用1减去sin值

PSet (x, y)

Next i

End Sub

Private Sub Form _ Activate ( )

huasin ‘调用huasin过程

End Sub

下图为运行结果:

有了这些基础,画出一个正圆也就没问题了。请看下面的代码。

Private Sub huayuan ( )

Dim x As Double

Dim y As Double

For i = 0 To 360

x = (1 – Sin ( i / 360 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 100 ) + 100

y = (1 – Cos ( i / 360 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 100 ) + 100

Pset ( x , y )

Next i

End Sub

Private Sub Form _ Activate ( )

huayuan

End Sub

上面的代码不难,好好思考一下吧.下面是运行结果:

上面的例子里,我们使用360个点组成了一个密集度挺高的圆形,可是既然v b中已给我们提供了现成的画圆形的函数,为什么不用呢?但通过上面的例子,我们应该想到,如果我们将360个点,变成60个点,那不就正好是一个钟表的刻度吗?!这样的话我们只需要改动两个地方,一个是点的个数,另一个是点与点之间的弧度,应该为360度的60分之一,也就是每60度画一个点。代码如下:

Private Sub huabiaopan ( )

Dim x As Double

Dim y As Double

For i = 0 To 60

x = ( 1 – Sin ( i / 60 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 100 ) + 100

y = ( 1 – Cos ( i / 60 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 100 ) + 100

PSet ( x , y )

Next i

End Sub

Private Sub Form _ Activate ( )

huabiaopan

End Sub

下面是运行结果: (为了看得清楚些,我将颜色设为了红色,大家可以随喜好自行修改,方法当然是在Pset函数中了)

看来我们距离成功越来越近了。对于钟表里的三个针来说,每一时刻都会指向其中一个刻度,所以我们只要在其中添加代码,让它实现从圆心到所指刻度画直线就可以实现钟表里的三个针了。

下面是关于其中一个针的走动,代码如下:

Private Function huamiao ( a As Integer )

'用同背景相同的颜色,在前一次的位置上,从新画直线,抹除前一次画的线

x = (1 – Sin ( ( a + 1 ) / 60 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 200 ) + 200

y = ( 1 – Cos ( ( a + 1 ) / 60 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 200 ) + 200

Line ( Form1 . ScaleHeight / 2 , Form1 . ScaleHeight / 2 ) - ( x , y ) , QBColor ( 7 )

'然后开始画後一秒的线

x = (1 – Sin (a / 60 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 200 ) + 200

y = (1 – Cos ( a / 60 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 200 ) + 200

Line ( Form1 . ScaleHeight / 2 , Form1 . ScaleHeight / 2 ) - ( x , y ) , QBColor ( 1 )

huamiao = a - 1

End Function

Private Sub Timer1 _ Timer ( )

mz = Second ( Time )

mz = 60 – mz ‘因为三角函数中,角度的变化方向,正好与钟表的方向相反,

‘所以60减去就相当于将角度变为负值,也就是说,和原来的角‘度增长方向正好相反,与钟表的增长方向相同。

mz = huamiao ( mz )

End Sub

下面是运行效果:

好了,现在我们可以加上,分针和时针了.下面是源代码和运行结果:

' = = = = = = = = = = = = = = = = = = = = = =

' 以下语句能画出表盘

‘ 六十个点表示六十个刻度,

' = = = = = = = = = = = = = = = = = = = = = =

Private Sub huayuan ( )

Dim x As Double

Dim y As Double

For i = 0 To 60

x = ( 1 – Sin ( i / 60 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 100 ) + 100

y = ( 1 – Cos ( i / 60 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 100 ) + 100

PSet ( x , y ) , QBColor ( 12 )

Next i

End Sub

‘ = = = = = = = = = = = = = = = = = = = = = = = = = =

‘下面代码作用是画出时针走的路线

‘时针是12个刻度,表示是12个钟点

‘ = = = = = = = = = = = = = = = = = = = = = = = = = =

Private Function xianshishi ( a As Integer )

'抹除前一次画的线

x = (1 – Sin ( ( a + 1 ) / 12 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 800 ) + 800

y = (1 – Cos ( ( a + 1 ) / 12 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 800 ) + 800

Line ( Form1 . ScaleHeight / 2, Form1 . ScaleHeight / 2 ) - ( x , y ) , QBColor ( 7 )

'开始画後一秒的线

x = ( 1 – Sin ( a / 12 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 800 ) + 800

y = ( 1 – Cos ( a / 12 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 800 ) + 800

Line ( Form1 . ScaleHeight / 2 , Form1 . ScaleHeight / 2 ) - ( x , y ) , QBColor ( 1 )

xianshishi = a - 1

End Function

‘ = = = = = = = = = = = = = = = = = = = = = = = = = =

‘下面代码作用是画出秒针走的路线

‘秒针是六十个刻度,表示是六十个秒点

‘ = = = = = = = = = = = = = = = = = = = = = = = = = =

Private Function xianshimiao ( a As Integer )

'抹除前一次画的线

x = ( 1 – Sin ( ( a + 1 ) / 59 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 200 ) + 200

y = ( 1 – Cos ( ( a + 1 ) / 60 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 200 ) + 200

Line ( Form1 . ScaleHeight / 2, Form1 . ScaleHeight / 2 ) - ( x , y ) , QBColor ( 7 )

'开始画後一秒的线

x = (1 – Sin ( a / 59 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 200 ) + 200

y = ( 1 – Cos ( a / 60 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 200 ) + 200

Line ( Form1 . ScaleHeight / 2 , Form1 . ScaleHeight / 2 ) - ( x , y ) , QBColor ( 1 )

xianshimiao = a - 1

End Function

‘ = = = = = = = = = = = = = = = = = = = = = = = = = =

‘下面代码作用是画出分针走的路线

‘分针是六十个刻度,表示是六十个分点

‘ = = = = = = = = = = = = = = = = = = = = = = = = = =

Private Function xianshifen ( a As Integer )

'抹除前一次画的线

x = (1 – Sin ( ( a + 1 ) / 59 * 2 * 3.1415926 ) ) * ( Form1.ScaleHeight / 2 – 400 ) + 400

y = ( 1 – Cos ( ( a + 1 ) / 60 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 400 ) + 400

Line ( Form1 . ScaleHeight / 2 , Form1 . ScaleHeight / 2 ) - ( x , y ) , QBColor ( 7 )

'开始画後一秒的线

x = (1 – Sin ( a / 59 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 400 ) + 400

y = (1 – Cos ( a / 60 * 2 * 3.1415926 ) ) * ( Form1 . ScaleHeight / 2 – 400 ) + 400

Line ( Form1 . ScaleHeight / 2 , Form1.ScaleHeight / 2 ) - ( x , y ) , QBColor ( 1 )

xianshifen = a - 1

End Function

‘ = = = = = = = = = = = = = = = = = = = = = = = =

‘ 每秒钟触发一次此事件,从而获取当时的时间,并调用相应的函数,画出三个针的位置

‘ = = = = = = = = = = = = = = = = = = = = = = = =

Private Sub Timer1 _ Timer ( )

miao = Second ( Time )

miao = 60 – miao

fen = Minute ( Time )

fen = 60 - fen

shi = Hour ( Time )

If shi > = 12 Then ‘因为一天之内时针要走二十四个钟头,也就是要走两圈,所以将下午和晚上的时间减去十二,就可以确定时针准确的位置

shi = shi - 12

End If

shi = 12 - shi

miao = xianshimiao ( miao )

fen = xianshifen ( fen )

shi = xianshishi ( shi )

End Sub

‘ = = = = = = = = = = = = = = = =

‘此事件,在窗体最初载入时触发,主要作用是画出表盘和刻度

‘ = = = = = = = = = = = = = = = =

Private Sub Form _ Load ( )

Form1 . Width = Form1 . Height - 250

Huayuan ‘画刻度

Form1 . Circle ( Form1 . ScaleHeight / 2 , Form1 . ScaleHeight / 2 ) , Form1 . ScaleHeight / 2 - 30

End Sub

运行效果如下图所示:

(二) 语音报时

下面我们再继续个它添加语音报时的功能.其实很简单,主要思路就是获取当前时间,如果是整点(即,分针,时针都为零)时,我们可以运用MCI ( Media Control Interface , 媒体控制接口)来播放,你已经录好的报时的声音文件.下面我们具体来看一看怎样实现这一功能.

现来了解一下MCI . MCI是Windows提供的一个可以处理音频和视频的API(应用程序编程接口),通过它,我们可以很方便的实现对音频设备,和视频设备及其其他设备的控制.这一接口极大的方便了使用者,使我们可以只使用设备接口,而不用对实际的物理设备进行直接的操作.

为了使用mci我们首先要点取Project ( 工程 ) / Components (组件)菜单,或在工具箱中点击右键,然后在弹除的菜单中选择部件,这时屏幕上会弹出如图所示的对话框.

在其中选中”microsoft Multimedia Control”,在单击确定按钮,就可以把MMControl控件添加到工具箱中了.当把MMControl控件添加到窗体中时,她的形状如下所示:

上面的九个按钮,分别表示九种功能.和普通的录音机上的按钮类似,从左到右分别是:Prev (向前) , Next (向后) , Play (播放) , Pause (暂停) , Back (快速倒带) , Step (快速进带) , Record ( 录音 ) ,和Eject (弹出).

使用时,先要为MMContorl控件指定一个要播放的文件,然后用Open命令打开它.然后再使用Play命令播放文件.最后关闭所打开的文件.

下面我们看看怎样用MMControl来实现语音报时功能.

下面是代码(我们这里主要给出所改动的地方):

‘ = = = = = = = = = = = = = = = = = = = = = = = =

‘ 每秒钟触发一次此事件,从而获取当时的时间,并调用相应的函数,画出三个针的位置

‘ = = = = = = = = = = = = = = = = = = = = = = = =

Private Sub Timer1 _ Timer ( )

miao = Second ( Time )

miao = 60 – miao

fen = Minute ( Time )

fen = 60 - fen

shi = Hour ( Time )

If shi > = 12 Then ‘因为一天之内时针要走二十四个钟头,也就是要走两圈,所以将下午和晚上的时间减去十二,就可以确定时针准确的位置

shi = shi - 12

End If

shi = 12 - shi

miao = xianshimiao ( maio )

fen = xianshifen ( fen )

shi = xianshishi ( shi )

If fen = 0 and miao = 0 then ‘如果分针和秒针都为零,这位整点,根据时针的数报时

Select case shi

Case 0 ‘零点,0.wav报时零点

MMControl1 . FileName = App . Path & “ 0.wav ” ‘选择要打开的文件

MMControl1 . Commond = “ Open ” ‘打开所选择的文件

MMControl1 . Commond = “ Play ” ‘播放所选择的文件

Case 1 ‘ 一点,1.wav报时一点,以下依次类推

MMControl1 . FileName = App . Path & “ 1.wav ” ‘选择要打开的文件

MMControl1 . Commond = “ Open ” ‘打开所选择的文件

MMControl1 . Commond = “ Play ” ‘播放所选择的文件

Case 2

MMControl1 . FileName = App . Path & “ 2.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 3

MMControl1 . FileName = App . Path & “ 3.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 4

MMControl1 . FileName = App . Path & “ 4.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 5

MMControl1 . FileName = App . Path & “ 5.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 6

MMControl1 . FileName = App . Path & “ 6.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 7

MMControl1 . FileName = App . Path & “ 7.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 8

MMControl1 . FileName = App . Path & “ 8.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 9

MMControl1 . FileName = App . Path & “ 9.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 10

MMControl1 . FileName = App . Path & “ 10.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 11

MMControl1 . FileName = App . Path & “ 11.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

End Select

MMControl1.Commond = “ Close ”

End Sub

不知道你的机子是否还能运行良好.毕竟再短短的一秒钟内,我们让计算机做的事情太多了.为了提高效率,我们可以考虑使用API函数.

我们先来看一下所要用到的相关知识.

1、 GetLocalTime

VB声明:Declare Sub GetLocalTime Lib " kernel32 " Alias " GetLocalTime " ( lpSystemTime As SYSTEMTIME )

说明:在lpSystemTime结构中装载本地日期和时间

参数:GetLocalTime函数只有一个参数lpSystemTim,指向SYSTEMTIME结构,用于装载本地时间的结构。

2、SYSTEMTIME结构

定义:Public Type SYSTEMTIME

wYear As Integer

wMonth As Integer

wDayOfWeek As Integer

wDay As Integer

wHour As Integer

wMinute As Integer

wSecond As Integer

wMilliseconds As Integer

End Type

说明:SYSTEMTIME结构表示一个日期和时间,年、月、日、星期、时、分、秒、毫秒各用一个成员来表示。其中wYear 为Integer型,表示当前的年份;wMonth 为 Integer型,表示当前的月份,从1月到12月分别用1到12来表示; wDayOfWeek 为 Integer型,表示当前的星期,从星期日开始,分别用0到6个数表示; wDay 为 Integer型,表示当前的日期; wHour 为 Integer型,表示当前的时刻; wMinute 为 Integer型,表示当前的分钟; wSecond 为 Integer型,表示当前的秒; wMilliseconds 为 Integer型,表示当前的毫秒。

3、mciExecute ()

vb声明: Public Declare Function mciExecute Lib " winmm.dll " Alias " mciExecute " ( ByVal lpstrCommand As String ) As Long

说明: mciExecute ( )函数用来传送一个命令字符串给MCI,以实现各种播放功能。

它的返回值为Long型值,如果返回值为0,表示调用失败,如果返回值不为0,表示调用成功。MciExecute ( )函数的参数只有一个lpstrCommand,为String型,表示MCI的命令字符串。

MCI的命令字符串共有7个,其名称、功能及其用法如下表:

名称

语法形式

说明

open

Open CDAudio alias CD

Open命令的功能是打开一个CDAudio设备,其中CDAudio为设备名;alias为赋予CDAudio设备的一个别名。

例如,要打开一个设备名称为CD的设备,我们可以这样写语句:mciExecute “open cdaudio alias cd”

close

Close 设备别名

Close命令的功能是关闭一个已经打开的CDAudio设备。

例如,要关闭一个设备名称为CD的设备,我们可以这样写语句:mciExecute “close cd”

play

Play 设备别名 from [position1] to [position2]

Play命令的功能是播放一个已经打开的CDAudio设备上的CD音乐。参数from [position1] to [position2] 指定CDAudio播放的起始位置和结束位置,如果省略,就从开始点播放到终点。

例如,要从开始点播放CDAudio设备上的CD音乐,我们可以这样写语句:mciExecute “play cd”

stop

Stop 设备别名

Stop命令的功能是停止一个正在播放的CDAudio设备上的CD音乐。

例如,要停止播放CDAudio设备上的CD音乐,我们可以这样写语句:mciExecute “stop cd”

seek

Seek 设备别名 参数

Seek命令的功能是搜索CDAudio设备上的指定位置。其中的参数有三种:(1)to position :移动到程序指定的位置(2)to start:移动到起始位置(3)to end:移动到结束的位置。

例如,要跳到CDAudio设备上的结束位置,设备别名为CD,我们可以这样写:mciExecute “ seek cd to end ”

set

Set 设备别名 参数

Set命令的功能是设置CDAudio设备的状态。其中的参数为:(1)Audio all on :关闭声音输出;(2)Audio all on :打开声音输出;(3)Audio left on :打开左声道声音输出;(4)Audio left off : 关闭左声道声音输出; (5)Audio right on :打开右声道声音输出; (6)Audio right off :关闭右声道声音输出; (7) Door open : 退出CD光牒 (8) Door closed : 合上光驱(8)Time format milliseconds :设置时间格式为毫秒

例如,我们要实现单声道(左声道)输出声音的效果,可以这样写:mciExecute “ set cd audio left on ”

mciExecute “ set cd audio right off ”

status

Status 设备别名 参数

Status命令的功能是获取已经打开的CDAudio设备上的信息。此命令的参数说明如下: (1) Length : CD 光碟的时间长度; (2) Mode : CDAudio 设备的状态; (3) Position:当前的位置;(4) start position : CD 光碟的起始位置 ; (5) Time format : 当前的时间格式; (6) Numer of track : CD光碟的轨道数

4、mciSendString ()

vb声明: Public Declare Function mciSendString Lib " winmm . dll " Alias " mciSendStringA " ( ByVal lpstrCommand As String , ByVal lpstrReturnString As String , ByVal uReturnLength As Long , ByVal hwndCallback As Long ) As Long

说明: mciSendString()函数的功能与mciExecute()函数相似,也是发送一个命令字符串给MCI,但是mciSendString()函数再传送字符串的同时还可以接受反馈的信息。

MciSendString()函数的返回值为Long型值,如果返回值为0,表示调用失败;如果返回值不为0,表示调用成功。

MciSendString()的参数说明如下:

(1)lpstrCommand : 传送给MCI的命令字符串;

(2)lpstrReturnString : 指向一个预备接受信息的文本缓冲区;

(3)uReturnLength : 所指定的文本缓冲区大小;

(4)hwndCallback : 用来接受确认信息的LpstrCommand,代表传送给MCI的命令字符串。

下面是lpstrCommand参数的取值:

( 1 ) open

语法形式:open 设备名称 参数

功能: 打开一个AVI动画播放设备。

说明:open命令的参数有[ 1 ] Alias : 设备别名 ;[ 2 ] Parent :播放动画窗口的父窗口;[ 3 ] style_sype : 显示动画的窗口类型 ; [ 4 ] style child : 播放动画的为子窗口 ; [ 5 ] style overlapped : 播放动画的为重叠窗口 ; [ 6 ] style popup : 播放动画的为突显示窗口 ;

[ 6 ] style device_type_AVI : 播放的设备.

( 2 ) play

语法形式: play 设备名称 参数

功能: 播放动画文件

说明: play 命令的参数有 [ 1 ] From position1 to position2 : 指定的开始位置播放到指定的结束位置; [ 2 ] Fullscreen : 以全屏幕的方式播放动画文件; [ 3 ] Windows : 在默认的窗口中播放动画文件.

( 3 ) cue

语法形式: cue 设备名称 参数

功能: 准备实例供播放使用

说明: cue命令参数有 [ 1 ] output : 准备一个实例供播放使用; [ 2 ] to position : 跳到指定位置,并且处于暂停状态.

下面是修改后的源代码:

Public Type SYSTEMTIME

wYear As Integer

wMonth As Integer

wDayOfWeek As Integer

wDay As Integer

wHour As Integer

wMinute As Integer

wSecond As Integer

wMilliseconds As Integer

End Type

Public Declare Sub GetLocalTime Lib " kernel32 " Alias " GetLocalTime " ( lpSystemTime As SYSTEMTIME )

Public Declare Function mciSendCommand Lib " winmm.dll " Alias " mciSendCommandA " ( ByVal wDeviceID As Long , ByVal uMessage As Long , ByVal dwParam1 As Long , ByVal dwParam2 As Any ) As Long

Public Declare Function mciSendString Lib " winmm.dll " Alias " mciSendStringA " ( ByVal lpstrCommand As String , ByVal lpstrReturnString As String , ByVal uReturnLength As Long , ByVal hwndCallback As Long ) As Long

Dim dangqianshijian AS SYSTEMTIME

‘ = = = = = = = = = = = = = = = = = = = = = = = =

‘ 每秒钟触发一次此事件,从而获取当时的时间,并调用相应的函数,画出三个针的位置

‘ = = = = = = = = = = = = = = = = = = = = = = = =

Private Sub Timer1 _ Timer ( )

Call GetLocalTime( dangqianshijian )

miao = dangqianshijain . wSecond

miao = 60 – miao

fen = dangqianshijian . wMinute

fen = 60 - fen

shi = dangqianshijian . wHour

If shi >= 12 Then ‘因为一天之内时针要走二十四个钟头,也就是要走两圈,所以将下午和晚上的时间减去十二,就可以确定时针准确的位置

shi = shi - 12

End If

shi = 12 - shi

miao = xianshimiao ( maio )

fen = xianshifen ( fen )

shi = xianshishi ( shi )

If fen = 0 and miao = 0 then ‘如果分针和秒针都为零,这位整点,根据时针的数报时

Select case shi

Case 0 ‘零点,0.wav报时零点

MMControl1 . FileName = App . Path & “ 0.wav ” ‘选择要打开的文件

ErrorCode = mciSendString ( “ Open ” & App . Path & “ 0.wav ” & “ type WaveAudio alias wave ” , ReturnString , 256, 0 )

‘打开所选择的文件

ErrorCode = mciSendString ( “ Play wave ”, ReturnStr , 256 , 0 )

‘播放所选择的文件

Case 1 ‘ 一点,1.wav报时一点,以下依次类推

MMControl1 . FileName = App . Path & “ 1.wav ” ‘选择要打开的文件

ErrorCode = mciSendString ( “ Open ” & App . Path & “ 0.wav ” & “ type WaveAudio alias wave ” , ReturnString , 256 , 0 )

‘打开所选择的文件

ErrorCode = mciSendString ( “ Play wave ” , ReturnStr , 256 , 0 )

‘播放所选择的文件

Case 2

MMControl1 . FileName = App . Path & “ 2.wav ”

ErrorCode = mciSendString ( “ Open ” & App . Path & “ 0.wav ” & “ type WaveAudio alias wave ” , ReturnString , 256 , 0 )

‘打开所选择的文件

ErrorCode = mciSendString ( “ Play wave ” , ReturnSt r , 256 , 0)

‘播放所选择的文件

Case 3

MMControl1 . FileName = App . Path & “ 3.wav ”

ErrorCode = mciSendString ( “ Open ” & App . Path & “ 0.wav ” & “ type WaveAudio alias wave ” , ReturnString , 256 , 0 )

‘打开所选择的文件

ErrorCode = mciSendString ( “ Play wave ” , ReturnStr , 256 , 0 )

‘播放所选择的文件

Case 4

MMControl1 . FileName = App . Path & “ 4.wav ”

ErrorCode = mciSendString ( “ Open ” & App . Path & “ 0.wav ” & “ type WaveAudio alias wave ” , ReturnString , 256 , 0 )

‘打开所选择的文件

ErrorCode = mciSendString ( “ Play wave ” , ReturnStr , 256 , 0 )

‘播放所选择的文件

Case 5

MMControl1 . FileName = App . Path & “ 5.wav ”

ErrorCode = mciSendString ( “ Open ” & App.Path & “ 0.wav ” & “ type WaveAudio alias wave ” , ReturnString , 256 , 0 )

‘打开所选择的文件

ErrorCode = mciSendString ( “ Play wave ” , ReturnStr , 256 , 0 )

‘播放所选择的文件

Case 6

MMControl1 . FileName = App . Path & “ 6.wav ”

ErrorCode = mciSendString ( “ Open ” & App . Path & “ 0.wav ” & “ type WaveAudio alias wave ” , ReturnString , 256 , 0 )

‘打开所选择的文件

ErrorCode = mciSendString ( “ Play wave ” , ReturnStr , 256 , 0 )

‘播放所选择的文件

Case 7

MMControl1 . FileName = App . Path & “ 7.wav ”

ErrorCode = mciSendString ( “ Open ” & App . Path & “ 0 . wav ” & “ type WaveAudio alias wave ” , ReturnString , 256 , 0 )

‘打开所选择的文件

ErrorCode = mciSendString ( “ Play wave ” , ReturnStr , 256 , 0 )

‘播放所选择的文件

Case 8

MMControl1 . FileName = App . Path & “ 8.wav ”

ErrorCode = mciSendString ( “ Open ” & App . Path & “ 0.wav ” & “ type WaveAudio alias wave ” , ReturnString , 256 , 0 )

‘打开所选择的文件

ErrorCode = mciSendString ( “ Play wave ” , ReturnStr , 256 , 0 )

‘播放所选择的文件

Case 9

MMControl1 . FileName = App . Path & “ 9.wav ”

ErrorCode = mciSendString ( “ Open ” & App . Path & “ 0.wav ” & “ type WaveAudio alias wave ” , ReturnString , 256 , 0 )

‘打开所选择的文件

ErrorCode = mciSendString ( “ Play wave ” , ReturnStr , 256 , 0 )

‘播放所选择的文件

Case 10

MMControl1 . FileName = App . Path & “ 10.wav ”

ErrorCode = mciSendString ( “ Open ” & App . Path & “ 0.wav ” & “ type WaveAudio alias wave ” , ReturnString , 256 , 0)

‘打开所选择的文件

ErrorCode = mciSendString ( “ Play wave ” , ReturnSt r , 256 , 0)

‘播放所选择的文件

Case 11

MMControl1 . FileName = App . Path & “ 11.wav ”

ErrorCode = mciSendString ( “ Open ” & App . Path & “ 0.wav ” & “ type WaveAudio alias wave ” , ReturnString , 256 , 0 )

‘打开所选择的文件

ErrorCode = mciSendString ( “ Play wave ” , ReturnStr , 256 , 0 )

‘播放所选择的文件

End Select

ErrorCode = mciSendString ( “ Close wave ” , ReturnStr , 256 , 0 )

End Sub

以上修改,因为结构上没有本质变化,都要临时载入wave文件,所以速度上没有质的改变,但我们应该知道因为vb中的函数也都是对windows提供的API的封装,所以,直接调用API效率要高于使用vb所提供的语句和函数.

(三)定时关机和定时报警

对于这两个内容,其实原理是相同的,只是功能不同罢了.下面我们来分析一下它的实现方法.这两个功能都是时时比较设定的时间和当前时间,如果相同,则触发事件,对于定时关机来说就是调用ExitWindowsEx ( ) 函数.而定时报警可以用任何方式 ( 如声音,或形象) 来引起使用者注意.

我们先来看看ExitWindowsEx ( ) 函数的相关知识.

ExitWindowsEx ( )

Vb声明: Declare Function ExitWindowsEx Lib " user32 " Alias " ExitWindowsEx " ( ByVal uFlags As Long , ByVal dwReserved As Long ) As Long

说明: 退出windows,并用特定的选项重新启动, 返回值为 Long 型,非零表示成功,零表示失败。会设置GetLastError

参数表

参数

类型及说明

uFlags

Long,指定下述一个或多个标志(用OR运算符合并到一起)

EWX_FORCE

强迫中止没有响应的进程

EWX_LOGOFF

中止进程,然后注销

EWX_SHUTDOWN

关掉系统电源(如果可能的话,ATX电源就可以)

EWX_REBOOT

重新引导系统

EWX_SHUTDOWN

关闭系统

dwReserved

Long,保留,设为零

这个函数调用后会立刻返回,系统关闭过程是在后台进行的。注意先中止自己的应用程序,使关闭过程更显平顺。当然,您的进程必须有足够的优先权,否则也不能执行这种操作.

下图为我们对程序界面的修改.其中我们主要添加了一个frame1 ,两个单选框( Option1和Option2 ) , 三个文本框( text1 , text2 , text3 ) , 三个标签( label1 , label2 , label3 ) 以及一个按钮Command1.其中两个单选框( Option1和Option2 ) ,可以通过选择其中的一个,来确定究竟要使用那种功能. 三个文本框( text1 , text2 , text3 )来接受设定的时间,之后点击按钮Command1来应用.

下面是添加和修改的代码:

‘ = = = = = = = = = = = = = = = = = = = =

‘下面的为新添加的

‘ = = = = = = = = = = = = = = = = = = = =

Dim guanji As Boolean

Dim sheshi As Integer

Dim shefen As Integer

Dim shemiao As Integer

Private Sub Command1 _ Click ( )

If Text1 . Text = "" Or Text2 . Text = "" Or Text3 . Text Then

MsgBox "请填完整"

End If

If Option1.Value = True Then

guanji = True

end if

sheshi = Text1 . Text

shefen = Text2 . Text

shemiao = Text3 . Text

End Sub

‘ = = = = = = = = = = = = = = = = = = = = = =

‘ 下面语句中,添加了一部分,有标示

‘ = = = = = = = = = = = = = = = = = = = = = =

Private Sub Timer1 _ Timer ( )

miao = Second ( Time )

miao = 60 – miao

fen = Minute ( Time )

fen = 60 - fen

shi = Hour ( Time )

If shi > = 12 Then ‘因为一天之内时针要走二十四个钟头,也就是要走两圈,所以将下午和晚上的时间减去十二,就可以确定时针准确的位置

shi = shi - 12

End If

shi = 12 - shi

miao = xianshimiao ( maio )

fen = xianshifen ( fen )

shi = xianshishi ( shi )

‘ = = = = = = = = = = = = = = = = = = = =

‘ 下面几句为新添加的

‘ = = = = = = = = = = = = = = = = = = = =

if sheshi = shi and shefen = fen and shemiao = miao then

if guanji = true then

call ExitWindowsEx ( EWX_SHUTDOWN , 0 )

else

Msgbox “ 您设定的时间已到 ”

End if

If fen = 0 and miao = 0 then ‘如果分针和秒针都为零,这位整点,根据时针的数报时

Select case shi

MMControl1 . FileName = App . Path & “ 0.wav ” ‘选择要打开的文件

MMControl1 . Commond = “ Open ” ‘打开所选择的文件

MMControl1 . Commond = “ Play ” ‘播放所选择的文件

Case 1 ‘ 一点,1.wav报时一点,以下依次类推

MMControl1 . FileName = App . Path & “ 1.wav ” ‘选择要打开的文件

MMControl1 . Commond = “ Open ” ‘打开所选择的文件

MMControl1 . Commond = “ Play ” ‘播放所选择的文件

Case 2

MMControl1 . FileName = App . Path & “ 2.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 3

MMControl1 . FileName = App . Path & “ 3.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 4

MMControl1 . FileName = App . Path & “ 4.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 5

MMControl1 . FileName = App . Path & “ 5.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 6

MMControl1 . FileName = App . Path & “ 6.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 7

MMControl1 . FileName = App . Path & “ 7.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 8

MMControl1 . FileName = App . Path & “ 8.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 9

MMControl1 . FileName = App . Path & “ 9.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 10

MMControl1 . FileName = App . Path & “ 10.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

Case 11

MMControl1 . FileName = App . Path & “ 11.wav ”

MMControl1 . Commond = “ Open ”

MMControl1 . Commond = “ Play ”

End Select

MMControl1.Commond = “ Close ”

End Sub

我们终于写出了一个完整的钟表程序,其中很多部分内容,大家都是熟悉的,但怎样将这些知识应用的实际的开发中呢?很现实的问题,希望本篇能让你对编程能够从新思考,深入理解.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有