Aracılığıyla paylaş


Klavye Girişi (Win32 ve C++'ı Kullanmaya Başlama)

Klavye, aşağıdakiler de dahil olmak üzere çeşitli farklı giriş türleri için kullanılır:

  • Karakter girişi. Kullanıcının bir belgeye veya düzenleme kutusuna girdiği metin.
  • Klavye kısayolları. Uygulama işlevlerini çağıran tuş vuruşları; örneğin, bir dosyayı açmak için CTRL + O tuşlarına basın.
  • Sistem komutları. Sistem işlevlerini çağıran tuş vuruşları; örneğin, pencereleri değiştirmek için ALT + SEKME tuşlarına basın.

Klavye girişini düşünürken, tuş vuruşunun karakterle aynı olmadığını unutmamak önemlidir. Örneğin, A tuşuna basmak aşağıdaki karakterlerden herhangi birine neden olabilir.

  • a
  • A
  • á (klavye diyakritik işaretleri birleştirmeyi destekliyorsa)

Ayrıca, ALT tuşu basılı tutulursa, A tuşuna basmak, sistemin bir karakter olarak değil, sistem komutu olarak işlemdiği ALT+A tuşlarını oluşturur.

Anahtar Kodları

Bir tuşa bastığınızda, donanım bir tarama koduoluşturur. Tarama kodları bir klavyeden diğerine farklılık gösterir ve tuş yukarı ve tuş aşağı olayları için ayrı tarama kodları vardır. Tarama kodlarını neredeyse hiç önemsemeyeceksiniz. Klavye sürücüsü, tarama kodlarını sanal anahtar kodlarına çevirir. Sanal anahtar kodları cihazdan bağımsızdır. Herhangi bir klavyede A tuşuna basmak aynı sanal anahtar kodunu oluşturur.

Genel olarak, sanal anahtar kodları ASCII kodlarına veya başka bir karakter kodlama standardına karşılık gelmez. Düşünürseniz bu durum açıktır, çünkü aynı tuş farklı karakterler (a, A, á) oluşturabilir ve işlev tuşları gibi bazı tuşlar herhangi bir karaktere karşılık gelmez.

Bununla birlikte, aşağıdaki sanal tuş kodları ASCII eşdeğerlerine eşlenir:

  • 0 ile 9 arasındaki tuşlar = ASCII '0' – '9' (0x30 – 0x39)
  • A-Z tuşları = ASCII 'A' – 'Z' (0x41 – 0x5A)

Bazı açılardan bu eşleme talihsiz bir durumdur çünkü sanal anahtar kodlarını tartışılan nedenlerle hiçbir zaman karakter olarak düşünmemelisiniz.

WinUser.h üst bilgi dosyası, sanal anahtar kodlarının çoğu için sabitleri tanımlar. Örneğin, SOL OK tuşunun sanal anahtar kodu VK_LEFT (0x25). Sanal anahtar kodlarının tam listesi için bkz. Virtual-Key Kodları. ASCII değerleriyle eşleşen sanal anahtar kodları için hiçbir sabit tanımlanmamıştır. Örneğin, A anahtarının sanal anahtar kodu 0x41 ancak VK_Aadlı sabit yoktur. Bunun yerine yalnızca sayısal değeri kullanın.

Key-Down ve Key-Up Mesajları

Bir tuşa bastığınızda, klavye odağı olan pencere aşağıdaki iletilerden birini alır.

WM_SYSKEYDOWN iletisi, sistem komutunu çağıran bir tuş vuruşu olan sistem anahtarını gösterir. İki tür sistem anahtarı vardır:

  • ALT + herhangi bir tuş
  • F10

F10 tuşu bir pencerenin menü çubuğunu etkinleştirir. Çeşitli ALT tuş bileşimleri sistem komutlarını çağırır. Örneğin, ALT + SEKME tuşları yeni bir pencereye geçer. Ayrıca, bir pencerenin menüsü varsa, menü öğelerini etkinleştirmek için ALT tuşu kullanılabilir. Bazı ALT tuş bileşimleri hiçbir şey yapmaz.

Diğer tüm tuş vuruşları sistem dışı anahtarlar olarak kabul edilir ve WM_KEYDOWN iletisini oluşturur. Bu, F10 dışındaki işlev tuşlarını içerir.

Bir tuşu serbest bıraktığınızda, sistem ilgili tuş bırakma mesajını gönderir.

Klavyenin yineleme özelliğini başlatacak kadar uzun bir tuşa basılı tutarsanız, sistem birden çok tuş aşağı ileti gönderir ve ardından tek bir tuş yukarı iletisi gönderir.

Şimdiye kadar açıklanan klavye iletilerinin dördünde de wParam parametresi anahtarın sanal anahtar kodunu içerir. lParam parametresi, 32 bit olarak paketlenmiş çeşitli bilgiler içerir. Genellikle lParamiçindeki bilgilere ihtiyacınız yoktur. Yararlı olabilecek bayraklardan biri, tekrarlanan anahtar basma iletileri için 1 olarak ayarlanan "önceki anahtar durumu" bayrağı, yani 30. bittir.

Adından da anlaşılacağı gibi, sistem tuş vuruşları öncelikli olarak işletim sistemi tarafından kullanılmak üzere tasarlanmıştır. WM_SYSKEYDOWN iletisini durdurursanız, daha sonra DefWindowProc çağırın. Aksi takdirde, işletim sisteminin komutu işlemesini engellersiniz.

Karakter İletileri

Tuş vuruşları, ilk olarak Modül 1'de gördüğümüz TranslateMessage işlevi tarafından karakterlere dönüştürülür. Bu işlev, tuş basma iletilerini inceler ve bunları karakterlere çevirir. Oluşturulan her karakter için TranslateMessage işlevi, pencerenin ileti kuyruğuna bir WM_CHAR veya WM_SYSCHAR iletisi yerleştirir. İletinin wParam parametresi UTF-16 karakterini içerir.

Tahmin edebileceğiniz gibi, WM_KEYDOWN iletilerden WM_CHAR iletiler oluşturulurken, WM_SYSCHAR iletiler WM_SYSKEYDOWN iletilerden oluşturulur. Örneğin, kullanıcının SHIFT tuşuna ve ardından A tuşuna basıldığını varsayalım. Standart bir klavye düzeni varsayarsak, aşağıdaki ileti dizisini alırsınız:

WM_KEYDOWN: SHIFT
WM_KEYDOWN: A
WM_CHAR: 'A'

Öte yandan ALT + P birleşimi şunları oluşturur:

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

(ALT anahtarının sanal anahtar kodu, geçmiş nedenlerle VK_MENU olarak adlandırılır.)

WM_SYSCHAR iletisi bir sistem karakterini gösterir. WM_SYSKEYDOWN'da olduğu gibi, bu iletiyi genellikle DefWindowProc'e iletmeniz gerekir. Aksi takdirde, standart sistem komutlarını engelleyebilirsiniz. Özellikle, WM_SYSCHAR'i kullanıcının yazdığı metin olarak değerlendirmeyin.

WM_CHAR iletisi normalde karakter girişi olarak düşündüğünüz iletidir. Karakterin veri türü, UTF-16 Unicode karakterini temsil eden wchar_tdeğeridir. Karakter girişi, özellikle de ABD dışında yaygın olarak kullanılan klavye düzenleri ile ASCII aralığının dışındaki karakterleri içerebilir. Bölgesel bir klavye yükleyip Ekran Klavyesi özelliğini kullanarak farklı klavye düzenlerini deneyebilirsiniz.

Kullanıcılar, standart klavyeyle Japonca karakterler gibi karmaşık betikler girmek için bir Giriş Yöntemi Düzenleyicisi (IME) de yükleyebilir. Örneğin, カ (ka) katakana karakterini girmek için Japonca IME kullanarak aşağıdaki iletileri alabilirsiniz:

WM_KEYDOWN: VK_PROCESSKEY (IME İŞLEM anahtarı)
WM_KEYUP: 0x4B
WM_KEYDOWN: VK_PROCESSKEY
WM_KEYUP: 0x41
WM_KEYDOWN: VK_PROCESSKEY
WM_CHAR: カ
WM_KEYUP: VK_RETURN (Geri dönüş tuşunun serbest bırakılması)

Bazı CTRL tuş bileşimleri ASCII denetim karakterlerine çevrilir. Örneğin, CTRL+A ASCII ctrl-A (SOH) karakterine (ASCII değeri 0x01) çevrilir. Metin girişi için genellikle denetim karakterlerini filtrelemeniz gerekir. Ayrıca klavye kısayollarını uygulamak için WM_CHAR kullanmaktan kaçının. Bunun yerine, WM_KEYDOWN iletileri kullanın; veya daha da iyisi, bir hızlandırıcı tablosu kullanın. Hızlandırıcı tabloları, sonraki konu başlığında Hızlandırıcı Tablolaraçıklanmıştır.

Aşağıdaki kod, hata ayıklayıcıda ana klavye iletilerini görüntüler. Farklı tuş vuruşu bileşimleriyle yürütmeyi deneyin ve hangi iletilerin oluşturulduğunu görün.

Not

wchar.h dosyasını eklediğinizden emin olun, aksi takdirde swprintf_s tanımlanmamış olur.

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

Çeşitli Klavye İletileri

Diğer bazı klavye iletileri çoğu uygulama tarafından güvenle yoksayılabilir.

  • WM_DEADCHAR iletisi, örneğin aksan işareti gibi bir birleştirme anahtarı için gönderilir. Örneğin, İspanyolca dil klavyesinde vurgu (') ve ardından E yazmak é karakterini üretir. vurgu karakteri için WM_DEADCHAR gönderilir.
  • WM_UNICHAR iletisi kullanımdan kaldırıldı. ANSI programlarının Unicode karakter girişi almasını sağlar.
  • WM_IME_CHAR karakteri, bir IME tuş vuruşu dizisini karakterlere çevirdiğinde gönderilir. Her zamanki WM_CHAR iletisine ek olarak gönderilir.

Klavye Durumu

Klavye iletileri olay odaklıdır. Başka bir ifadeyle, tuş basılması gibi ilginç bir şey olduğunda bir ileti alırsınız ve ileti size az önce ne olduğunu söyler. Ancak, GetKeyState işlevini çağırarak istediğiniz zaman bir anahtarın durumunu test edebilirsiniz.

Örneğin, sol fare tıklaması + ALT tuşunun birleşimini nasıl algılayabilirsiniz? Tuş basımı mesajlarını dinleyerek ve bir bayrak depolayarak ALT tuşunun durumunu izleyebilirsiniz, ancak GetKeyState işinizi kolaylaştırır. WM_LBUTTONDOWN iletisini aldığınızda, GetKeyState aşağıdaki gibi çağırın:

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

GetKeyState iletisi giriş olarak bir sanal anahtar kodu alır ve bir bit bayrağı kümesi (aslında yalnızca iki bayrak) döndürür. 0x8000 değeri, tuşa şu anda basılıp basılmadığını test eden bit bayrağını içerir.

Çoğu klavyede sol ve sağ olmak üzere iki ALT tuşu vardır. Önceki örnek, herhangi birinin basılıp basılmadığını test eder. Alt, SHIFT veya CTRL tuşlarının sol ve sağ örneklerini ayırt etmek için GetKeyStatede kullanabilirsiniz. Örneğin aşağıdaki kod, doğru ALT tuşuna basılıp basılamadığını test ediyor.

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

GetKeyState işlevi, sanal klavye durumunu bildirdiğinden ilginçtir. Bu sanal durum, ileti kuyruğunuzun içeriğini temel alır ve iletileri kuyruktan kaldırdığınızda güncelleştirilir. Programınız pencere iletilerini işlerken, GetKeyState size her iletinin kuyruğa alındığı sırada klavyenin anlık görüntüsünü verir. Örneğin, kuyrukta son ileti WM_LBUTTONDOWNise, GetKeyState kullanıcı fare düğmesine tıkladığında klavye durumunu bildirir.

GetKeyStateileti kuyruğunuzu temel alması nedeniyle, başka bir programa gönderilen klavye girişini de yoksayar. Kullanıcı başka bir programa geçerse, o programa gönderilen tüm tuş basmaları GetKeyStatetarafından yoksayılır. Klavyenin anlık fiziksel durumunu gerçekten bilmek istiyorsanız, bunun için bir işlev vardır: GetAsyncKeyState. Ancak çoğu kullanıcı arabirimi kodu için doğru işlev GetKeyState'dır.

Sonraki

Hızlandırıcı Tabloları