Pergunta

Em VB6, eu usei uma chamada para a API do Windows, GetAsyncKeyState , para determinar se o usuário pressione a tecla ESC para permitir que eles para sair de um loop de longa duração.

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

Existe um equivalente em .NET puro que requer uma chamada direta para a API?

Foi útil?

Solução

Você pode encontrar a declaração P / Invoke para GetAsyncKeyState de http: // pinvoke. net / default.aspx / user32 / GetAsyncKeyState.html

Aqui está o # assinatura C por exemplo:

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

Outras dicas

Dependendo do seu uso desejado há um par de opções, incluindo invocando o mesmo método descrito acima). A partir de um aplicativo console:

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

Se você estiver trabalhando em um Windows Form, toda forma tem uma série de eventos relacionados-chave que você pode ouvir e alça conforme necessário (simplificado maior parte da 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;
        }
    }

}

Note que este é muito simplificado - não lidar com qualquer dos problemas de threading habituais ou qualquer coisa assim. Como foi salientado nos comentários, o go-round original não resolver esse problema, eu adicionei uma rápida chamada pouco ThreadPool para enfiar o trabalho de fundo. Também nota, que o problema com a escuta para os eventos-chave é que outros controles pode realmente lidar com eles, então você precisa se certificar de que você se registrar para o evento no controle correta (s). Se um aplicativo de formulário windows é a direção que você está dirigindo, você também pode tentar injetar a si mesmo no próprio ...

loop de mensagem
public override bool PreProcessMessage(ref Message msg)
{
  // Handle the message or pass it to the default handler...
  base.PreProcessMessage(msg);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top