RegisterHotkey和循环。如果按下某个键则中断

时间:2018-11-19 02:53:39

标签: c# api

我有一个热键,如果我按该热键,它将每2秒按一次f1,如果要按f2,我希望它中断循环。你们可以帮忙吗?

此代码不会破坏循环plz帮助

public Form1()
    {
        InitializeComponent();
        int id = 0;     // The id of the hotkey. 
        RegisterHotKey(this.Handle, id, (int)KeyModifier.None, Keys.A.GetHashCode());
    }
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);

        if (m.Msg == 0x0312)
        {


            Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);                  
            KeyModifier modifier = (KeyModifier)((int)m.LParam & 0xFFFF);       
            int id = m.WParam.ToInt32();                                        


            int i = 1;
            while (true)
            {
                System.Threading.Thread.Sleep(2000);
                SendKeys.Send("{F1}");

                if (Control.ModifierKeys == Keys.F2)
                {
                    break;
                }
                Console.WriteLine(i++);
            }


        }
    }

2 个答案:

答案 0 :(得分:0)

这种操作需要非托管Windows API才能正确执行。密钥钩和密钥发送器本身都是棘手的野兽。这部分我帮不了你。

无论如何,您都需要某种形式的多任务处理来实现这一目标。您的具体情况应该可以使用计时器解决。可能甚至是极简的WindwosForms。仅凭一个sendkey的2秒钟延迟就无法克服限制。

但是,如果您想学习正确的多任务处理,则应该改用BackgroudnWorker。这是通过多线程学习多任务的一种很好的方法。如果您采用多线程的方法,这是我曾经写过的限速代码。请记住,它必须在备用线程中运行或适用于没有线程的多任务处理:

integer interval = 20;
DateTime dueTime = DateTime.Now.AddMillisconds(interval);

while(true){
  if(DateTime.Now >= dueTime){
    //insert code here

    //Update next dueTime
    dueTime = DateTime.Now.AddMillisconds(interval);
  }
  else{
    //Just yield to not tax out the CPU
    Thread.Sleep(1);
  }
}

答案 1 :(得分:0)

如果您使用的是WinForms,则可以使用System.Windows.Forms.Timer轻松完成。

首先,在表单中放置两个Timer。 (它将自动进入组件区域)

一个用于按键检查,一个用于按键


根据需要设置Timer.Interval(每N个 ms 个)
例如,如果将Timer.Interval设置为100,则启用Timer时,Timer.Tick事件将每100毫秒触发一次。

双击您的计时器组件->这将为您创建Tick事件

// timer1 for key checking, recommend you to set interval 10
private void timer1_Tick(object sender, EventArgs e) {
    // check key press with GetAsyncKeyState
    if (GetAsyncKeyState(Keys.F1) == -32768) {
        // disable timer2 
        timer2.Enabled = false;
    }
}

// timer2 for key pressing, recommend you to set interval 2000
private void timer2_Tick(object sender, EventArgs e) {
    SendKeys.Send("{F1}");
}

MSDN / PInvoke上的GetAsyncKeyState

如果您是韩国人,也可以参考this blog