感谢IT之家网友一道残阳铺水中的原创投稿

大概很早以前,每天深夜或者周二下午,打开电视都会看到这样类似下图的画面。这种画面被称为测试图,也叫测试卡,是电视台在正式节目之前播放的供用户校验电视图像的画面,而电视台也通常在这个间隙对设备进行维护。而如今越来越多的电视台加入了 24 小时播出的行列,因此观众看到测试图的机会就越来越少了。

午夜 12 点的守候:教你打造 “IT之家电视台”

今天我们就来虚拟一张 “IT之家电视台”的测试图。用到的软件,PowerPoint 就够了。

1、先从网上找到空白(即不含台标、报时等信息)的测试图大图,并将其设置为幻灯片的背景,再在合适的位置上加上台标、电视台信息、主报时和右上角角标报时,并应用上美观的格式。做完以后,就像下图。

午夜 12 点的守候:教你打造 “IT之家电视台”

这就完成了吗?当然不是,那就没必要写一篇文章了。现在的幻灯片还是静态的,我们可要让它动起来,让报时器变成名副其实的报时器。于是 VBA 就登场了。

2、启动 VBA 编辑器(该编辑器的入口在 “开发工具”选项卡下。该选项卡默认隐藏,可以在功能区设置中取消隐藏),从 “插入”菜单中新建一个标准模块。

新建一个过程,名为 Tick,并填充如下代码。

Sub Tick()

With ActivePresentation.Slides(1)

.Shapes(3).TextFrame.TextRange = Format(Date, "yyyy-MM-dd")

.Shapes(4).TextFrame.TextRange = Format(Time, "hh:mm:ss")

.Shapes(5).TextFrame.TextRange = Format(Time, "hh:mm:ss")

End With

End Sub

代码说明:文本框和形状等本质上是属于 shape 类型的,在一张幻灯片上添加的 shape 可以通过其下的 shapes 集合来访问。在本例中,shapes(3)表示主报时的日期部分,shapes(4)表示主报时的时间部分,shapes(5)则表示右上角的角标报时。所以上述代码的作用是刷新一次报时器。

3、刷新报时器的代码是写完了,但是无论你进行什么操作,这段代码都不会运行,因为没有触发条件。而我们希望在启动幻灯片放映后,执行该代码。于是便引入了一个能够自动运动的宏 OnSlideShowPageChange。如若把过程命名为该名称,则它所包含的代码会在放映时幻灯片切换时被执行——其实并不是启动时执行,但是因为现在只有一张幻灯片,所以可以大致等效。于是就有了这样的代码:

Sub OnSlideShowPageChange()

Call Tick()

End Sub

然后启动幻灯片放映,发现时间确实被刷新了!但是,好像哪里不对劲。时间刷新了一次后,它就不走了。于是我们应该来个定时器之类的控件,让 Tick 过程能每秒执行一次。然而,VBA 并不像 VB6.0 一样提供定时器控件。

午夜 12 点的守候:教你打造 “IT之家电视台”

4、这并不意味着我们就束手无策了。既然没有定时器控件,那就不用控件来实现呗。我们仍可以通过 Windows API 来实现定时器的功能,先声明 API 函数:

Public Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long

Public Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long

代码说明:SetTimer 和 KillTimer 是相反的,前者是设置计时器(开始计时),后者是取消计时器(停止计时)。它们的参数中,hwnd 是窗口的句柄(类似于 ID),nIDEvent 是计时器的 ID,uElapse 是计时间隔(以毫秒为单位),lpTimerFunc 是要让计时器执行的函数或者过程。而因为参数中还要求句柄,那么需要再来一个函数来获取活动窗体的句柄。

Public Declare Function GetActiveWindow Lib "user32" () As Long

5、接着,我们把 OnSlideShowPageChange 过程中的代码修改如下:

Sub OnSlideShowPageChange()

SetTimer GetActiveWindow, 101, 1000, AddressOf Tick

End Sub

再次启动幻灯片放映,我们发现时间真的一秒一下地走起来了!(文末会上效果图)但是注意到角标报时一直悬挂在右上角,而通常电视台只会在半点和整点时显示角标报时。有什么办法可以做到这点呢?当然有!

6、新建一个判断是否为半点或整点的函数 ifHalfHour:

Function ifHalfHour()

Dim TimeValue As Double

TimeValue = CDbl(Time) * 86400

If TimeValue Mod 1800 >= 1770 Or TimeValue Mod 1800 <= 30 Then

ifHalfHour = True

End If

End Function

代码说明:time 是 date 类型,转成 double 表示的当前时间占全天的比值。比如 12:00:00 正好时一天的正中,因此表示 12:00:00 的 date 转换为 double 后正好是 0.5。那么可以再乘上一天的总秒数 86400 秒,来表示是一天中的第几秒,再根据除以 1800 秒(半个小时是 1800 秒)所得的余数,即可判断是否到半点或整点了。余数 1770 表示 XX:29:30 或 XX:59:30,余数 30 表示 XX:30:30 或 XX:00:30。

7、接着我们把表示角标报时的 shapes(5)的 visible(是否可见)属性与该函数的返回值绑定在一起。在 Tick 过程的 With 块中,新增一行:

.Shapes(5).Visible = ifHalfHour

这样任务就基本完成了。另外,我们还希望能在退出幻灯片放映后能够停止计时,能重置报时器等,于是就引入了 OnSlideShowTerminate(在放映结束时自动运行)和 Reset(尚未定义触发条件)过程:

Sub OnSlideShowTerminate()

KillTimer GetActiveWindow, 101

End Sub

Sub Reset()

With ActivePresentation.Slides(1)

.Shapes(3).TextFrame.TextRange = "0000-00-00"

.Shapes(4).TextFrame.TextRange = "00:00:00"

.Shapes(5).TextFrame.TextRange = "00:00:00"

.Shapes(5).Visible = True

End With

End Sub

现在奉上半点报时时的效果动图,报时长达 1 分钟(动图效果:点此观看)。

更多设想:为了丰富测试图的内容,大家还可以加入背景音乐;当然也可以把 “IT之家电视台”再办下去,让它开播等等。

最后给出做好的 PowerPoint 文档、效果图、测试卡底图等(点此下载),打开的时候别忘了允许宏运行。大家发挥想象,自己玩去吧。

相关文章