Поделиться через


Практическое руководство. Изменение ввода с клавиатуры в стандартном элементе управления

Обновлен: Ноябрь 2007

Windows Forms предоставляет возможность получать и изменять ввод данных с клавиатуры. Получением клавиши называется обработка клавиши внутри метода или обработчика событий таким образом, чтобы другие методы и события в очереди сообщений не получали значение этой клавиши. Изменением клавиши называется изменение значения клавиши таким образом, чтобы следующие методы и обработчики событий очереди сообщений получали другое значение клавиши. В этом разделе показано, как выполнять эти задачи.

Для получения клавиши, выполните следующие действия.

  • В обработчике события KeyPress установите для свойства Handled класса KeyPressEventArgs значение true.

    -или-

    В обработчике события KeyDown установите для свойства Handled класса KeyEventArgs значение true.

    ms171537.alert_note(ru-ru,VS.90).gifПримечание.

    Установка свойства Handled в обработчике события KeyDown не препятствует возникновению событий KeyPressKeyUp для текущей клавиши. Для этой цели используется свойство SuppressKeyPress.

    Следующий пример является фрагментом кода оператора switch, который проверяет свойство KeyChar класса KeyPressEventArgs, полученное обработчиком события KeyPress. Этот код получает клавиши со знаками "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 задайте свойству KeyChar класса KeyPressEventArgs значение новой клавиши знака.

    Следующий пример является фрагментом кода оператора switch, изменяющего клавиши "B" на "A" и "b" на "a". Следует отметить, что для свойства Handled параметра KeyPressEventArgs установлено значение 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;
    

Чтобы изменить клавишу, не связанную со знаком, выполните следующие действия.

  • Переопределите метод Control, который обрабатывает сообщения Windows, найдите сообщение WM_KEYDOWN или WM_SYSKEYDOWN и установите для свойства WParam параметра Message значение Keys, представляющее новую клавишу, не связанную со знаком.

    В следующем примере кода демонстрируется, как переопределить метод PreProcessMessage элемента управления для обнаружения клавиш с F1 по F9 и изменения клавиши F3 на F1. Дополнительные сведения о методах Control, которые можно переопределить для перехвата сообщений клавиатуры, см. в разделах Ввод данных пользователем в приложении Windows Forms и Принцип работы ввод с клавиатуры.

    ' 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 путем вставки кода в новый проект. Дополнительные сведения см. в разделах Практическое руководство. Компиляция и выполнение откомпилированного примера кода формы Windows Forms с помощью Visual Studio и Практическое руководство. Компиляция и выполнение откомпилированного примера кода формы Windows Forms с помощью Visual Studio и Практическое руководство. Компиляция и выполнение откомпилированного примера кода формы Windows Forms с помощью Visual Studio.

См. также

Основные понятия

Ввод данных пользователем в приложении Windows Forms

Принцип работы ввод с клавиатуры

Другие ресурсы

Ввод с клавиатуры в приложении Windows Forms