|
|
先看代码
'==================================================================================================
' 鼠标类
'==================================================================================================
Option Explicit
Implements DirectXEvent8
Private Const W_BUFFER_SIZE = 2
Private w_Devices As DirectInputDevice8
Private w_EventHandle As Long
Private w_hDeviceWindow As Long
Private w_MouseData(1 To W_BUFFER_SIZE) As DIDEVICEOBJECTDATA
Private w_NumItems As Byte
Private w_DoubleClickTime As Long
Private w_LastClickTime(12 To 19) As Long
Private w_clientRect As RECT
Private w_clientRectWidth As Long
Private w_clientRectHeight As Long
'******************************************************************************************
' 捕捉区域
'
Public Property Get rectX() As Long
rectX = w_clientRect.Left
End Property
Public Property Let rectX(newRectX As Long)
w_clientRect.Left = newRectX
End Property
Public Property Get rectY() As Long
rectY = w_clientRect.Top
End Property
Public Property Let rectY(newRectY As Long)
w_clientRect.Top = newRectY
End Property
Public Property Get rectWidth() As Long
rectWidth = w_clientRectWidth
End Property
Public Property Let rectWidth(newRectWidth As Long)
w_clientRectWidth = newRectWidth
w_clientRect.Right = w_clientRect.Left + newRectWidth
End Property
Public Property Get rectHeight() As Long
rectHeight = w_clientRectHeight
End Property
Public Property Let rectHeight(newRectHeight As Long)
w_clientRectHeight = newRectHeight
w_clientRect.bottom = w_clientRect.Top + newRectHeight
End Property
Public Property Get clientRect() As RECT
clientRect = w_clientRect
End Property
Public Property Let clientRect(newRect As RECT)
w_clientRect = newRect
End Property
'******************************************************************************************
' 初始化鼠标程序 initMouse()
'
' DevicehWnd 窗体句柄
'
'使用DirectMouse会隐藏鼠标指针
Public Function initMouse(DevicehWnd As Long) As Boolean
Set w_Devices = WDInput.CreateDevice("guid_SysMouse")
w_Devices.SetCommonDataFormat DIFORMAT_MOUSE '3键3轴鼠标
On Error GoTo invalidhWnd
w_Devices.SetCooperativeLevel DevicehWnd, DISCL_BACKGROUND Or DISCL_NONEXCLUSIVE 'DISCL_FOREGROUND Or DISCL_EXCLUSIVE
w_hDeviceWindow = DevicehWnd
'指定w_Devices取得消息
w_EventHandle = WDDX.CreateEvent(Me)
w_Devices.SetEventNotification w_EventHandle
Dim diProp As DIPROPLONG
diProp.lHow = DIPH_DEVICE
diProp.lObj = 0
diProp.lData = W_BUFFER_SIZE 'W_BUFFER_SIZE为局部常量
w_Devices.SetProperty "DIPROP_BUFFERSIZE", diProp
w_Devices.Acquire
'先定捕捉区域
Dim clientRect As RECT
GetClientRect w_hDeviceWindow, w_clientRect
w_DoubleClickTime = GetDoubleClickTime
initMouse = True
Exit Function
invalidhWnd:
initMouse = False
End Function
Private Sub DirectXEvent8_DXCallback(ByVal eventid As Long)
If w_Devices Is Nothing Then Exit Sub
On Error Resume Next
w_NumItems = w_Devices.GetDeviceData(w_MouseData, 0)
If Err.Number = DIERR_NOTACQUIRED Or Err.Number = DIERR_INPUTLOST Then
'Dim CursorPoint As POINTAPI
' Move private cursor to system cursor.
'Call GetCursorPos(CursorPoint) ' Get position before Windows loses cursor
'Call ScreenToClient(w_hDeviceWindow, CursorPoint)
w_Devices.Acquire
Exit Sub
End If
'Debug.Print w_clientRect.Top & " " & w_clientRect.bottom
Dim tmpX As Long, tmpY As Long
Dim CursorPoint As POINTAPI
GetCursorPos CursorPoint
ScreenToClient w_hDeviceWindow, CursorPoint
tmpX = CursorPoint.X
tmpY = CursorPoint.Y
If tmpX >= w_clientRect.Left And tmpX <= w_clientRect.Right And _
tmpY >= w_clientRect.Top And tmpY <= w_clientRect.bottom Then
Dim i As Byte
Dim mdd As WD_ENUM_INPUT_MESSAGE
For i = 1 To w_NumItems
mdd = w_MouseData(i).lOfs
Select Case mdd
' 同时加入鼠标的相对位置和绝对位置消息
' WD_MOUSE_X (WD_MOUSE_Y) 标签为鼠标移动的相对位置
' WD_MOUSE_POSITION_X (WD_MOUSE_POSITION_Y) 标签为鼠标的绝对位置
Case WD_MOUSE_X
queueUpMsg WD_INPUT_DEVICES_MOUSE, mdd, CInt(w_MouseData(i).lData)
queueUpMsg WD_INPUT_DEVICES_MOUSE, WD_MOUSE_POSITION_X, CLng(tmpX)
Case WD_MOUSE_Y
queueUpMsg WD_INPUT_DEVICES_MOUSE, mdd, CInt(w_MouseData(i).lData)
queueUpMsg WD_INPUT_DEVICES_MOUSE, WD_MOUSE_POSITION_Y, CLng(tmpY)
'滚轮的位移
Case WD_MOUSE_Z
queueUpMsg WD_INPUT_DEVICES_MOUSE, mdd, CInt(w_MouseData(i).lData)
'按键状态设定
' -1 按下
' 0 释放
' 2 双击
Case 12 To 19
Dim buttonsState As Boolean
buttonsState = CBool(w_MouseData(i).lData)
queueUpMsg WD_INPUT_DEVICES_MOUSE, mdd, CInt(buttonsState)
'双击按键消息
If buttonsState Then
Dim subtractTime As Long
subtractTime = GetTickCount - w_LastClickTime(mdd)
If subtractTime <= w_DoubleClickTime Then
queueUpMsg WD_INPUT_DEVICES_MOUSE, mdd, 2
End If
w_LastClickTime(mdd) = GetTickCount
End If
Case Else
queueUpMsg WD_INPUT_DEVICES_MOUSE, w_MouseData(i).lOfs, CInt(w_MouseData(i).lData)
End Select
Next
End If
End Sub
Private Sub Class_Terminate()
On Error Resume Next
If w_EventHandle <> 0 Then WDDX.DestroyEvent w_EventHandle
If Not w_Devices Is Nothing Then w_Devices.Unacquire
Set w_Devices = Nothing
End Sub
此类不能由用户创建,只能让另一个类创建并收集消息(就是输入设备管理类),但测试中发现,管理类执行Set Nothing后,此鼠标类的Terminate事件没有触发,到底是什么原因?请指教 |
|