Руководство программиста в Photon (1037671), страница 9
Текст из файла (страница 9)
PtCallbackInfo_t *cbinfo )
{
/* предотвращает предупреждения (варнинги) об отсутствии ссылок */
link_instance = link_instance,
apinfo = apinfo,
cbinfo = cbinfo;
return( Pt_CONTINUE );
}
на следующий:
int aboutdlg_setup( PtWidget_t *link_instance,
ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo ) {
/* предотвращает предупреждения (варнинги) об отсутствии ссылок */
link_instance = link_instance, apinfo = apinfo, cbinfo = cbinfo;
PtSetResource( ABW_about_version, Pt_ARG_TEXT_STRING,
"1.00", 0);
return( Pt_CONTINUE );
}
Код поместит номер версии (1.00) в ресурс текстовой строки виджета about_version. Чтобы сделать это, код вызывает PtSetResource(), чтобы установить значение ресурса виджета about_version. Код использует сгенерированную PhAB'ом декларацию ABW_about_version, которая обеспечивает доступ к указателю на экземпляр виджета. Мы можем безопасно использовать эту декларацию, поскольку имеем дело с модулем диалога – PhAB гарантирует, что в данное время будет существовать только один экземпляр диалога.
-
Сохраните Ваши изменения и закройте текстовый редактор.
Компиляция и запуск на выполнение
Теперь Вы готовы компилировать и запускать программу.
-
Щёлкните кнопку "Make". Если Ваша программа откомпилирована и слинкована без ошибок (что и будет, если Вы корректно редактировали функцию), щёлкните на кнопку "Run" для запуска приложения.
-
Из запущенного приложения откройте меню "Help" и выберите пункт "About Demo". Откроется диалог и Вы увидите номер версии (1.00) под надписью "About this Demo". Заметьте, что диалог появится в заданном Вами месте.
-
Теперь попытайтесь вызвать второй экземпляр диалога. Как Вы видите, это не работает. PhAB всегда гарантирует, что существует только один экземпляр виджета диалога.
-
Щёлкните на "Done", чтобы закрыть диалог, затем завершите приложение, выбрав пункт "Quit" из меню "File". Наконец, закройте диалог "Build+Run".
Желаете узнать больше?
Чтобы узнать больше о: | См. раздел: | В главе: |
Использовании диалога | Модули диалога | Работа с модулями |
Именах экземпляров | Имена экземпляров Переменные и декларации | Создание виджетов в PhAB Работа с кодом |
Ответных реакциях | Ответные реакции Код функций ответных реакций | Редактирование ресурсов и ответных реакций в PhAB Работа с кодом |
Генерирование кода | Генерирование кода приложения | Генерирование, компиляция и запуск кода на выполнение |
Урок 5. Создание окон
На предыдущем уроке Вы научились, как оперировать модулями диалога, которые поддерживают только один экземпляр. На этом уроке Вы изучите, как оперировать модулями окна, которые поддерживают множественность экземпляров.
На этом уроке используется приложение, созданное Вами на уроке 4.
Для поддержания множественности экземпляров модули окна обеспечивают большую гибкость, нежели диалоги. Но чтобы получить преимущества этой гибкости, Вы должны поддерживать связь с каждым указателем на экземпляр окна. Это гарантирует Вам, что Вы корректно ссылаетесь на виджеты внутри каждого экземпляра окна. Вы не можете безопасно использовать сгенерированную глобальную декларацию ABW_xxx, поскольку она ссылается только на последний созданный экземпляр.
Для упрощения задачи работы с множественными экземплярами PhAB обеспечивает функции библиотеки API, позволяющие Вам получить доступ к любому виджету через его глобальную переменную – имя (ABN_xxx).
Создание окна
Для начала давайте создадим модуль окна и прикрепим его к пункту "New" меню "File" в tut4. Это окно будет содержать кнопки, которые изменяют цвет другого виджета.
На предыдущем уроке Вы создали модуль диалога из редактора ответных реакций. Но на этот раз Вы используете переключатель модулей (module selector), чтобы создать требуемый Вам модуль. В дальнейшем используйте тот метод, который Вам больше нравится.
-
Откройте приложение tut4, если Вы удалили его из рабочей области PhAB.
-
Сохраните приложение как tut5.
-
Сверните в иконку модуль диалога aboutdlg.
-
В меню "Application" выберите пункт "Windows", чтобы открыть переключатель модулей.
-
В области "Name" наберите newwin для имени экземпляра окна, затем нажмите <Enter> или щёлкните на "Open". Когда PhAB предложит Вам выбрать стиль окна, выберите "Plain" и щёлкните "Continue".
-
Закройте переключатель модулей. Модуль окна будет теперь выбранным элементом.
Прикрепление ответной реакции
Поскольку модуль окна поддерживает множественность экземпляров, Вы создаёте код функции, которая будет вызвана всякий раз, когда окно будет открыто или закрыто (т.е. всякий раз, когда окно создаётся или уничтожается). Так что давайте прежде всего установим ответную реакцию, определяющую, когда окно закрывается:
-
Переключитесь, если необходимо, на панель управления ответными реакциями.
-
Из списка ответных реакций выберите "Window Manager". Вы хотите использовать ответную реакцию менеджера окон, поскольку она вызывается, когда Photon'овский менеджер окон закрывает окно.
-
В зоне "Function" наберите newwin_close. Вы не выбираете тип обратной реакции, поскольку принимаемый по умолчанию "Code" – это то, что Вы хотите.
Щёлкните на "Apply", затем на "Done".
-
Переключитесь на панель управления ресурсами и выберите ресурс "Flags: Notify". Убедитесь, что флаг Ph_WM_CLOSE установлен (т.е. подсвечен), затем щёлкните на "Done". Этот флаг указывает менеджеру окон уведомлять Ваше приложение, когда окно закрывается.
-
Теперь давайте установим функцию, которая будет вызываться при открытии окна. Откройте модуль меню filemenu, затем выберите ресурс "Menu Items" в панели управления ресурсами. Вы увидите редактор меню.
-
Убедитесь, что в списке пунктов меню "Menu Items" выбран пункт "New", затем щёлкните на иконке ответной реакции, чтобы открыть редактор ответных сявзей.
-
Выберите тип модуля "Window", затем щёлкните на стрелке возле области "Name". Вы увидите список существующих модулей окон.
-
Выберите newwin, который является окном, только что Вами созданным.
-
В области "Setup Function" введите newwin_setup как имя установочной функции. В дальнейшем Вы модифицируете newwin_setup, чтобы манипулировать множественными экземплярами окон.
-
Щёлкнтте "Apply", затем "Done". Щёлкните ещё раз "Done", чтобы закрыть редактор меню.
Добавление виджетов
Давайте теперь добавим несколько виджетов в модуль окна newwin. Используя эти виджеты, Вы научитесь, как обновлять информацию в текущем или другом экземпляре модуля окна.
-
Добавьте виджет PtRect и четыре виджета PtButton, как показано ниже:
-
Теперь модифицируем левую кнопку:
-
Изменим текст надписи кнопки на Red.
-
Присвоим кнопке имя экземпляра btn_red
-
Прикрепим ответную реакцию "Activate", зададим тип кода "Code" и имя функции color_change.
-
Модифицируем среднюю кнопку:
-
Изменим текст надписи кнопки на Green.
-
Зададим имя экземпляра кнопки btn_green.
-
Прикрепим Activate/Code ответную реакцию к той же функции, что и выше – color_change.
-
Модифицируем правую кнопку:
-
Изменим текст надписи кнопки на Blue.
-
Зададим имя экземпляра кнопки btn_blue.
-
Прикрепим ответную реакцию типа Activate/Code к той же функции, что и выше – color_change.
-
Модифицируем большую кнопку:
-
Изменим текст надписи на "Change previous window's color".
-
Зададим имя экземпляра кнопки btn_prev.
-
Прикрепим ответную реакцию типа Activate/Code к той же функции, что и выше color_change.
-
Наконец, присвоим прямоугольнику имя экземпляра color_rect. Вам необходимо задать это имя, так чтобы функция color_change() могла изменить цвет прямоугольника.
Ваше окно теперь будет выглядеть таким образом:
Генерирование и модификация кода
На последнем уроке Вы использовали сгенерированную декларацию ABW_xxx, чтобы получить доступ к указателю на экземпляр диалога. При работе с множественными экземплярами модуля окна Вы не можете использовать эту декларацию, поскольку она ссылается только на последнее созданное окно. Вместо этого Вы добавляете код к сгенерированной функции установки окна, так чтобы она хранила копию каждого указателя на экземпляр окна в глобальном массиве виджетов. На этом уроке Вам понадобятся эти указатели для работы кнопки "Change Previous Window Color".
Генерирование кода
Откройте диалог "Build+Run" и перегенерируйте код.
Модификация функции установки
Теперь давайте модифицируем функцию newwin_setup(), так чтобы она :
-
ограничивала число возможных экземпляров пятью;
-
хранила копии каждого указателя на окно;
-
отображала номер экземпляра окна на панели заголовка этого окна.
Отредактируйте файл newwin_setup.с, как показано ниже:
int win_ctr = 0;
PtWidget_t *win[5];
int
newwin_setup( PtWidget_t *link_instance,
ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
char buffer[40];
/* предотвращает предупреждения (варнинги) об отсутствии ссылок */
link_instance = link_instance, apinfo = apinfo, cbinfo = cbinfo;
/* Заметьте: Возвращение Pt_END в предреализационной функции установки
указывает PhAB удалять модуль без его реализации */
/* позволяет только 5 окон максимум */
if ( win_ctr == 5 ) {
return( Pt_END );
}
/* сохранение указателя на экземпляр модуля окна */
win[win_ctr] = link_instance;
sprintf( buffer, "Window %d", win_ctr + 1 );
PtSetResource( win[win_ctr], Pt_ARG_WINDOW_TITLE,
buffer, 0 );
win_ctr++;
return( Pt_CONTINUE );
}
Модификация функции изменения цвета
Теперь давайте модифицируем функцию color_change(), так чтобы :
-
нажатие кнопки "Red", "Green" или "Blue" изменяло цвет прямоугольника в цвет кнопки;
-
нажатие на кнопку "Change Previsious Window Color" изменяло фон предыдущего окна на цвет из массива.
Если бы это был модуль диалога, Вы бы могли использовать декларацию ABW_color_rect, чтобы обновить цвет прямоугольника. Однако, поскольку это модули окон, Вы должны использовать указатель на экземпляр окна, в котором нажата кнопка.
Чтобы получить указатель на экземпляр виджета текущего окна, Вам необходимо вызвать:
-
ApGetInstance() для получения указателя на окно, содержащее виджет, вызвавший ответную реакцию
-
ApGetWidgetPtr() для получения указателя на виджет с данной декларацией ABN_...
Если гарантировано существование только одного экземпляра окна, нижеследующее будет работать:
PtSetResource (ABW_color_rect, Pt_APG_FILL_COLOR, buffer, 0);
Но в рассматриваемом случае color_change должно использовать:
PtSetResourse (ApGetWingetPtr (ApGetInstance (winget), ABN_color_rect),
Pt_APG_FILL_COLOR, buffer, 0);
Поэтому Вам необходимо изменить color_change.c таким образом:
PgColor_t colors[5] = {Pg_BLACK, Pg_YELLOW, Pg_MAGENTA,
Pg_CYAN, Pg_DGREEN};
int base_clr = -1;
extern int win_ctr;
extern PtWidget_t *win[5];