0

以下代码有效,并在用户按下键盘上的 a 键时打印到 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 消息。在 Case WM_KEYDOWN 处设置的断点永远不会被命中。

如果我删除按钮,代码将再次开始工作。

有什么建议么?

谢谢。

4

1 回答 1

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 对其进行测试。

于 2013-02-01T01:46:27.550 回答