标签:VBA,Windows API
在使用VBA创建用户窗体时,通常会将其设置为特定的大小。然而,通过一些编码技巧,可以为其实现类似的调整大小效果。
本文的代码整理自exceloffthegrid.com,供有兴趣的朋友参考。
本文代码能够实现:允许调整用户窗体的大小;调整窗体大小时用户窗体的Resize事件能捕获;每次Resize事件后,对象的大小或位置都会发生变化。
首先,在VBE中插入一个标准模块,输入下面的代码:
Public Const GWL_STYLE = -16
Public Const WS_CAPTION = &HC00000
Public Const WS_THICKFRAME = &H40000
#If VBA7 Then
Public Declare PtrSafe Function GetWindowLong _
Lib "user32" Alias "GetWindowLongA" ( _
ByVal hWnd As Long, ByVal nIndex As Long) As Long
Public Declare PtrSafe Function SetWindowLong _
Lib "user32" Alias "SetWindowLongA" ( _
ByVal hWnd As Long, ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Public Declare PtrSafe Function DrawMenuBar _
Lib "user32" (ByVal hWnd As Long) As Long
Public Declare PtrSafe Function FindWindowA _
Lib "user32" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
#Else
Public Declare Function GetWindowLong _
Lib "user32" Alias "GetWindowLongA" ( _
ByVal hWnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong _
Lib "user32" Alias "SetWindowLongA" ( _
ByVal hWnd As Long, ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Public Declare Function DrawMenuBar _
Lib "user32" (ByVal hWnd As Long) As Long
Public Declare Function FindWindowA _
Lib "user32" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
#End If
Sub ResizeWindowSettings(frm As Object, show As Boolean)
Dim windowStyle As Long
Dim windowHandle As Long
'获取Windows内存中对窗口和样式位置的引用
windowHandle = FindWindowA(vbNullString, frm.Caption)
windowStyle = GetWindowLong(windowHandle, GWL_STYLE)
'确定要应用的样式
If show = False Then
windowStyle = windowStyle And (Not WS_THICKFRAME)
Else
windowStyle = windowStyle + (WS_THICKFRAME)
End If
'应用新样式
SetWindowLong windowHandle, GWL_STYLE, windowStyle
'使用新样式重新创建用户窗体窗口
DrawMenuBar windowHandle
End Sub
上面的两个代码段创建了一个可重复使用的过程,可以使用它来打开或关闭调整用户窗体大小的设置。如果想要能够调整用户窗体大小,使用:
Call ResizeWindowSettings(myUserForm, True)
关闭调整用户窗体大小,使用:
Call ResizeWindowSettings(myUserForm, False)
其中,myUserForm是要调整大小的用户窗体的名称。
示例
在VBE中,插入一个用户窗体,如下图1所示。
图1
可以看到,该用户窗体上包括一个名为“lstListBOx”的列表框和一个名为“cmdClose”的命令按钮。
当该用户窗体调整大小时,这两个元素都应该作出相应更改。lstListBox的大小应更改,但位置不应更改,而cmdClose的位置将更改,但大小不应更改。为此,需要从该用户窗体的底部和右侧了解这些对象的位置。如果与底部和右侧保持相同的距离,则这些元素似乎与该用户窗体同步移动。
在该用户窗体代码窗口,输入下面的代码:
Private lstListBoxBottom As Double
Private lstListBoxRight As Double
Private cmdCloseBottom As Double
Private cmdCloseRight As Double
Private Sub UserForm_Initialize()
'调用Window API启用调整大小
Call ResizeWindowSettings(Me, True)
'获取要调整大小的对象的右下角定位点位置
lstListBoxBottom = Me.Height - lstListBox.Top - lstListBox.Height
lstListBoxRight = Me.Width - lstListBox.Left - lstListBox.Width
cmdCloseBottom = Me.Height - cmdClose.Top - cmdClose.Height
cmdCloseRight = Me.Width - cmdClose.Left - cmdClose.Width
End Sub
Private Sub UserForm_Resize()
On Error Resume Next
'设置对象的新位置
lstListBox.Height = Me.Height - lstListBoxBottom - lstListBox.Top
lstListBox.Width = Me.Width - lstListBoxRight - lstListBox.Left
cmdClose.Top = Me.Height - cmdCloseBottom - cmdClose.Height
cmdClose.Left = Me.Width - cmdCloseRight - cmdClose.Width
On Error GoTo 0
End Sub
运行用户窗体,效果如下图2所示。
图2
欢迎在下面留言,完善本文内容,让更多的人学到更完美的知识。