Вычисление автоклика

#c# #visual-studio #winforms

#c# #visual-studio #winforms

Вопрос:

Я создаю программу автоклика, и у меня уже есть проблема. Я хочу, чтобы моя программа могла изменять поле кликов в секунду так, как этого хочет пользователь. Итак, я сделал это.

 private void textBoxCps_TextChanged(object sender, EventArgs e)
{
    try
    {
        time = Convert.ToDouble(textBoxCps.Text);
        time = 1000 / time;
        Math.Round(time);
    }
    catch (Exception)
    {

    }
}
  

Математика правильная (я думаю …)

 while (IsRunning)
{
    if ((Control.ModifierKeys amp; Keys.Alt) != 0)
    {
        DoMouseClicks();
        Thread.Sleep(Convert.ToInt32(time));
    }
    else
    {

    }
}
  

Когда я пытаюсь поместить 1 CPS в текстовое поле, он делает 1 клик в секунду, то же самое для 2 и 3, но когда это 4 и выше, я получаю 3,80 и ниже CPS.

Комментарии:

1. Thread.Sleep() это плохая идея в WinForms. Используйте таймер. Кроме того, вы должны использовать double.TryParse() вместо обертывания Convert.ToDouble() оператор try-catch .

2. Математика. Round() ничего не делает, потому что вы не используете возвращаемое значение.

Ответ №1:

Итак, оператор вводит некоторый текст, который должен представлять период времени (TimeSpan), и после запуска запуска вы хотите вызывать метод DoMouseClicks каждый раз, пока выполнение не будет остановлено.

Одна из проблем заключается в том, что во время выполнения этой процедуры вы хотите, чтобы ваш пользовательский ввод был отзывчивым.

Вместо режима ожидания вам следует использовать один из таймеров Windows. Их несколько, и у каждого есть свои преимущества и недостатки. В вашем случае используемый вами таймер зависит от необходимой вам точности. Смотрите Эту статью для сравнения между различными таймерами

Это проблема, если щелчки немного задерживаются, если пользовательский поток занят? Если нет, то проще всего создать систему.Таймеры.Таймер

 System.Timers.Timer timer = new System.Timers.Timer()
timer.Elapsed  = TimerElapsed;

private void TimerElapsed(object sender, ...)
{
    DoMouseClicks();
}
  

Чтобы изменить интервал:

 TimeSpan TimerInterval
{
    get => TimeSpan.FromMilliseconds(this.timer.Interval);
    set => this.Timer.Interval = value.TotalMilliseconds;
}
  

Я решил использовать интервал времени в качестве интервала времени. Таким образом, изменения в коде будут минимальными, если в будущих версиях вы решите разрешить оператору вводить свои интервалы времени в секундах или в формате времени («01:00»)

Для запуска и остановки таймера:

 private bool IsTimerStarted
{
    get => this.timer.Enable;
    set => this.timer.Enabled = value;
}
  

Теперь мы готовы реагировать на ввод данных оператором. Вы решили действовать с помощью TextBoxChanged. Вы уверены, что хотите этого? Что произойдет, если оператор захочет ввести «1000», чтобы указать интервал времени в одну секунду. Он начинается с ввода «1», вы сразу же запускаете щелчки мыши с частотой 1 мс. Это то, чего вы хотите?

Еще одна проблема: если оператор допустит ошибку ввода: «10) 0» вместо «1000»?

Надлежащий пользовательский интерфейс позволил бы оператору указать, что он закончил вводить интервал, нажав кнопку. При нажатии кнопки вы читаете текст. Если возникает ошибка, вы уведомляете оператора, если нет, вы запускаете таймер.

Альтернативой является отключение кнопки, если текстовое поле содержит недопустимый текст. Хотя это кажется приятным, недостатком является то, что оператор не знает, почему его кнопка не включена.

 private void OnButtonStart_Clicked(object sender, ...)
{
    TimeSpan intervalTime = this.ReadTextBoxInterval();
    this.TimerInterval = intervalTime;
    this.IsTimerStarted = true;

    // if desired: show the operator that the action is running
}
private void OnButtonStop_Clicked(object sender, ...)
{
    this.IsTimerStarted = false;
    // if the timer was handling event Elapsed, it is finished neatly.

    // if desired show the operator that the action is stopped.
}
  

Я решил отделить действие от интерпретации ввода оператора. Таким образом, изменения в коде минимальны, если вы решите изменить вводимый оператором с мс на секунды или даже формат времени («00:01»). Или если вы решите использовать поле со списком вместо окна редактирования.

 TimeSpan ReadTextBoxInterval()
{
    string textBoxText = this.TextBoxInterval.Text;
    return IntervalFromMsecText(textBoxText);
}

TimeSpan IntervalFromMsecText(string intervalText)
{
    if (Double.TryParse(intervalText, NumberStyles.Any, CultureInfo.CurrentCulture,
        out double msecInterval))
    {
        // input is a proper double
        return TimeSpan.FromMilliseconds(msecInterval);
    }
    else
    {
        // invalid input. Notify the operator?
    }
}