创建可调大小的用户窗体——使用Windows API

2023-08-29 21:11:50 浏览数 (1)

标签:VBA,Windows API

在使用VBA创建用户窗体时,通常会将其设置为特定的大小。然而,通过一些编码技巧,可以为其实现类似的调整大小效果。

本文的代码整理自exceloffthegrid.com,供有兴趣的朋友参考。

本文代码能够实现:允许调整用户窗体的大小;调整窗体大小时用户窗体的Resize事件能捕获;每次Resize事件后,对象的大小或位置都会发生变化。

首先,在VBE中插入一个标准模块,输入下面的代码:

代码语言:javascript复制
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

上面的两个代码段创建了一个可重复使用的过程,可以使用它来打开或关闭调整用户窗体大小的设置。如果想要能够调整用户窗体大小,使用:

代码语言:javascript复制
Call ResizeWindowSettings(myUserForm, True)

关闭调整用户窗体大小,使用:

代码语言:javascript复制
Call ResizeWindowSettings(myUserForm, False)

其中,myUserForm是要调整大小的用户窗体的名称。

示例

在VBE中,插入一个用户窗体,如下图1所示。

图1

可以看到,该用户窗体上包括一个名为“lstListBOx”的列表框和一个名为“cmdClose”的命令按钮。

当该用户窗体调整大小时,这两个元素都应该作出相应更改。lstListBox的大小应更改,但位置不应更改,而cmdClose的位置将更改,但大小不应更改。为此,需要从该用户窗体的底部和右侧了解这些对象的位置。如果与底部和右侧保持相同的距离,则这些元素似乎与该用户窗体同步移动。

在该用户窗体代码窗口,输入下面的代码:

代码语言:javascript复制
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

欢迎在下面留言,完善本文内容,让更多的人学到更完美的知识。

0 人点赞