пятница, 27 марта 2009 г.

Почему сообщение WM_KILLFOCUS не подходит для проверки правильности ввода

Это перевод WM_KILLFOCUS is the wrong time to do field validation. Автор: Реймонд Чен.

"Я буду делать проверку ввода, когда мне придёт сообщение WM_KILLFOCUS".

Это плохо по многим причинам.

Во-первых, вы можете не получить сообщение о потере фокуса до тех пор, пока не станет слишком поздно.

Рассмотрим диалоговое окно с edit-контролом и кнопкой ОК. Edit-контрол проверяет своё содержимое при получении сообщения WM_KILLFOCUS. Предположим, пользователь ввёл некоторые неверные данные.

При благоприятных обстоятельствах, пользователь нажимает кнопку ОК. Нажатие на кнопку ОК приводит к тому, что фокус уходит с edit-контрола, поэтому получает управление код edit-контрола для WM_KILLFOCUS, и edit-контрол получает шанс сообщить пользователю, что введённые данные не годятся. Поскольку щелчок на кнопку не срабатывает, пока кнопку мыши не отпустят, всплывающее окно с сообщением о недействительных данных крадёт фокус, и теперь отпускание кнопки мыши не перейдёт к кнопке ОК. Результат: появляется сообщение об ошибке и действие IDOK не выполняется.

Теперь рассмотрим менее благоприятные условия. Вместо нажатия на кнопку ОК, пользователь просто нажимает Enter или набирает быструю комбинацию клавиш для любой кнопки, которая закрывает диалог. Нажатия этих кнопок приводят к появлению WM_COMMAND, но фокус при этом не меняется.

Теперь обработчик IDOK (или любой другой) запускается и вызывает EndDialog или выполняет любые другие действия, для которых предназначена кнопка. Если диалоговое окно закрывается, тогда фокус уходит с edit-контрола как часть уничтожения диалогового окна, и только в этот момент произойдёт проверка ввода, но теперь уже слишком поздно. Диалог уже закрывается.

Или же, если реакция на кнопку предусматривает не закрытие диалога, а скорее запуск какой-либо процедуры, то тогда работа будет происходить с непроверенными данными в диалоговом окне - скорее всего, это не то, чего вы хотите. Только тогда, когда эта процедура переместит фокус (например, для показа диалога хода операции), edit-контрол получит WM_KILLFOCUS, но в это время уже слишком поздно что-либо проверять. Процедура (с использованием непроверенных данных) уже запущена.

Существует также проблема юзабилити при проверке данных при смене фокуса. Предположим, пользователь начинает вводить данные в edit-контрол, а затем он отвлекается. Может быть, он хочет прочитать фрагмент электронной почты, где находится нужная ему информация. Возможно, он получил телефонный звонок, и ему нужно посмотреть что-то в своей базе данных контактов. Может быть, он пошёл в ванную и поэтому запустился хранитель экрана. Пользователь не хочет видеть в эти моменты диалог с ошибкой "Извините, но вот эта частично введённая вами информация недопустима", потому что он еще не закончил ввод данных.

Я сейчас говорил вам о тех местах, где вам не нужно делать проверки, но ничего не сказал о том, где вам следует их делать.

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

(Предупреждения, которые не изменяют фокус - разрешены. Например, всплывающий балун с подсказкой, что вы включили Caps Lock при вводе пароля).

1 комментарий:

  1. Спасибо! Теперь у меня есть хорошие аргументы начальству, чтобы не делать проверку по такому принципу.

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

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