Sdílet prostřednictvím


Zadávání pomocí klávesnice (Začínáme s Win32 a C++)

Klávesnice se používá pro několik různých typů vstupu, mezi které patří:

  • Znakový vstup Text, který uživatel zadá do dokumentu nebo textového pole
  • Klávesové zkratky. Klíčové tahy, které volají aplikační funkce; Například CTRL +O pro otevření souboru.
  • Systémové příkazy. Klíčové tahy, které volají systémové funkce; Například ALT+TAB pro přepínání oken.

Při úvahách o vstupu klávesnice je důležité si uvědomit, že tah kláves není stejný jako znak. Například stisknutí klávesy A může mít za následek některý z následujících znaků.

  • a
  • A
  • á (pokud klávesnice podporuje kombinování diakritiky)

Dále platí, že pokud je stisknutá klávesa ALT, stisknutí klávesy A vytvoří alt+A, které systém vůbec nezachází jako se znakem, ale spíše jako systémový příkaz.

Kódy klíčů

Když stisknete klávesu, hardware vygeneruje scan kód. Kódy skenování se liší mezi klávesnicemi a existují samostatné kódy pro stisknutí a uvolnění kláves. Téměř nikdy vás nebudou zajímat skenovací kódy. Ovladač klávesnice převádí skanovací kódy do virtuálních kódů kláves. Kódy virtuálních klíčů jsou nezávislé na zařízení. Stisknutím klávesy A na libovolné klávesnici vygenerujete stejný kód virtuální klávesy.

Obecně platí, že kódy virtuálních klíčů neodpovídají kódům ASCII ani žádnému jinému standardu kódování znaků. To je zřejmé, pokud si o tom myslíte, protože stejný klíč může generovat různé znaky (a, A, á) a některé klíče, jako jsou funkční klávesy, neodpovídají žádnému znaku.

To znamená, že následující kódy virtuálních klíčů se mapují na ekvivalenty ASCII:

  • Klíče 0 až 9 = ASCII '0' – '9' (0x30 – 0x39)
  • A až Z klíče = ASCII 'A' – 'Z' (0x41 – 0x5A)

V některých ohledech je toto mapování nešťastné, protože byste nikdy neměli myslet na kódy virtuálních klíčů jako znaky z důvodů probíraných.

Soubor hlaviček WinUser.h definuje konstanty pro většinu kódů virtuálních klíčů. Například kód virtuálního klíče pro klávesu ŠIPKA VLEVO je VK_LEFT (0x25). Úplný seznam kódů virtuálních klíčů najdete v části Virtual-Key Kódy. Pro kódy virtuálních klíčů, které odpovídají hodnotám ASCII, nejsou definovány žádné konstanty. Například kód virtuálního klíče pro klíč A je 0x41, ale neexistuje žádná konstanta pojmenovaná VK_A. Místo toho použijte číselnou hodnotu.

zprávy Key-Down a Key-Up

Když stisknete klávesu, okno s fokusem klávesnice dostane jednu z následujících zpráv.

Zpráva WM_SYSKEYDOWN označuje systémový klíč, což je tah klávesy, který vyvolá systémový příkaz. Existují dva typy systémového klíče:

  • ALT + libovolná klávesa
  • F10

Klávesa F10 aktivuje nabídkovou lištu okna. Různé kombinace kláves ALT vyvolávají systémové příkazy. Alt + TAB se například přepne do nového okna. Pokud má okno nabídku, můžete k aktivaci položek nabídky použít klávesu ALT. Některé kombinace kláves ALT nic nedělá.

Všechny ostatní tahy kláves jsou považovány za nesystémové klávesy a vytvářejí WM_KEYDOWN zprávu. To zahrnuje jiné funkční klávesy než F10.

Když uvolníte klávesu, systém odešle odpovídající zprávu o uvolnění klávesy.

Pokud podržíte klávesu dostatečně dlouho, aby se spustila funkce opakování klávesnice, systém odešle několik zpráv o stisknutí klávesy, za kterými následuje jedna zpráva o uvolnění klávesy.

Ve všech čtyřech dosud probíraných zprávách klávesnice parametr wParam obsahuje kód virtuálního klíče. Parametr lParam obsahuje různé informace zabalené do 32 bitů. Obvykle nepotřebujete informace v lParam. Jeden užitečný příznak je bit 30, příznak "předchozí stav klávesy", který je nastaven na 1 pro opakované zprávy o stisknuté klávese.

Jak název napovídá, systémové tahy kláves jsou primárně určeny pro použití operačním systémem. Pokud zachytíte WM_SYSKEYDOWN zprávu, zavolejte DefWindowProc poté. Jinak zablokujete zpracování příkazu operačním systémem.

Zprávy postav

Stisky kláves se převedou na znaky funkcí TranslateMessage, kterou jsme poprvé viděli v Modulu 1. Tato funkce prozkoumá zprávy stisků kláves a přeloží je do znaků. Pro každý vyprodukovaný znak umístí funkce TranslateMessage zprávu WM_CHAR nebo WM_SYSCHAR do fronty zpráv okna. Parametr wParam zprávy obsahuje znak UTF-16.

Jak můžete uhodnout, WM_CHAR zprávy se generují z WM_KEYDOWN zpráv, zatímco WM_SYSCHAR zprávy se generují ze zpráv WM_SYSKEYDOWN. Předpokládejme například, že uživatel stiskne klávesu SHIFT následovanou klávesou A. Za předpokladu standardního rozložení klávesnice byste získali následující posloupnost zpráv:

WM_KEYDOWN: SHIFT
WM_KEYDOWN: A
WM_CHAR: "A"

Na druhé straně by kombinace ALT + P vygenerovala:

WM_SYSKEYDOWN: VK_MENU
WM_SYSKEYDOWN: 0x50
WM_SYSCHAR: "p"
WM_SYSKEYUP: 0x50
WM_KEYUP: VK_MENU

(Kód virtuálního klíče pro klávesu ALT má název VK_MENU z historických důvodů.)

Zpráva WM_SYSCHAR označuje systémový znak. Stejně jako u WM_SYSKEYDOWNbyste měli tuto zprávu obecně předat přímo do DefWindowProc. Jinak můžete kolidovat se standardními systémovými příkazy. Zejména nezacházejte s WM_SYSCHAR jako s textem, který uživatel zadal.

Zpráva WM_CHAR je to, co normálně považujete za zadávání znaků. Datový typ znaku je wchar_t, představující znak UTF-16 Unicode. Zadávání znaků může obsahovat znaky mimo rozsah ASCII, zejména u rozložení klávesnice, která se běžně používají mimo USA. Různá rozložení klávesnice můžete vyzkoušet tak, že nainstalujete místní klávesnici a pak použijete funkci Klávesnice na obrazovce.

Uživatelé mohou také nainstalovat editor IME (Input Method Editor) pro zadávání složitých skriptů, jako jsou japonské znaky, se standardní klávesnicí. Například zadáním znaku katakana カ (ka) pomocí japonského editoru IME můžete získat následující zprávy:

WM_KEYDOWN: VK_PROCESSKEY (klíč procesu IME)
WM_KEYUP: 0x4B
WM_KEYDOWN: VK_PROCESSKEY
WM_KEYUP: 0x41
WM_KEYDOWN: VK_PROCESSKEY
WM_CHAR: カ
WM_KEYUP: VK_RETURN

Některé kombinace kláves CTRL se překládají na řídicí znaky ASCII. Například ctrl+A se přeloží na znak ASCII ctrl-A (SOH) (hodnota ASCII 0x01). U textového zadání byste měli obecně vyfiltrovat řídicí znaky. Vyhněte se také použití WM_CHAR k implementaci klávesových zkratek. Místo toho používejte WM_KEYDOWN zprávy; nebo ještě lépe, použijte tabulku akcelerátorů. Tabulky akcelerátorů jsou popsány v dalším tématu Tabulky akcelerátoru.

Následující kód zobrazí hlavní zprávy klávesnice v ladicím programu. Zkuste hrát s různými kombinacemi stisknutí kláves a podívejte se, jaké zprávy se generují.

Poznámka

Nezapomeňte zahrnout wchar.h nebo jinak swprintf_s nebude definován.

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);
}

Různé zprávy klávesnice

Většina aplikací může bezpečně ignorovat některé další zprávy klávesnice.

  • Zpráva WM_DEADCHAR se odešle pro kombinační klíč, například diakritiku. Například na španělské klávesnici stisknutím znak (') následovaným písmenem E vznikne písmeno é. Příkaz WM_DEADCHAR je odeslán pro akcentový znak.
  • Zpráva WM_UNICHAR je zastaralá. Umožňuje programům ANSI přijímat vstup znaků Unicode.
  • Znak WM_IME_CHAR se odešle, když editor IME přeloží sekvenci stisknutí kláves na znaky. Odesílá se navíc k obvyklé zprávě WM_CHAR.

Stav klávesnice

Zprávy klávesnice jsou řízené událostmi. To znamená, že dostanete zprávu, když se stane něco zajímavého, například stisknutí klávesy, a zpráva vám řekne, co se právě stalo. Stav klíče ale můžete kdykoli otestovat také voláním funkce GetKeyState.

Představte si například, jak byste zjistili kombinaci levého kliknutí myší + ALT. Stav klávesy ALT můžete sledovat nasloucháním zpráv tahů klávesami a uložením příznaku, ale GetKeyState vám potíže ušetří. Když se zobrazí zpráva WM_LBUTTONDOWN, stačí zavolat GetKeyState následujícím způsobem:

if (GetKeyState(VK_MENU) & 0x8000)
{
    // ALT key is down.
}

Zpráva GetKeyState přebírá jako vstup kód virtuálního klíče a vrací sadu bitových příznaků (ve skutečnosti jen dva příznaky). Hodnota 0x8000 obsahuje bitový příznak, který testuje, zda je klávesa aktuálně stisknuta.

Většina klávesnic má dvě klávesy ALT, vlevo a vpravo. Předchozí příklad testuje, zda byl některý z těchto dvou stisknut. K rozlišení mezi instancemi kláves ALT, SHIFT nebo CTRL můžete také použít GetKeyState. Například následující kód testuje, pokud je stisknuta pravá klávesa ALT.

if (GetKeyState(VK_RMENU) & 0x8000)
{
    // Right ALT key is down.
}

FunkceGetKeyStateje zajímavá, protože hlásí virtuální stav klávesnice. Tento virtuální stav je založený na obsahu fronty zpráv a při odebírání zpráv z fronty se aktualizuje. Když program zpracovává zprávy oken, GetKeyState poskytuje snímek klávesnice v době, kdy byla každá zpráva zařazena do fronty. Pokud byla například poslední zpráva ve frontě WM_LBUTTONDOWN, GetKeyState hlásí stav klávesnice v okamžiku, kdy uživatel klikl na tlačítko myši.

Protože GetKeyState je založený na frontě zpráv, ignoruje také vstup klávesnice odeslaný do jiného programu. Pokud uživatel přepne do jiného programu, všechny klávesy odeslané do tohoto programu jsou ignorovány GetKeyState. Pokud opravdu chcete znát okamžitý fyzický stav klávesnice, existuje funkce pro to: GetAsyncKeyState. Pro většinu kódu uživatelského rozhraní je však správná funkce GetKeyState.

Další

tabulky akcelerátorů