0

我想编写一个算法来顺序按下 F1-F3 键。我的表单有这些控件:

lblF1
textboxF1
lblF2
textboxF2
lblF3
textboxF3
btnStart

在 textboxF1-textboxF3 中输入以秒为单位的时间。这在程序是按热键的时候。重要的是程序不能同时按下两个键,例如 F1 和 F2。它可能不会在一秒钟内按下一个以上的键。当我单击 btnStart 时,它会调用 Run()。

这就是我试图解决这个问题的方法:

static int counterF1 = 9999;
static int counterF2 = 9999;
static int counterF3 = 9999;

    public void Run()
    {
        counterF1 = 9999;
        counterF2 = 9999;
        counterF3 = 9999;
        while (true)
        {
            Loop();
        }
    }

    public void Loop()
    {
        bool used = false;

            if (counterF1 >= (int)textboxF1.text)
            {
                counterF1 = PressKey(VK_F1);
                used = true;
            }

            if (counterF2 >= (int)textboxF2.text)
            {
                counterF2 = PressKey(VK_F2);
                used = true;
            }

            if (counterF3 >= (int)textboxF3.text)
            {
                counterF3 = PressKey(VK_F3);
                used = true;
            }
        if (used == false)
        {
            IncrementCounters();
            Delay(1000);
        }
    }

    public double PressKey(uint key)
    {
        myPostMessageA(hWindow, WM_KEYDOWN, (uint)key, (uint)key); 
        IncrementCounters();
        return 1; //return 1 because one second
    }

    public void IncrementCounters()
    {
        counterF1++;
        counterF2++;
        counterF3++;
    }

但通常它不按任何键(可能为时已晚,但不能是遗漏)。你能解释一下如何为此制定算法吗?

4

1 回答 1

1

我们将使用一个类KeyStroke来存储特殊键的必要数据:

public class KeyStroke
{
    public int period { get; set; } // Period in which to hit key
    public int next { get; set; } // ticks to the next hit of this key
    public int VK { get; set; } //KeyCode
}
public List<KeyStroke> keys = new List<KeyStroke>();

需要一个 Initialize() 方法来从文本框中读取数据并初始化模拟。我们使用一个间隔为一秒的计时器来运行模拟。在我的示例中,我不从文本框中读取,而是使用常量值。添加输入和错误处理。如果您使用 WPF,您可以将 KeyStroke 对象绑定到文本框。

void Init()
{
    //Initialize keys with according periods from input
    keys.Clear();
    keys.Add(new KeyStroke() { VK = VK_F1, period = 1, next = 1 });
    keys.Add(new KeyStroke() { VK = VK_F2, period = 10, next = 10 });
    keys.Add(new KeyStroke() { VK = VK_F3, period = 5, next = 5 });

    //sort keys by period (descending), in order to handle long period keys, too
    keys.Sort((first, second) => second.period.CompareTo(first.period));

    //Start the program
    var t = new DispatcherTimer();
    t.Interval = TimeSpan.FromSeconds(1);
    t.Tick += new EventHandler(t_Tick);
    t.Start();
}

tick 事件与您的类似:

void t_Tick(object sender, EventArgs e)
{
    bool used = false;
    foreach (var key in keys)
    {
        if (key.next <= 0 && !used)
        {
            PressKey(key.VK);
            key.next = key.period;
            used = true;
        }
        key.next--;
    }
}
于 2012-07-14T14:44:45.907 回答