سؤال

هل يمكن لأحد أن يخبرني بالمعرف للمفتاح @؟

على سبيل المثال Keys.escape هو مفتاح ESC. أود أن أعرف ما هو عليه @

شكرا لك.

هل كانت مفيدة؟

المحلول

ال رمز المفتاح هو ما تحصل عليه زر أسفل و keyup الأحداث. نظرًا لأن هذا شخصية تحولت ، فإنه يعتمد على تخطيط لوحة المفاتيح. على حد علمي ، فإن معظم لوحات المفاتيح فوقها أعلى من الرقم 2 ، وهذا يعني التحقق من أجل e.Shift && e.KeyCode == Keys.D2 (Winforms). لكن على بعض معظم لوحات المفاتيح الدولية ، هذا لن ينجح.

لكن لاحظ أن التعامل مع ضغط المفتاح الحدث أكثر موثوقية: e.KeyChar == '@'

تحرير: لقد ألقيت نظرة سريعة على هذه الصفحة, ومعظم لوحات المفاتيح الدولية لديها " على مدار 2 المفتاح واستخدام ALT-Something للحصول على ملف @.

نصائح أخرى

على لوحة المفاتيح الخاصة بي ، يكون keys.d2 لأن @ هو نفس مفتاح الرقم 2.

ومع ذلك ، إذا تعاملت مع حدث Keypress ، فستحصل keypresseventargs.keychar. وهذه الخاصية تحتوي على حرف بدلاً من رمز المفاتيح.

يجب ألا تستخدم حدث KeyDown للتعرف على مفاتيح الكتابة مثل @. تعتمد الترجمة من رمز المفتاح الظاهري (keyeventargs.keydata) إلى مفتاح الكتابة على تخطيط لوحة المفاتيح. ربما يكون الأمر مختلفًا في المملكة المتحدة عن واحد في الولايات المتحدة الأمريكية ، لديك رطل للضغط في مكان ما. وبالتأكيد مختلفة على لوحة المفاتيح في موقع الشرق الأقصى.

استخدم حدث Keypressed بدلاً من ذلك.

تحتاج أولاً إلى فئة للف مكالمات نظام التشغيل اللازمة لفحص تخطيط لوحة المفاتيح:

public class KeyboardPointer : IDisposable
{
  [DllImport("user32.dll", CharSet = CharSet.Unicode)]
  static extern short VkKeyScanEx(char ch, IntPtr dwhkl);
  [DllImport("user32.dll")]
  static extern bool UnloadKeyboardLayout(IntPtr hkl);
  [DllImport("user32.dll")]
  static extern IntPtr LoadKeyboardLayout(string pwszKLID, uint Flags);
  private readonly IntPtr pointer;
  public KeyboardPointer(int klid)
  {
    pointer = LoadKeyboardLayout(klid.ToString("X8"), 1);
  }
  public KeyboardPointer(CultureInfo culture)
    :this(culture.KeyboardLayoutId){}
  public void Dispose()
  {
    UnloadKeyboardLayout(pointer);
    GC.SuppressFinalize(this);
  }
  ~KeyboardPointer()
  {
    UnloadKeyboardLayout(pointer);
  }
  public bool GetKey(char character, out Keys key)
  {
    short keyNumber = VkKeyScanEx(character, pointer);
    if(keyNumber == -1)
    {
      key = Keys.None;
      return false;
    }
    key = (System.Windows.Forms.Keys)(((keyNumber & 0xFF00) << 8) | (keyNumber & 0xFF));
    return true;
  }
}

ثم إذا قمت بتشغيل:

Keys atKey;
bool hasAtKey;
using(var keyboard = new KeyboardPointer(CultureInfo.CurrentCulture))
  hasAtKey = keyboard.GetKey('@', out atKey);

hasAtKey سيكون صحيحًا إذا كانت لوحة المفاتيح لديها مزيج مفتاح @, ، في أي حالة atKey سيحتفظ بالقيمة المقابلة ، في حين أنها ستحتفظ بها Keys.None.

على سبيل المثال ، عندما أقوم بتشغيله بعد ذلك atKey يحتوي على القيمة Keys.Oemtilde | Keys.Shift, ، ولكن إذا قمت بتغيير الكود لتمريره CultureInfo.GetCultureInfo("en-US") أنه يحتوي على Keys.D2 | Keys.Shift.

كما ترون، KeyboardPointer مكتوبة لقبول كل من الثقافة ومعرف رقمي حتى لا تقتصر على لوحة المفاتيح الأساسية لثقافة ما ولكن أيضًا تخطيطات أخرى تستخدم معها ، مثل تخطيطات Dvorak وما إلى ذلك.

ما ورد أعلاه يستخدم جميع المكالمات في وظائف Windows 'User32 ، لذلك سيكون هناك نهج آخر ضروري على منصات أخرى.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top