Przechwytywanie zdarzeń klawiatury. Kody klawiszy edycyjnych i funkcyjnych
Zdarzenia pochodzące od klawiatury, które możemy przechwycić w dowolnej aplikacji związane są z wciśnięciem dowolnego klawisza, klawisza edycyjnego i zwolnienie dowolnego klawisza. Znajomość kodu używanego klawisza pozwala programowo ubogacić komunikację użytkownika z działającym programem. Na przykład reakcja na klawisze funkcyjne F1, F2...itp.
Zdarzenia wysyłane przez klawiaturę obsługiwane są poprzez komunikaty KeyDown, KeyPress, KeyUP. Komunikaty wysyłane są w wyżej podanej kolejności. Każdy z klawiszy ma swój przypisany kod, na przykład klawisz Esc ma kod 27. Klawisz A jako klawisz edycyjny ma znaczenie "A", jego kod ASCII to 65. Gdy traktujemy go jako "a", to kod ASCII wynosi 97
Cel: Napisz aplikację, która zwróci informację o naciśnięciu dowolnego klawisza, klawisza edycyjnego i zwolnieniu dowolnego klawisza.
Krok 1. Układ komponentów
Na formatce umieścimy poniższe komponenty
- GroupBox- sztuk 3
- Label- sztuk 4
Komponenty GroupBox posłużą nam w celach estetycznych, zaś komponenty typu Label będą wyświetlać przechwycone komunikaty pochodzące od klawiatury
Krok 2. Przechwytujemy komunikat wciśnięcia klawisza edycyjnego
Klawisze znajdujące sie na klawiaturze podzielone są na klawisze funkcyjne i klawisze edycyjne. Klawisze edycyjne to klawisze alfanumeryczne. Każdy z klawiszy edycyjnych ma przypisany znak kodu ASCII. Wartość tę oraz pozycję (indeks) w zbiorze znaków możemy odczytać. Umiejętność ta może być przydatna w wielu poważniejszych projektach.
Przechwycenie zdarzenia KeyPress (jak i pozostałych) zrealizujemy dla całej tworzonej formatki aplikacji, czyli w klasie Form oprogramujemy zdarzenie KeyPress- musimy odczytać odpowiednie właściwości zwracane przez argument e klasy KeyPressEventArgs
Ciało funkcji Form1_KeyPress wypełnimy poniższym kodem
Wskazówka:
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
label1.Text = "Naciśnięto klawisz edycyjny: "
+ e.KeyChar + ". Pozycja znaku ASCII: "
+ Convert.ToInt16(e.KeyChar) ;
}
Po skompilowaniu projektu powinniśmy zarejestrować wciśnięcie klawisza edycyjnego. Patrz poniższa ilustracja
Krok 3. Przechwytujemy zdarzenie wciśnięcia dowolnego klawisza
Przechwycenie zdarzenia KeyDown zrealizujemy analogicznie jak KeyPress z tą różnicą, że będziemy odczytywać odpowiednie właściwości parametru e, ale z klasy KeyEventArgs
Ciało funkcji Form1_KeyDown wypełnimy poniższym kodem
Wskazówka:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
label2.Text = "Naciśnięto klawisz: "
+ e.KeyValue.ToString() +" Jego znaczenie: "
+ e.KeyCode.ToString();
}
Po kompilacji projektu powinniśmy zarejestrować wciśniecie dowolnego klawisza, w tym klawiszy funkcyjnych
Krok 4. Przechwytujemy zdarzenie zwolnienia dowolnego klawisza
Przechwycenie zdarzenia KeyUp zrealizujemy analogicznie jak KeyDown
Ciało funkcji Form1_KeyUp wypełnimy poniższym kodem
Wskazówka:
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
label3.Text = "Zwolniono klawisz: "
+ e.KeyValue.ToString()
+ " Jego znaczenie: "
+ e.KeyCode.ToString();
}
Po kompilacji projektu powinniśmy zarejestrować zwolnienie dowolnego klawisza
Ćwiczenie sprawdzające
Zmodyfikuj aplikacje tak, aby można było ją zamknąć po wciśnięciu klawisza Esc z zabezpieczeniem poprzez wyborem opcji zamykania umieszczonej w oknie dialogowym (patrz poniższa ilustracja)
W przypadku braku pomysłu możesz skorzystać z poniższego kodu
Wskazówka:
if (e.KeyValue == 27) {
DialogResult wynik = MessageBox.Show(
"Czy zamknąć aplikację?",
"Komunikat",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (wynik == DialogResult.Yes)
this.Close();
else return;
}
Pełny kod utworzonej aplikacji
Wskazówka:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace kodKlawisza
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
label1.Text = "Naciśnięto klawisz edycyjny: "
+ e.KeyChar + ". Pozycja znaku ASCII: "
+ Convert.ToInt16(e.KeyChar) ;
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
label2.Text = "Naciśnięto klawisz: "
+ e.KeyValue.ToString() +" Jego znaczenie: "
+ e.KeyCode.ToString();
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
label3.Text = "Zwolniono klawisz: "
+ e.KeyValue.ToString()
+ " Jego znaczenie: "
+ e.KeyCode.ToString();
if (e.KeyValue == 27) {
DialogResult wynik = MessageBox.Show(
"Czy zamknąć aplikację?",
"Komunikat",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (wynik == DialogResult.Yes)
this.Close();
else return;
}
}
}
}
Ćwiczenie 2:
Napisz aplikację przy pomocy, której po zwolnieniu klawisza funkcyjnego F1, F2, F3, F4 wykona podstawowe działania matematyczne na dwóch dowolnych liczbach rzeczywistych.
Proponowany układ kontrolek
Aktywność reakcji na zwolnienie klawisza funkcyjnego F1, F2 itd. zrealizujemy we wspólnym zdarzeniu zwolnieni klawisza KeyUp dla kontrolek TextBox przeznaczonych do wprowadzania danych
W zdarzeniu KeyUp musimy wprowadzić zabezpieczenie przed wykonaniem konwersji zamiany typu String na float gdy wartość pola Text jest pusta. Proponowane rozwiązanie nie zawiera zabezpieczenia przed dzieleniem przez zero.
Wskazówka:
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if(textBox1.Text.Length<1 || textBox2.Text.Length<1)return;
float a = (float)Convert.ToDouble(textBox1.Text),
b = (float)Convert.ToDouble(textBox2.Text),
w = 0;
switch (e.KeyValue)
{
//F1
case 112: w = a + b; break;
//F2
case 113: w = a - b; break;
//F3
case 114: w = a * b; break;
//F4
case 115: w = a / b; break;
//ESC
case 27: this.Close(); break;
default: return;
}
MessageBox.Show("w = " + w.ToString("F2"),
"Komunikat",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
Skompiluj program i sprawdź efekt działania. Poniżej wykonanie odejmowania po wybraniu klawisza F2
Pełny kod rozwiązania
Wskazówka:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _8kodKlawiszaDzialanieMatematyczne
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void textBox1_Enter(object sender, EventArgs e)
{
//przechwyć obiekt
TextBox tb =sender as TextBox;
//sprzwdź czy pole Text przechwyconej kontrolki TextBox
//nie jest puste
if(!string.IsNullOrEmpty(tb.Text) )
{
//nie jest puste to na czas skupienia
//aktywności podświetl na zółto
tb.ForeColor = Color.Black;
tb.BackColor = Color.Yellow;
tb.Select(tb.Text.Length, 0);
}
}
private void textBox1_Leave(object sender, EventArgs e)
{
//przechwyć obiekt
TextBox tb = sender as TextBox;
//na koniec skupienia aktywności
//przywróć poprzedni ekolory
tb.ForeColor = Color.Black;
tb.BackColor = Color.White;
tb.Select(0, 0);
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if(textBox1.Text.Length<1 || textBox2.Text.Length<1)return;
float a = (float)Convert.ToDouble(textBox1.Text),
b = (float)Convert.ToDouble(textBox2.Text),
w = 0;
switch (e.KeyValue)
{
//F1
case 112: w = a + b; break;
//F2
case 113: w = a - b; break;
//F3
case 114: w = a * b; break;
//F4
case 115: w = a / b; break;
//ESC
case 27: this.Close(); break;
default: return;
}
MessageBox.Show("w = " + w.ToString("F2"),
"Komunikat",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
}
}