Как изменить ввод с клавиатуры в стандартный элемент управления
Windows Forms предоставляет возможность использовать и изменять ввод клавиатуры. Поглощение ключа относится к его обработке в методе или обработчике событий, чтобы другие методы и события ниже по очереди сообщений не получали значение ключа. Изменение ключа относится к изменению значения ключа, чтобы методы и обработчики событий дальше вниз очереди сообщений получали другое значение ключа. В этом разделе показано, как выполнить эти задачи.
Использование ключа
В обработчике событий KeyPress задайте для свойства Handled класса KeyPressEventArgs значение
true
.-или-
В обработчике событий KeyDown задайте для свойства Handled класса KeyEventArgs значение
true
.Заметка
Установка свойства Handled в обработчике событий KeyDown не препятствует вызову KeyPress и KeyUp событий для текущего нажатия клавиш. Используйте свойство SuppressKeyPress для этой цели.
В следующем примере приведен фрагмент инструкции
switch
, которая проверяет свойство KeyChar объекта KeyPressEventArgs, полученное обработчиком события KeyPress. Этот код использует ключи символов "A" и "a".// Consume 'A' and 'a'. case (char)65: case (char)97: MessageBox.Show("Control.KeyPress: '" + e.KeyChar.ToString() + "' consumed."); e.Handled = true; break;
' Consume 'A' and 'a'. Case ChrW(65), ChrW(97) MessageBox.Show(("Control.KeyPress: '" + _ e.KeyChar.ToString() + "' consumed.")) e.Handled = True
Изменение стандартного ключа символа
В обработчике событий KeyPress задайте для свойства KeyChar класса KeyPressEventArgs значение нового символьного ключа.
В следующем примере показан фрагмент из оператора
switch
, который изменяет значение "B" на "A" и "b" на "a". Обратите внимание, что свойство Handled параметра KeyPressEventArgs имеет значение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;
' 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
Изменение несимвольной клавиши
Переопределите метод 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 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 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
Пример
Следующий пример кода — это полное приложение для примеров кода в предыдущих разделах. Приложение использует пользовательский элемент управления, производный от класса TextBox, для обработки и изменения ввода с клавиатуры.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace KeyboardInput
{
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;
}
}
}
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);
}
}
}
Imports System.Drawing
Imports System.Security
Imports System.Security.Permissions
Imports System.Windows.Forms
Namespace KeyboardInput
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
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
Компиляция кода
Для этого примера требуется:
- Ссылки на сборки System, System.Drawing и System.Windows.Forms.
См. также
- Ввод с клавиатуры в приложениях Windows Forms
- Ввод данных пользователем в приложения Windows Forms
- Как работает ввод клавиатуры
.NET Desktop feedback