Input Keyboard (Mulai menggunakan Win32 dan C++)
Keyboard digunakan untuk beberapa jenis input yang berbeda, termasuk:
- Input karakter. Teks yang diurutkan pengguna ke dalam dokumen atau kotak edit.
- Pintasan keyboard. Goresan kunci yang memanggil fungsi aplikasi; misalnya, CTRL + O untuk membuka file.
- Perintah sistem. Goresan kunci yang memanggil fungsi sistem; misalnya, ALT + TAB untuk beralih jendela.
Ketika memikirkan input keyboard, penting untuk diingat bahwa goresan kunci tidak sama dengan karakter. Misalnya, menekan tombol A dapat menghasilkan salah satu karakter berikut.
- a
- A
- á (jika keyboard mendukung penggandaan diakritik)
Selanjutnya, jika tombol ALT ditahan, menekan tombol A menghasilkan ALT+A, yang tidak diperlakukan sistem sebagai karakter sama sekali, melainkan sebagai perintah sistem.
Kode Kunci
Saat Anda menekan tombol, perangkat keras menghasilkan kode pemindaian. Kode pemindaian bervariasi dari satu keyboard ke keyboard berikutnya, dan ada kode pemindaian terpisah untuk peristiwa key-up dan key-down. Anda hampir tidak akan pernah peduli tentang kode pemindaian. Driver keyboard menerjemahkan kode pemindaian ke dalam kode kunci virtual. Kode kunci virtual tidak bergantung pada perangkat. Menekan tombol A pada keyboard apa pun menghasilkan kode kunci virtual yang sama.
Secara umum, kode kunci virtual tidak sesuai dengan kode ASCII atau standar pengodean karakter lainnya. Ini jelas jika Anda memikirkannya, karena kunci yang sama dapat menghasilkan karakter yang berbeda (a, A, á), dan beberapa kunci, seperti kunci fungsi, tidak sesuai dengan karakter apa pun.
Meskipun demikian, kode kunci virtual berikut memetakan ke setara ASCII:
- Kunci 0 hingga 9 = ASCII '0' – '9' (0x30 – 0x39)
- Kunci A hingga Z = ASCII 'A' – 'Z' (0x41 – 0x5A)
Dalam beberapa hal pemetaan ini sangat disayangkan, karena Anda tidak boleh menganggap kode kunci virtual sebagai karakter, karena alasan yang dibahas.
File header WinUser.h mendefinisikan konstanta untuk sebagian besar kode kunci virtual. Misalnya, kode kunci virtual untuk kunci LEFT ARROW VK_LEFT (0x25). Untuk daftar lengkap kode kunci virtual, lihat Kode Kunci Virtual. Tidak ada konstanta yang didefinisikan untuk kode kunci virtual yang cocok dengan nilai ASCII. Misalnya, kode kunci virtual untuk kunci A 0x41, tetapi tidak ada konstanta bernama VK_A. Sebagai gantinya, cukup gunakan nilai numerik.
pesan Key-Down dan Key-Up
Saat Anda menekan tombol, jendela yang memiliki fokus keyboard menerima salah satu pesan berikut.
Pesan WM_SYSKEYDOWN menunjukkan kunci sistem, yang merupakan goresan kunci yang memanggil perintah sistem. Ada dua jenis kunci sistem:
- ALT + kunci apa pun
- F10
Kunci F10 mengaktifkan bilah menu jendela. Berbagai kombinasi alt-key memanggil perintah sistem. Misalnya, ALT + TAB beralih ke jendela baru. Selain itu, jika jendela memiliki menu, kunci ALT dapat digunakan untuk mengaktifkan item menu. Beberapa kombinasi kunci ALT tidak melakukan apa pun.
Semua goresan kunci lainnya dianggap sebagai kunci nonsstem dan menghasilkan pesan WM_KEYDOWN . Ini termasuk kunci fungsi selain F10.
Saat Anda merilis kunci, sistem mengirim pesan kunci-up yang sesuai:
Jika Anda menahan tombol cukup lama untuk memulai fitur pengulangan keyboard, sistem akan mengirim beberapa pesan key-down, diikuti dengan satu pesan key-up.
Di keempat pesan keyboard yang dibahas sejauh ini, parameter wParam berisi kode kunci virtual kunci. Parameter lParam berisi beberapa informasi lain-lain yang dikemas ke dalam 32 bit. Anda biasanya tidak memerlukan informasi di lParam. Satu bendera yang mungkin berguna adalah bit 30, bendera "status kunci sebelumnya", yang diatur ke 1 untuk pesan kunci-turun berulang.
Seperti namanya, goresan kunci sistem terutama ditujukan untuk digunakan oleh sistem operasi. Jika Anda mencegat pesan WM_SYSKEYDOWN , hubungi DefWindowProc setelahnya. Jika tidak, Anda akan memblokir sistem operasi untuk menangani perintah.
Pesan Karakter
Goresan kunci dikonversi menjadi karakter oleh fungsi TranslateMessage , yang pertama kali kita lihat di Modul 1. Fungsi ini memeriksa pesan key-down dan menerjemahkannya ke dalam karakter. Untuk setiap karakter yang diproduksi, fungsi TranslateMessage menempatkan pesan WM_CHAR atau WM_SYSCHAR pada antrean pesan jendela. Parameter wParam pesan berisi karakter UTF-16.
Seperti yang mungkin Anda duga, pesan WM_CHAR dihasilkan dari pesan WM_KEYDOWN , sementara pesan WM_SYSCHAR dihasilkan dari pesan WM_SYSKEYDOWN . Misalnya, pengguna menekan tombol SHIFT diikuti dengan tombol A. Dengan asumsi tata letak keyboard standar, Anda akan mendapatkan urutan pesan berikut:
WM_KEYDOWN: SHIFT
WM_KEYDOWN: A
WM_CHAR: 'A'
Di sisi lain, kombinasi ALT + P akan menghasilkan:
WM_SYSKEYDOWN: VK_MENU
WM_SYSKEYDOWN: 0x50
WM_SYSCHAR: 'p'
WM_SYSKEYUP: 0x50
WM_KEYUP: VK_MENU
(Kode kunci virtual untuk kunci ALT diberi nama VK_MENU karena alasan historis.)
Pesan WM_SYSCHAR menunjukkan karakter sistem. Seperti halnya WM_SYSKEYDOWN, Anda umumnya harus meneruskan pesan ini langsung ke DefWindowProc. Jika tidak, Anda dapat mengganggu perintah sistem standar. Secara khusus, jangan perlakukan WM_SYSCHAR sebagai teks yang telah ditik pengguna.
Pesan WM_CHAR adalah apa yang biasanya Anda anggap sebagai input karakter. Jenis data untuk karakter wchar_t, mewakili karakter Unicode UTF-16. Input karakter dapat mencakup karakter di luar rentang ASCII, terutama dengan tata letak keyboard yang umumnya digunakan di luar Amerika Serikat. Anda dapat mencoba tata letak keyboard yang berbeda dengan menginstal keyboard regional lalu menggunakan fitur Keyboard Di Layar.
Pengguna juga dapat menginstal Editor Metode Input (IME) untuk memasukkan skrip kompleks, seperti karakter Jepang, dengan keyboard standar. Misalnya, menggunakan IME Jepang untuk memasukkan karakter katakana カ (ka), Anda mungkin mendapatkan pesan berikut:
WM_KEYDOWN: VK_PROCESSKEY (kunci PROSES IME)
WM_KEYUP: 0x4B
WM_KEYDOWN: VK_PROCESSKEY
WM_KEYUP: 0x41
WM_KEYDOWN: VK_PROCESSKEY
WM_CHAR: カ
WM_KEYUP: VK_RETURN
Beberapa kombinasi tombol CTRL diterjemahkan ke dalam karakter kontrol ASCII. Misalnya, CTRL+A diterjemahkan ke karakter ASCII ctrl-A (SOH) (nilai ASCII 0x01). Untuk input teks, Anda umumnya harus memfilter karakter kontrol. Selain itu, hindari menggunakan WM_CHAR untuk mengimplementasikan pintasan keyboard. Sebagai gantinya, gunakan pesan WM_KEYDOWN ; atau lebih baik lagi, gunakan tabel akselerator. Tabel Akselerator dijelaskan dalam topik berikutnya, Tabel Akselerator.
Kode berikut menampilkan pesan keyboard utama di debugger. Coba mainkan dengan kombinasi penekanan tombol yang berbeda dan lihat pesan apa yang dihasilkan.
Catatan
Pastikan untuk menyertakan wchar.h atau swprintf_s tidak akan terdefinisi.
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
wchar_t msg[32];
switch (uMsg)
{
case WM_SYSKEYDOWN:
swprintf_s(msg, L"WM_SYSKEYDOWN: 0x%x\n", wParam);
OutputDebugString(msg);
break;
case WM_SYSCHAR:
swprintf_s(msg, L"WM_SYSCHAR: %c\n", (wchar_t)wParam);
OutputDebugString(msg);
break;
case WM_SYSKEYUP:
swprintf_s(msg, L"WM_SYSKEYUP: 0x%x\n", wParam);
OutputDebugString(msg);
break;
case WM_KEYDOWN:
swprintf_s(msg, L"WM_KEYDOWN: 0x%x\n", wParam);
OutputDebugString(msg);
break;
case WM_KEYUP:
swprintf_s(msg, L"WM_KEYUP: 0x%x\n", wParam);
OutputDebugString(msg);
break;
case WM_CHAR:
swprintf_s(msg, L"WM_CHAR: %c\n", (wchar_t)wParam);
OutputDebugString(msg);
break;
/* Handle other messages (not shown) */
}
return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}
Pesan Keyboard Lain-lain
Beberapa pesan keyboard lainnya dapat diabaikan dengan aman oleh sebagian besar aplikasi.
- Pesan WM_DEADCHAR dikirim untuk kunci gabungan, seperti diakritik. Misalnya, pada keyboard bahasa Spanyol, aksen pengetikan (') diikuti oleh E menghasilkan karakter é. WM_DEADCHAR dikirim untuk karakter aksen.
- Pesan WM_UNICHAR usang. Ini memungkinkan program ANSI untuk menerima input karakter Unicode.
- Karakter WM_IME_CHAR dikirim ketika IME menerjemahkan urutan penekanan tombol ke dalam karakter. Ini dikirim selain pesan WM_CHAR biasa.
Status Keyboard
Pesan keyboard digerakkan oleh peristiwa. Artinya, Anda mendapatkan pesan ketika sesuatu yang menarik terjadi, seperti tekan tombol, dan pesan memberi tahu Anda apa yang baru saja terjadi. Tetapi Anda juga dapat menguji status kunci kapan saja, dengan memanggil fungsi GetKeyState .
Misalnya, pertimbangkan bagaimana Anda akan mendeteksi kombinasi klik mouse kiri + tombol ALT. Anda dapat melacak status kunci ALT dengan mendengarkan pesan key-stroke dan menyimpan bendera, tetapi GetKeyState menghemat masalah Anda. Saat Anda menerima pesan WM_LBUTTONDOWN , cukup panggil GetKeyState sebagai berikut:
if (GetKeyState(VK_MENU) & 0x8000)
{
// ALT key is down.
}
Pesan GetKeyState mengambil kode kunci virtual sebagai input dan mengembalikan sekumpulan bendera bit (sebenarnya hanya dua bendera). Nilai 0x8000 berisi bendera bit yang menguji apakah tombol saat ini ditekan.
Sebagian besar keyboard memiliki dua tombol ALT, kiri dan kanan. Contoh sebelumnya menguji apakah salah satu dari mereka ditekan. Anda juga dapat menggunakan GetKeyState untuk membedakan antara instans kiri dan kanan tombol ALT, SHIFT, atau CTRL. Misalnya, kode berikut menguji apakah tombol ALT yang tepat ditekan.
if (GetKeyState(VK_RMENU) & 0x8000)
{
// Right ALT key is down.
}
Fungsi GetKeyState menarik karena melaporkan status keyboard virtual . Status virtual ini didasarkan pada konten antrean pesan Anda, dan diperbarui saat Anda menghapus pesan dari antrean. Saat program Anda memproses pesan jendela, GetKeyState memberi Anda rekam jepret keyboard pada saat setiap pesan diantrekan. Misalnya, jika pesan terakhir pada antrean WM_LBUTTONDOWN, GetKeyState melaporkan status keyboard saat ini ketika pengguna mengklik tombol mouse.
Karena GetKeyState didasarkan pada antrean pesan Anda, GetKeyState juga mengabaikan input keyboard yang dikirim ke program lain. Jika pengguna beralih ke program lain, tombol apa pun menekan yang dikirim ke program tersebut diabaikan oleh GetKeyState. Jika Anda benar-benar ingin mengetahui status fisik keyboard langsung, ada fungsi untuk itu: GetAsyncKeyState. Namun, untuk sebagian besar kode UI, fungsi yang benar adalah GetKeyState.
Berikutnya