Практическое руководство. Изменение ввода с клавиатуры в стандартном элементе управления
Формы Windows Forms предоставляют возможность получать и изменять вводимые с клавиатуры данные. Получением клавиши называется обработка клавиши внутри метода или обработчика событий таким образом, чтобы следующие методы и события в очереди сообщений не получали значение этой клавиши. Изменением клавиши называется изменение значения клавиши таким образом, чтобы следующие методы и обработчики событий в очереди сообщений получали другое значение клавиши. В этом разделе показано, как выполнять эти задачи.
Получение клавиши
В обработчике событий KeyPress установите для свойства Handled класса KeyPressEventArgs значение
true
.-или-
В обработчике событий KeyDown установите для свойства Handled класса KeyEventArgs значение
true
.Note
Установка свойства 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;
Изменение стандартной символьной клавиши
В обработчике событий 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;
Изменение клавиши, не связанной со знаком
Переопределите метод 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); }
Пример
В примере ниже полностью представлено приложение для примеров кода из предыдущих разделов. Для получения и изменения вводимых с клавиатуры данных в приложении используется пользовательский элемент управления, производный от класса TextBox.
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#, см. в разделе построение из командной строки или командной строки создания с помощью csc.exe. Можно также сборке этого примера в Visual Studio путем вставки кода в новый проект.