我正在做一个 VBA UserForm
(在 Excel
),它允许用户在表单中移动标签,并显示另一个表单(或一个 MessageBox
我前面会告诉你)。)
仅仅为了这个问题的目的,这里是我使用的表格。
如你所见 LABEL01
标签是唯一 control
的形式。
然后,我开始声明一些有用的变量。
Public DOWN As Boolean 'To check if the mouse is down
Public OFF_X As Single 'Horizontal offset of the pointer inside the label
Public OFF_Y As Single 'Vertical offset of the pointer inside the label
表单通过事件初始化。
Private Sub UserForm_Initialize()
LABEL01.MousePointer = 5 'Mouse pointer 5 - move
End Sub
为了移动标签,我使用了事件:
Private Sub LABEL01_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
DOWN = True: OFF_X = X: OFF_Y = Y
End Sub
Private Sub LABEL01_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If DOWN Then
LABEL01.Left = LABEL01.Left + X - OFF_X
LABEL01.Top = LABEL01.Top + Y - OFF_Y
End If
End Sub
Private Sub LABEL01_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
DOWN = False
End Sub
我使用事件来显示消息框。
Private Sub LABEL01_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
MsgBox "It's like I'm over it..."
End Sub
一切都很好,唯一的问题是,当我双击这个事件的时候 label
呼叫留言箱,我提高了。MouseDown
事件,并且,在关闭消息框后。MouseDown/MouseMove/MouseUp
链条保持不完整。
有什么办法可以解决这个问题?
在MsgBox之后,Userform似乎没有意识到它得到了焦点(而且鼠标现在在不同的位置)。我发现的唯一解决方法是模拟鼠标点击表单。这个点击应该发生在保存的位置,以防止任何不必要的动作(如点击按钮)。我发现的最佳位置是在表单本身的左上角。
要做到这一点,你首先需要一个模块(你不能把代码放入表单中)。
Public Type POINTAPI
X As Long
Y As Long
End Type
Public Declare Function GetCursorPos Lib "user32" (Point As POINTAPI) As Long
Public Declare Function SetCursorPos Lib "user32" (ByVal X As Integer, ByVal Y As Integer) As Long
Public Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, _
ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Public Const MOUSEEVENT_LEFTDOWN = &H2
Public Const MOUSEEVENT_LEFTUP = &H4
这个模块可以访问三个例程来获取和设置鼠标位置,并模拟鼠标事件。
现在,在窗体中放入一个模拟鼠标点击的Sub,在调用msgBox之后调用该例程。
Sub AdjustMouse()
Dim mousePos As POINTAPI
' Save current mouse pos
GetCursorPos mousePos
' "Move" the mouse to the top left corner of the form
SetCursorPos Me.Left + 1, Me.Top + 1
' Simulate a MouseClick so that form gets back the focus.
mouse_event MOUSEEVENT_LEFTDOWN, 0, 0, 0, 0
mouse_event MOUSEEVENT_LEFTUP, 0, 0, 0, 0
' "Move" the mouse back to the previous position
SetCursorPos mousePos.X, mousePos.Y
End Sub