|
|

楼主 |
发表于 2025-12-7 10:11
|
显示全部楼层
第7期-创建有多个部分的状态栏
在上期的文章中,我们介绍了状态栏拆分的原理,以及要使用到的两个消息SB_SETPARTS和SB_GETPARTS。那么,这期文章就给出完整的应用代码:创建一个具有多个组成部分的状态栏!
创建一个具有多个组成部分的状态栏
大家依旧只需要复制粘贴以下两个代码即可:
1. 新建一个类模块,命名为TheStatusBar,添加以下代码
- #If VBA7 And Win64 Then
- Private ParentWindow As LongPtr
- Private ParentClient As LongPtr
- Private StatusBar As LongPtr
- Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
- Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
- Private Declare PtrSafe Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal HwndParent As LongPtr, ByVal hMenu As LongPtr, ByVal Hinstance As LongPtr, lpParam As Any) As LongPtr
- Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
- Private Declare PtrSafe Function DestroyWindow Lib "user32" (ByVal hwnd As LongPtr) As Long
- Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
- Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
- Private Declare PtrSafe Function GetClientRect Lib "user32" (ByVal hwnd As LongPtr, lpRect As RECT) As Long
- #Else
- Private ParentWindow As Long
- Private ParentClient As Long
- Private StatusBar As Long
- Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
- Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
- Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal HwndParent As Long, ByVal hMenu As Long, ByVal Hinstance As Long, lpParam As Any) As Long
- Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
- Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long
- Private Declare Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" (ByVal Hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
- Private Declare Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongA" (ByVal Hwnd As Long, ByVal nIndex As Long) As Long
- Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
- #End If
- Private Const STATUSCLASSNAME = "msctls_statusbar32"
- Private Const WS_CHILD = &H40000000
- Private Const WS_VISIBLE = &H10000000
- Private Const CCS_TOP = &H1
- Private Const SBARS_SIZEGRIP = &H100
- Private Const SBT_TOOLTIPS = &H800
- Private Const WM_SIZE = &H5
- Private Const GWL_STYLE = (-16)
- Private Const WS_THICKFRAME = &H40000
- Private Const WS_MINIMIZEBOX = &H20000
- Private Const WS_MAXIMIZEBOX = &H10000
- Private Const WM_USER = &H400
- Private Const SB_SETPARTS = (WM_USER + 4)
- Private Const SB_GETPARTS = (WM_USER + 6)
- Private Type RECT
- Left As Long
- Top As Long
- Right As Long
- Bottom As Long
- End Type
- Sub Create(ByVal Caption As String)
- ParentWindow = FindWindow(IIf(Application.Version < 9, "ThunderXFrame", "ThunderDFrame"), Caption)
- ParentClient = FindWindowEx(ParentWindow, 0, vbNullString, vbNullString)
- StatusBar = CreateWindowEx(0, STATUSCLASSNAME, vbNullString, WS_CHILD Or WS_VISIBLE Or SBARS_SIZEGRIP, 0, 0, 0, 0, ParentClient, 0, 0, ByVal 0)
- Split
- End Sub
- Sub Destroy()
- If StatusBar Then
- DestroyWindow StatusBar
- StatusBar = 0
- End If
- End Sub
- Sub Refresh()
- Split
- SendMessage StatusBar, WM_SIZE, 0, ByVal 0
- End Sub
- Sub Split()
- Dim Cret As RECT: GetClientRect ParentWindow, Cret
- Dim Part(2) As Long: Part(0) = 22: Part(1) = (3 / 4) * Cret.Right: Part(2) = -1
- SendMessage StatusBar, SB_SETPARTS, UBound(Part) + 1, ByVal VarPtr(Part(0))
- End Sub
- Property Let IsParentTrickFrame(ByVal Value As Boolean)
- If Value Then
- SetWindowLongPtr ParentWindow, GWL_STYLE, GetWindowLongPtr(ParentWindow, GWL_STYLE) Or WS_THICKFRAME Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX
- Else
- SetWindowLongPtr ParentWindow, GWL_STYLE, GetWindowLongPtr(ParentWindow, GWL_STYLE) And Not (WS_THICKFRAME Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX)
- End If
- End Property
- Property Get PartsCount() As Long
- PartsCount = CLng(SendMessage(StatusBar, SB_GETPARTS, 0, ByVal 0))
- End Property
- Property Get PartsRight() As String
- Dim Parts&, i&: ReDim Part(1 To 256) As Long
- Parts = CLng(SendMessage(StatusBar, SB_GETPARTS, 256, ByVal VarPtr(Part(1))))
- ReDim Preserve Part(1 To Parts) As Long
- PartsRight = Part(1)
- For i = 2 To Parts
- PartsRight = PartsRight & "," & Part(i)
- Next
- End Property
复制代码
2. 新建一个窗体,命名为UserForm1,添加以下代码
- Private StatusBar As New TheStatusBar
- Private Sub UserForm_Initialize()
- StatusBar.Create Me.Caption
- End Sub
- Private Sub UserForm_Terminate()
- StatusBar.Destroy
- Set StatusBar = Nothing
- End Sub
- Private Sub UserForm_Resize()
- StatusBar.Refresh
- End Sub
- Private Sub UserForm_Click()
- StatusBar.IsParentTrickFrame = True
- End Sub
- Private Sub UserForm_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
- If Button = 2 Then MsgBox "当前状态栏被拆分为" & StatusBar.PartsCount & "个部件,每个部件的右边缘位置为" & StatusBar.PartsRight, vbInformation + vbOKOnly, "LELEDY"
- End Sub
复制代码
接下来,大家就可以运行窗体代码了。你可以使用鼠标左键/右键单击窗体的空白区域,以触发不同的效果。左键之后可以使窗体支持大小调整功能,右键之后可以查看状态栏各个部件的信息。
第7期-创建有多个部分的状态栏.rar
(47.16 KB, 下载次数: 5)
以上就是本期的全部内容了,我们下期再见。
下期,晚间会带领大家实现状态栏最核心的功能——显示文本内容!
|
|