Оконный интерфейс


DOS и OS/2 имеют однотипные графические операционные оболочки - MS Windows (Windows) и Presentation Manager (PM) соответственно. Правда, в то время как РМ входит в стандартную поставку OS/2 и распространяется фирмами Microsoft и IBM, Windows не входит в DOS и является независимым продуктом, конкурирующим с другими системами такого же класса.
Внутренние интерфейсы Windows и РМ очень похожи. Это часто позволяет создавать программы так, что методами условной компиляции выбирается конкретная система, под управлением которой будет работать программа. Видимо, при некоторых ограничениях это можно делать и на стадии компоновки с помощью специальных библиотек, но их пока нет.
Windows существует в двух версиях - l.xx и 2.хх. Основное различие: в Windows l.xx окна были не перекрывающимися, а полностью заполняющими (tiled) весь экран дисплея так, что при изменении размеров и положения одного из окон требовалось изменить и другие окна, чтобы всегда поле экрана дисплея было полностью заполнено окнами. Такой метод заполнения экрана окнами убыстрял работу системы, гак как перевысвечивание изображения в окне обычно не требовало отсечения по сложной форме видимой пользователю части окна.
С развитием мощности компьютеров, увеличением оперативной памяти это требование фактически перестало быть существенным, и в Windows 2.хх стали использоваться не заполняющие окна, а перекрывающиеся (overlapped).
РМ можно считать дальнейшим развитием Windows. С одной стороны, несколько упорядочен внутренний программный интерфейс, битовые поля и другие программные структуры, с другой стороны, расширены функциональные возможности как чисто внешние - вложение окон, так и функциональные - использование многозадачных OS/2.
С точки зрения многозадачных возможностей Windows и РМ кажутся схожими, хотя реализованы совершенно разными способами.
Windows базируется на однозадачной ОС и создает видимость многозадачности. В связи с этим в Windows нет разделения времени, переключение между задачами (независимо запущенными программами) может происходить только при обращении к системе определенными функциями (GetMessage, WaitMessage, PeekMessage, Yeld).
В OS/2 встроена система разделения времени, включающая развитый механизм процессов и задач, средств их взаимодействия, приоритетов. Таким образом, РМ не реализует сам многозадачных возможностей, а использует то, что предоставляет OS/2.
Естественно, что под управлением РМ может быть запущено несколько процессов, каждый из которых состоит из набора задач. Взаимодействие между процессами (process) и задачами (thread) осуществляется средствами OS/2. Но имеется ряд ограничений на использование ключей различных объектов, методов доступа к ним (если ограничения касаются задачи, то они касаются и процесса, но не наоборот).
Программисту, начинающему работать с Windows или РМ, наиболее тяжело дается непривычная структура программы. Это связано с тем, что базовым механизмом взаимодействия прикладной программы с оконной системой являются сообщения, посылаемые от оконной системы к прикладной программе. Таким образом, оконная система оказывается активным участником взаимодействия прикладной программы с системой. С другой стороны, прикладная программа должна быть всегда готова к обработке очередного сообщения (в том числе - перевысветить все изображение в окне), постоянно с помощью специальных функций опрашивать очередь сообщений.
Обычно программа, использующая Windows или РМ, состоит из следующих частей:
Инициализация. В Windows это функция WinMain, которая первой получает управление от системы и может выполнять некоторую подготовительную работу. WinMain соответствует функции main языка С. Таким образом, если программа пишется на языке С, то надо использовать не функцию main, а функцию WinMain. Перед вызовом WinMain стандартный пролог оконной программы, присоединяемый из библиотеки, произведет необходимые действия по подключению программы к Windows.
В РМ для подключения к оконной системе задача должна вызвать функцию Winlnitialize. Результатом ее работы будет hab (anchor block handle) - ключ программы-пользователя РМ. Для создания очереди сообщений в данной задаче используется WinCreateMsgQueue.

Цикл приема сообщений.

Программа как в Windows, так и в РМ должна сама взять очередное сообщение из буфера с помощью функций GetMessage и WinGetMsg в Windows и РМ соответственно. Оконная система не умеет прерывать прикладную программу при передаче ей очередного сообщения. Если программа не будет сама забирать сообщения из очереди, то в конце концов очередь переполнится и часть сообщений будет утеряна. Таким образом, программа должна периодически обращаться к функциям доступа к очереди сообщений. Обычно программа состоит из цикла, в котором принимаются сообщения с помощью функций GetMessage, PeekMessage,
TranslateMessage, DispatchMessage, WaitMessage, Yeld в Windows и WinGetMsg, WinPeekMsg, WinDispatchMsg в РМ.
Кроме того, если в Windows нет обращений к функциям GetMessage, PeekMessage, WaitMessage, Yeld, то не может произойти переключение задач и они в других окнах будут приостановлены. Переход к выполнению других прикладных программ, сделанный функциями GetMessage, PeekMessage, WaitMessage, Yeld, может сопровождаться перемещением стека и сегмента данных и программы. Перемещение выполняется для того, чтобы предоставить в распоряжение работающей программы область памяти нужного размера. В результате такого перемещения длинные (состоящие из селектора и смещения) адреса данных, находящихся в сегменте данных или в стеке (т. е. глобальных или локальных переменных), станут после обращения к функции GetMessage, PeekMessage или WaitMessage неверными. Параметры, передаваемые в функции, и адреса функций, созданных с помощью MakeProcInstance, остаются правильными всегда.
Обработка сообщения. Обработка сообщения заключается в вызове функции, указанной при регистрации класса окна или при создании подкласса с помощью функций GetWindowLong, SetWindowLong в Windows и WinSubclassWindow в РМ. Здесь эта функция называется WinProc, но можно использовать любое другое имя. Обычно WinProc вызывается функцией DispatchMessage в Windows и WinDispatchMsg в РМ. Перед вызовом DispatchMessage в Windows необходимо обратиться к функции TranslateMessage, которая сообщения о нажатии и отпускании клавиш переводит в сообщения с ASCII-кодами.
Завершение программы. В Windows завершение программы состоит в выходе из WinMain. В РМ необходимо уничтожить очередь сообщений данной задачи функцией WinDestroyMsgQueue, а затем указать системе об окончании работы задачи с оконной системой (но не выходом из программы), вызвав WinTerminate. После вызова WinTerminate ключ программы-пользователя РМ становится недействительным, но программа может продолжать работу, не используя оконный интерфейс. Естественно, и в РМ и в Windows правила хорошего тона требуют, чтобы перед выходом были уничтожены все объекты, созданные в процессе (задаче), освобождены все области памяти, закрыты файлы. Конечно, все это система попытается сделать сама, но у нее это может получиться не столь аккуратно, как хотелось бы.
 


Обсудить вопрос в студенческом форуме

 

Сайт содержит информацию о учебном заведении и студенческой общине и не является официальным