Руководство программиста в Photon (1037671), страница 34
Текст из файла (страница 34)
typedef struct Pt_callback_info {
unsigned long reason;
unsigned long reason_subtype;
PhEvent_t *event;
void *cbdata;
} PtCallbackInfo_t;
Элементы структуры PtCallbackInfo_t имеют следующий смысл:
| – указывает причину вызова ответной реакции; обычно это устанавливается на имя ресурса ответной реакции, чей список ответных реакций был вызван. |
| – указывает конкретный тип ответной реакции, связанный с reason; для большинства ответных реакций это значение равно 0. |
| – указатель на структуру PhEvent_t (см. "Справочник библиотечных функций Photon'а"), которая описывает событие Photon'а, послужившее причиной вызова ответной реакции. |
| – вызывает данные, которые являются специфическими для ресурса ответной реакции, послужившей причиной вызова функции ответной реакции. |
Для получения более полной информации см. описание ответных реакций, определённых для каждого виджета, в "Справочнике виджетов".
Удаление ответных реакций
Вы можете удалить одну или более ответных реакций из списка ответных реакций, связанных с ресурсом виджета, используя функции PtRemoveCallbacks() и PtRemoveCallback().
Не пытайтесь удалять ответные реакции, которые были добавлены через PhAB; результатом может стать непредсказуемое поведение.
Функция PtRemoveCallbacks() берёт массив записей ответных реакций как аргумент и удаляет все ответные реакции, заданные ей в списке ответных реакций. Функция PtRemoveCallback() удаляет только одну функцию ответной реакции из списка ответных реакций. Обе функции берут виджет как первый аргумент и ресурс виджета как второй аргумент.
Чтобы удалить ответную реакцию с кнопки, созданной нами выше, мы должны сделать следующее:
int push_button_cb( PtWidget_t *, void *, PtCallbackInfo_t *);
PtCallback_t callbacks[] = { {push_button_cb, NULL} };
PtRemoveCallbacks(button, Pt_CB_ACTIVATE, callbacks, 1);
или так:
int push_button_cb( PtWidget_t *, void *, PtCallbackInfo_t *);
PtRemoveCallback(button, Pt_CB_ACTIVATE, push_button_cb,
[Прим.пер. – так в тексте, без последнего параметра. Вероятно, должнен быть равен 1].
Оба – указатель на функции ответной реакции и указатель на данные клиента – важны при удалении ответных реакций. Только первый элемент списка ответных реакций, который имеет одновременно и ту же функцию ответной реакции, и тот же указатель на данные клиента, будет удалён из списка ответных реакций.
Просмотр ответных реакций
Вы можете просмотреть список ответных реакций, чтобы получить значение соответствующего ресурса списка ответных реакций. Тип значения, которое Вы получаете из ресурса списка ответных реакций, отличается от значения, использованного для установки ресурса. Несмотря на то, что этот ресурс установлен на массив записей ответных реакций, значение, полученное при получении ресурса, является указателем на список записей ответных реакций. Типом этого списка является PtCallbackList_t. Каждый элемент списка содержит член cb (т.е. запись ответной реакции) и следующий указатель (который указывает на следующий элемент списка).
Следующий пример показывает, как Вы можете пройти по списку ответных реакций Pt_CB_ACTIVATE для виджета, чтобы найти все экземпляры конкретной функции ответной реакции cb:
...
PtCallbackList_t *cl;
PtGetResources(widget, Pt_CB_ACTIVATE, &cl, 0);
for ( ; cl; cl = cl->next )
{
if ( cl->cb.func == cb )
break;
}
Обработчики событий
Вы можете добавлять и удалять обработчики событий (необработанные или отфильтрованные ответные реакции) в программном коде Вашего приложения, так же как и в PhAB – однако, имеются несколько отличий между двумя типами.
Описание необработанных и отфильтрованных ответных реакций, и то, как это используется, см. в разделе "Обработчики событий – необработанные и отфильтрованные ответные реакции" в главе "События".
Для получения более полной информации по добавлению обработчиков событий в PhAB см. раздел "Обработчики событий – необработанные и отфильтрованные ответные реакции" в главе "Редактирование ресурсов и ответных реакций в PhAB".
Добавление обработчиков событий
Как и в случае ответных реакций, Вы так же можете установить или просмотреть обработчики событий, чтобы выполнить установку или получить данные, в ресурсе обработчика событий. Следующие ресурсы в PtWidget позволяют Вам задавать обработчики для событий Photon'a:
-
Pt_CB_FILTER
-
Pt_CB_RAW
Для получения более полной информации по этим ресурсам ответных реакций см. "Справочник виджетов Photon'a".
Операция установки требует массива записей обработчиков событий типа PtRawCallback_t. Они похожи на записи ответных реакций, обсуждавшиеся выше, и имеют поля event_mask, event_f и data.
Поле event_mask – это маска типов событий Photon'a (см. описание PhEvent_t в "Справочнике библиотечных функций Photon'a"), указывающая, какие события будут являться причиной вызова функции ответной реакции [Прим. пер. Наверное, это неточность: не функции ответной реакции, а функции обработчика ]. Члены event_f и data – это функция обработчика события и данные клиента соответственно.
Если Вы добавляете обработчик событий реализованному виджету и регион виджета нечувствителен к одному или более типов событий, содержащихся в маске событий, то регион делается чувствительным к ним.
Если Вы добавляете обработчик событий перед тем, как реализовать виджет, Вы должны приспособить чувствительность региона сами, после того как виджет будет реализован. См. функцию PhRegionChange() в "Справочнике библиотечных функций Photon'a".
Операция получения данных получает список PtRawCallbackList* записей обработчиков событий. Как и в случае списка ответных реакций, список содержит два члена: next и cb. Член cb – это запись обработчика события.
Вы можете добавить обработчики событий Pt_CB_RAW, используя функции PtAddEventHandler() или PtAddEventHandlers(). Вы можете добавить обработчики событий Pt_CB_FILTER, используя функции PtAddFilterCallback() или PtAddFilterCallbacks(). Аргументами PtAddEventHandler() и PtAddFilterCallback() являются:
widget | Виджет, к которому должен быть добавлен обработчик события |
event_mask | Маска событий определяет, какие события будут приводить к вызову обработчика событий |
event_f | Функция обработки события |
data | Указатель, передаваемый обработчику событий и указывающий на клиентские данные |
Аргументами функций PtAddEventHandlers() и PtAddFilterCalbacks() являются:
widget | Виджет, к которому должны быть добавлены обработчики событий |
handlers | Массив записей обработчиков событий |
nhandlers | Число обработчиков событий, задаваемых в массиве |
Удаление обработчиков событий
Вы можете удалить обработчики событий Pt_CB_RAW, вызвав функции PtRemoveEventHandler() или PtRemoveEventHandlers(). Вы можете удалить обработчики событий Pt_CB_FILTER, вызвав функции Pt_RemoveFilterCallback() или Pt_RemoveFilterCallbacks().
Не удаляйте обработчики событий, которые были добавлены через PhAB; результатом может стать непредсказуемое поведение.
Параметрами функций PtRemoveEventHandler() и PtRemoveFilterCallback() являются:
widget | Виджет, с которого удаляется обработчик событий |
event_mask | Маска событий, задающая события, к которым чувствителен обработчик |
event_f | Функция обработки события |
data | Данные клиента, присоединённые к обработчику |
Это выполняет поиск обработчика событий с такой сигнатурой – т.е. идентичными event_mask, data и event_f – в виджете и удалении такового, если он найден.
Параметрами функций PtRemoveEventHandlers() и PtRemoveFilterCallbacks() являются:
widget | Виджет, с которого удаляются обработчики событий |
handlers | Массив записей обработчиков событий |
nhandlers | Число обработчиков событий, определённых в массиве |
Как и для функций PtRemoveEventHandler() и PtRemoveFilterCallback(), обработчик событий удаляется только тогда, когда он имеет в точности ту же сигнатуру, что и один из обработчиков событий, заданных в массиве записей обработчиков событий.
Запуск обработчика событий
При запуске обработчики событий получают те же аргументы, что и функции ответных реакций, т.е. параметрами являются:
-
виджет, получивший событие (widget)
-
данные клиента, присоединённые к обработчику событий (client_data)
Данные клиента, передаваемые обработчику событий, не являются такими, как и данные apinfo, передаваемые обработчику событий, добавленному через PhAB.
-
информация ответной реакции, связанная с конкретным событием (info).
Обработчики событий возвращают целое значение, которое обработчик события должен использовать для указания на то, должна ли или не должна производиться дальнейшая обработка события. Если обработчик событий возвращает значение Pt_END, это указывает, что дальнейшая обработка события Photon не выполняется, и событие исчерпано.
Член event параметра info содержит указатель на события, послужившие причиной запуска обработчика событий. Вы должны проверить для этого события член type, чтобы определиться, как поступить с этим событием. Это будет один из типов событий, определённых в event_mask, заданной при добавлении обработчика событий к виджету.
Для получения данных, присоединённых к конкретному событию, вызывается функция PhGetData() с указателем на событие в качестве параметра. Эта функция вернёт указатель на структуру с данными, специфическими для данного конкретного типа события. Этот тип структуры зависит от типа события.
Стили виджетов
Стили классов виджетов позволяют Вам на лету подстраивать под себя или модифицировать внешний вид виджетов, их размеры и поведение. Они также обеспечивают различный внешний вид одного и того же типа виджета, существующие одновременно. В сущности, стиль класса виджета представляет из себя набор методов и данных, определяющих внешний вид и реакции экземпляров класса виджета.
Каждый класс виджета имеет принимаемый по умолчанию стиль, но Вы можете в любой момент добавить или модифицировать неограниченное количество дополнительных стилей. Вы можете даже модифицировать принимаемый по умолчанию для данного класса стиль, изменив внешний вид и реакцию любых экземпляров этого класса, которые используют принимаемый по умолчанию стиль.
Каждый экземпляр виджета может ссылаться на определённый стиль, обеспечиваемый его классом. Вы можете изменить стиль, которым какой-либо виджет сможет воспользоваться в любой момент, когда это Вам понадобится.
Каждый стиль имеет набор членов, включающих имя стиля и функции, которые заменяют или расширяют какие-либо методы класса виджета. Методы являются функциями уровня класса, определяющими, как виджет инициализирует себя, прорисовывает себя, вычисляет свои размеры и прочая. Для получения более полной информации о методах см. руководство "Построение подстраиваемых виджетов". Члены стиля определены следующими декларациями: