OpenGL в Delphi

       

Минимальная Windows-программа


Посмотрите на проект из подкаталога Ex07 - код минимальной программы Windows. Минимальной она является в том смысле, что в результате получается просто пустое окно. Также ее можно назвать минимальной программой потому, что откомпилированный модуль занимает всего около 16 Кбайт. Приложение меньшего размера, имеющее собственное окно, получить уже никак не удастся, хотя могут быть и программы еще короче и меньше, например, такая:

program p; uses Windows;
begin
MessageBeep(mb_ok)
end.

Единственное, что делает эта программа, - подача звукового сигнала. Однако вернемся к коду проекта из подкаталога Ex07. Первое, на что необходимо обратить внимание: в списке uses указаны только два модуля - windows и Messages. Это означает, что в программе используются исключительно функции API, и как следствие - длинный С-подобный код. И действительно, перенести эту и подобные ей программы на С потребует немного усилий.
Данная программа для нас крайне важна, поскольку она станет шаблоном для некоторых других примеров.
Программу условно можно разделить на две части - описание оконной функции и собственно головная программа.
В оконной функции задается реакция приложения на сообщения Windows. Именно оконную функцию необходимо дополнять кодом обработчиков сообщений для расширения функциональности приложения. Нечто подобное мы имеем в событийно-ориентированном программировании, но, конечно, в совершенно ином качестве.
В минимальной программе задана реакция на единственное сообщение wm_Destroy. На все остальные сообщения вызывается функция ядра операционной системы DefWindowProc, осуществляющая стандартную реакцию окна. Полученное окно ведет себя обычно, его можно изменять в размерах, минимизировать, максимизировать. Приложение реагирует также привычным образом, однако необходимости кодировать все эти действия нет.
В принципе, можно удалить и обработку сообщения wm_Destroy, но в этом случае приложение после завершения работы оставит след в памяти, съедающий ресурсы операционной системы.
Значение переменной-результата обнуляется в начале описания оконной функции для предотвращения замечания компилятора о возможной неинициализации переменной.
Головная программа начинается с того, что определяются атрибуты окна. Термин "структура", перешедший в Delphi из языка С, соответствует термину "запись". Термин "класс окна" имеет к терминологии объектно-ориентированного программирования скорее приближенное, чем непосредственное отношение.
Значения, задаваемые полям структуры, определяют свойства окна. В этой программе я задал значения всем полям, что, в принципе, делать не обязательно, мы обязаны указать адрес оконной функции, а все остальные значения можно брать по умолчанию. Однако в этом случае окно будет выглядеть или вести себя необычно. Например, при запуске любого приложения операционная система задает курсор для него в виде песочных часов, и если мы не станем явно задавать вид курсора в классе окна, курсор окна приложения так и останется в виде песочных часов.
После заполнения полей класса окна его необходимо зарегистрировать в операционной системе.
В примере я анализирую результат, возвращаемый функцией Registerclass. Это также делать не обязательно, невозможность регистрации класса окна - ситуация крайне редкая при условии корректного заполнения его полей.
Следующие строки можно интерпретировать как "создание конкретного экземпляра на базе зарегистрированного класса" Очень похоже на ООП, но схожесть эта весьма приблизительная и объясняется тем, что первая версия Windows создавалась в эпоху первоначального становления концепции объектно-ориентированного программирования.
При создании окна мы уточняем его некоторые дополнительные свойства - заголовок, положение, размеры и прочее. Значения этих свойств задаются аргументами функции createWindow, возвращающей внимание, величину типа HWND - ту самую ссылку на окно, что в Delphi называется Handle. После создания окна его можно отобразить - вызываем функцию showWindow. Как правило, окно сразу после этого перерисовывают вызовом функции updateWindow - действие тоже необязательное, но для корректной работы приложения удалять эту строку нежелательно.
Далее следует цикл обработки сообщений, наиважнейшее место в программе, фактически это и есть собственно работа приложения. В нем происходит диалог приложения с операционной системой: извлечение очередного сообщения из очереди и передача его для обработки в оконную функцию. Как уже говорилось, функции API и сообщения - темы очень обширные, и я не ставлю целью исчерпывающе осветить эти темы. В разумных объемах я смогу изложить только самое необходимое, а более подробную информацию можно получить в оперативной помощи Delphi.
К сожалению, версии Delphi 3 и 4 поставляются с системой помощи, не настроенной должным образом для получения информации по функциям API и командам OpenGL. Если судить по содержанию помощи, то может сложиться впечатление, что эти разделы в ней вообще отсутствуют.
Можно либо настраивать справочную систему самостоятельно, либо, что я и предлагаю, пользоваться контекстной подсказкой - для получения сведений по любой функции API достаточно поставить курсор на соответствующую строку и нажать клавишу <F1>.

Замечание
В пятой версии Delphi система помощи настроена вполне удовлетворительно, а сами файлы помощи обновлены

Кстати, обращаю внимание, что описания функций приводятся из файлов фирмы Microsoft, предназначенных главным образом для программистов, использующих язык С, поэтому полученную информацию необходимо интерпретировать в контекст Delphi.
Код минимальной программы я подробно прокомментировал, так что надеюсь, что все возникшие вопросы вы сможете разрешить с помощью моих комментариев.

Замечание
Итак, в приложениях Windows на самом деле управление постоянно находится в цикле обработки сообщений, событийно-ориентированная схема как таковая отсутствует. При получении окном очередного сообщения управление передается оконной функции, в которой задается реакция на него, либо вызывается функция API DefWindowProc для реакции, принятой по умолчанию

Приведенный пример лишь отдаленно напоминает то, что мы имеем в Delphi - событийно-ориентированное программирование, основанное на объектах. Конечно, совершить путь, обратный исторически пройденному, нелегко. Отказаться от библиотеки VCL при написании программ на Delphi для многих оказывается непосильным. Вознаграждением здесь может стать миниатюрность полученных программ: как мы видим, минимальная программа уменьшилась минимум в десять раз, быстрее загружается, выполняется и быстрее выгружается из памяти.
Такой размер нелегко, а порой и невозможно получить в любом другом компиляторе, кроме как в Delphi. К тому же проекты, в списке uses которых стоят только windows и Messages, компилируются еще стремительнее, несмотря на устрашающую массивность кода.
А сейчас посмотрите проект из подкаталога Ex08, где окно дополнено кнопкой и меткой. В коде появились новые строки, а простейшие манипуляции, например, изменение шрифта метки, еще потребуют дополнительных строк.
Подобный обширный код обычно обескураживает новичков, поэтому я не буду злоупотреблять такими примерами и ограничусь только самыми необходимыми для нас темами - как создать обработчик мыши, клавиатуры и таймера.
Я не буду заставлять вас писать все программы таким изнурительным способом, нам просто нужно иметь представление о работе базовых механизмов, чтобы лучше понимать, что делает за нас Delphi и что необходимо сделать, чтобы подключить OpenGL к нашим проектам.



Содержание раздела