Pregunta

En VB6, utilicé una llamada a la API de Windows, GetAsyncKeyState , para determinar si el usuario presionó la tecla ESC para permitirles salir de un ciclo de ejecución prolongado.

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

¿Existe un equivalente en .NET puro que requiera una llamada directa a la API?

¿Fue útil?

Solución

Puede encontrar la declaración P / Invoke para GetAsyncKeyState en http: // pinvoke. net / default.aspx / user32 / GetAsyncKeyState.html

Aquí está la firma de C #, por ejemplo:

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

Otros consejos

Dependiendo de su uso deseado, hay un par de opciones, incluida la invocación del mismo método descrito anteriormente. Desde una aplicación de consola:

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

Si está trabajando en un formulario de Windows, cada formulario tiene una serie de eventos clave relacionados que puede escuchar y manejar según sea necesario (Simplificó la mayor parte de la lógica):

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

}

Tenga en cuenta que esto es muy simplificado: no maneja ninguno de los problemas de subprocesos habituales ni nada de eso. Como se señaló en los comentarios, la ronda original no solucionó ese problema, agregué una pequeña llamada rápida de ThreadPool para enhebrar el trabajo de fondo. También tenga en cuenta que el problema con la escucha de los eventos clave es que otros controles realmente pueden manejarlos, por lo que debe asegurarse de registrarse para el evento en los controles correctos. Si una aplicación de formulario de Windows es la dirección hacia la que se está dirigiendo, también puede intentar insertarse en el bucle del mensaje ...

public override bool PreProcessMessage(ref Message msg)
{
  // Handle the message or pass it to the default handler...
  base.PreProcessMessage(msg);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top