Я надеюсь, что смогу объяснить мою проблему достаточно хорошо, чтобы кто-то помог.
По сути, у меня есть горизонтальная полоса прокрутки (в диапазоне от 0 до 1000) и элемент управления для редактирования, который представляет положение полосы прокрутки, деленное на 1000, так что пользователь может использовать любую полосу прокрутки для выбора диапазона чисел от 0 до 1 с точностью до 3 десятичных знаков (.001, .002, ..., .987 и т. д.) или введите свой номер в поле для редактирования. Когда они прокручивают полосу прокрутки, число в элементе управления редактирования изменяется, отражая новую позицию прокрутки. Когда вводится новый номер, полоса прокрутки устанавливает себя в новую позицию, отражающую введенный номер. Тем временем я также выполняю некоторые вычисления с этим числом по мере его изменения (либо с помощью полосы прокрутки, либо с помощью элемента управления редактирования) и отображаю результаты в другом диалоговом окне.
Вот моя проблема: у меня возникают проблемы с решением, какие обработчики событий использовать для создания правильного поведения, когда пользователь вводит число в элемент управления для редактирования.
Я использую переменную с двойным значением fuelMargin для управления моим элементом управления и переменную CScrollBar, которая называется FuelScroll для обработки полосы прокрутки.
В моем событии HSCROLL я установил регулятор редактирования в положение прокрутки / 1000. Никаких проблем там нет; когда пользователь прокручивает полосу прокрутки, окно редактирования корректно обновляется.
Что касается поля ввода, моей первой попыткой было событие ONCHANGE:
void MarginDlg::OnEnChangeFueledit()
{
CEdit* editBox;
editBox = (CEdit*)GetDlgItem(IDC_FUELEDIT);
CString editString;
editBox->GetWindowText(editString);
if (editString.Compare(".") != 0 && editString.Compare("0.") != 0
&& editString.Compare(".0") != 0 && editString.Compare("0.0") != 0
&& editString.Compare(".00") != 0 && editString.Compare("0.00") != 0)
{
UpdateData();
UpdateData(FALSE);
if (fuelMargin > 1)
{
UpdateData();
fuelMargin = 1;
UpdateData(FALSE);
}
if (fuelMargin < 0)
{
UpdateData();
fuelMargin = 0;
UpdateData(FALSE);
}
fuelScroll.SetScrollPos(int(fuelMargin*1000));
}
}
Сначала мне понадобился оператор if, чтобы не выполнять UpdateData (), когда пользователь пытается набрать число, например .5 или .05 или .005. Тем не менее, он производит несколько странных поведений; когда пользователь пытается набрать что-то вроде .56, после .5 выполняется UpdateData (), число становится равным 0,5, и курсор перемещается в крайнее левое положение, поэтому, если он попытается ввести .56, он случайно окажется набрав 60,5 - что соответствует 1, поскольку я не позволю им вводить числа ниже 0 или выше 1. Однако, если они введут 0,56, такого поведения избегают.
Для второй попытки я закомментировал событие ONCHANGE и вместо него поместил событие ONKILLFOCUS:
void MarginDlg::OnEnKillfocusFueledit()
{
UpdateData();
UpdateData(FALSE);
if (fuelMargin > 1)
{
UpdateData();
fuelMargin = 1;
UpdateData(FALSE);
}
if (fuelMargin < 0)
{
UpdateData();
fuelMargin = 0;
UpdateData(FALSE);
}
fuelScroll.SetScrollPos(int(fuelMargin*1000));
}
Так что теперь пользователь может закончить вводить свой номер, и все будет просто так - до тех пор, пока он щелкнет из поля редактирования. Полоса прокрутки не будет двигаться, и результаты не будут рассчитываться, пока окно не потеряет фокус.
Я хочу, чтобы результаты вычислялись по мере ввода чисел в поле; Я хочу, чтобы полоса прокрутки двигалась по мере набора цифр. Но я не хочу, чтобы ввод был прерван, т. Е. Фактические цифры в поле изменились или курсор каким-либо образом переместился.
Предложения
Спасибо!