- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Программирование в X Window средствами Free Pascal - А. Полищук
Шрифт:
Интервал:
Закладка:
Действия по обработке Expose начинаются с создания графического контекста - структуры, которая содержит данные, необходимые для вывода информации, в нашем случае - текста:
prGC:= XCreateGC(prDisplay, prWnd, 0, NIL);
После этого рисуется строка "Hello, world!". Более графический контекст не нужен - он уничтожается:
XFreeGC(prDisplay, prGC);
Окно может получить несколько событий Expose одновременно. Чтобы не перерисовывать себя многократно, программа дожидается прихода последнего из них и только потом осуществляет вывод.
Приход события KeyPress означает, что программу надо завершить: прекратить связь с сервером, для чего вызывать XCloseDisplay(prDisplay), и вызвать функцию halt().
XCloseDisplay() закрывает соединение с Х сервером, закрывает все окна и удаляет идентификаторы ресурсов, созданных клиентом на дисплее. Для удаления только окна без разрыва связи с Х сервером необходимо использовать функции XDestroyWindow() и XDestroySubWindows().
1.1.7 События
Когда пользователь нажимает на кнопку мыши или клавишу клавиатуры, или когда окно программы нуждается в перерисовке, или когда происходят другие изменения в системе, сервер подготавливает соответствующий пакет данных и отправляет его той или иной программе (или программам). Этот пакет данных называется событием.
Типичная GUI программа имеет следующую структуру:
1. Выполняются инициализационные процедуры.
2. Устанавливается соединение с Х сервером.
3. Выполняются инициализационные процедуры, связанные с Х.
4. Пока не завершились:
1. Получаем следующее событие от Х сервера.
2. Обрабатываем событие, возможно посылая различные запросы на рисование к Х серверу.
3. Если событие было завершающим, заканчиваем цикл.
5. Закрываем соединение с Х сервером.
6. Выполняем завершающие действия.
Возможных событий достаточно много; их список можно найти в файле X.pp. Каждое из них имеет свой тип и соответствующую структуру данных. Все они вместе, как было сказано выше, описываются объединением XEvent.
Как мы видели из примера в предыдущем пункте, программа для каждого из своих окон может выбрать события, которые будут ему передаваться. Делается это с помощью функции XSelectInput(). При вызове этой процедуры требуемые события идентифицируются соответствующими флагами. Так событию, ButtonPress (нажатие кнопки мыши) соответствует флаг ButtonPressMask. Когда кнопка отпускается, сервер порождает событие ButtonRelease, которому соответствует флаг - ButtonReleaseMask.
Маска выбираемых событий может составляться с помощью побитового "ИЛИ" из таких значений:
• 0 - не ожидать никаких событий
• KeyPressMask - ожидать событие нажатия клавиши
• KeyReleaseMask - ожидать событие отпускания клавиши
• ButtonPressMask - ожидать событие нажатия кнопки мыши
• ButtonReleaseMask - ожидать событие отпускания кнопки мыши
• EnterWindowMask - ожидать событие входа в окно
• LeaveWindowMask - ожидать событие выхода из окна
• PointerMotionMask - ожидать событие движения мышиного курсора
• PointerMotionHintMask - ожидать событие движения мышиного курсора с дополнительными указаниями
• Button1MotionMask - ожидать событие движения мышиного курсора при нажатой первой кнопке
• Button2MotionMask - ожидать событие движения мышиного курсора при нажатой второй кнопке
• Button3MotionMask - ожидать событие движения мышиного курсора при нажатой третьей кнопке
• ButtonMotionMask - ожидать событие движения мышиного курсора при любой нажатой кнопке
• ExposureMask - ожидать событие необходимости перерисовки окна
• VisibilityChangeMask - ожидать событие изменения видимости
• ResizeRedirectMask - ожидать событие изменения размеров окна
• FocusChangeMask - ожидать событие изменения фокуса ввода
Некоторые события посылаются окну независимо от того, выбраны они или нет. Это:
• MappingNotify - посылается, когда изменяется состояние клавиатуры (соответствие физических и логических кодов;
• ClientMessage - так идентифицируются события, посылаемые от клиента к клиенту с помощью процедуры XSendEvent();
• SelectionClear, SelectionNotify, SelectionRequest - эти события используются в стандартном механизме общения между программами, работающими в X;
• Expose, NoExpose - эти события могут посылаться, когда клиент пытается копировать содержимое одного окна в другое.
Частой ошибкой начинающих программистов является добавление кода для обработки нового события без добавления маски для этого события в XSelectInput(). Можно часам сидеть и отлаживать программу в недоумении, почему она не реагирует на отпускание кнопки, только из-за того, что для кнопок событие нажатия зарегистрировано, а событие отпускания - нет.
Программа получает события в своем основном цикле. Для этого можно использовать ряд процедур. Наиболее простая из них:
function XNextEvent(prDisplay: PDisplay; prEvent: PXEvent): longint; cdecl; external;
Она "вынимает" из очереди событие, находящееся в ее "голове", сохраняет информацию о нем в переменной, на которую указывает параметр prEvent, и возвращается. При этом само событие удаляется из очереди. Функция XPeekEvent() также возвращает переданное сервером событие, но не удаляет его из очереди.
Процедура XPending() возвращает общее число событий в очереди программы.
Итак, если событие выбрано для окна, то оно будет передано ему на обработку. А если нет? В этом случае событие передается родителю окна. Если и тот не желает обращать внимание на данное событие, то оно отправляется дальше, вверх по иерархии окон, и так до тех пор, пока либо не будет найдено окно, выбравшее это событие, либо событие не потеряется.
Задача может влиять на этот процесс продвижения события по иерархии окон. Если программа включает флаг, соответствующий событию, в специальный атрибут окна, то оно, достигнув это окно, не будет передано родителю, а будет тут же "снято с повестки дня". Этот атрибут - do_not_propagate.
1.1.8 Атрибуты окна
Многие атрибуты окна задаются при его создании с помощью процедуры XCreateWindow() или XCreateSimpleWindow(). Впоследствии параметры можно изменить, обратившись к процедуре XChangeWindowAttributes().
Характеристики окна описываются структурами типа TXSetWindowAttributes и TXWindowAttributes. Получить их можно с помощью процедуры XGetWindowAttributes().
Все они делятся на две группы. В первую входят параметры, доступные "на чтение" и "на запись". Вторая группа представляет собой внутренние данные. Программа может прочитать их, но не может менять.
Сначала перечислим поля этих структур, которые относятся к "изменяемым" параметрам.
Фон окна определяется атрибутами background_pixmap и background_pixel. Первый из них задает картинку (карту пикселей), которая используется для заливки фона окна. При необходимости картина повторяется слева направо и сверху вниз. Если параметр background_pixmap равен None (задается по умолчанию), то он игнорируется. Если же при этом поле background_pixel не задано (установлено по умолчанию), то окно считается "прозрачным", в противном случае его фон заливается цветом background_pixel. Атрибуты background_pixmap и background_pixel могут также принимать значение ParentRelative. В этом случае характеристики фона заимствуются у родительского окна.
Вид края окна определяется полями border_pixmap и border_pixel. Первый атрибут определяет карту пикселей, используемую для заполнения края. Если он равен None, то край заполняется цветом border_pixel. Если же и поле border_pixel не задано, то для изображения края используются соответствующие характеристики родителя. То же самое происходит, если параметр border_pixmap равен CopyFromParent (взять у родителя). Последнее значение есть значение по умолчанию.
На перерисовку окна после изменения его размеров влияют атрибуты bit_gravity и win_gravity. Когда окно меняет размер, например, увеличивается или уменьшается, то, в принципе, нет необходимости перерисовывать все его содержимое. Часть окна остается неизменной. Правда, эта часть может поменять свое положение: переместиться вправо, влево, вверх или вниз. Поле bit_gravity говорит серверу, что делать с оставшейся частью изображения. Возможные значения параметра следующие:
• ForgetGravity - содержимое окна перерисовывается (считается значением по умолчанию);
• StaticGravity - остающаяся часть не должна менять положение по отношению к главному (корневому - root) окну сервера;
• NorthWestGravity - остающаяся часть смещается к левому верхнему углу;
• NorthGravity - остающаяся часть смещается к верху окна;
• NorthEastGravity - остающаяся часть смещается к правому верхнему углу;
• WestGravity - остающаяся часть смещается к левому краю окна;
• CenterGravity - остающаяся часть смещается к центру окна;
• EastGravity - остающаяся часть смещается к правому краю окна;
• SouthWestGravity - остающаяся часть смещается к левому нижнему углу;
• SouthGravity - остающаяся часть смещается к нижнему краю окна;
• SouthEastGravity - остающаяся часть смещается к правому нижнему углу.