如何在 vb.net 中的表单上的任意位置检测鼠标单击?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37638463/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 19:55:28  来源:igfitidea点击:

How do I detect a mouse click anywhere on a form in vb.net?

vb.net

提问by Lachlan Court

Ok so I know how to check if the user has clicked on a specific object, however I really don't care if where the user clicks, I just need to know if they've clicked (Whether on the actual form or on an object or whatever). My code is this:

好的,所以我知道如何检查用户是否点击了特定对象,但是我真的不在乎用户是否点击了哪里,我只需要知道他们是否点击了(无论是在实际表单上还是在对象上管他呢)。我的代码是这样的:

Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

    If GetAsyncKeyState(1) Then
        Label1.Text = "Left"
    Else
        Label1.Text = "Right"
    End If
End Sub

When I run the code, I get an error:

当我运行代码时,出现错误:

PInvokeStackImbalance was detected

检测到 PInvokeStackImbalance

"A call to PInvoke function 'Mouse click!Mouse_click.Form1::GetAsyncKeyState' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature."

“对 PInvoke 函数 'Mouse click!Mouse_click.Form1::GetAsyncKeyState' 的调用使堆栈不平衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否匹配目标非托管签名。”

I'm very new to vb.net so the documentation really doesn't help me. Any help would be awesome :)

我对 vb.net 很陌生,所以文档真的对我没有帮助。任何帮助都是极好的 :)

采纳答案by Apachi

There are several ways really to do this and it depends on what exactly you are trying to accomplish. One way would be to have a specific place that you route all click events:

有几种方法可以真正做到这一点,这取决于您究竟要完成什么。一种方法是在一个特定的地方路由所有点击事件:

Public Sub ClickHandler(sender As Object, e As MouseEventArgs) Handles Me.MouseClick, PictureBox1.MouseClick, Label1.MouseClick, Button1.MouseClick
    Label1.Text = String.Format("Clicked ""{0}"" with the {1} mouse button.", sender.name, e.Button.ToString.ToLower)
End Sub

Notice all the Events that this Sub handles? And if you want to determine what button was pushed, you might be able to do something like this:

注意到这个 Sub 处理的所有事件了吗?如果您想确定按下了哪个按钮,您可以执行以下操作:

Select Case e.Button
    Case MouseButtons.Left
        Label1.Text = "Left"
    Case MouseButtons.Right
        Label1.Text = "Right"
    Case MouseButtons.Middle
        Label1.Text = "Middle"
    Case Else
        Label1.Text = "Some other button"
End Select

Again, this is just one way and not very practical for large apps full of controls or working across any application. Something like that would be more involved and might require a system wide hook.

同样,这只是一种方式,对于充满控件或跨任何应用程序工作的大型应用程序来说并不是很实用。类似的事情会更复杂,并且可能需要系统范围的钩子。

[EDIT]:
Along the lines of what Robin commented (excellent suggestion, by the way) is that you can alternatively add the handler in a separate line of code to avoid having to include every control up front. In fact, if you did follow this method, which I really like, you could do this with each control on the form with a loop:

[编辑]:
按照罗宾的评论(顺便说一句,很好的建议),您可以选择在单独的代码行中添加处理程序,以避免必须预先包含每个控件。事实上,如果你确实遵循了我非常喜欢的这个方法,你可以用一个循环对表单上的每个控件执行此操作:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    For Each c As Control In Controls
        AddHandler c.MouseClick, AddressOf ClickHandler
    Next
End Sub

Private Sub ClickHandler(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
    Label1.Text = String.Format("Clicked ""{0}"" with the {1} mouse button.", sender.name, e.Button.ToString.ToLower)

    Select Case e.Button
        Case MouseButtons.Left
            Label2.Text = "Left"
        Case MouseButtons.Right
            Label2.Text = "Right"
        Case MouseButtons.Middle
            Label2.Text = "Middle"
        Case Else
            Label2.Text = "Some other button"
    End Select
End Sub

Thanks for that, Robin! Completely escaped my mind...

谢谢你,罗宾!完全从我的脑海中消失了......