代码如下: 'VB控件随窗体大小而变化 '当窗体大小改变时,如何动态的改变控件的大小是许多VB程序员头痛的 '事。有的人设置窗体Resizable但却不改变控件的大小;有的人则根据控件的 '绝对位置与窗口大小相加减的办法来重新定位控件与改变大小,这种办法比 '较繁琐,且不可重用;当然也有人则限定窗口干脆不让改变。有没有一种简 '便易行的办法?答案是肯定的,下面给出一个一劳永逸的办法,源程序如下: '模块 Option Explicit Dim FormOldWidth As Long '窗体旧的宽度值 Dim FormOldHeight As Long '窗体旧的高度值
Public Sub ResizeInit(FormName As Form) Dim pCtl As Control
On Error Resume Next For Each pCtl In FormName '设置窗体中控件的Tag值(根据空间的位置和大小来设置)
'返回或设置一个表达式,它存储程序需要的额外数据。 '与其它属性不同,Visual Basic 不使用 Tag 属性的值; '可用该属性识别对象。
pCtl.Tag = pCtl.Left & " " & pCtl.Top & " " & pCtl.Width & " " & pCtl.Height & " " Next pCtl On Error GoTo 0 End Sub Public Sub ResizeForm(FormName As Form) Dim Pos(4) As Double Dim i As Long, tmpPos As Long, staPos As Long Dim pCtl As Control Dim ScaleX As Double, ScaleY As Double
'变化窗体内的各控件 For Each pCtl In FormName staPos = 1 For i = 0 To 4 '位置和大小 '取得控件的原始位置和大小 tmpPos = InStr(staPos, pCtl.Tag, " ", vbTextCompare) If tmpPos > 0 Then Pos(i) = Mid(pCtl.Tag, staPos, tmpPos - staPos) staPos = tmpPos + 1 Else Pos(i) = 0 End If
'根据控件的原始位置及窗体改变大小的 '比例对控件重新定位与改变大小 pCtl.Move Pos(0) * ScaleX, Pos(1) * ScaleY, Pos(2) * ScaleX, Pos(3) * ScaleY Next i Next pCtl On Error GoTo 0 End Sub
'在窗体启动时,调用ResizeInit函数 '以记录窗体中各控件的大小和位置 Private Sub Form_Load() Call ResizeInit(Me) End Sub'窗体大小发生变化时,根据窗体改变大小的比例 '对窗体中各控件重新定位和改变大小。 Private Sub Form_Resize() Call ResizeForm(Me) End Sub
在Form的Resize事件中调用函数Resize_All就能实现控件自动调整大小,如:Private Sub Form_Resize() Dim H, i As Integer On Error Resume Next Resize_ALL Me 'Me是窗体名,Form1,Form2等等都可以End Sub 在模块中添加以下代码:Public Type ctrObj Name As String Index As Long Parrent As String Top As Long Left As Long Height As Long Width As Long ScaleHeight As Long ScaleWidth As Long End TypePrivate FormRecord() As ctrObj Private ControlRecord() As ctrObj Private bRunning As Boolean Private MaxForm As Long Private MaxControl As Long Private Const WM_NCLBUTTONDOWN = &HA1 Private Declare Function SendMessage Lib "USER32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function ReleaseCapture Lib "USER32" () As LongFunction ActualPos(plLeft As Long) As Long If plLeft < 0 Then ActualPos = plLeft + 75000 Else ActualPos = plLeft End IfEnd FunctionFunction FindForm(pfrmIn As Form) As Long Dim i As Long FindForm = -1 If MaxForm > 0 Then
For i = 0 To (MaxForm - 1) If FormRecord(i).Name = pfrmIn.Name Then FindForm = i Exit Function End If Next i End IfEnd Function Function AddForm(pfrmIn As Form) As Long Dim FormControl As Control Dim i As Long ReDim Preserve FormRecord(MaxForm + 1) FormRecord(MaxForm).Name = pfrmIn.Name FormRecord(MaxForm).Top = pfrmIn.Top FormRecord(MaxForm).Left = pfrmIn.Left FormRecord(MaxForm).Height = pfrmIn.Height FormRecord(MaxForm).Width = pfrmIn.Width FormRecord(MaxForm).ScaleHeight = pfrmIn.ScaleHeight FormRecord(MaxForm).ScaleWidth = pfrmIn.ScaleWidth AddForm = MaxForm MaxForm = MaxForm + 1 For Each FormControl In pfrmIn i = FindControl(FormControl, pfrmIn.Name) If i < 0 Then i = AddControl(FormControl, pfrmIn.Name) End If Next FormControlEnd FunctionFunction FindControl(inControl As Control, inName As String) As Long Dim i As Long FindControl = -1 For i = 0 To (MaxControl - 1) If ControlRecord(i).Parrent = inName Then If ControlRecord(i).Name = inControl.Name Then On Error Resume Next If ControlRecord(i).Index = inControl.Index Then FindControl = i Exit Function End If On Error GoTo 0 End If End If Next i End FunctionFunction AddControl(inControl As Control, inName As String) As Long ReDim Preserve ControlRecord(MaxControl + 1) On Error Resume Next ControlRecord(MaxControl).Name = inControl.Name ControlRecord(MaxControl).Index = inControl.Index ControlRecord(MaxControl).Parrent = inName If TypeOf inControl Is Line Then ControlRecord(MaxControl).Top = inControl.Y1 ControlRecord(MaxControl).Left = ActualPos(inControl.X1) ControlRecord(MaxControl).Height = inControl.Y2 ControlRecord(MaxControl).Width = ActualPos(inControl.X2) Else ControlRecord(MaxControl).Top = inControl.Top ControlRecord(MaxControl).Left = ActualPos(inControl.Left) ControlRecord(MaxControl).Height = inControl.Height ControlRecord(MaxControl).Width = inControl.Width End If inControl.IntegralHeight = False On Error GoTo 0 AddControl = MaxControl MaxControl = MaxControl + 1 End FunctionFunction PerWidth(pfrmIn As Form) As Long Dim i As Long i = FindForm(pfrmIn) If i < 0 Then i = AddForm(pfrmIn) End If PerWidth = (pfrmIn.ScaleWidth * 100) \ FormRecord(i).ScaleWidth End FunctionFunction PerHeight(pfrmIn As Form) As Double Dim i As Long i = FindForm(pfrmIn) If i < 0 Then i = AddForm(pfrmIn) End If PerHeight = (pfrmIn.ScaleHeight * 100) \ FormRecord(i).ScaleHeight End FunctionPublic Sub ResizeControl(inControl As Control, pfrmIn As Form) On Error Resume Next Dim i As Long Dim widthfactor As Single, heightfactor As Single Dim minFactor As Single Dim yRatio, xRatio, lTop, lLeft, lWidth, lHeight As Long yRatio = PerHeight(pfrmIn) xRatio = PerWidth(pfrmIn) i = FindControl(inControl, pfrmIn.Name) If inControl.Left < 0 Then lLeft = CLng(((ControlRecord(i).Left * xRatio) \ 100) - 75000) Else lLeft = CLng((ControlRecord(i).Left * xRatio) \ 100) End If lTop = CLng((ControlRecord(i).Top * yRatio) \ 100) lWidth = CLng((ControlRecord(i).Width * xRatio) \ 100) lHeight = CLng((ControlRecord(i).Height * yRatio) \ 100) If TypeOf inControl Is Line Then If inControl.X1 < 0 Then inControl.X1 = CLng(((ControlRecord(i).Left * xRatio) \ 100) - 75000) Else inControl.X1 = CLng((ControlRecord(i).Left * xRatio) \ 100) End If inControl.Y1 = CLng((ControlRecord(i).Top * yRatio) \ 100) If inControl.X2 < 0 Then inControl.X2 = CLng(((ControlRecord(i).Width * xRatio) \ 100) - 75000) Else inControl.X2 = CLng((ControlRecord(i).Width * xRatio) \ 100) End If inControl.Y2 = CLng((ControlRecord(i).Height * yRatio) \ 100) Else inControl.Move lLeft, lTop, lWidth, lHeight inControl.Move lLeft, lTop, lWidth inControl.Move lLeft, lTop End IfEnd SubPublic Sub ResizeForm(pfrmIn As Form) Dim FormControl As Control Dim isVisible As Boolean Dim StartX, StartY, MaxX, MaxY As Long Dim bNew As Boolean If Not bRunning Then bRunning = True If FindForm(pfrmIn) < 0 Then bNew = True Else bNew = False End If If pfrmIn.Top < 30000 Then isVisible = pfrmIn.Visible On Error Resume Next If Not pfrmIn.MDIChild Then On Error GoTo 0 ' ' pfrmIn.Visible = False Else If bNew Then StartY = pfrmIn.Height StartX = pfrmIn.Width On Error Resume Next For Each FormControl In pfrmIn If FormControl.Left + FormControl.Width + 200 > MaxX Then MaxX = FormControl.Left + FormControl.Width + 200 End If If FormControl.Top + FormControl.Height + 500 > MaxY Then MaxY = FormControl.Top + FormControl.Height + 500 End If If FormControl.X1 + 200 > MaxX Then MaxX = FormControl.X1 + 200 End If If FormControl.Y1 + 500 > MaxY Then MaxY = FormControl.Y1 + 500 End If If FormControl.X2 + 200 > MaxX Then MaxX = FormControl.X2 + 200 End If If FormControl.Y2 + 500 > MaxY Then MaxY = FormControl.Y2 + 500 End If Next FormControl On Error GoTo 0 pfrmIn.Height = MaxY pfrmIn.Width = MaxX End If On Error GoTo 0 End If For Each FormControl In pfrmIn ResizeControl FormControl, pfrmIn Next FormControl On Error Resume Next If Not pfrmIn.MDIChild Then On Error GoTo 0 pfrmIn.Visible = isVisible Else If bNew Then pfrmIn.Height = StartY pfrmIn.Width = StartX For Each FormControl In pfrmIn ResizeControl FormControl, pfrmIn Next FormControl End If End If On Error GoTo 0 End If bRunning = False End IfEnd SubPublic Sub SaveFormPosition(pfrmIn As Form) Dim i As Long If MaxForm > 0 Then For i = 0 To (MaxForm - 1) If FormRecord(i).Name = pfrmIn.Name Then FormRecord(i).Top = pfrmIn.Top FormRecord(i).Left = pfrmIn.Left FormRecord(i).Height = pfrmIn.Height FormRecord(i).Width = pfrmIn.Width Exit Sub End If Next i AddForm (pfrmIn) End If End SubPublic Sub RestoreFormPosition(pfrmIn As Form) Dim i As Long If MaxForm > 0 Then For i = 0 To (MaxForm - 1) If FormRecord(i).Name = pfrmIn.Name Then If FormRecord(i).Top < 0 Then pfrmIn.WindowState = 2 ElseIf FormRecord(i).Top < 30000 Then pfrmIn.WindowState = 0 pfrmIn.Move FormRecord(i).Left, FormRecord(i).Top, FormRecord(i).Width, FormRecord(i).Height Else pfrmIn.WindowState = 1 End If Exit Sub End If Next i End If End SubPublic Sub Resize_ALL(Form_Name As Form) Dim OBJ As Object For Each OBJ In Form_Name ResizeControl OBJ, Form_Name Next OBJ End SubPublic Sub DragForm(frm As Form) On Local Error Resume Next Call ReleaseCapture Call SendMessage(frm.hwnd, WM_NCLBUTTONDOWN, 2, 0)End Sub
代码如下: 'VB控件随窗体大小而变化
'当窗体大小改变时,如何动态的改变控件的大小是许多VB程序员头痛的
'事。有的人设置窗体Resizable但却不改变控件的大小;有的人则根据控件的
'绝对位置与窗口大小相加减的办法来重新定位控件与改变大小,这种办法比
'较繁琐,且不可重用;当然也有人则限定窗口干脆不让改变。有没有一种简
'便易行的办法?答案是肯定的,下面给出一个一劳永逸的办法,源程序如下:
'模块
Option Explicit
Dim FormOldWidth As Long '窗体旧的宽度值
Dim FormOldHeight As Long '窗体旧的高度值
Public Sub ResizeInit(FormName As Form)
Dim pCtl As Control
'设置窗体旧的高度与宽度
FormOldWidth = FormName.ScaleWidth
FormOldHeight = FormName.ScaleHeight
On Error Resume Next
For Each pCtl In FormName
'设置窗体中控件的Tag值(根据空间的位置和大小来设置)
'返回或设置一个表达式,它存储程序需要的额外数据。
'与其它属性不同,Visual Basic 不使用 Tag 属性的值;
'可用该属性识别对象。
pCtl.Tag = pCtl.Left & " " & pCtl.Top & " " & pCtl.Width & " " & pCtl.Height & " "
Next pCtl
On Error GoTo 0
End Sub Public Sub ResizeForm(FormName As Form)
Dim Pos(4) As Double
Dim i As Long, tmpPos As Long, staPos As Long
Dim pCtl As Control
Dim ScaleX As Double, ScaleY As Double
'保存窗体的宽度与高度缩放比例
ScaleX = FormName.ScaleWidth / FormOldWidth
ScaleY = FormName.ScaleHeight / FormOldHeight
On Error Resume Next
'变化窗体内的各控件
For Each pCtl In FormName
staPos = 1
For i = 0 To 4 '位置和大小
'取得控件的原始位置和大小
tmpPos = InStr(staPos, pCtl.Tag, " ", vbTextCompare)
If tmpPos > 0 Then
Pos(i) = Mid(pCtl.Tag, staPos, tmpPos - staPos)
staPos = tmpPos + 1
Else
Pos(i) = 0
End If
'根据控件的原始位置及窗体改变大小的
'比例对控件重新定位与改变大小
pCtl.Move Pos(0) * ScaleX, Pos(1) * ScaleY, Pos(2) * ScaleX, Pos(3) * ScaleY
Next i
Next pCtl
On Error GoTo 0
End Sub
'在窗体启动时,调用ResizeInit函数
'以记录窗体中各控件的大小和位置
Private Sub Form_Load()
Call ResizeInit(Me)
End Sub'窗体大小发生变化时,根据窗体改变大小的比例
'对窗体中各控件重新定位和改变大小。
Private Sub Form_Resize()
Call ResizeForm(Me)
End Sub
留下的邮箱,我发给你。
Dim H, i As Integer
On Error Resume Next
Resize_ALL Me 'Me是窗体名,Form1,Form2等等都可以End Sub 在模块中添加以下代码:Public Type ctrObj
Name As String
Index As Long
Parrent As String
Top As Long
Left As Long
Height As Long
Width As Long
ScaleHeight As Long
ScaleWidth As Long
End TypePrivate FormRecord() As ctrObj
Private ControlRecord() As ctrObj
Private bRunning As Boolean
Private MaxForm As Long
Private MaxControl As Long
Private Const WM_NCLBUTTONDOWN = &HA1
Private Declare Function SendMessage Lib "USER32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function ReleaseCapture Lib "USER32" () As LongFunction ActualPos(plLeft As Long) As Long If plLeft < 0 Then
ActualPos = plLeft + 75000
Else
ActualPos = plLeft
End IfEnd FunctionFunction FindForm(pfrmIn As Form) As Long Dim i As Long
FindForm = -1 If MaxForm > 0 Then
For i = 0 To (MaxForm - 1)
If FormRecord(i).Name = pfrmIn.Name Then
FindForm = i
Exit Function
End If
Next i
End IfEnd Function
Function AddForm(pfrmIn As Form) As Long Dim FormControl As Control
Dim i As Long
ReDim Preserve FormRecord(MaxForm + 1) FormRecord(MaxForm).Name = pfrmIn.Name
FormRecord(MaxForm).Top = pfrmIn.Top
FormRecord(MaxForm).Left = pfrmIn.Left
FormRecord(MaxForm).Height = pfrmIn.Height
FormRecord(MaxForm).Width = pfrmIn.Width
FormRecord(MaxForm).ScaleHeight = pfrmIn.ScaleHeight
FormRecord(MaxForm).ScaleWidth = pfrmIn.ScaleWidth
AddForm = MaxForm
MaxForm = MaxForm + 1 For Each FormControl In pfrmIn
i = FindControl(FormControl, pfrmIn.Name)
If i < 0 Then
i = AddControl(FormControl, pfrmIn.Name)
End If
Next FormControlEnd FunctionFunction FindControl(inControl As Control, inName As String) As Long Dim i As Long
FindControl = -1 For i = 0 To (MaxControl - 1)
If ControlRecord(i).Parrent = inName Then
If ControlRecord(i).Name = inControl.Name Then
On Error Resume Next
If ControlRecord(i).Index = inControl.Index Then
FindControl = i
Exit Function
End If
On Error GoTo 0
End If
End If
Next i
End FunctionFunction AddControl(inControl As Control, inName As String) As Long ReDim Preserve ControlRecord(MaxControl + 1)
On Error Resume Next
ControlRecord(MaxControl).Name = inControl.Name
ControlRecord(MaxControl).Index = inControl.Index
ControlRecord(MaxControl).Parrent = inName If TypeOf inControl Is Line Then
ControlRecord(MaxControl).Top = inControl.Y1
ControlRecord(MaxControl).Left = ActualPos(inControl.X1)
ControlRecord(MaxControl).Height = inControl.Y2
ControlRecord(MaxControl).Width = ActualPos(inControl.X2)
Else
ControlRecord(MaxControl).Top = inControl.Top
ControlRecord(MaxControl).Left = ActualPos(inControl.Left)
ControlRecord(MaxControl).Height = inControl.Height
ControlRecord(MaxControl).Width = inControl.Width
End If inControl.IntegralHeight = False
On Error GoTo 0
AddControl = MaxControl
MaxControl = MaxControl + 1
End FunctionFunction PerWidth(pfrmIn As Form) As Long Dim i As Long
i = FindForm(pfrmIn) If i < 0 Then
i = AddForm(pfrmIn)
End If PerWidth = (pfrmIn.ScaleWidth * 100) \ FormRecord(i).ScaleWidth
End FunctionFunction PerHeight(pfrmIn As Form) As Double Dim i As Long
i = FindForm(pfrmIn) If i < 0 Then
i = AddForm(pfrmIn)
End If PerHeight = (pfrmIn.ScaleHeight * 100) \ FormRecord(i).ScaleHeight
End FunctionPublic Sub ResizeControl(inControl As Control, pfrmIn As Form) On Error Resume Next
Dim i As Long
Dim widthfactor As Single, heightfactor As Single
Dim minFactor As Single
Dim yRatio, xRatio, lTop, lLeft, lWidth, lHeight As Long
yRatio = PerHeight(pfrmIn)
xRatio = PerWidth(pfrmIn)
i = FindControl(inControl, pfrmIn.Name) If inControl.Left < 0 Then
lLeft = CLng(((ControlRecord(i).Left * xRatio) \ 100) - 75000)
Else
lLeft = CLng((ControlRecord(i).Left * xRatio) \ 100)
End If lTop = CLng((ControlRecord(i).Top * yRatio) \ 100)
lWidth = CLng((ControlRecord(i).Width * xRatio) \ 100)
lHeight = CLng((ControlRecord(i).Height * yRatio) \ 100)
If TypeOf inControl Is Line Then If inControl.X1 < 0 Then
inControl.X1 = CLng(((ControlRecord(i).Left * xRatio) \ 100) - 75000)
Else
inControl.X1 = CLng((ControlRecord(i).Left * xRatio) \ 100)
End If inControl.Y1 = CLng((ControlRecord(i).Top * yRatio) \ 100)
If inControl.X2 < 0 Then
inControl.X2 = CLng(((ControlRecord(i).Width * xRatio) \ 100) - 75000)
Else
inControl.X2 = CLng((ControlRecord(i).Width * xRatio) \ 100)
End If inControl.Y2 = CLng((ControlRecord(i).Height * yRatio) \ 100)
Else
inControl.Move lLeft, lTop, lWidth, lHeight
inControl.Move lLeft, lTop, lWidth
inControl.Move lLeft, lTop
End IfEnd SubPublic Sub ResizeForm(pfrmIn As Form) Dim FormControl As Control
Dim isVisible As Boolean
Dim StartX, StartY, MaxX, MaxY As Long
Dim bNew As Boolean If Not bRunning Then
bRunning = True If FindForm(pfrmIn) < 0 Then
bNew = True
Else
bNew = False
End If
If pfrmIn.Top < 30000 Then
isVisible = pfrmIn.Visible
On Error Resume Next
If Not pfrmIn.MDIChild Then
On Error GoTo 0
' ' pfrmIn.Visible = False
Else If bNew Then
StartY = pfrmIn.Height
StartX = pfrmIn.Width
On Error Resume Next
For Each FormControl In pfrmIn
If FormControl.Left + FormControl.Width + 200 > MaxX Then
MaxX = FormControl.Left + FormControl.Width + 200
End If If FormControl.Top + FormControl.Height + 500 > MaxY Then
MaxY = FormControl.Top + FormControl.Height + 500
End If If FormControl.X1 + 200 > MaxX Then
MaxX = FormControl.X1 + 200
End If If FormControl.Y1 + 500 > MaxY Then
MaxY = FormControl.Y1 + 500
End If If FormControl.X2 + 200 > MaxX Then
MaxX = FormControl.X2 + 200
End If If FormControl.Y2 + 500 > MaxY Then
MaxY = FormControl.Y2 + 500
End If Next FormControl On Error GoTo 0
pfrmIn.Height = MaxY
pfrmIn.Width = MaxX
End If On Error GoTo 0
End If For Each FormControl In pfrmIn
ResizeControl FormControl, pfrmIn
Next FormControl On Error Resume Next If Not pfrmIn.MDIChild Then
On Error GoTo 0
pfrmIn.Visible = isVisible
Else If bNew Then
pfrmIn.Height = StartY
pfrmIn.Width = StartX For Each FormControl In pfrmIn
ResizeControl FormControl, pfrmIn
Next FormControl End If
End If
On Error GoTo 0
End If
bRunning = False
End IfEnd SubPublic Sub SaveFormPosition(pfrmIn As Form) Dim i As Long If MaxForm > 0 Then For i = 0 To (MaxForm - 1) If FormRecord(i).Name = pfrmIn.Name Then FormRecord(i).Top = pfrmIn.Top
FormRecord(i).Left = pfrmIn.Left
FormRecord(i).Height = pfrmIn.Height
FormRecord(i).Width = pfrmIn.Width
Exit Sub
End If
Next i AddForm (pfrmIn)
End If
End SubPublic Sub RestoreFormPosition(pfrmIn As Form) Dim i As Long
If MaxForm > 0 Then
For i = 0 To (MaxForm - 1)
If FormRecord(i).Name = pfrmIn.Name Then
If FormRecord(i).Top < 0 Then
pfrmIn.WindowState = 2
ElseIf FormRecord(i).Top < 30000 Then
pfrmIn.WindowState = 0
pfrmIn.Move FormRecord(i).Left, FormRecord(i).Top, FormRecord(i).Width, FormRecord(i).Height
Else
pfrmIn.WindowState = 1
End If
Exit Sub
End If
Next i
End If
End SubPublic Sub Resize_ALL(Form_Name As Form) Dim OBJ As Object
For Each OBJ In Form_Name
ResizeControl OBJ, Form_Name
Next OBJ
End SubPublic Sub DragForm(frm As Form) On Local Error Resume Next
Call ReleaseCapture
Call SendMessage(frm.hwnd, WM_NCLBUTTONDOWN, 2, 0)End Sub