2017-08-04 138 views
1

在我的应用程序中发生了一些奇怪的事情,我无法弄清楚它是什么。我试图模拟鼠标单击并以编程方式滚动。鼠标事件轮子最后发生

我可以成功执行鼠标单击并以编程方式滚动,但问题在于鼠标滚轮最后发生。

这是代码:

<DllImport("user32.dll", EntryPoint:="mouse_event")> 
    Private Shared Sub mouse_event(ByVal dwFlags As UInteger, ByVal dx As 
    Integer, ByVal dy As Integer, ByVal dwData As Integer, ByVal dwExtraInfo 
    As UInteger) 
End Sub 

标志:

Const MOUSEEVENTF_LEFTDOWN As UInteger = &H2 '0x0002' 
Const MOUSEEVENTF_LEFTUP As UInteger = &H4 '0x0004' 
Const MOUSEEVENTF_WHEEL As UInteger = &H800 
Const MOUSEEVENTF_XDOWN As UInteger = &H80 


Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click 

    scroll_to_end() 
    Thread.Sleep(300) 
    click_perf() 

    MessageBox.Show("S") 
End Sub 
Private Sub scroll_to_end() 
    'Focus panel1' 

    c_point = New Point(Panel1.Location.X + 1, Panel1.Location.Y + 1) 
    Cursor.Position = Me.PointToScreen(c_point) 
    mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) 
    mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) 
    'Wait' 
    Thread.Sleep(150) 

    'Scroll to the end of the page' 
    Dim scroll_down As Integer = -(10 * 120) 'Perform 10 scrolls down' 
    mouse_event(MOUSEEVENTF_WHEEL, 0, 0, scroll_down, 0) 

    'This is the fix:' 
    Application.DoEvents() 
End Sub 
Private Sub click_perf() 
    'Move mouse diagonally 200px' 

    c_point.X += 200 
    c_point.Y += 200 
    Cursor.Position = Me.PointToScreen(c_point) 

    'Perform click' 
    mouse_event(MOUSEEVENTF_LEFTDOWN, c_point.X, c_point.Y, 0, 0) 
    mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) 
End Sub 

当我点击按钮3,我想集中PANEL1然后滚动至年底,并移动鼠标200像素对角线向下,然后模拟点击。

究竟发生了什么:鼠标移动到panel1,模拟鼠标按钮和鼠标按钮。然后,它将对角线移动鼠标200px并显示消息框。滚动甚至没有发生,现在当我关闭消息框面板1可能失去焦点并且不滚动。

如果我删除messagebox.show(“”):鼠标移动到panel1并将其聚焦,就像上面一样。它滚动到最后,但它在向下滚动之前执行点击。

编辑: 要解决这个问题,我们需要把Application.DoEvents()滚轮鼠标事件之后。

+0

如果你把'Application.DoEvents()'每个步骤后? – djv

+0

@djv就是这样。非常感谢你!你可以发布这个答案,也许提供更多的信息? – lowarago

+0

'MessageBox'不是一个调试工具;它更不适合调试事件流程 – Plutonix

回答

1

将这个每个UI操作后,迫使它为了

Application.DoEvents() 

UI事件的处理message loop,它看起来在消息队列,并处理它们发生。不能保证,如果它们在代码中同时引发,那么它们将按照它们引发的顺序进行处理,因为代码比循环更快。 Application.DoEvents()将停止您的代码执行并强制循环处理所有未决消息,从而使它们按顺序发生。

但是,由于广泛的误用,通常认为使用这种方法的做法很差。我认为你的情况很好,也许是我见过的唯一。

我很想看看是否有人能提供最佳的替代...

+0

感谢您与我们分享!这很有帮助! – lowarago