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.
![zdarzenia klawiatury kody klawiszy visual studio c#](./g-VS/p7-1.png)
Krok 1. Układ komponentów
Na formatce umieścimy poniższe komponenty
- GroupBox- sztuk 3
- Label- sztuk 4
![keypress visual studio](./g-VS/p7-2.png)
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
![visual studio keypress](./g-VS/p7-3.png)
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
![void Form1_KeyDown(object sender, KeyEventArgs e)](./g-VS/p7-4.png)
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
![keyDown visual studio](./g-VS/p7-10.png)
Krok 4. Przechwytujemy zdarzenie zwolnienia dowolnego klawisza
Przechwycenie zdarzenia KeyUp zrealizujemy analogicznie jak KeyDown
![void Form1_KeyUp(object sender, KeyEventArgs e)](./g-VS/p7-5.png)
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
![Form1_KeyUp visual studio](./g-VS/p7-9.png)
Ć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)
![MessageBox.Show visual studio](./g-VS/p7-7.png)
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
![kod klawisza działani amatematyczne. Visual Studio C#](./g-VS/8-kod-klawisza-dzialania-matematyczne-1.webp)
Aktywność reakcji na zwolnienie klawisza funkcyjnego F1, F2 itd. zrealizujemy we wspólnym zdarzeniu zwolnieni klawisza KeyUp dla kontrolek TextBox przeznaczonych do wprowadzania danych
![kod klawisza działani amatematyczne KeyUp. Visual Studio C#](./g-VS/8-kod-klawisza-dzialania-matematyczne-3.webp)
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
![po zwolnieniu klawisza funkcyjnego F1, F2, F3, F4 wykona podstawowe działania matematyczne, Visual Studio C#](./g-VS/8-kod-klawisza-dzialania-matematyczne-4.webp)
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);
}
}
}