воскресенье, 6 сентября 2009 г.

Логические выводы из способа Windows конвертирования одиночных кликов в двойные клики

Это перевод Logical consequences of the way Windows converts single-clicks into double-clicks. Автор: Реймонд Чен.

Сначала, я сошлюсь на документацию MSDN по мышиным кликам, поскольку она и является отправной точкой. Я собираюсь предположить, что вы знаете, как одинарные щелчки мышью преобразуются в двойные.

Okей, теперь, когда вы прочитали всё это, давайте поговорим о некоторых логических выводах из этой статьи, и что это всё означает для вас, когда вы проектируете свой интерфейс пользователя.

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

Конечно же, вы понимаете, что это требует ясновидения. Когда кнопка мыши нажимается в первый раз, оконный менеджер не знает, последует ли за этим второй щелчок или нет (чёрт возьми, иногда сам пользователь этого не знает!). Поэтому он выплёвывает сообщение WM_LBUTTONDOWN и ждёт дальше.

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

Ну, одной вещью, которую можно сделать - ничего не делать при приёме WM_LBUTTONDOWN сообщения, кроме как установить таймер на срабатывание через GetDoubleClickTime миллисекунд. Если вы получите сообщение WM_LBUTTONDBLCLK в этот интервал, то это значит, что у нас всё же произошёл двойной щелчок. Если не получаете - значит, это был одинарный щелчок, так что вы можете выполнить своё действие (из обработчика таймера) по одиночному щелчку (хотя и немного позже).

Эта техника "подождать тик" также необходима, если у вас просто нет действия по двойному щелчку, а второй щелчок вызовет неприятности в сочетании с первым. Почему необходима? Потому что многие пользователи просто дважды-щёлкают по всему. Вот несколько примеров, где можно увидеть "задержать действие для избежания повторного выполнения":

  • Контекстное меню, которое появляется из иконок в области уведомления панели задач. Если бы контекстное меню появлялось бы сразу по одинарному щелчку, то тогда второй щелчок отменял бы меню, оставляя пользователя совершенно запутанным: "я щёлкнул по меню, что-то быстро мелькнуло и ничего не произошло" (пользователи никогда не говорят "я дважды щёлкнул"; они просто говорят, что они щёлкнули. Двойной щелчок - это единственная вещь, которую они знают, как делать, поэтому они называют его просто "щелчком". По той же причине, почему вы не говорите "я веду мою синюю машину", если у вас только один автомобиль).
  • Если Проводник находится в режиме одинарных щелчков (переключается в настройках; в этом режиме для открытия папки или запуска программы нужно по ним просто щёлкнуть - прим.пер.), то он ждёт второго щелчка, и если он будет - то игнорирует его. В противном случае, те люди, которые делают даб-клик, просто запустят две копии программы. Более того, если вы просто заглушите второй щелчок, но не будете ждать, то запущенная программа окажется под окном Проводника, потому что пользователь щёлкает по окну Проводника уже после запуска программы.
  • Меню Пуск в стиле XP игнорирует второй щелчок. В противном случае, люди, которые дважды щёлкают по кнопке Пуск, первым щелчком откроют меню Пуск, а вторым щелчком закроют его! (иногда это называют "debouncing".)

Давайте покажем, как бы вы могли реализовать задержку щелчка. Создайте пустое VCL приложение и добавьте следующее:

procedure TForm1.FormClick(Sender: TObject);
begin
Timer1.Interval := GetDoubleClickTime;
Timer1.Enabled := True;
end;

procedure TForm1.FormDblClick(Sender: TObject);
begin
Timer1.Enabled := False;

Caption := 'Doubleclicked';
MessageBeep(MB_ICONASTERISK);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;

Caption := 'Singleclicked';
MessageBeep(MB_OK);
end;

Когда вы запустите эту программу, попробуйте щёлкать и дважды-щёлкать в клиентской области окна. Заметьте, что программа не реагирует на первый одинарный щелчок, пока не истечёт время ожидания второго щелчка для дабл-клика, потому что программа ждёт, чтобы узнать, собираетесь ли вы делать двойной или одинарный щелчок.

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

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

  1. debouncing = "антидребезг".

    "Железные" кнопки, прежде чем успокоиться, несколько миллисекунд включаются-выключаются. Это называется дребезг контактов. Когда программируешь микроконтроллер, приходится делать какую-то защиту от этого самого дребезга - например, регистрировать второе нажатие, только если оно было через 50 мс после первого.

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

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

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

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

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

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