HTMLayout User Guide
От: Зверёк Харьковский  
Дата: 24.11.06 02:38
Оценка: 171 (14)
Решил написать сабж потихоньку (прямо тут, в форуме, а чо?).
Это описание HTMLayout, в котором теоретически легко будет найти ответ на большинство вопросов, возникающих при использовании.
Несколько предуведомлений:
1. Я пользователь, а не разработчик, т.е. ошибки возможны.
2. Мне лень писать вступительные главы (что такое HTMLayout и зачем это надо).
3. Все сходу не одолел, поэтому буду писать по главам.
4. Получился все ж таки User Guide (что и как тут делать), а не Tutorial (начало работы с библиотекой по шагам)

План ближайших глав:
1. Работа с DOM (Document Object Model) HTMLayout — уже написано, сейчас запостю.
2. Обработка событий (Events and Behaviors) — будет в течение 2-3 дней.
3. ? — вносите ваши предложения.

Ну-с, с Б-гом!



24.11.06 09:28: Перенесено модератором из 'Пользовательский интерфейс: проектирование, usability' — der Igel
25.11.06 12:55: Перенесено из 'Веб программирование'
16.12.06 17:07: Перенесено модератором из 'Средства разработки' — Odi$$ey
FAQ — це мiй ай-кью!
Re: 1. Работа с DOM HTMLayout
От: Зверёк Харьковский  
Дата: 24.11.06 02:41
Оценка: 176 (12)
Управление всем UI происходит, как правило, работой с элементами DOM.
DOM (Document Object Model) — это дерево всех элементов, из которых состоит отображаемый HTML. В первом приближении можно считать, что один DOM-элемент соответствует одному теги исходного текста HTML, впрочем, из этого правила есть исключения (см. Примечание 1).

Изменение DOM (состава, внешнего вида, состояния) происходит только следующими способами (весь API для этого описан в заголовочном файле htmlayout_dom.h, тонкая C++-обертка "для примера" — htmlayout_dom.hpp):
0. Навигация по DOM — используется для того, чтобы найти элемент, который собираешься менять.
1. Добавление/удаление DOM элементов — используется, собственно, для изменения элементов UI.
2. Изменение HTML элементов DOM — альтернатива модификации DOM путем удаления/вставки элементов
3. Изменение текста элементов DOM
4. Изменение аттрибутов элементов DOM — используется для изменения представления элементов
5. Изменение состояния элементов DOM — используется для того, для чего и можно предположить по названию
6. Изменение "значения" (value) элементов DOM — быстрый способ изменения значимой части состояния элемента

Далее подробнее.

0. Навигация по DOM
Методы навигации:
* прямой перебор всех "детей" данной вершины: HTMLayoutGetChildrenCount, HTMLayoutGetNthChild
* прямой переход к родителю: HTMLayoutGetParentElement
* некоторые специальные функции: HTMLayoutFindElement (элемент в данной точке [x, y]), HTMLayoutGetFocusElement (текущий элемент в фокусе)
* поиск элемента по css-селектору — достаточно сложные функции, которые принимают на вход параметры для поиска и callback-функцию, которую надо вызвать для найденных элементов. Таких функций 3: HTMLayoutSelectElements (ищет вниз по DOM от заданного элемента), HTMLayoutSelectParent (ищет вверх по DOM), HTMLayoutVisitElements (ищет не по css-селектору, а по именам тагов и аттрибутов, которые могут содержать wildcards).

1. Добавление/удаление элементов
Реализуется, соответственно, функциями: HTMLayoutInsertElement, HTMLayoutDetachElement.
Полезно знать:
* элемент, удаленный из DOM, можно использовать и дальше (например, вставить в другое место DOM), пока он актуален. Актуальность контролируется счетчиком ссылок элемента (Примечание 2).
* элемент вставляемый в DOM при помощи HTMLayoutInsertElement, может быть:
а) совершенно новым элементом, созданным с помощью HTMLayoutCreateElement
б) элементом, ранее вытащенным из DOM с помощью HTMLayoutDetachElement
в) клоном существующего элемента, созданным с помощью HTMLayoutCloneElement.
* чтобы отсортировать элементы, лежащие в контейнере (например, строки в таблице), не нужно их все по очереди удалять из DOM и опять вставлять: для этого существует специальная функция HTMLayoutSortElements
* если нужно сделать элемент "временно невидимым", а потом опять показать (например, как реакцию на кнопку "Скрыть/Показать подробности"), то лучше делать это не удалением/вставкой, а с помощью изменения стилей (например, установить атрибут class в hidden, а в CSS прописать: ".hidden{display:none;}")
* некоторые изменения DOM вызывают side effects (вставку дополнительных, "синтетических" элементов). Например, если в таблицу с 5 колонками вставить tr, в котором всего 4 ячейки, в него добавится дополнительная, пятая синтетическая ячейка.
* находится ли данный элемент в DOM, и если да, то какого окна, можно узнать функцией HTMLayoutGetElementHwnd.
* порядковый номер данного элемента внутри его родительского элемнта можно узнать функцией HTMLayoutGetElementIndex.

2. Изменение HTML элементов DOM
Выполняется, естественно, функциями HTMLayoutGetElementHtml/HTMLayoutSetElementHtml.
Важно понимать, что не все прямые изменения HTML одинаково полезны (и безопасны). Например, попытка установить для элемента <tr> какой-нибудь другой html, кроме набора <td>, может привести к совершенно непредсказуемым последствиям.

Лично я предпочитаю использовать HTMLayoutSetElementHtml только в простейших случаях, когда нужно, скажем, в ячейке таблицы написать "немножко <b>жирного</b> текста", а все более глобальные изменения UI выполнять методами, описанными в разделе 1.

3. Изменение текста элементов DOM
Чтобы узнать текст, используются функции HTMLayoutGetElementText, HTMLayoutGetElementInnerText — первая вернет текст с "дырками" на месте дочерних элементов, вторая — полный текст. (например, для элемента "<p>some text with <b>bold</b> part</p>" первая вернет "some text with \0 part", вторая — "some text with bold part").

Чтобы изменить текст, используется функция HTMLayoutSetElementInnerText. Внимание! Все дочерние элементы будут удалены. (То есть вызывать эту функцию для <table> — не очень разумная идея).

Эти функции (как и большинство других функций HTMLayout) работают с текстом в кодировке UTF-8.

Существуют также UTF-16 варианты: HTMLayoutGetElementInnerText16, HTMLayoutSetElementInnerText16.

4. Изменение аттрибутов элементов DOM
Перебор всех аттрибутов: HTMLayoutGetAttributeCount, HTMLayoutGetNthAttribute
Запрос/установка значения аттрибута по имени: HTMLayoutGetAttributeByName, HTMLayoutSetAttributeByName.
Сброс всех аттрибутов: HTMLayoutClearAttributes.

БОльшую часть всех аттрибутов можно использовать разве что для изменения стиля элемента (например, установить элементу "class=red", если в CSS прописано ".red{color:red;}" и т.п.)

Впрочем, есть некоторые аттрибуты, которые обрабатывает сам HTMLayout, и их изменение вызовет side effects. Примеры:
* аттрибут src тега img (изменит отображаемую картинку)
* аттрибут fixedrows тега table (изменит количество "непрокручиваемых" строк таблицы)
* аттрибут type тега input (изменит тип элемента ввода)

5. Изменение состояния элементов DOM
HTMLayoutGetElementState/HTMLayoutSetElementState

Используется для запроса и установки состояний элементов, которые изменяются под действиями пользователя.
Например:
* выбранный чекбокс имеет состояние STATE_CHECKED
* элемент в фокусе имеет состояние STATE_FOCUS
* элемент, над которым находится мышка, имеет состояние STATE_HOVER
Вообще, все возможные состояния перечислены в enum ELEMENT_STATE_BITS в файле htmlayout_dom.h. Там же — подробные комментарии, какое состояние что означает.

Очевидно, что элемент может иметь несколько состояний одновременно (допустим, FOCUS | HOVER | CHANGED).

Полезные применения состояний:
* просто запросить (мышка над этим элементом?)
* установить (скажем, состояние VISITED для ссылки)
* использовать в CSS-селекторах (практически каждому STATE_XXXX соответствует CSS-селектор :xxxx) — таким образом можно, например, установить особый стиль для элемента, над которым мышь; или для нажатой кнопки (STATE_ACTIVE, :active) или для отключенного (STATE_DISABLED, :disabled)

Вообще, работа с состояниями идет согласно с человеческой логикой: если нужно изменить состояние некоего элемента (например, свернутый/развернутый для вершины дерева), нужно в первую очередь поискать соответствующую константу STATE (STATE_COLLAPSED/STATE_EXPANDED).


6. Изменение "значения" (value) элементов DOM
HTMLayoutControlGetValue/HTMLayoutControlSetValue — удобные "шорткаты" для работы с элементами ввода, позволяет однообразно запросить/установить значение для разных элементов. Все, что делается этими функциями, может быть сделано и без них (но несколько менее удобно).

Например:
* для поля ввода текста, value — это и будет вводимый текст; его также можно запросить/установить с помощью GetText/SetText
* для чекбокса, value — булевое значение "выбран/не выбран"; его также можно запросить/установить с помощью GetState/SetState (STATE_CHECKED)
* для списка, value — это выбранная option; чтобы узнать ее "руками", надо найти option со state = STATE_CHECKED
и т.п.

Некоторые дополнительные сведения
* в htmlayout_dom.h определено еще несколько полезных функций. Часть из них я опишу в следующих главах — работа с behaviors и events, работа с popup-ами; другую часть (HTMLayoutScrollToView и т.п.) оставляю для самостоятельного изучения.
* все функции htmlayout_dom.h возвращают HLDOM_RESULT; возможные его значения можно посмотреть все в том же файле. Кодом успеха являются HLDOM_OK, HLDOM_OK_NOT_HANDLED, все остальные — коды ошибки (операция не удалась). Впрочем, из этого правила есть исключения: например, функция HTMLayoutGetElementHwnd на "детачнутом" элементе вернет HLDOM_INVALID_HWND, что можно считать не ошибкой, а просто символом "неприаттаченности элемента".

Все, на сегодня хватит.



Примечание 1
В первом приближении можно считать, что один DOM-элемент соответствует одному теги исходного текста HTML, впрочем, из этого правила есть исключения . Например, вот такой исходный HTML:
<select>
  <option>1</option>
  <option>2</option>
  <option>3</option>
</select>

(выпадающий список с 3-мя элементами) "на самом деле" преобразуется вот в такой:
<select>
  <caption></caption>
  <select>
    <option>1</option>
    <option>2</option>
    <option>3</option>
  <select>
</select>

В некоторых случаях этот нюанс оказывается важным.

Примечание 2
Элементы DOM HTMLayout — это объекты со счетчиками ссылок, они удаляются, когда счетчик ссылок равен 0. Пользователь может контролировать счетчик ссылок функциями HTMLayout_UseElement, HTMLayout_UnuseElement. Пока элемент находится в DOM, счетчик ссылок у него > 0. Если пользователь удалил элемент из DOM (HTMLayoutDetachElement), то его можно продолжать использовать дальше, пока счетчик ссылок > 0.
FAQ — це мiй ай-кью!
Re[2]: 1. Работа с DOM HTMLayout
От: c-smile Канада http://terrainformatica.com
Дата: 24.11.06 03:18
Оценка: 52 (5)
Здравствуйте, Зверёк Харьковский, Вы писали:

Класс, зверски клево


Небольшой коментарий по поводу:

ЗХ>Примечание 2

ЗХ>Элементы DOM HTMLayout — это объекты со счетчиками ссылок, они удаляются, когда счетчик ссылок равен 0. Пользователь может контролировать счетчик ссылок функциями HTMLayout_UseElement, HTMLayout_UnuseElement. Пока элемент находится в DOM, счетчик ссылок у него > 0. Если пользователь удалил элемент из DOM (HTMLayoutDetachElement), то его можно продолжать использовать дальше, пока счетчик ссылок > 0.

Прямой аналог HTMLayout_UseElement, HTMLayout_UnuseElement это AddRef и Release в COM.

Поэтому голый HTMLayoutDetachElement звать не надо. А надо так:

1) HTMLayout_UseElement(el) <- ++refcount = 2
2) HTMLayoutDetachElement(el) <- удален из контейнера соответсвенно --refcount = 1
3) HTMLayoutInsertElement(some_other_parent, el); <- добавлен в другой контейнер, соответсвенно ++refcount = 2
4) HTMLayout_UnuseElement(el) <- --refcount = 1. ( refcount == 1 — parent держит данный элемент)

Для C++ есть класс в htmlayout_dom.hpp:

htmlayout::dom::element
.
Это smart pointer элемента DOM который делает Use/UnuseElement когда надо +
все API методы обернуты в нечто более привычное для C++ по нотации и способу пользования.


Зверь, еще раз большое спасибо.
Re[2]: 1. Работа с DOM HTMLayout
От: FreshMeat Россия http://www.rsdn.org
Дата: 24.11.06 10:55
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Управление всем UI происходит, как правило, работой с элементами DOM.


Зверек, респект!
Меня давно покусавало за ласты желание написать подобный мануал, но по качеству и охвату он был бы сильно хуже. Отличная работа
Хорошо там, где мы есть! :)
Re: HTMLayout User Guide
От: Alex Reyst Россия  
Дата: 24.11.06 11:44
Оценка: +4
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Решил написать сабж потихоньку (прямо тут, в форуме, а чо?).


Я так думаю, что это надо чуть-чуть довести до ума и оформить в качестве серии статей на RSDN, а не просто форумных сообщений. Заметнее будет, нет?
Все, что здесь сказано, может и будет использоваться против меня...
Re[2]: HTMLayout User Guide
От: Зверёк Харьковский  
Дата: 24.11.06 12:07
Оценка:
Здравствуйте, Alex Reyst, Вы писали:

ЗХ>>Решил написать сабж потихоньку (прямо тут, в форуме, а чо?).


AR>Я так думаю, что это надо чуть-чуть довести до ума и оформить в качестве серии статей на RSDN, а не просто форумных сообщений. Заметнее будет, нет?


С одной стороны да.
С другой стороны:
1. этим (оформлением, причесыванием) должен кто-то заниматься.
2. для этого нужно написать вводную статью "что такое HTMLayout, кому и зачем он нужен".
3. увеличить иллюстративность материала — нужны и примеры кода, и картинки.
ничем из этого мне, честно говоря, заниматься не хочется абсолютно. просто неинтересно.
FAQ — це мiй ай-кью!
Re[3]: HTMLayout User Guide
От: Alex Reyst Россия  
Дата: 24.11.06 12:18
Оценка: +1
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>С другой стороны:


А ты не преувеличивай сложность.
Просто согласуй фактическую сторону дела с Андреем. Он ведь делает дельные замечания
Автор: c-smile
Дата: 24.11.06
. Станьте соавторами, наконец — я не понимаю, например, его скромности в продвижении библиотеки на российский рынок. Денег он здесь не добудет — но есть ведь еще и слава

А хорошая статья — это просто полезная статья, а не красиво оформленная и т.п. Взялся за гуж... и далее...
Все, что здесь сказано, может и будет использоваться против меня...
Re[2]: HTMLayout User Guide
От: anonymous Россия http://denis.ibaev.name/
Дата: 24.11.06 13:41
Оценка: +2
Здравствуйте, Alex Reyst, Вы писали:

ЗХ>>Решил написать сабж потихоньку (прямо тут, в форуме, а чо?).

AR>Я так думаю, что это надо чуть-чуть довести до ума и оформить в качестве серии статей на RSDN, а не просто форумных сообщений. Заметнее будет, нет?

Вот для этого пригодилась бы вики. Однако ж мечты.
Re[3]: HTMLayout User Guide
От: anonymous Россия http://denis.ibaev.name/
Дата: 24.11.06 16:50
Оценка: +1
Здравствуйте, anonymous, Вы писали:

A>Вот для этого пригодилась бы вики. Однако ж мечты.


Хотя для HTMLayout User Guide вики может поставить и с-smile на своём сайте.
Re[3]: HTMLayout User Guide
От: akasoft Россия  
Дата: 24.11.06 22:51
Оценка:
Здравствуйте, anonymous, Вы писали:

A>Вот для этого пригодилась бы вики.


Полагаю, Януса и превью в нём вполне достаточно
Автор: anvaka
Дата: 15.05.06
.

Для умельца по Ворду есть Шаблон для верстки статей RSDN
Автор: Виталий Брусенцев
Дата: 30.07.03
.

И вообще, вначале нужно сочинить, а уже потом красиво разметить.
... << RSDN@Home 1.2.0 alpha rev. 668>> SQL Express 2005
Re[4]: HTMLayout User Guide
От: c-smile Канада http://terrainformatica.com
Дата: 25.11.06 01:42
Оценка:
Здравствуйте, anonymous, Вы писали:

A>Здравствуйте, anonymous, Вы писали:


A>>Вот для этого пригодилась бы вики. Однако ж мечты.


A>Хотя для HTMLayout User Guide вики может поставить и с-smile на своём сайте.


Согласен, имеет смысл.
На самом деле была вики один раз. Закрыл благодаря усилиям вот этих товарищей:
http://www.spamhaus.org/statistics/spammers.lasso
Re[4]: HTMLayout User Guide
От: anonymous Россия http://denis.ibaev.name/
Дата: 25.11.06 08:27
Оценка:
Здравствуйте, akasoft, Вы писали:

A>>Вот для этого пригодилась бы вики.

A>Полагаю, Януса и превью в нём вполне достаточно
Автор: anvaka
Дата: 15.05.06
.

A>Для умельца по Ворду есть Шаблон для верстки статей RSDN
Автор: Виталий Брусенцев
Дата: 30.07.03
.

A>И вообще, вначале нужно сочинить, а уже потом красиво разметить.

Я говорю о совместном сочинении, а не об украшательстве.
Re[2]: 1. Работа с DOM HTMLayout
От: adontz Грузия http://adontz.wordpress.com/
Дата: 25.11.06 16:48
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>

ЗХ>Примечание 1
ЗХ>В первом приближении можно считать, что один DOM-элемент соответствует одному теги исходного текста HTML, впрочем, из этого правила есть исключения . Например, вот такой исходный HTML:
ЗХ>
ЗХ><select>
ЗХ>  <option>1</option>
ЗХ>  <option>2</option>
ЗХ>  <option>3</option>
ЗХ></select>
ЗХ>

ЗХ>(выпадающий список с 3-мя элементами) "на самом деле" преобразуется вот в такой:
ЗХ>
ЗХ><select>
ЗХ>  <caption></caption>
ЗХ>  <select>
ЗХ>    <option>1</option>
ЗХ>    <option>2</option>
ЗХ>    <option>3</option>
ЗХ>  <select>
ЗХ></select>
ЗХ>

ЗХ>В некоторых случаях этот нюанс оказывается важным.

Ещё один важный случай

<table>
  <tr>
    <td>одын ячёка</td> <!-- Вах, нет ячейка. Абидна, да? -->
  </tr>
  <tr>
    <td>одын ячёка</td><td>другой ячёка</td>
  </tr>
</table>


Все сгенерированные элементы имеют установленный бит состояния STATE_SYNTHETIC, что позволяет их отсеивать.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: 1. Работа с DOM HTMLayout
От: Зверёк Харьковский  
Дата: 25.11.06 20:05
Оценка:
Здравствуйте, adontz, Вы писали:

A>Ещё один важный случай


A>
A><table>
A>  <tr>
A>    <td>одын ячёка</td> <!-- Вах, нет ячейка. Абидна, да? -->
A>  </tr>
A>  <tr>
A>    <td>одын ячёка</td><td>другой ячёка</td>
A>  </tr>
A></table>
A>


A>Все сгенерированные элементы имеют установленный бит состояния STATE_SYNTHETIC, что позволяет их отсеивать.


Было помянуто:

* некоторые изменения DOM вызывают side effects (вставку дополнительных, "синтетических" элементов). Например, если в таблицу с 5 колонками вставить tr, в котором всего 4 ячейки, в него добавится дополнительная, пятая синтетическая ячейка.


Правда, я не расшифровал "синтетическая".
FAQ — це мiй ай-кью!
Re: HTMLayout User Guide
От: Kubyshev Andrey  
Дата: 26.11.06 20:36
Оценка: +1
ЗХ>Ну-с, с Б-гом!

Есть те кто мечтают (я), а есть те кто делают! Респект!
Re: HTMLayout User Guide
От: Left2 Украина  
Дата: 27.11.06 10:40
Оценка:
Спрошу здесь — благо в этой ветке вижу и создателя библиотеки, и людей которые её юзали. У меня есть HTA-application, средней величины — и есть мечта уползти от MSHTML и пришить HTMLLayout, за счёт чего получить возможность портировать всё это на CE (я правильно понимаю что HTMLLayout работает на CE?).

Так вот — хотелось бы узнать во сколько уважаемые знатоки ( ) оценят трудоёмкость переезда с MSHTML на HTMLLayout? В частности, у меня на форме хостятся пару ActiveX-ов (грубо говоря — самописные ListControl и TreeControl). Как у HTML Layout с поддержкой ActiveX?. Плюс к этому, через window.external в клиентский JavaScript выставляется довольно много ActiveX-контролов (писаных на ATL). Насколько трудоёмко переписать их под HTMLLayout? Да, и есть ли проблемы с переездом JavaScript из MS-овской имплементации в имплементацию HTMLLayout?
Ну и самый интересный для меня вопрос — насчёт отладки JavaScript внутри HTMLLayout — возможно ли это, есть ли выделенный отладчик, и т.п.

Заранее благодарен за ответы — развёрнутых ответов не прошу, буду рад хотя бы просто ссылкам или ключевым словам.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: HTMLayout User Guide
От: Зверёк Харьковский  
Дата: 27.11.06 10:49
Оценка: 4 (1)
Здравствуйте, Left2, Вы писали:

L>Спрошу здесь — благо в этой ветке вижу и создателя библиотеки, и людей которые её юзали. У меня есть HTA-application, средней величины — и есть мечта уползти от MSHTML и пришить HTMLLayout, за счёт чего получить возможность портировать всё это на CE (я правильно понимаю что HTMLLayout работает на CE?).


L>Так вот — хотелось бы узнать во сколько уважаемые знатоки ( ) оценят трудоёмкость переезда с MSHTML на HTMLLayout? В частности, у меня на форме хостятся пару ActiveX-ов (грубо говоря — самописные ListControl и TreeControl). Как у HTML Layout с поддержкой ActiveX?. Плюс к этому, через window.external в клиентский JavaScript выставляется довольно много ActiveX-контролов (писаных на ATL). Насколько трудоёмко переписать их под HTMLLayout? Да, и есть ли проблемы с переездом JavaScript из MS-овской имплементации в имплементацию HTMLLayout?

L>Ну и самый интересный для меня вопрос — насчёт отладки JavaScript внутри HTMLLayout — возможно ли это, есть ли выделенный отладчик, и т.п.

L>Заранее благодарен за ответы — развёрнутых ответов не прошу, буду рад хотя бы просто ссылкам или ключевым словам.


Про ActiveX ответ чисто теоретический (сам не пробовал):
в HTML пишешь следующее
<widget type=my-cool-type/>


И HTMLayout присылает тебе нотификации, которые нужно обработать (HLN_CONTROL_CREATED), в ответ на который ты можешь создавать контрол и возвращать его HWND.

По поводу JavaScript: HTMLayout — это чисто layout-движок, встроенного скрипта там нету. HTMLayout со встроенным скриптом называется Sciter — вариация языка, которая там используется, описана вот тут.
FAQ — це мiй ай-кью!
Re[3]: HTMLayout User Guide
От: Left2 Украина  
Дата: 27.11.06 11:05
Оценка:
ЗХ>По поводу JavaScript: HTMLayout — это чисто layout-движок, встроенного скрипта там нету. HTMLayout со встроенным скриптом называется Sciter — вариация языка, которая там используется, описана вот тут.

Спасибо, за ответы! А какая лицензия на Sciter? Как говорят у нас таксисты — шо по деньгам?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: HTMLayout User Guide
От: Зверёк Харьковский  
Дата: 27.11.06 11:08
Оценка: 4 (1)
Здравствуйте, Left2, Вы писали:

ЗХ>>По поводу JavaScript: HTMLayout — это чисто layout-движок, встроенного скрипта там нету. HTMLayout со встроенным скриптом называется Sciter — вариация языка, которая там используется, описана вот тут.


L>Спасибо, за ответы! А какая лицензия на Sciter? Как говорят у нас таксисты — шо по деньгам?


ЕМНИП, такая же (все бесплатно, premium support — за деньги).
FAQ — це мiй ай-кью!
Re: 2. Обработка событий: events and behaviors
От: Зверёк Харьковский  
Дата: 29.11.06 15:41
Оценка: 108 (7)
Эта глава посвящена обработке событий. "События" в терминах HTMLayout — это, в общем, именно то, что можно предположить логически: сообщения, посылаемые в результате каких-либо действий пользователя. HTMLayout посылает и "физические" события (кликнута мышь, нажата кнопка на клавиатуре), и "логические" (кликнута кнопка, изменился фокус). Все события разделены на несколько групп (мышь, клавиатура, фокус, рисование и т.п.), описанных в enum EVENT_GROUPS в файле htmlayout_behavior.h, подписаться можно на одну или несколько групп. Но, прежде чем мы поговорим о подписке на события и их обработке, вкратце разберемся, как и куда они посылаются.

Модель передачи событий в HTMLayout

HTMLayout реализует так называемую "event sinking/bubbling model" ("модель погружения/всплытия"). В ней событие проходит 2 раза: от всего окна к конкретному элементу, и от элемента к окну. Например, если есть вот такой html:
<html>
  <body>
    <p><button>click me, please!</button></p>
  </body>
</html>


...и пользователь кликает по кнопке "click me, please!", то событие MOUSE_DOWN | SINKING (это две константы, объединенные операцией "или") будет последовательно получено элементами DOM, соответствующими "html", "body", "p", "button", а затем, событие MOUSE_DOWN (уже без флага SINKING) будет последовательно получено элементами "button", "p", "body", "html".

В любом из этих элементов событие может быть обработано (если "повесить" соответствующий обработчик) и пропущено дальше (возвращением FALSE из обработчика) или остановлено (возвращением TRUE). Если событие "остановлено", оно считается обработанным и последующим элементам не передается. Причем, если остановить событие еще на стадии "погружения" (sinking), то и никакого "всплытия" не будет. Например, если повесить на элемент <html> обработчик клавиатурных событий и всегда возвращать из него TRUE, никакие другие элементы "видеть клавиатуру" не будут.

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

Обработка событий

Для того, чтобы обработать событие, нужно "прицепить" к элементу DOM обработчик события Делается это функцией HTMLayoutAttachEventHandler или HTMLayoutAttachEventHandlerEx (первая подписывает на все события, последняя позволяет указать, на какие именно группы событий вы подписываетесь).

Внимание! Если подписаться на события смены фокуса (HANDLE_FOCUS), то элемент, к которому прицеплен обработчик, считается focusable (в него будет попадать фокус по Tab). Это не всегда то, что вы имели в виду. Поэтому функцией HTMLayoutAttachEventHandler (которая подписывает на все события) нужно пользоваться с осторожностью.

Обработчик события, который передается как аргумент в функцию HTMLayoutAttachEventHandler(Ex) — это C-функция со следующим прототипом:

BOOL CALLBACK ElementEventProc(LPVOID tag, HELEMENT he, UINT evtg, LPVOID prms);


Здесь he — хэндл того элемента DOM, к которому цеплялся обработчик, evtg — группа событий, prms — параметры события, для каждой группы событий они свои.

Замечание. Обратите внимание, что he — это элемент, к которому прицеплен обработчик, а не тот, с которым произошло событие. Для примера выше, если обработчик повешен на <html>, а кликнули по кнопке, то he будет равен хендлу <html>, а p->target в примере ниже — хэндлу <button>

Вот типичный "тупой" код обработчика всех событий (тупой — в смысле, в лоб):
BOOL CALLBACK naive_handler(LPVOID tag, HELEMENT he, UINT evtg, LPVOID prms )
{
  switch( evtg )
  {
    case HANDLE_MOUSE:
    {
      MOUSE_PARAMS *p = (MOUSE_PARAMS *)prms; //специфичные для мыши параметры

      HELEMENT target = p->target;//узнаем элемент, на который реально кликнули
      
      switch(p->cmd) //вот это - конкретное событие
      {
        case MOUSE_DOWN: ...
        case MOUSE_UP: ...
        case MOUSE_MOVE: ...
        ...
      }
    }
    case HANDLE_KEY:
    {
      //та же петрушка, в общем
      KEY_PARAMS *p = (KEY_PARAMS *)prms;
      HELEMENT target = p->target;
      switch(p->cmd){...}
    }
    ....
  }

  return FALSE;
}


Все структуры MOUSE_PARAMS, KEY_PARAMS и т.п.; константы, соответствующие конкретным событиям и прочая справочная информация доступна, опять же, в htmlayout_behavior.h

Замечание. Обратите внимание, что, если хотите поймать событие на стадии погружения, нужно проверять код события (p->cmd в коде выше) на наличие в нем флага SINKING (то есть на стадии погружения код события будет MOUSE_DOWN | SINKING).

Бережно относитесь к возвращаемому значению! Напоминаю, если вернуть TRUE, то событие дальше не пойдет.


Концепция behaviors (поведений)

Behavior (поведение) в модели HTMLayout — это именованный набор обработчиков событий, который можно "прицепить" к элементу DOM декларативно, написав в CSS:
behavior: name-of-my-behavior;


Встретив такую конструкцию в CSS, HTMLayout посылает notification HLN_ATTACH_BEHAVIOR, аргументом передавая "name-of-my-behavior", в обработчике которой можно сделать с соответствующим элементом что угодно (увы, глава по notifications мною еще не написана, она будет следующей).

Существуют несколько встроенных поведений, о которых знает HTMLayout, например, все контролы (поля ввода, чекбоксы, списки и т.п.) — это всего лишь поведения. То есть, если написать в CSS, к примеру:
td{
  behavior: edit;
}

...то получим таблицу с редактируемым текстом ячеек. Редактор в ячейках будет вести себя совершенно так же, как и <input type=text>. Самое смешное, что можно и наоборот:
input[type=text]{
  behavior: none;
}

...и поля ввода больше не будут таковыми

Замечание. На сайте HTMLayout есть такая вещь, как Master style sheet — таблица стилей, которые определяют внешний вид элементов по умолчанию. Там можно подсмотреть, какой набор стилей (в том числе behavior) определяет тот или иной элемент.

Интересная вещь, связанная с поведениями, определенными в CSS — можно легко изменить. Например, если определить в CSS стили таким образом:
td:current /*поведение edit только у ячейки в состоянии STATE_CURRENT*/
{
  behavior:edit;
}

...то меняя state (состояние) ячеек таблицы, мы меняем и их "редактируемость".

Напоследок остается сказать, что в HTMLayout SDK поставляются достаточно удобные C++-классы, облегчающие создание своих поведений (см. htmlayout_behavior.hpp).

В папке behaviors/ содержатся также несколько примеров поведений, созданных на основе этих классов (например, табы-закладки, разворачиваемые списки и прочие приятности).

Замечание. Поведения в папке behaviors/ не являются встроенными. То есть, чтобы использовать их в своей программе, придется слинковаться с соответствующими cpp-файлами и обработать HLN_ATTACH_BEHAVIOR.




Хватит покуда. Следующая глава — про notifications.
Оставляйте заявки, задавайте вопросы.
FAQ — це мiй ай-кью!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.