Windows 窗体提供了使用和修改键盘输入的功能。 使用键是指在方法或事件处理程序中对键进行处理,以便消息队列中随后的其他方法和事件不会收到键值。 修改键是指修改键值,以便消息队列中随后的方法和事件处理程序收到另一个键值。 本主题显示如何完成这些任务。
使用键
- 在 KeyPress 事件处理程序中,将 KeyPressEventArgs 类的 Handled 属性设置为 true。 - - 或 - - 在 KeyDown 事件处理程序中,将 KeyEventArgs 类的 Handled 属性设置为 true。 - 提示 - 如果在 KeyDown 事件处理程序中设置 Handled 属性,将不会阻止对当前按键引发 KeyPress 和 KeyUp 事件。 请将 SuppressKeyPress 属性用于此目的。 - 下面的示例摘录自 switch 语句,该语句检查 KeyPress 事件处理程序所收到的 KeyPressEventArgs 的 KeyChar 属性。 此代码使用“A”和“a”字符键。 - ' Consume 'A' and 'a'. Case ChrW(65), ChrW(97) MessageBox.Show(("Control.KeyPress: '" + _ e.KeyChar.ToString() + "' consumed.")) e.Handled = True- // Consume 'A' and 'a'. case (char)65: case (char)97: MessageBox.Show("Control.KeyPress: '" + e.KeyChar.ToString() + "' consumed."); e.Handled = true; break;
修改标准字符键
- 在 KeyPress 事件处理程序中,将 KeyPressEventArgs 类的 KeyChar 属性设置为新字符键的值。 - 下面的示例摘录自 switch 语句,该语句将“B”修改为“A”,并将“b”修改为“a”。 注意,KeyPressEventArgs 的 Handled 属性设置为 false,以便将新的键值传播到消息队列中的其他方法和事件。 - ' Modify 'B' to 'A' and forward the key. Case ChrW(66) MessageBox.Show(("Control.KeyPress: '" + _ e.KeyChar.ToString() + "' replaced by 'A'.")) e.KeyChar = ChrW(65) e.Handled = False ' Modify 'b' to 'a' and forward the key. Case ChrW(98) MessageBox.Show(("Control.KeyPress: '" + _ e.KeyChar.ToString() + "' replaced by 'a'.")) e.KeyChar = ChrW(97) e.Handled = False- // Detect 'B', modify it to 'A', and forward the key. case (char)66: MessageBox.Show("Control.KeyPress: '" + e.KeyChar.ToString() + "' replaced by 'A'."); e.KeyChar = (char)65; e.Handled = false; break; // Detect 'b', modify it to 'a', and forward the key. case (char)98: MessageBox.Show("Control.KeyPress: '" + e.KeyChar.ToString() + "' replaced by 'a'."); e.KeyChar = (char)97; e.Handled = false; break;
修改非字符键
- 重写用于处理 Windows 消息的 Control 方法,并检测 WM_KEYDOWN 或 WM_SYSKEYDOWN 消息,然后将 Message 参数的 WParam 属性设置为表示新的非字符键的 Keys 值。 - 下面的代码示例演示如何重写控件的 PreProcessMessage 方法,以检测键 F1 到 F9,并将任何 F3 键修改为按 F1 键。 有关可以重写以截获键盘消息的 Control 方法的更多信息,请参见 Windows 窗体应用程序中的用户输入 和 键盘输入工作原理。 - ' Detect F1 through F9 during preprocessing and modify F3. Public Overrides Function PreProcessMessage(ByRef m As Message) _ As Boolean If m.Msg = WM_KEYDOWN Then Dim keyCode As Keys = CType(m.WParam, Keys) And Keys.KeyCode ' Detect F1 through F9. Select Case keyCode Case Keys.F1, Keys.F2, Keys.F3, Keys.F4, Keys.F5, _ Keys.F6, Keys.F7, Keys.F8, Keys.F9 MessageBox.Show(("Control.PreProcessMessage: '" + _ keyCode.ToString() + "' pressed.")) ' Replace F3 with F1, so that ProcessKeyMessage will ' receive F1 instead of F3. If keyCode = Keys.F3 Then m.WParam = CType(Keys.F1, IntPtr) MessageBox.Show(("Control.PreProcessMessage: '" + _ keyCode.ToString() + "' replaced by F1.")) End If End Select End If ' Send all other messages to the base method. Return MyBase.PreProcessMessage(m) End Function- // Detect F1 through F9 during preprocessing and modify F3. public override bool PreProcessMessage(ref Message m) { if (m.Msg == WM_KEYDOWN) { Keys keyCode = (Keys)m.WParam & Keys.KeyCode; // Detect F1 through F9. switch (keyCode) { case Keys.F1: case Keys.F2: case Keys.F3: case Keys.F4: case Keys.F5: case Keys.F6: case Keys.F7: case Keys.F8: case Keys.F9: MessageBox.Show("Control.PreProcessMessage: '" + keyCode.ToString() + "' pressed."); // Replace F3 with F1, so that ProcessKeyMessage will // receive F1 instead of F3. if (keyCode == Keys.F3) { m.WParam = (IntPtr)Keys.F1; MessageBox.Show("Control.PreProcessMessage: '" + keyCode.ToString() + "' replaced by F1."); } break; } } // Send all other messages to the base method. return base.PreProcessMessage(ref m); }
示例
下面的代码示例是上述各节中的全部代码示例应用程序。 应用程序使用从 TextBox 类派生的自定义控件来使用和修改键盘输入。
Imports System
Imports System.Drawing
Imports System.Security
Imports System.Security.Permissions
Imports System.Windows.Forms
Namespace KeyboardInput
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _ 
    Class Form1
        Inherits Form
        ' The following Windows message value is defined in Winuser.h.
        Private WM_KEYDOWN As Integer = &H100
        Private WithEvents CustomTextBox1 As New CustomTextBox()
        <STAThread()> _
        Public Shared Sub Main()
            Application.EnableVisualStyles()
            Application.Run(New Form1())
        End Sub
        Public Sub New()
            Me.AutoSize = True
            Me.Controls.Add(CustomTextBox1)
        End Sub
        ' Consume and modify several character keys.
        Sub CustomTextBox1_KeyPress(ByVal sender As Object, _
            ByVal e As KeyPressEventArgs) Handles CustomTextBox1.KeyPress
            Select Case e.KeyChar
                ' Consume 'A' and 'a'.
                Case ChrW(65), ChrW(97)
                    MessageBox.Show(("Control.KeyPress: '" + _
                        e.KeyChar.ToString() + "' consumed."))
                    e.Handled = True
                    ' Modify 'B' to 'A' and forward the key.
                Case ChrW(66)
                    MessageBox.Show(("Control.KeyPress: '" + _
                        e.KeyChar.ToString() + "' replaced by 'A'."))
                    e.KeyChar = ChrW(65)
                    e.Handled = False
                    ' Modify 'b' to 'a' and forward the key.
                Case ChrW(98)
                    MessageBox.Show(("Control.KeyPress: '" + _
                        e.KeyChar.ToString() + "' replaced by 'a'."))
                    e.KeyChar = ChrW(97)
                    e.Handled = False
            End Select
        End Sub
    End Class
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _ 
    Public Class CustomTextBox
        Inherits TextBox
        ' The following Windows message value is defined in Winuser.h.
        Private WM_KEYDOWN As Integer = &H100
        Public Sub New()
            Me.Size = New Size(100, 100)
            Me.AutoSize = False
        End Sub
        ' Detect F1 through F9 during preprocessing and modify F3.
        Public Overrides Function PreProcessMessage(ByRef m As Message) _
            As Boolean
            If m.Msg = WM_KEYDOWN Then
                Dim keyCode As Keys = CType(m.WParam, Keys) And Keys.KeyCode
                ' Detect F1 through F9.
                Select Case keyCode
                    Case Keys.F1, Keys.F2, Keys.F3, Keys.F4, Keys.F5, _
                         Keys.F6, Keys.F7, Keys.F8, Keys.F9
                        MessageBox.Show(("Control.PreProcessMessage: '" + _
                            keyCode.ToString() + "' pressed."))
                        ' Replace F3 with F1, so that ProcessKeyMessage will  
                        ' receive F1 instead of F3.
                        If keyCode = Keys.F3 Then
                            m.WParam = CType(Keys.F1, IntPtr)
                            MessageBox.Show(("Control.PreProcessMessage: '" + _
                                keyCode.ToString() + "' replaced by F1."))
                        End If
                End Select
            End If
            ' Send all other messages to the base method.
            Return MyBase.PreProcessMessage(m)
        End Function
        ' Detect F1 through F9 during processing.
        Protected Overrides Function ProcessKeyMessage(ByRef m As Message) _
            As Boolean
            If m.Msg = WM_KEYDOWN Then
                Dim keyCode As Keys = CType(m.WParam, Keys) And Keys.KeyCode
                ' Detect F1 through F9.
                Select Case keyCode
                    Case Keys.F1, Keys.F2, Keys.F3, Keys.F4, Keys.F5, _
                         Keys.F6, Keys.F7, Keys.F8, Keys.F9
                        MessageBox.Show(("Control.ProcessKeyMessage: '" + _
                            keyCode.ToString() + "' pressed."))
                End Select
            End If
            ' Send all messages to the base method.
            Return MyBase.ProcessKeyMessage(m)
        End Function
    End Class
End Namespace
using System;
using System.Drawing;
using System.Windows.Forms;
namespace KeyboardInput
{
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
    class Form1 : Form
    {
        // The following Windows message value is defined in Winuser.h.
        private int WM_KEYDOWN = 0x100;
        CustomTextBox CustomTextBox1 = new CustomTextBox();
        [STAThread]
        public static void Main()
        {
            Application.EnableVisualStyles();
            Application.Run(new Form1());
        }
        public Form1()
        {
            this.AutoSize = true;
            this.Controls.Add(CustomTextBox1);
            CustomTextBox1.KeyPress +=
                new KeyPressEventHandler(CustomTextBox1_KeyPress);
        }
        // Consume and modify several character keys.
        void CustomTextBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            switch (e.KeyChar)
            {
                // Consume 'A' and 'a'.
                case (char)65:
                case (char)97:
                    MessageBox.Show("Control.KeyPress: '" +
                        e.KeyChar.ToString() + "' consumed.");
                    e.Handled = true;
                    break;
                // Detect 'B', modify it to 'A', and forward the key.
                case (char)66:
                    MessageBox.Show("Control.KeyPress: '" +
                        e.KeyChar.ToString() + "' replaced by 'A'.");
                    e.KeyChar = (char)65;
                    e.Handled = false;
                    break;
                // Detect 'b', modify it to 'a', and forward the key.
                case (char)98:
                    MessageBox.Show("Control.KeyPress: '" +
                        e.KeyChar.ToString() + "' replaced by 'a'.");
                    e.KeyChar = (char)97;
                    e.Handled = false;
                    break;
            }
        }
    }
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
    public class CustomTextBox : TextBox
    {
        // The following Windows message value is defined in Winuser.h.
        private int WM_KEYDOWN = 0x100;
        public CustomTextBox()
        {
            this.Size = new Size(100, 100);
            this.AutoSize = false;
        }
        // Detect F1 through F9 during preprocessing and modify F3.
        public override bool PreProcessMessage(ref Message m)
        {
            if (m.Msg == WM_KEYDOWN)
            {
                Keys keyCode = (Keys)m.WParam & Keys.KeyCode;
                // Detect F1 through F9.
                switch (keyCode)
                {
                    case Keys.F1:
                    case Keys.F2:
                    case Keys.F3:
                    case Keys.F4:
                    case Keys.F5:
                    case Keys.F6:
                    case Keys.F7:
                    case Keys.F8:
                    case Keys.F9:
                        MessageBox.Show("Control.PreProcessMessage: '" +
                          keyCode.ToString() + "' pressed.");
                        // Replace F3 with F1, so that ProcessKeyMessage will  
                        // receive F1 instead of F3.
                        if (keyCode == Keys.F3)
                        {
                            m.WParam = (IntPtr)Keys.F1;
                            MessageBox.Show("Control.PreProcessMessage: '" +
                                keyCode.ToString() + "' replaced by F1.");
                        }
                        break;
                }
            }
            // Send all other messages to the base method.
            return base.PreProcessMessage(ref m);
        }
        // Detect F1 through F9 during processing.
        protected override bool ProcessKeyMessage(ref Message m)
        {
            if (m.Msg == WM_KEYDOWN)
            {
                Keys keyCode = (Keys)m.WParam & Keys.KeyCode;
                // Detect F1 through F9.
                switch (keyCode)
                {
                    case Keys.F1:
                    case Keys.F2:
                    case Keys.F3:
                    case Keys.F4:
                    case Keys.F5:
                    case Keys.F6:
                    case Keys.F7:
                    case Keys.F8:
                    case Keys.F9:
                        MessageBox.Show("Control.ProcessKeyMessage: '" +
                          keyCode.ToString() + "' pressed.");
                        break;
                }
            }
            // Send all messages to the base method.
            return base.ProcessKeyMessage(ref m);
        }
    }
}
编译代码
此示例需要:
- 对 System、System.Drawing 和 System.Windows.Forms 程序集的引用。
有关从 Visual Basic 或 Visual C# 的命令行生成此示例的信息,请参见从命令行生成 (Visual Basic) 或在命令行上使用 csc.exe 生成。 也可以通过将代码粘贴到新项目,在 Visual Studio 中生成此示例。 有关更多信息,请参见 如何:使用 Visual Studio 编译和运行完整的 Windows 窗体代码示例 和 如何:使用 Visual Studio 编译和运行完整的 Windows 窗体代码示例 和 如何:使用 Visual Studio 编译和运行完整的 Windows 窗体代码示例 和 如何:使用 Visual Studio 编译和运行完整的 Windows 窗体代码示例 和 如何:使用 Visual Studio 编译和运行完整的 Windows 窗体代码示例.