用好VB的PrintForm语句

软件世界

我们知道,VB的打印功能是相对较弱的,简单地说,它仅提供了两种方法:
1.在窗体中建立所需要的输出,然后用PrintForm语句打印屏幕。
2.将正文和图形传送到Printer对象,然后再用NewPage和EndDoc方法打印。
然而,这两种方法均有缺陷。利用Printer对象打印需要额外的、烦琐的编程,本文不对此多作讨论。Printform语句是把窗体的位图送到当前打印机,从而窗体可见区域的所有东西都送往了打印机。这就产生了两个问题:
问题一:有些东西,如命令按钮,我们并不希望它被打印;但也被打印出来了。
问题二:窗体上各类控件的背景色(包括窗体本身的背景色)也被打印出来了,而这也不是我们所希望的。
鉴于这些原因,不少程序员(包括笔者本人)都在利用VB调用Office(尤其是Word)提供的OLE自动化服务功能进行打印输出。
但是,当窗体上有图形要打印,或者在许多实时数据采集和实时监控的情形下,我们又恰恰需要进行整个屏幕打印输出。为了避免PrintForm语句引起的上述两个问题,我们就不得不另想办法加以改进了。
针对问题一,我们可以令不想被打印的控件的Visible属性为False:
如:Command1.Visible = False
针对问题二,我们可以令控件的BackColor属性为白色:
如:Label1.Backcolor = vbWhite
Me.Backcolor = vbWhite
利用PrintForm语句打印输出后,为了保持窗体的原有面貌,我们还需要通过适当的语句将它们的相应属性予以恢复。
如果窗体上这样的控件很少,为它们各自编写相应的语句还可以忍受。而如果这样的控件较多,一个一个地为它们编写单独的语句就令人厌烦了。
那么,有没有好的解决办法呢?回答是肯定的。我们可以利用VB 的对象(Object)和Controls集合功能编写一个通用窗体屏幕打印例程(见下面的Sub PrintScreen程序),将它放在通用模块中。在需要屏幕打印的窗体上加一个Print菜单,并为它编写如下语句:
Private Sub mnuPrint_Click()
PrintScreen Me
End Sub
需要打印时,点一下这个菜单,就可以从打印机打出既简洁又美观的屏幕拷贝了。
顺便提一句,例程列出了一些常用的不具有BackColor属性的控件。如果你的窗体上另有其他不具有BackColor属性的控件,请自己添加进去。如果你认为一个一个手工添加比较麻烦,还可以利用VB的ON ERROR语句和ERR、ERROR$函数编写一段处理VB ERR=438号错误(“对象不支持该属性或方法”)的语句对例程做些修改,使之更通用。本文没有用ON ERROR语句的主要考虑是为了使例程便于理解。
Public Sub PrintScreen(obj As Form)
Dim ctl As Control, i As Integer, T0 As Single
ReDim BColor(obj.Controls.Count) '用来保存控件背景色的数组
i = 0
BColor(0) = Obj.BackColor '保存窗体本身的背景色
Obj.BackColor = vbWhite
For Each ctl In obj
If TypeName(ctl) = "CommandButton" Then
ctl.Visible = False '使命令按钮不可见,因而也不被打印
Else
If TypeName(ctl) <> "Timer" And TypeName(ctl) <> "MSComm" _
And TypeName(ctl) <> "Menu" Then
' 排除那些没有BackColor属性的控件,这很重要
i = i + 1
BColor(i) = ctl.BackColor '保存控件背景色
ctl.BackColor = vbWhite '令该控件的背景色为白色
End If
End If
Next
T0 = Timer '延时2秒,让VB做属性变换
Do While Timer < T0 +2
DoEvents
Loop
Obj.PrintForm '打印输出
'下面做恢复工作
i = 0
For Each ctl In obj
If TypeName(ctl) = "CommandButton" Then
ctl.Visible = True
Else
If TypeName(ctl) <> "Timer" And TypeName(ctl) <> "MSComm" _
And TypeName(ctl) <> "Menu" Then
i = i + 1
ctl.BackColor = BColor(i)
End If
End If
Next
Obj.BackColor = BColor(0)
End Sub