朱彦廷
摘 要: 当VB窗体大小改变时,其中的控件(以及控件上的文字)大小不会自动随之改变,这是VB的一个缺陷,要解决该问题,应该保证控件宽度、高度、距窗体左边和上边的距离,以及窗体宽度、高度的比值不变,控件上的文字面积和窗体面积的比值不变,据此,给出了较为完美、简单、健壮的解决方法。
关键词: VB; 窗体; 控件; 文字
中图分类号:TP312 文献标志码:A 文章编号:1006-8228(2014)03-42-02
0 引言
VB简单易学,是非常适合非专业程序员的可视化程序设计语言[1]。但当窗体大小改变时,其中的控件大小不会自动随之改变,这将破坏原来的布局,因此改变几乎毫无意义,所以很多程序员只好限制窗体改变大小,但这样编写出来的程序不完美。对于这样的“先天”不足,我们在此尝试“后天”弥补。
1 原理
当窗体大小改变时,对于控件,应保证其宽度、高度、距窗体左边和上边的距离,以及窗体宽度、高度的比值不变。记下最初的这几个比值,以后据此足以算出控件新的大小和位置。
控件上可能有文字,如果不对其处理,即大小不变,扩大窗体文字又可能显得太小,特别是逐渐缩小窗体,文字将由横排变成竖排、边缘缺失,甚至控件布局也将错乱(见图2,原来大小一致(见图1)的小文本框(里面有文字,但尚未输入)变得不一致(如其中第61和62个)),而且窗体还不能太小(届时鼠标将不能再向小拖动边框),因此文字的大小也应随窗体改变。
但窗体中文字高度(即字号)、宽度的比值是固定的,无法同时保证其宽度、高度,以及窗体宽度、高度的比值不变,所以不能沿用对控件的做法,文献[2]很难得注意到了这个问题,提出了一个解决方法,即:保证文字高度和窗体高度的比值不变。但这样如果只改变窗体宽度和文字高度,也即大小(因高度、宽度的比值固定)将不会改变,缩小宽度时还将出现前述的情形,可见这种方法并没有完全解决问题。本文认为,应该保证文字面积和窗体面积的比值不变,即
故
Controls(i).Font.Size'
=Controls(i).Font.Size
=Controls(i).Font.Size
=ap(i).sp
其中,Controls(i).Font.Size是控件i上的文字最初的高度[3],Controls.(i).Font.Size'是它在窗体改变后的高度,Form1.Width是窗体最初的宽度,Form1.Width'是窗体改变后的宽度,Form1.Height是窗体最初的高度,Form1.Height'是窗体改变后的高度,a是文字宽度、高度的比值,ap(i).sp是控件上的文字高度和窗体最初面积的平方根的比值。这样只要窗体大小改变,文字大小就会随之改变,窗体可以小到只剩标题栏,而且原来的布局不变(见图3)。
图1 原来的窗体
图2 缩小的窗体(文字大小不变)
图3 缩小的窗体(文字大小随之改变)
具体地说,窗体高度包括上、下边框、标题栏的高度,它们不与窗体高度成比例改变(与窗体类型有关,对于某一类型的窗体其实是固定值),因此为保证布局不变,应用窗体内部高度(除去上、下边框、标题栏的高度)而不是窗体高度,那么它的值是多少呢?幸运的是,属性ScaleHeight[4]表示的就是窗体内部高度,不用再想办法求出。窗体宽度包括左、右边框的宽度,其余和窗体高度类似。
2 代码
具体的程序代码(所用的VB版本是6.0)如下:
Private Type cp
wp As Single
hp As Single
tp As Single
lp As Single
sp As Single
End Type
Private ap() As cp
Private Sub Form_Load()
ReDim ap(0 To Controls.Count-1)
Dim i As Integer
On Error Resume Next'当发生错误(因有的控件(如图像框)没有Font属性;有的控件(如定时器)没有Width、Height属性)时,忽略该行,继续执行
For i=0 To Controls.Count-1
ap(i).wp=Controls(i).Width/Form1.ScaleWidth
'记录控件宽度和窗体内部宽度的比值
ap(i).hp=Controls(i).Height/Form1.ScaleHeight
'记录控件高度和窗体内部高度的比值
ap(i).tp=Controls(i).Top/Form1.ScaleHeight
'记录控件到窗体上边的距离和窗体内部高度的比值
ap(i).lp=Controls(i).Left/Form1.ScaleWidth
'记录控件到窗体左边的距离和窗体内部宽度的比值
ap(i).sp=Controls(i).Font.Size/Sqr(Form1.ScaleHeight*Form1
.ScaleWidth) '记录控件上的文字字号和窗体内部面积的平方根的比值
Next i
End Sub
Private Sub Form_Resize()
Dim i As Integer
On Error Resume Next'当发生错误(有的控件(如图像框)没有Font属性;有的控件(如定时器)没有Width、Height属性;文字小于1.5磅(如果窗体太小);窗体内部高度为0(缩小窗体到只剩标题栏、最小化时)时,忽略该行,继续执行[5]
For i=0 To Controls.Count - 1
Controls(i).Left=ap(i).lp*Form2.ScaleWidth
Controls(i).Top=ap(i).tp*Form2.ScaleHeight
Controls(i).Width=ap(i).wp*Form2.ScaleWidth
Controls(i).Height=ap(i).hp*Form2.ScaleHeight '以上4条语句
如简化为Controls(i).Move ap(i).lp*Form1.ScaleWidth,ap(i).tp*Form1.ScaleHeight, ap(i).wp*Form1.ScaleWidth, ap(i).hp *Form1.ScaleHeight,对有的控件(如组合框,其Height是不可改变的),将因出错导致语句不能执行,致使控件位置、宽度、高度均不能改变
Controls(i).Font.Size=ap(i).sp*Sqr(Form1.ScaleHeight
*Form1.ScaleWidth)
Next i
End Sub
3 结束语
与这方面见到的其他文献(几乎都见于网络,期刊上几乎没有)相比,本文给出的方法更为完美。本文使用窗体内部高度、内部宽度,而不是直接用高度、宽度,排除了窗体边框、标题栏的影响,更为严谨、美观;较好地解决了控件上的文字的改变问题。本文的方法简单;应用方便;健壮,即遇到错误能够被妥善处理,不会导致程序崩溃。
参考文献:
[1] 教育部考试中心.Visual Basic语言程序设计[M].高等教育出版社,
2013.
[2] 陈翠松.在VB中实现控件大小的自动改变[J].计算机时代,2001.1.
[3] 李淑华.VB程序设计及应用[M].高等教育出版社,2003.
[4] 《视窗世界》杂志社.手把手VB100例[M].北京赛迪电子出版社,
2004.
[5] 沈祥玖.VB程序设计[M].高等教育出版社,2003.