2011-01-27 16 views
6

Klavyesine benzeyen kullanıcıya özelleştirme için bir klavye düzeni oluşturmam gerekirse, bunu nasıl yapabilirim? BöyleKullanılan klavye ile aynı olan bir klavye düzeni oluşturmak mümkün mü?

Örneğin şey:

enter image description here

Fransızca, İsveççe, İngilizce, Kanada, vb doğru, farklı düzenler olacaktır. Bu, çok fazla iş mi yoksa sadece .NET bölgesel sınıflarında bir tür kullanma meselesi mi?

+4

Birisinin yazabileceği güzel bir eklenti gibi görünüyor;) – Oded

+0

Uluslararası klavye düzenlerinin resimlerini yalnızca Google Görseller'i kullanarak bulabilirsiniz. Örneğin, [Fransızca klavye düzeni] (http://www.google.com/images?hl=tr&q=french+keyboard+layout) için googling yapmayı deneyin. – Timwi

+0

Evet ama önceden belirlenmiş bir stil ile sıfırdan çizmem gerekiyor. Ayrıca mizanpaj kullanırsam, tüm görüntüleri saklamak zorundayım, değil mi? Bunu çalışma zamanında dinamik olarak yapmalıyım (özelleştirme iletişim kutusu başlatıldığında). –

cevap

8

Tuşa basıldığında, Windows işletim sistemine bir "tarama kodu" bildiren bir donanım olayı oluşturulur. Bu tarama kod sonra (Caps da beklemede olan ölü anahtar devlet, Shift/Alt/Ctrl keystate Kilit ve diğer klavye devlet faktörleri ile birlikte tarama koduna göre bir "sanal anahtar kodu" dönüştürülür vuruş). Dönüştürülen VK değeri, KeyDown olayı tarafından bildirilen değerdir.

Tarama kodundan VK koduna dönüştürme, geçerli giriş yerel ayarına bağlıdır - basitçe, giriş yerel ayarı tarama kodları ile sanal anahtar kodları arasındaki bir eşlemeyi tanımlar. Klavye girişinin tam açıklaması için the MSDN documentation'a bakın.

Bu arama işlemini tersine çevirerek, her sanal anahtar koduna karşılık gelen tarama kodunu belirlemek mümkündür (elbette, aynı tarama kodu, shift/ctrl/alt durumu vb. Nedeniyle birden çok VK koduna eşlenecektir). Win32 API, MAPVK_VK_TO_VSC_EX seçeneğini kullanarak bu eşleştirmeyi gerçekleştirmek için MapVirtualKeyEx işlevini sağlar. Hangi tarama kodunun belirli VK kodunu oluşturduğunu belirlemek için bunu kullanabilirsiniz.

Ne yazık ki, programatik olarak gidebildiğiniz kadarıyla - klavyenin fiziksel düzenini veya her tarama kodu için anahtarın yerini belirlemenin bir yolu yoktur. Bununla birlikte, çoğu fiziksel klavyeyle aynı şekilde bağlanır, bu nedenle (örneğin) üst sol tuşun çoğu fiziksel klavye tasarımlarında aynı tarama koduna sahip olacaktır. Temel fiziksel klavye düzenine (101-tuş, 102-anahtar vb.) Bağlı olarak, bir tarama koduna karşılık gelen fiziksel konumu bulmak için bu varsayılan sözleşmeyi kullanabilirsiniz. Garanti edilmiyor, ama oldukça güvenli bir tahmin.

Aşağıdaki kod, yazdığım daha büyük bir klavye kullanım kitaplığından (açık kaynak oluşturmayı planlıyorum ama zamanım olmadı) bir alıntıdır. Yöntem, belirli bir giriş yerel ayarı için VK koduyla indekslenen (this._inputLanguage içinde saklanan ve System.Windows.Forms.InputLanguage olarak bildirilen bir dizi (this._virtualKeyScanCodes) diziyi başlatır. Örneğin, this._virtualKeyScanCodes[VK_NUMPAD0] inceleyerek VK koduna karşılık gelen tarama kodunu belirlemek için diziyi kullanabilirsiniz. - Tarama kodu sıfır ise, bu VK mevcut giriş yerel ayarında klavyede mevcut değildir, sıfır değilse, fiziksel anahtarı çıkarabileceğiniz tarama kodudur.

Ne yazık ki, ölü tuşların alemine girdiğinizde (örneğin, aksanlı karakterler oluşturan çoklu tuş kombinasyonları), konular bundan biraz daha karmaşıktır. Şu ana kadar çok karmaşık bir durum var ama Michael S. Kaplan, daha fazla araştırmak isterseniz blog posts numaralı seriyi yazdı. İyi şanslar!

private void Initialize() 
{ 
    this._virtualKeyScanCodes = new uint[MaxVirtualKeys]; 

    // Scroll through the Scan Code (SC) values and get the Virtual Key (VK) 
    // values in it. Then, store the SC in each valid VK so it can act as both a 
    // flag that the VK is valid, and it can store the SC value. 
    for (uint scanCode = 0x01; scanCode <= 0xff; scanCode++) 
    { 
     uint virtualKeyCode = NativeMethods.MapVirtualKeyEx(
      scanCode, 
      NativeMethods.MAPVK_VSC_TO_VK, 
      this._inputLanguage.Handle); 
     if (virtualKeyCode != 0) 
     { 
      this._virtualKeyScanCodes[virtualKeyCode] = scanCode; 
     } 
    } 

    // Add the special keys that do not get added from the code above 
    for (KeysEx ke = KeysEx.VK_NUMPAD0; ke <= KeysEx.VK_NUMPAD9; ke++) 
    { 
     this._virtualKeyScanCodes[(uint)ke] = NativeMethods.MapVirtualKeyEx(
      (uint)ke, 
      NativeMethods.MAPVK_VK_TO_VSC, 
      this._inputLanguage.Handle); 
    } 

    this._virtualKeyScanCodes[(uint)KeysEx.VK_DECIMAL] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_DECIMAL, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_DIVIDE] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_DIVIDE, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_CANCEL] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_CANCEL, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle); 

    this._virtualKeyScanCodes[(uint)KeysEx.VK_LSHIFT] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_LSHIFT, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_RSHIFT] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_RSHIFT, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_LCONTROL] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_LCONTROL, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_RCONTROL] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_RCONTROL, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_LMENU] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_LMENU, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_RMENU] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_RMENU, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_LWIN] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_LWIN, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_RWIN] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_RWIN, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_PAUSE] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_PAUSE, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_VOLUME_UP] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_VOLUME_UP, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_VOLUME_DOWN] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_VOLUME_DOWN, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_VOLUME_MUTE] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_VOLUME_MUTE, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle); 

    this._virtualKeyScanCodes[(uint)KeysEx.VK_MEDIA_NEXT_TRACK] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_MEDIA_NEXT_TRACK, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_MEDIA_PREV_TRACK] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_MEDIA_PREV_TRACK, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_MEDIA_PLAY_PAUSE] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_MEDIA_PLAY_PAUSE, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle); 
    this._virtualKeyScanCodes[(uint)KeysEx.VK_MEDIA_STOP] = 
     NativeMethods.MapVirtualKeyEx(
      (uint)KeysEx.VK_MEDIA_STOP, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle); 

    this._stateController = new KeyboardStateController(); 
    this._baseVirtualKeyTable = new VirtualKeyTable(this); 
} 

Düzenleme: Ayrıca sizinkine benzer this question bakın.

+2

+1 Bu, cevabımdaki yorumlarda tartıştığımızdan daha iyiydi :) – GWLlosa

2

Klavye düzenlerini içeren yerleşik bir .NET sınıfı yok. Klavye düzenleri, genellikle Windows İşletim Sisteminin bir işlevidir. .NET devreye girdiğinde, basılan anahtar bir donanım olayından bir yazılım haline dönüştürüldü. Bunu eylem halinde görmek istiyorsanız, bir anahtarın aralarında taşındığı 2 klavye düzenini bulun. olayında bir olay işleyici ile bir kukla uygulama kurun ve sonra olay hatalarının aynı olduğunu unutmayın; - tuşuna basarsanız, - anahtarına, - anahtarının nerede bulunduğundan bağımsız olarak basın.

+0

Teşekkürler, bu mantıklı. Fakat bunları Rusça, Çince klavyeler için nasıl yapıyorlar? Keys.A, vb. Anahtarın ne tür olduğu gibi. Ayrıca bazı uygulamalar, ekranda kullandığınız klavyenin düzenini yeniden oluşturabilecekleri bu şeyi nasıl yaparlar? Windows OSD klavye bunu yapar mı? –

+0

Windows OSD kullanıyor olabilirler; Bu bir işletim sistemi yardımcı olduğundan, aslında düzen farkındadır; bkz http://www.microsoft.com/windowsxp/using/accessibility/osklayout.mspx – GWLlosa

+0

Teşekkürler ama nasıl kullanabilirler? Başka bir uygulama değil mi? –