Domanda

In VB6, ho usato una chiamata all'API di Windows, GetAsyncKeyState , per determinare se l'utente ha premuto il tasto ESC per consentire loro di uscire da un ciclo prolungato.

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

Esiste un equivalente in .NET puro che richiede una chiamata diretta all'API?

È stato utile?

Soluzione

Puoi trovare la dichiarazione P / Invoke per GetAsyncKeyState da http: // pinvoke. net / default.aspx / user32 / GetAsyncKeyState.html

Ecco la firma C # per esempio:

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

Altri suggerimenti

A seconda dell'uso desiderato ci sono un paio di opzioni, incluso il richiamo dello stesso metodo descritto sopra). Da un'app 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 stai lavorando su un modulo di Windows, ogni modulo ha un numero di eventi chiave correlati che puoi ascoltare e gestire se necessario (la maggior parte della logica semplificata):

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

}

Nota che questo è molto semplificato - non gestisce nessuno dei soliti problemi di threading o qualcosa del genere. Come è stato sottolineato nei commenti, la soluzione originale non ha risolto il problema, ho aggiunto una breve chiamata ThreadPool per avviare il lavoro in background. Si noti inoltre che il problema con l'ascolto degli eventi chiave è che altri controlli potrebbero effettivamente gestirli, quindi è necessario assicurarsi di registrarsi per l'evento sui controlli corretti. Se un'applicazione di Windows Form è la direzione in cui stai andando, puoi anche tentare di iniettarti nel loop del messaggio stesso ...

public override bool PreProcessMessage(ref Message msg)
{
  // Handle the message or pass it to the default handler...
  base.PreProcessMessage(msg);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top