Небольшое отступление

Прошёл месяц с тех пор как я написал первую часть ( http://www.delphikingdom.com/helloworld/directx.htm ) статьи по использованию DirectX в среде Delphi. У меня накопилось ещё несколько примеров, которые, надеюсь, послужат наглядным руководством для начинающих.

Прежде, чем описывать предложенные общему вниманию программы, хочу сообщить о некоторых изменениях в их коде по сравнению с примерами первой статьи, чтобы не останавливаться впоследствии на этих мелких деталях.

Вызовы _AddRef() и _Release() больше не используются – в конце концов я посчитал это бессмысленной тратой времени при наборе кода. К тому же, как выяснилось, что вызов именно этих методов привёл к неработоспособности одного из примеров предыдущей статьи – если кто интересовался, знает, что это был пример опроса клавиатуры с использованием DirectInput. После удаления вызовов программа стал работать корректно. По-видимому, имело место некорректное взаимодействие с драйвером клавиатуры.

Выражение вида if COM-объект <> nil then COM-объект := nil переписано с использованием процедуры следующего вида:

procedure SAFE_DELETE( p: TInterfacedObject ); begin if p <> nil then p := nil end;

Теперь достаточно написать SAFE_DELETE( @COM-объект ) – может, это покажется и излишним, но поверьте, в более крупных программах, где надо удалить 15-20 COM-интерфейсов, это становится удобным и сокращает код. Все эти соображения навеяны под влиянием примеров из MS SDK. Кстати, может, кто-то несогласен с правильностью описанной процедуры?

Модуль basedd8.pas в проектах для DirectDraw переименован в basedd7.pas – всё-таки DirectDraw – это часть DirectX 7, в версий 8 он как таковой отсутствует.

В функции LoadFiles() добавлен вызов DeleteObject() – как известно, после работы объекты GDI надо удалять, иначе они поглощают ресурсы системы. В данном случае именно такой объект создаётся при вызове функции GDI LoadImage() – казалось бы, тип HBITMAP – это всего лишь переопределение типа LongWord, копилятор самостоятельно удалит переменную этого типа после выхода из функции. На самом деле GDI при вызове LoadImage() (и других подобных функций) создаёт ресурс GDI и резервирует для него часть системной памяти, а переменная hBmp – всего лишь идентификатор этого ресурса в общем списке ресурсов Windows. Поэтому в процессе выполнения программы будет удаляться только идентификатор, а ресурс, на который он указывает, будет «висеть» в памяти. Именно поэтому следует вызвать DeleteObject() для удаления объекта GDI. В предыдушем примере я не сделал этого по причине недосмотра.

Большая часть примеров в этой статье предназначена для работы с DirectDraw – как мне кажется, наиболее востребованному элементу DirectX (кроме, естественно, Direct3D).

Надеюсь, мой стиль написания кода программ покажется удовлетворительным – он почти во всём подобен стилю, который использовали составители DirectX SDK. Вообще, многие пишут, как курица лапой – и предлагают свои творения на всеобщее обозрение. Ещё полезно заглянуть на страницу в нашем уважаемом Королевстве - http://www.delphikingdom.com/article/tassel.htm - это классика.