سؤال

في VB6، استخدمت استدعاء Windows API، GetAsyncKeyState, لتحديد ما إذا كان المستخدم قد ضغط على مفتاح ESC للسماح له بالخروج من حلقة طويلة جارية.

Declare Function GetAsyncKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer

هل هناك ما يعادله في .NET الخالص الذي يتطلب اتصالاً مباشرًا بواجهة برمجة التطبيقات (API)؟

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

المحلول

يمكنك العثور على إعلان P/Invine لـ GetAsyncKeyState من http://pinvoc.net/default.aspx/user32/GetAsyncKeyState.html

إليك توقيع C# على سبيل المثال:

[DllImport("user32.dll")]
static extern short GetAsyncKeyState(int vKey);

نصائح أخرى

اعتمادًا على الاستخدام المطلوب، هناك خياران، بما في ذلك استدعاء نفس الطريقة الموضحة أعلاه).من تطبيق وحدة التحكم:

bool exitLoop = false;
for(int i=0;i<bigNumber && !exitLoop;i++)
{
    // Do Stuff.
    if(Console.KeyAvailable)
    {
        // Read the key and display it (false to hide it)
        ConsoleKeyInfo key = Console.ReadKey(true);
        if(ConsoleKey.Escape == key.Key)
        {
            exitLoop=false;
        }
    }
}

إذا كنت تعمل على نموذج Windows، فإن كل نموذج يحتوي على عدد من الأحداث الرئيسية ذات الصلة التي يمكنك الاستماع إليها والتعامل معها حسب الضرورة (تبسيط معظم المنطق):

public partial class Form1 : Form
{
    private bool exitLoop;
    public Form1()
    {
        InitializeComponent();
        this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp);
    }
    public void doSomething()
    {
        // reset our exit flag:
        this.exitLoop = false;
        System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(delegate(object notUsed)
            {
                while (!exitLoop)
                {
                    // Do something
                }
            }));
    }
    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        if (Keys.Escape == e.KeyCode)
        {
            e.Handled = true;
            this.exitLoop = true;
        }
    }

}

لاحظ أن هذا جداً مبسط - لا يتعامل مع أي من مشكلات الترابط المعتادة أو أي شيء من هذا القبيل.كما تمت الإشارة إليه في التعليقات، لم تعالج الجولة الأصلية هذه المشكلة، لقد أضفت استدعاء ThreadPool سريعًا لربط العمل في الخلفية.لاحظ أيضًا أن مشكلة الاستماع للأحداث الرئيسية هي أن عناصر التحكم الأخرى قد تتعامل معها بالفعل، لذلك تحتاج إلى التأكد من تسجيلك للحدث على عنصر التحكم (عناصر التحكم) الصحيح.إذا كان تطبيق نموذج Windows هو الاتجاه الذي تتجه إليه، فيمكنك أيضًا محاولة إدخال نفسك في حلقة الرسالة نفسها...

public override bool PreProcessMessage(ref Message msg)
{
  // Handle the message or pass it to the default handler...
  base.PreProcessMessage(msg);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top