VB代码:让控件支持鼠标移入移出MouseOver事件
html中支持mouseover事件,但是vb中没有,很多时候我们迫切需要这样的功能,比如鼠标划过时,让picturebox改变背景图片,划出时再恢复。这里给出明晨网络的解决办法。这段代码比较啰嗦,有更好的思路烦请指点。
如果绑定一个无标题的Form对象的句柄,通过Resize和SetPointer方法,可以改变窗体大小及拖动窗体
使用方法如下:
-
'支持任何有句柄的控件,这里以名称为Pic_Skin_CMD_Close的Picturebox为例,别忘了在Form_Load中使用Set Mouse = New Cls_MouseOver来实例化
-
Private WithEvents Mouse As Cls_MouseOver
-
-
'在目标控件的MouseMove事件中绑定句柄
-
'如果有其他控件要支持Mouse_Over,也在MouseMove事件中绑定句柄,可以随时随意绑定N个句柄
-
Private Sub Pic_Skin_CMD_Close_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
-
Mouse.BindMouseOver Pic_Skin_CMD_Close.hWnd
-
End Sub
-
-
'========================================
-
'函数名称:Mouse_Over
-
'函数作用:鼠标滑过控件事件,FillwithPic是明晨网络Mingchennet.COM自定义的图片载入函数,可以注释掉换成自己的代码
-
'========================================
-
Private Sub Mouse_Over(ByVal hWnd As Long, ByVal Enter As Boolean)
-
Select Case hWnd
-
Case Pic_Skin_CMD_Close.hWnd
-
If Enter Then
-
FillwithPic Pic_Skin_CMD_Close, LoadPicture(Skin_Ctrl_Form_Close_Over)
-
Else
-
FillwithPic Pic_Skin_CMD_Close, LoadPicture(Skin_Ctrl_Form_Close)
-
End If
-
End Select
-
End Sub
Cls_MouseOver类模块,代码比较长
- Option Explicit
- Private WithEvents Timer As clsXTimer
- '========================================
- '声明作用:获取坐标
- '========================================
- 'Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
- 'Private Type POINTAPI
- ' X As Long
- ' Y As Long
- 'End Type
- 'Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
- 'Private Type RECT
- ' Left As Long
- ' Top As Long
- ' Right As Long
- ' Bottom As Long
- 'End Type
- Private Declare Function ReleaseCapture Lib "user32" () As Long
- Private Declare Function SetCapture Lib "user32" (ByVal hWnd As Long) 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 Const HTCAPTION = 2
- Private Const WM_NCLBUTTONDOWN = &HA1
- Private Const HTLEFT = 10
- Private Const HTRIGHT = 11
- Private Const HTTOP = 12
- Private Const HTTOPLEFT = 13
- Private Const HTTOPRIGHT = 14
- Private Const HTBOTTOM = 15
- Private Const HTBOTTOMLEFT = 16
- Private Const HTRIGHTBOTTOM = 17
- '所要执行的动作变量,是移动还是改变大小及从哪个方向改变大小
- Private Action As String
- '========================================
- '声明作用:获取坐标
- '========================================
- Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As Rect) As Long
- Private Type PointApi
- X As Long
- Y As Long
- End Type
- Private Declare Function GetCursorPos Lib "user32" (lpPoint As PointApi) As Long
- Private Type Rect
- Left As Long
- Top As Long
- Right As Long
- Bottom As Long
- End Type
- '========================================
- '声明作用:坐标快照
- '========================================
- Private Type StationCapture
- hWnd As Long '句柄
- In As Boolean '鼠标是否在窗体上面
- End Type
- '========================================
- '声明作用:鼠标趋势
- '========================================
- Private Type MouseDirect
- hWnd As Long '句柄
- Moved As Boolean '是否运动
- Enter As Boolean '是否进入,否则为退出
- End Type
- Private CurrenHWnd As Long
- '========================================
- '声明作用:鼠标滑过事件
- '========================================
- Public Event Over(ByVal hWnd As Long, ByVal Enter As Boolean)
- '========================================
- '函数名称:Resize
- '函数作用:改变有句柄的目标窗体的大小
- '========================================
- Public Sub Resize(ByVal hWnd As Long)
- '为当前的应用程序释放鼠标捕获
- ReleaseCapture
- Select Case Action
- Case "Left"
- SendMessage hWnd, WM_NCLBUTTONDOWN, HTLEFT, 0
- Case "Right"
- SendMessage hWnd, WM_NCLBUTTONDOWN, HTRIGHT, 0
- Case "Up"
- SendMessage hWnd, WM_NCLBUTTONDOWN, HTTOP, 0
- Case "LeftUp"
- SendMessage hWnd, WM_NCLBUTTONDOWN, HTTOPLEFT, 0
- Case "RightUp"
- SendMessage hWnd, WM_NCLBUTTONDOWN, HTTOPRIGHT, 0
- Case "Down"
- SendMessage hWnd, WM_NCLBUTTONDOWN, HTBOTTOM, 0
- Case "LeftDown"
- SendMessage hWnd, WM_NCLBUTTONDOWN, HTBOTTOMLEFT, 0
- Case "RightDown"
- SendMessage hWnd, WM_NCLBUTTONDOWN, HTRIGHTBOTTOM, 0
- Case "Move"
- SendMessage hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0
- End Select
- End Sub
- '========================================
- '函数名称:SetPointer
- '函数作用:设置鼠标指针样式
- '========================================
- Public Sub SetPointer(ByVal hWnd As Long)
- Dim MyRect As Rect
- Dim MyPoint As PointApi
- ' MyRect返回当前窗口位置
- Call GetWindowRect(hWnd, MyRect)
- ' MyPoint返回当前鼠标位置
- Call GetCursorPos(MyPoint)
- Select Case True
- '鼠标位于窗体左上方
- Case MyPoint.X < MyRect.Left + 5 And MyPoint.Y < MyRect.Top + 5
- Screen.MousePointer = vbSizeNWSE
- Action = "LeftUp"
- '鼠标位于窗体右下方
- Case MyPoint.X > MyRect.Right - 5 And MyPoint.Y > MyRect.Bottom - 5
- Screen.MousePointer = vbSizeNWSE
- Action = "RightDown"
- '鼠标位于窗体右上方
- Case MyPoint.X > MyRect.Right - 5 And MyPoint.Y < MyRect.Top + 5
- '45度双向鼠标指针
- Screen.MousePointer = vbSizeNESW
- Action = "RightUp"
- '鼠标位于窗体左下方
- Case MyPoint.X < MyRect.Left + 5 And MyPoint.Y > MyRect.Bottom - 5
- Screen.MousePointer = vbSizeNESW
- Action = "LeftDown"
- '鼠标位于窗体左边
- Case MyPoint.X < MyRect.Left + 5
- '水平双向鼠标指针
- Screen.MousePointer = vbSizeWE
- Action = "Left"
- '鼠标位于窗体右边
- Case MyPoint.X > MyRect.Right - 5
- Screen.MousePointer = vbSizeWE
- Action = "Right"
- '鼠标位于窗体上方
- Case MyPoint.Y < MyRect.Top + 5
- '垂直双向鼠标指针
- Screen.MousePointer = vbSizeNS
- Action = "Up"
- '鼠标位于窗体下方
- Case MyPoint.Y > MyRect.Bottom - 5
- Screen.MousePointer = vbSizeNS
- Action = "Down"
- '鼠标位于窗体顶部以下,移动区以上
- Case MyPoint.Y > MyRect.Top + 5 And MyPoint.Y <= MyRect.Top + 20
- '默认鼠标指针
- Screen.MousePointer = 0
- Action = "Move"
- '鼠标位于窗体其他位置
- Case Else
- Screen.MousePointer = 0
- Action = ""
- End Select
- End Sub
- '========================================
- '函数名称:SetSC
- '函数作用:建立坐标快照
- '========================================
- Private Function SetSC(ByVal hWnd As Long) As StationCapture
- Dim tPoint As PointApi
- Dim tRect As Rect
- GetCursorPos tPoint
- GetWindowRect hWnd, tRect
- SetSC.hWnd = hWnd
- If tRect.Left < tPoint.X And tPoint.X < tRect.Right And tRect.Top < tPoint.Y And tPoint.Y < tRect.Bottom Then
- SetSC.In = True
- Else
- SetSC.In = False
- End If
- End Function
- '========================================
- '函数名称:CreateEvent
- '函数作用:事件通知,该事件需要被触发,一般通过50ms的定时器来实现
- '========================================
- Public Sub CreateEvent()
- '建立坐标快照
- Dim SC As StationCapture
- Static LastSC As StationCapture
- SC = SetSC(CurrenHWnd)
- '如果是同一个控件,则判断鼠标移动是否超出控件范围
- If SC.hWnd = LastSC.hWnd Then
- If SC.In And LastSC.In = False Then
- RaiseEvent Over(CurrenHWnd, True)
- ElseIf SC.In = False And LastSC.In Then
- RaiseEvent Over(CurrenHWnd, False)
- End If
- Else
- If SC.In Then
- If LastSC.hWnd <> 0 Then
- '从其他控件退出,进入到当前控件
- RaiseEvent Over(LastSC.hWnd, False)
- RaiseEvent Over(CurrenHWnd, True)
- Else
- '从未知控件(空白区)进入
- RaiseEvent Over(CurrenHWnd, True)
- End If
- End If
- End If
- LastSC = SC
- End Sub
- '========================================
- '函数名称:BindMouseOver
- '函数作用:设置要监控的控件句柄
- '========================================
- Public Sub BindMouseOver(ByVal hWnd As Long)
- CurrenHWnd = hWnd
- End Sub
- Private Sub Class_Initialize()
- '这个类模块定时器用来监视鼠标轨迹,如果使用VB自带的TIMER控件来计时,可以注释本过程
- Set Timer = New clsXTimer
- Timer.Interval = 50
- Timer.Enabled = True
- End Sub
- Private Sub Class_Terminate()
- '这个类模块定时器用来监视鼠标轨迹,如果使用VB自带的TIMER控件来计时,可以注释本过程
- Timer.Enabled = False
- Set Timer = Nothing
- End Sub
- '这个类模块定时器用来监视鼠标轨迹,如果使用VB自带的TIMER控件来计时,可以注释本过程
- '通过窗体的TIMER控件,间隔50ms来执行CreateEvent也可以
- Private Sub Timer_Tick()
- CreateEvent
- End Sub
文章源自:明晨网络,admin,《VB代码:让控件支持鼠标移入移出MouseOver事件》,http://www.mingchennet.com/tec/code/vb/31.htm
- 上一篇:VB代码:可在非窗体模块中使用的定时器
- 下一篇:让VBS支持WithEvents