2017-08-04 54 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