添加表单按钮可防止发送WM_KEYDOWN消息

时间:2013-02-01 01:17:26

标签: vb.net winforms wndproc windows-messages

以下代码有效,当用户按下键盘上的某个键时,将打印到Label1:

Public Class Form1

Sub New()

    InitializeComponent()

End Sub

Public Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal HWND As IntPtr, ByVal WMSG As Integer, ByVal WPARAM As Integer, ByVal LPARAM As IntPtr) As IntPtr

Private WM_KEYDOWN As Integer = &H100

Protected Overrides Sub WndProc(ByRef WindowsMessage As Message)

    Select Case WindowsMessage.Msg

        Case WM_KEYDOWN

            Dim VirtualKeyCode As Integer = CType(WindowsMessage.WParam, Integer)

            Select Case (VirtualKeyCode)

                Case Keys.A
                    Label1.Text = "The a key was pressed"

            End Select

    End Select

    MyBase.WndProc(WindowsMessage)

End Sub

结束班

将代码添加(拖动)到表单后代码停止工作。一旦按钮在表单上,​​就不再发送WM_KEYDOWN消息。在案例WM_KEYDOWN中设置的断点永远不会被命中。

如果我删除该按钮,代码将重新开始工作。

有什么建议吗?

感谢。

1 个答案:

答案 0 :(得分:0)

键盘消息将发布到具有焦点的窗口。只要您的表单没有任何子控件,表单就会在激活时获得焦点。虽然它不是很擅长处理焦点,但它没有任何方法表明它具有焦点,例如它本身没有用于击键。

只要您将控件放在 的表单上,就像获得焦点一样,那就会发生变化。像一个按钮。现在控件总是得到焦点,你不能把它还给表单。因此,表单停止接收WM_KEYDOWN消息,而是转到Button。

有一种方法可以让表单响应击键,如果它们是快捷键,它们就很重要。就像F1应该显示帮助一样,无论控件有什么重点。在Winforms中有内置支持,您可以覆盖ProcessCmdKey()方法。像这样:

Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
    If keyData = Keys.Control Or Keys.A Then
        MessageBox.Show("yada")
        Return True
    End If
    Return MyBase.ProcessCmdKey(msg, keyData)
End Function

将其粘贴到表单的代码中,然后按Ctrl + A进行测试。