VR-Online для программистов #3

Page 1

VR-online JOURNAL Фленов Михаил and VR-Team VR-online для программистов №3

Delphi: Объектно-ориентированное программирование ...........................................................3 Delphi: Работа с WinAPI ...............................................................................................................7 Delphi (Графика): Рисуем внутри ListBox.................................................................................11 Delphi (Базы данных): Поисковые поля и SQL запросы..........................................................15 WinSock: Подключение и отключение сетевых дисков ..........................................................20 OpenGL: Реалистичные изображения........................................................................................23 SQL: Занятие второе....................................................................................................................26 Геймер: Рисование картинок ......................................................................................................29 Форматы данных: Формат файла PCX ......................................................................................32 Java для всех.................................................................................................................................34

Copyright: VR-online Journal http://www.cydsoft.com/vr-online


VR-online Journal (Horrific and VR-Team)

Недавно ехал я в метро и невольно услышал разговор двух молодых людей, лет примерно 16-18. И вот один говорит: "Достала меня эта страна, не могу здесь больше жить. Страна мне ничего не дает, у родителей денег нет мне купить даже мобильный телефон. Властям пофигу на наши проблемы, вот уехать бы куда-нибудь в Европу, там все хорошо, у всех все есть" Другой ему отвечает: "Да, страна - гавно, тоже нихочу здесь жить". Хорошо, мне на следующей остановке выходить надо было. Короче до конца дня я был просто в шоке. И это молодое поколение, которому предстоит жить в этой стране? Родители не могут купить мобильный телефон, значит "страна - гавно"? Лично мне это совсем не понять. Ребята, это ваша Родина, это самое дорогое что у вас есть. Все в наших руках: сделать страну лучше или хуже. Здесь жить нашим детям и внукам, здесь прах наших предков, которые не задумываясь рисковали жизнью и умирали за нас, за нашу свободу. Или может это я чего не понимаю, может меня кто вразумит? Недавно я писал вступительный экзамен в институт. Вообще от природы мне не дано писать сочинения. С грамотностью у меня проблем нет, а вот само раскрытие темы и т.п. вызывают проблемы. И я взял тему "Какой мы хотим видеть свою страну". Всю душу я вложил в эту работу и написал на "зачет". Подумайте о истинных ценностях своей жизни. Все в наших руках. Приятного чтения... Crazy_Script

Для программистов №3

VR-online JOURNAL Horrific aka Фленов Михаил

INFO: ИДЕЯ И РЕАЛИЗАЦИЯ: Флёнов Михаил (Horrific) ГРАФИКА: Фленов Михаил, tr4sh

VR-Team: Crazy_Script, Del, Demogorgon, Fighter, Mish!, Negus, Spider NE, tr4sh INTERNET: WWW: http://www.cydsoft.com/vr-online E-MAIL: vr_online@cydsoft.com ДИЗАЙН САЙТА: tr4sh КОДИНГ САЙТА: Mish!

Данный журнал распространяется в виде PDF файлов. Вы можете выкладывать номера на любые носители без изменения внешнего вида журнала, без перевода в другие форматы, без изменения самого файла. В журнал запрещается вносить изменения. Перепечатка материалов запрещена. Журнал распространяется бесплатно, и ты можешь скачать его с нашего сайта, поэтому мы не видим смысла в перепечатывании материалов. Если ты хочешь стать автором журнала, то присылай свою статью на наш e-mail и мы обязательно включим её в очередной номер.

http://www.cydsoft.com/vr-online

2


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Delphi: Объектно-ориентированное программирование Я уже много рассказывал о программировании на Delphi и мы достаточно много рассмотрели примеров, но для начинающего не всё понятно, потому что немного не хватает теории. Сегодня я решил заделать эту пробоину, так что меньше слов, переходим к делу. Рассмотрим самый простейший пример программы на Delphi:

unit Unit1; // Название проекта interface // После этого ключевого слова идут объявления uses

Windows, Messages, SysUtils; //Подключаются глобальные модули.

Type //Объявление типов TForm1 = class(TForm) //Объявления событий и свойств procedure FormCreate(Sender: TObject); private { Private declarations } //Объявление закрытых процедур и функций. procedure ExitProgramm; public { Public declarations } //Объявление открытых процедур и функций. end;//Конец объявления объекта TForm1 var Form1: TForm1; //Объявление глобальных переменных Implementation //После этого слова идёт код программы uses Unit2; //Локальные объявления const //Константы Mode = 1; {$R *.DFM}// подключаем файл формы procedure TForm1.FormCreate(Sender: TObject); var I:Integer; // Объявление локальной переменной Begin //Начало процедуры //Здесь пишется код программы. end; //Конец процедуры FormCreate procedure TForm1.ExitProgramm; begin Close; end;

http://www.cydsoft.com/vr-online

3


VR-online Journal (Horrific and VR-Team)

Для программистов №3

end. // Конец модуля - "end" и точка.

Теперь разберём всё подробнее. В самом начале у нас стоит название формы. Оно может быть любым, но таким же, как и имя файла без расширения. Желательно давать понятные названия, чтобы ты мог по имени определить, что находится внутри. Подключение глобальных модулей. Все процедуры, функции, константы описаны в каком-нибудь модуле, и прежде чем эти процедуры использовать, нужно подключить этот модуль. Ты можешь знать о существовании какой-нибудь функции. Но чтобы об этом узнал компилятор, ты должен указать модуль, где описана эта функция понятным для компилятора языком. Как узнать, в каком модуле объявлена нужная процедура? Очень просто, для этого существует помощь. Вот вырезка из файла помощи для процедуры StrToInt: Converts a string that represents an integer (decimal or hex notation) to a number. Unit Sysutils Category type conversion routines function StrToInt(const S: string): Integer; Первая строка объясняет назначение функции. Во второй строке ты можешь увидеть слово Unit, после которого идёт Sysutils. Значит эта функция описана в модуле Sysutils, вот именно его тебе и надо подключить. Дальше идут объявления типов. Строка TForm1 = class(TForm) говорит о том, что мы создаём новый объект TForm1 , который будет происходить от объекта TForm . А это значит, что TForm1 Будет обладать всеми возможностями TForm , и плюс то, что мы захотим. После этого идут объявления событий. Здесь ты не будешь работать ручками. Все объявления здесь делает Delphi когда ты устанавливаешь на форму новый компонент или создаёшь для него событие. Объявление закрытых и открытых процедур и функций и переменных. Тебе нужно помнить, что закрытые процедуры и функции видны только внутри объекта, а открытыми ты можешь пользоваться из другого объекта. В нашем примере объявлена одна закрытая процедура - ExitProgramm . Эту процедуру можно использовать в любой другой процедуре объекта TForm1 . Но если ты создашь другой объект и попытаешься использовать ExitProgramm , то нарвёшься на мешок ошибок. В этом случае придётся перенести объявление процедуры в раздел Public . Объявление глобальных переменных - эти переменные будут видны во всех процедурах, функциях, объектах этого модуля. Мы объявили одну переменную Form1 типа TForm1 . Вот именно через эту переменную ты будешь работать, когда захочешь вызвать процедуру объекта TForm1 из какого-нибудь другова объекта. Подключение локальных модулей (Вообще-то разделение на локальные и глобальные я делаю условно). В этом объявлении ты объявляешь свои модули проекта. Например, в твоём проекте два модуля (две формы), и чтобы ты мог из первого модуля вызвать

http://www.cydsoft.com/vr-online

4


VR-online Journal (Horrific and VR-Team)

Для программистов №3

процедуру находящуюся во втором модуле, ты должен подключать второй модуль здесь. Для примера я подключил свой модуль Unit2, в котором создам ещё одну форму. Запомни, что ты подключаешь здесь те модули, которые подключены к твоему проекту. Конечно же ты можешь подключать и другие модули, но желательно этого не делать. Чтобы не запутаться, используй для объявления меню "Use unit" из меню "File". Чтобы просмотреть, какие формы у тебя есть в проекте, используй "Project meneger" из меню "Project". Объявление констант. А зачем они нужны? В принципе можно обойтись без них, но представь себе ситуацию: Ты очень часто используешь какое-нибудь число, и вдруг тебе нужно изменить его на другое. В этом случае тебе придётся лазить по всему модулю и менять числа, а я в это время изменю одно число и всё. Во избежание таких проблем используются константы. Я присваиваю имени (в данном случае Mode) какоето число, и потом обращаюсь к этому числу через имя (например, I:= Mode+1, результатом будет "2"). Константы нельзя изменять внутри программы, потому что это не переменные, а числа. Представь себе запись Mode:=5, это тоже самое, что написать 1:=5, а это не реально. Подключение файла формы. Здесь также не желательно ничего менять, потому что Delphi. Это подключение файла, в котором храниться всё, что ты визуально наделал на форме. Изменения здесь нужны только в крайних случаях, но я их ещё не встречал. В процедуре FormCreate я объявил локальную переменную. Эту переменную можно использовать только внутри этой процедуры. В других она не будет видна. Вот и всё. Я надеюсь, что у тебя теперь будет намного меньше вопросов. Единственное, на чём я хочу ещё остановится, так это на том, когда нужно ставить begin и end, а когда нет. Условный оператор IF выглядит так: if условие then оператор Оператор может быть только один. Если нужно выполнить несколько операторов, то надо заключить их в скобки из begin и end. Например if I=0 then I:=2; // Begin не нужен, оператор только один if I=0 then begin //Дальше будет два оператора, поэтому ставлю begin. I:=2; I:=I+5; end; // Конец условия IF Тоже самое происходит с циклом FOR. for условие1 to условие2 do оператор В цикле выполняется только один оператор, а если нужно несколько, то ставится begin и end. Вроде бы на сегодня всё, надеюсь, что скоро увидимся. Copyright © Фленов Михаил aka Horrific

http://www.cydsoft.com/vr-online

5


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Тебя мучает одна проблема, которую ты не можешь решить? Заходи на форум на нашем сайте, подумаем вместе!!! На нашем форуме ты можешь задать любой вопрос и получить ответ по следующим темам: • Программирование (Delphi, JBuilder, C++ Builder, Kylix, Visual C++Visual Basic и другие); • Технологии программирования (сети, мультимедиа, DirectX, OpenGL); • Администрирование; • Операционные системы; • Базы данных (SQL Server, язык SQL и другие); • Железо; • Internet технологии (Perl, PHP, Flash, XML); • Софт; • Сети; Адрес сайта http://www.cydsoft.com/vr-online

http://www.cydsoft.com/vr-online

6


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Delphi: Работа с WinAPI Что такое WinAPI? Это функции, грубо говоря, встроенные в Windows. Большинство из них описаны в файле Windows.pas. Этот файл подключается по умолчанию каждый раз, когда ты создаёшь новый проект, поэтому тебе не нужны дополнительные действия для использования этих функций. Все функции WinAPI я рассказать не в состоянии, потому что их тысячи, но мы будет потихонечку знакомится с наиболее интересными из них. Примеры к этим функциям я давать не буду. Если ты внимательно читал предыдущие номера и внимательно прочтёшь эту статью, то никаких проблем с реализацией у тебя не возникнет. Тем более, что я уже использовал WinAPI, когда писал статью про нестандартные окна в 5-м номере 2000г. Итак, меньше болтовни а больше дела. function ExitWindowsEx( Code: Word; dwReserved: DWORD; ): BOOL; Первый параметр может принимать следующие значения: • • • • •

EWX_FORCE Закрытие Windows без предупреждения. Если использовать этот флаг, то запущенные приложения не получат сообщения о закрытии и могут потерять данные. Используй этот флаг только в аварийных ситуациях. EWX_LOGOFF Это тоже самое, что и завершение сеанса. Все приложения будут закрыты и появиться приглашение войти в систему под новым именем. EWX_POWEROFF Выключить компьютер. Функция с этим флагом работает не на всех компьютерах, а только на тех, которые поддерживают автоматическое отключение питания. EWX_REBOOT Перезагрузить компьютер EWX_SHUTDOWN Завершение работы Windows без отключения питания у компьютера.

Второй параметр зарезервирован и игнорируется. Для совместимости с будущими версиями лучше ставить ноль. Вот и всё, теперь ты сможешь выключать компьютер из своей программы. Теперь перейдём к режиму энергосбережения. Зачем это нужно? Например, мемед не умеет выводить компьютер из состояния каматоза, поэтому об этом можем позаботиться мы. Выключение монитора: SendMessage(Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, 0); Включение монитора: SendMessage(Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, -1);

http://www.cydsoft.com/vr-online

7


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Как видишь, функция одна, просто они отличаются только последним параметром. Теперь давай рассмотрим не менее интересную проблему - запуск только одной копии проги. Для этого мы опять же будем использовать WinAPI.

Рис 1. Project Manager Весь код будем писать в DPR файле проекта. Чтобы его вызвать, нужно выбрать Project Maneger из меню View . Теперь щёлкни правой кнопкой мышки по имени проекта. Перед тобой откроется меню, как на рисунке 1. Выбери в этом меню пункт View Source . Вот какой текст ты должен в нём написать: program Project1; uses Forms,Windows, Unit1 in 'Unit1.pas' {Form1}; {$R *.RES} var hwin:HWND; begin hwin:=FindWindow('TForm1','Hallo World!!!'); if hwin<>0 then begin

http://www.cydsoft.com/vr-online

8


VR-online Journal (Horrific and VR-Team)

Для программистов №3

SetForegroundWindow(hwin); Application.Terminate; end; Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end. Давай рассмотрим самые интересные вещи. Первая API функция, которую я использую - FindWindow. Эта функция ищет окно по имени объекта окна (первый параметр) и заголовка окна (второй параметр). Если в качестве заголовка передать NIL, то будет найдено первое окно с таким именем объекта. Функция возвращает указатель на окно. После вызова этой функции я проверяю, было ли найдено какое-нибудь окно. Если нет, то программа продолжит загрузку. Если да то вызывается функция SetForegroundWindow, которая делает активным найденное окно. В качестве параметра передаётся указатель на окошко. После этого программа прерывается с помощью Application.Terminate . Это не нормальное прерывание программы. Я его использую только потому, что уверен, что никаких действий по инициализации ещё не произошло. Я не советую тебе использовать эту функцию в других случаях. Я бы и здесь не использовал её, просто нет другого выхода, потому что ещё не запущено приложение, и прерывать больше нечего. Это самый простейший и достаточно эффективный способ проверки на запуск второй копии. Совсем забыл, в файле DPR по умолчанию не подключается файл Windows, поэтому ты должен сам дописать его в раздел USES вначале проекта, как это сделал я. Вот и всё. Как видишь, WinAPI используются так же, как и любые другие функции Delphi. На сегодня всё. Первое знакомство с WinAPI закончено, но в будущем мы ещё будем встречаться с этими функциями. Удачи тебе. Copyright © Фленов Михаил aka Horrific

http://www.cydsoft.com/vr-online

9


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Реклама в журнале VR-online Почему вы обязаны разместить рекламу на страницах VRonline:

4. 5. 6. 7.

1. Таких низких цен вы не видели ни где. 2. У нас располагается нестареющая информация. Которая будет актуальна всегда. 3. Вы имеете возможность пожизненно расположить свой банер на наших страницах по самым низким ценам. Пожизненность гарантируется в не зависимости от роста числа посещаемости. У нас есть потенциал для роста, как в объемах страниц, так и в посещаемости. Наши материалы очень часто сохраняются на дисках посетителей. Ваша реклама будет доступна в любых вариантах журнала. Журнал распространяется не только с сайта VR-online, но и другими сайтами и даже на CD, поэтому тираж огромен.

Если вы собираетесь рекламировать не просто сайт в интернете, а компанию, которая занимается информационными технологиями, то ваша дорога лежит сюда. Это лучшее рекламное место, которое можно найти в сети. Торопитесь такие цены не надолго. Расценки на размещение рекламы на страницах VR-online: • Банер 100х100 на главной странице сайта в течении месяца-$25 • Банер 468х60 на главной странице сайта в течении месяца-$30 • Банер 100х100 на странице оглавления на сайте 1-го номера (пожизненно)-$25 • Банер 468х60 на странице оглавления на сайте 1-го номера (пожизненно)-$30 • Страница в журнале-$200 • Половина страницы в журнале-$100 • Банер на странице статьи журнала.-$50

http://www.cydsoft.com/vr-online

10


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Delphi (Графика): Рисуем внутри ListBox Очень часто, для лучшего представления данных, тебе будет нужно рисовать внутри компонента TListBox. Что я имею ввиду? Посмотри на рисунок 1, и ты всё поймёшь. Может это покажется странным, но всё это делается за семь строчек кода. Конечно же, в одну строку можно записать и двадцать операций, но я этот случай не учитываю.

Рис 1. Пример Секрет рисования заключается в том, что у компонента TListBox1 параметр Style должен быть lbOwnerDrawFixed или lbOwnerDrawVariable . После этого создаёшь обработчик события OnDrawItem и в нём пишешь: procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); begin with ListBox1.Canvas do begin Brush.Color:=clRed; // Задаём красный цвет кисти. Brush.Style:=TBrushStyle(Index); // Выбираем стиль кисти Pen.Style:=psClear; Rectangle(Rect.Left,Rect.Top,Rect.Left+100,Rect.Bottom); Brush.Style:=bsClear; Font.Color:=clBlue; TextOut(Rect.Left+110,Rect.Top,IntToStr(index)); end; end; Вот и всё. Твоя прога готова, жми на запуск и наслаждайся. А я начинаю объяснять, что же я тут нарисовал. Первая строка: with ListBox1.Canvas do

http://www.cydsoft.com/vr-online

11


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Оператор "With" говорит, что все последующие операции будут производится с компонентом (объектом) "ListBox1". Для того, чтобы ты лучше понял я приведу код без этой строки: procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); begin ListBox1.Canvas.Brush.Color:=clRed; ListBox1.Canvas.Brush.Style:=TBrushStyle(Index); ListBox1.Canvas.Pen.Style:=psClear; ListBox1.Canvas.Rectangle(Rect.Left,Rect.Top,Rect.Left+100,Rect.Bottom); ListBox1.Canvas.Brush.Style:=bsClear; ListBox1.Canvas.Font.Color:=clBlue; ListBox1.Canvas.TextOut(Rect.Left+110,Rect.Top,IntToStr(index)); end; Если у тебя есть глаза, то ты можешь увидеть, что в каждой строке появились подписи ListBox1.Canvas . Код стал очень не красивым. Постоянно нужно говорить, что Brush или ещё что-нибудь нужно взять у ListBox1.Canvas . Поэтому я и использовал оператор With With "Объект" do Begin Всё, что находится здесь, будет относиться к объекту "Объект". Поэтому не надо писать имя объекта перед каждым используемым Свойством или методом. End; Я надеюсь, что я доходчиво объяснил. Если ты опять что-то не понял, то не надо отчаиваться. Я же говорил, что мы будем изучать всё постепенно. Практика лучше всего откладывает в памяти любые знания, поэтому ею мы и занимаемся. А остальное дело времени. Теперь ещё несколько подводных камней нашей проги. Конструкция Brush.Style:=TBrushStyle(Index) выбирает кисть в зависимости от рисуемого в данный момент элемента. Всего существует восемь стилей кисти. Когда вываливается сообщение OnDrawItem для первого элемента (об этом говорит параметр index передаваемый в процедуру ListBox1DrawItem), мы рисуем элемент с кистью первого стиля. Для второго элемента будет использоваться второй стиль кисти и т.д.

Рис 2. Пример Карандаш я выбрал прозрачным Pen.Style:=psClear , это для того, чтобы не было никаких оборок. Попробуй убрать эту строку и строки в TListBox1 будут выглядеть уже

http://www.cydsoft.com/vr-online

12


VR-online Journal (Horrific and VR-Team)

Для программистов №3

как на рисунке 2. Как видишь, у каждой строки появились оборки. Вот именно их я убирал с помощью этой конструкции. Функция Rectangle(х1,у2,х2,у2) с соответствующими координатами. Дальше я делал прозрачной кисть и задавал цвет фона. После этого я просто выводил текст строки с помощью функции TextOut(х, у, текст). Всё очень просто. В любой книге по Delphi этот материал считается сложным, но я не вижу в этом ничего сложного. Надеюсь, для тебя эта статья тоже была очень лёгкой. Попробуй сделать тоже самое с компонентом TComboBox. Не забудь про свойство Style у этого компонента. А в остальном, весь код будет таким же. Исходники примера находятся в файле Delphi.zip Copyright © Фленов Михаил aka Horrific

http://www.cydsoft.com/vr-online

13


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Программирование в Delphi глазами хакера Автор: Фленов Михаил aka Horrific Из книги ты узнаешь: • Кто такой Хакер и как им стать; • Как создавать программы маленького размера; • Как оптимизировать код программы; • Как заставить летать кнопку «Пуск»; • Научишься контролировать системную палитру; • Научишься изменять разрешение экрана из своих программ; • Увидишь множество шуточного кода; • Узнаешь, как подсматриваем пароли, спрятанные под звездочками; • Напишешь программу мониторинга запускных файлов и клавиатурный шпион; • Сможешь портить окна чужих программ; • Как создавать окна неправильной формы; • Научишься работать с сетью через компоненты Delphi и увидишь как создаются сканеры портов, утилиты ping и др. • Узнаешь, как работать с сетью на уровне библиотеки WinSock; • Узнаешь, как работать с железом И многое другое. Посмотри на содержимое диска, и ты поймёшь, что он стоит того, чтобы купить эту книгу с диском: \Headers - Все необходимые заголовочные файлы, которые нужно будет подключать к Delphi для компиляции некоторых примеров \Source - Исходные коды своих простых программ, чтобы вы могли ознакомиться с реальными приложениями. Их немного, но посмотреть стоит. \Soft - Инсталляционный пакет программы Adobe Acrobat Reader v5.0. Если у вас нет этой программы, то вы должны её установить, чтобы можно было читать документацию, расположенную на диске. \Vr-online - Полная копия сайта автора, а это 100 мегабайт документации, полезной информации, исходных кодов и компонентов. Здесь же вы можете найти мою книгу "Библия Delphi" - в электронном виде. В ней вы найдёте все необходимые для понимания этого материала основы и если вы ещё ни разу не видели Delphi, то после прочтения этой книги вы сможете понять всё описанное здесь. \Документация - Дополнительная документация, которая может понадобиться для понимания каких-то глав. \Иконки - В этой директории вы найдёте большую коллекцию иконок, которые вы можете использовать в своих программах. Эту коллекцию я подбирал достаточно долго и все иконки хорошего качества. \Компоненты - Дополнительные компоненты, которые будут использоваться в примерах книги. \Программы - Программы, которые пригодятся в программировании. Среди них Header Convert - программа, которая конвертирует заголовочные файлы с языка С на Delphi и ASPack - программа сжатия запускных файлов. Спрашивай книгу в книжных магазинах своего города!!!

http://www.cydsoft.com/vr-online

14


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Delphi (Базы данных): Поисковые поля и SQL запросы Начиная с этого номера, в качестве примеров я буду использовать базу данных описанную мной в статье "Язык запросов SQL" прошлого номера. Это будет удобней для понимания обоих материалов. Ещё одно отличие от предыдущих номеров - все компоненты для работы с таблицами (TDataSource, TТable и др.) будут хранится в отдельном модуле (Data Module). Для его создания нужно щёлкнуть по "New" из меню "File" и выбрать "Data Module". На появившейся форме (рис 2), можно расставлять компоненты для работы с базой данных также, как мы это делали раньше.

Рис 1. Окно DataModule Теперь у нас в проекте две формы. Для того, чтобы открыть любую из них можно воспользоваться Project Manager-ом (рисунок 2). Как всегда, для понимания материала тебе понадобятся исходники сегодняшней проги, которые находятся в архиве. Всё готово, можно переходить к рассмотрению примера. Приготовся, занятие будет насыщенное. Перейди в окно DataModule (рисунок 1). Как настроены связи я рассказывать не буду, потому что это мы уже проходили. Теперь дважды щёлкни по Table2. Что здесь нового? Ты наверно сразу не заметишь, но новое здесь есть - это "поисковое поле" (ого какое я слово выдумал). Ты можешь заметить что-то неладное, если обратишь внимание на то, что у нас два похожих поля "Country" и "Countr". Второе нас сейчас и будет интересовать.

http://www.cydsoft.com/vr-online

15


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Рис 2. Project Manager Создание "поискового поля". Сначала я объясню, для чего оно нужно. У таблицы 2 в поле "Country" хранится ссылка на поле из таблицы "Country". Поэтому в DBGrid будет показываться индекс (я так и назвал это поле "индекс страны", это поле ты можешь сделать невидимым). Теперь щёлкни правой кнопкой мыши в окошке свойств полей (рисунок 3). Выбери пункт "New field". В появившемся окне, нужно заполнить свойства (рис 3): • • • • • • • • •

Name - любое, как тебе удобно Component - тоже любое, как тебе удобно Type - В нашем случае название страны - это строка. Size - Размер (если нужен). Field type - Тип поля. В нашем случае это Lookup (поисковое). Key field - связующие поле из этой таблицы. Dataset - Dataset указывающий на таблицу-справочник. Lookup field - связующие поле из справочника. Связь будет осуществляться как "Key field" - "Lookup field". Result field - Значение этого поля справочника будет показываться вместо индекса.

http://www.cydsoft.com/vr-online

16


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Рис 3. Создание нового поля Теперь остановись и внимательно обдумай всё что я здесь сказал. Попробуй пощёлкать по спискам, но ничего не меняй. Итак, у нас получается, что поле "Countr" будет показываться поле "Country" из справочника, соответствующее полю "Country" из Table2. Запусти программу, и посмотри на результат в работе.

Рис 4. Свойства нового поля Если что-то непонятно, то скоро будет ещё яснее. Сейчас мы познакомимся с компонентом TDBLookupComboBox , результат действия которого будет примерно таким же. Вот свойства, которые должны быть заполнены для получения такого эффекта: •

DataSource - Таблицы, в которую сохраняется значение. В нашем случае это "User1.db".

http://www.cydsoft.com/vr-online

17


VR-online Journal (Horrific and VR-Team) • • • •

Для программистов №3

DataField - Поле в этой таблице, где будет сохраняться значение. В нашем случае это "Country". ListSource - Таблица, которая будет использоваться в качестве элементов выпадающего списка. В нашем случае это "Country.db". ListFieldIndex - Поле из этой таблицы, которым будет запелнен выпадающий список. В нашем случае это "Country". KeyField - Поле, по которому будет происходить связь между таблицами. В нашем случае это "key1".

В итоге получается похожий эффект. Попробую объяснить на словах. У компонента похожего на TСomboBox, выпадающий список заполняется значениями поля указанного в ListFieldIndex из таблицы ListSource. Когда пользователь выбирает значение из списка, то в поле указанное в DataField таблицы DataSource заноситься текущее значение поля KeyField из таблицы ListSource. Остановись и хорошенько обдумай всё, что я сказал. Если что-то непонятно, то придётся тебе играть с программой и смотреть, что в это время происходит в базе данных. Если и это не поможет, то иди мыть унитазы, программирование не для тебя. Теперь рассмотрим простейший пример SQL запроса. Поставь в DataModule два компонента: TDataSource и TQuery. Соедини их так же как ты соединял TDataSource и TTable. У TQuery установи свойство DatabaseName также как и у TTable. Это нужно, чтобы запрос смог найти базу данных. Теперь дважды щёлкни по свойству SQL. В появившемся окне напиши: SELECT * FROM user1.db Теперь установи свойство Active в "TRUE", и твой запрос выполнится. Результат запроса я отобразил в "DBGrid3" (расположен внизу формы). В нашем случае запрос очень простой, поэтому в нём нет ничего особенного, но со временем ты научишься писать достаточно серьёзные запросы к базам данных. TQuery и TTable очень похожи и большинство из того, что мы проходили по TTable, ты можешь применить и к TQuery. На этом наше занятие считаю оконченным. Удачи тебе. Исходники находятся в файле database.zip Copyright © Фленов Михаил aka Horrific

http://www.cydsoft.com/vr-online

18


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Ты ищешь хорошую книгу по Delphi? Зайди на www.cydsoft.com/vr-online и скачай полный электронный вариант Библии Delphi от Фленова Михаила абсолютно бесплатно. Эта книгу научит тебя программировать, даже если ты никогда в жизни не написал ни строчки кода. В ней описано всё, начиная от основ программирования и заканчивая реальными примерами программ и задач, которые программисты решают каждый день. Библия Delphi – самая иллюстрированная и самая бесплатная книга. По ней научились программировать множество людей и ты тоже сможешь.

http://www.cydsoft.com/vr-online

19


VR-online Journal (Horrific and VR-Team)

Для программистов №3

WinSock: Подключение и отключение сетевых дисков В этом номере есть статья о том, как работать с WinAPI. Честно сказать, я немного запоздал с этой статьёй, потому что я уже давно использую их. Например, сетевые функции, которые я использую, относятся к WinAPI, значит ты уже давно знаком с этой тематикой. Хватит болтовни, давай продолжим изучать WinAPI, то есть функции для работы с сетью. Взгляни на рисунок 1. Вот такую прогу нам предстоит сегодня написать. Точнее, улучшить прогу, написанную в прошлом месяце.

Рис.1 Пример работы проги В программе используется две новые функции: function WNetConnectionDialog( hwnd: HWND; dwType: DWORD): DWORD; stdcall; Показать окно подключения сетевого устройства. function WNetDisconnectDialog ( hwnd: HWND; dwType: DWORD): DWORD; stdcall; Показать окно отключения сетевого устройства. Функции очень похожи. В качестве первого параметра передаётся указатель на окно владельца. Второй параметр - это флаги: •

RESOURCETYPE_DISK Отображать в выпадающем списке диалога сетевые диски.

http://www.cydsoft.com/vr-online

20


VR-online Journal (Horrific and VR-Team) • •

Для программистов №3

RESOURCETYPE_PRINT Отображать в выпадающем списке диалога сетевые принтеры. RESOURCETYPE_ANY Отображать в выпадающем списке диалога всё, что попадётся под руку.

Эти функции вызываю уже давно тебе известный диалог (если ты уже работал в локальной сети). Посмотри на рисунок 2 и убедись.

Рис.2 Окно подключения сетевого устройства Как видишь всё просто. На этом я заканчиваю объяснение сегодняшней проги, но это не значит, что заканчивается статья. Знакомство с сетевыми функциями продолжается. Я ещё тебя не познакомил с функциями, которыми можно подключить те же устройства без использования стандартного диалога. Так что крепись. В конце статьи ты сможешь написать собственные диалоги подключения сетевых устройств. function WNetAddConnectionA( lpRemoteName, lpPassword, lpLocalName: PansiChar ): DWORD; stdcall; Эта функция подключает сетевое устройство. В качестве параметров ты должен передать: • • •

lpRemoteName -адрес указывающий куда подсоединится, например, \\333\D . lpPassword - пароль, он и в Африке пароль. Если ты будешь использовать NIL, то будет использоваться значение по умолчанию. lpLocalName - Какое твоё устройство должно переадресовываться сетевым. Чё-то заумно я сказал. Короче, используй NIL и не будет проблем.

function WNetCancelConnectionA( lpName: PAnsiChar; fForce: BOOL ): DWORD; stdcall; Отключить сетевое устройство. Первый параметр указывает на строку, которая хранит имя сетевого ресурса для отключения. Если второй параметр TRUE, то даже если на сетевом ресурсе открыты файлы, он всё равно закроется. Если FALSE, то в этом случае произойдёт ошибка. Как видишь, всё также просто как два пальца описать (ударение на второй слог, специально для прапорщиков - это буква "и"). Всё. Вот мы и закончили знакомится с функциями имеющими тип WNet…. Дальше будет ещё веселее.

http://www.cydsoft.com/vr-online

21


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Увидимся через месяц. Исходники находятся в файле sockets.zip Copyright © Фленов Михаил aka Horrific

http://www.cydsoft.com/vr-online

22


VR-online Journal (Horrific and VR-Team)

Для программистов №3

OpenGL: Реалистичные изображения В прошлый раз мы научились делать реальные трёхмерные изображения. Но наше изображение получилось не совсем реалистичное. Тест глубины, который мы включали, проверял только отсечение поверхностей, но никак не влиял на перспективу. Что я имею ввиду? С удалённостью объекта изменяется теплота цвета, нет бликов от освещения и так далее. Об освещении мы поговорим позже, а сегодня мы поговорим о теплоте цвета. Когда мы смотрим в даль, то удалённые объекты кажутся нам расплывчатыми. Этого эффекта можно добиться с помощью тумана. Что такое туман? Это, грубо говоря, густой воздух.

Рис 1. Туман На этом я думаю закончить с теорией и приступить к практике. Посмотри на рисунок 1. Как видишь, сегодняшняя прога не сильно отличается от предыдущей. Я просто добавил туман к программе используемой в прошлом номере. В моём примере используется туман красного цвета, поэтому по мере удаления цвет объекта становится всё более красным. Давай посмотрим, как рисуется туман: procedure TForm1.FormPaint(Sender: TObject); var ps:TPaintStruct; fogColor : Array[0..3] of GLfloat; begin BeginPaint(Handle,ps); glClearColor(1,0.5,0.5,1); glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); glRotated(45,1,0,0); glEnable(GL_DEPTH_TEST);

http://www.cydsoft.com/vr-online

23


VR-online Journal (Horrific and VR-Team)

Для программистов №3

glDepthFunc(GL_LESS); glEnable(GL_FOG); glFogi(GL_FOG_MODE,GL_EXP2);// Выставляю режим тумана fogColor[0]:=1; fogColor[1]:=0; fogColor[2]:=0; glFogfv(GL_FOG_COLOR, @fogColor);//Выставляю цвет тумана glFogi(GL_FOG_DENSITY,100);// Плотность glFogi(GL_FOG_END,10);//дальняя точка тумана. glColor3f (0.0, 1.0, 0.0); glBegin(GL_QUAD_STRIP); glVertex3f(1.25,1.25,1); glVertex3f(1.25,-1.0,1); glVertex3f(-1,1.25,0); glVertex3f(-1,-1.0,0); glEnd; glColor3f (1.0, 1.0, 0.0); glBegin(GL_QUAD_STRIP); glVertex3f(1.0,1.0,0); glVertex3f(1.0,-1.25,0); glVertex3f(-1.25,1.0,1); glVertex3f(-1.25,-1.25,1); glEnd; glFlush(); swapBuffers(dc); EndPaint(Handle,ps); end; Туман включается всё той же функцией glBegin с параметром GL_FOG . С помощью функции glFog устанавливаются параметры тумана. Эта функция может быть двух типов glFogi (в качестве второго параметра выступает целое число) и glFogf (второй параметр - это число с плавающей запятой). Есть ещё две разновидности - glFogfv, glFogiv, но все они выполняют одну и ту же роль, поэтому я рассмотрю только одну: glFogf( pname: GLenum; param: GLfloat); В качестве первого параметра могут выступать: • • •

• •

GL_FOG_MODE - устанавливает тип тумана. В этом случае второй параметр может содержать одно из следующих значений: GL_LINEAR, GL_EXP, или GL_EXP2 GL_FOG_DENSITY - устанавливает плотность (густоту) тумана. В этом случае, второй параметр - целое число, указывающее плотность тумана. По умолчанию это 1,0. GL_FOG_START или GL_FOG_END - Начало и конец действия тумана. До начального значения тумана нет, а после конечного туман настолько плотный, что ничего не видно. Второй параметр - целое число устанавливающее соответствующее значение. GL_FOG_INDEX - Индекс цвета тумана, только если вы используете палитру. GL_FOG_COLOR - Цвет тумана. В качестве второго параметра выступает массив из четырёх чисел символизирующих значения красного, зелёного, голубого цвета и прозрачность.

http://www.cydsoft.com/vr-online

24


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Вот и всё. Внимательно взгляни на код примера и всё будет ясно. Ой. Я не отключил туман. После рисования не забывай отключать туман glDisable(GL_FOG) и тест глубины glDisable(GL_DEPTH_TEST). Всё это нужно делать после рисования. Сначала включил всё это, нарисовал и потом отключил. Исходники находятся в файле opengl.zip Copyright © Фленов Михаил aka Horrific

http://www.cydsoft.com/vr-online

25


VR-online Journal (Horrific and VR-Team)

Для программистов №3

SQL: Занятие второе В прошлом номере я познакомил тебя с основами баз данных. Вполне возможно, что это тебе пригодиться. Последнее, что я успел рассмотреть, это оператор DISTINCT. Давай продвигать наши знания об SQL дальше. Сегодня мы начнём писать полноценные запросы. Если ты захочешь их отлаживать на какой-нибудь базе данных, то будь внимателен, тебя подстерегают некоторые опасности: • • •

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

Я уже предостерегал тебя в прошлом номере, но всё же мне захотелось повториться (повторенье - мать мученья). Следующий оператор, с которым я хочу тебя познакомить, будет WHERE . Этот оператор задаёт критерии поиска. Например, мне надо выбрать все записи из таблицы User.db, где в поле Country содержится значение "USA". В этом случае я должен написать следующий запрос: SELECT * FROM User WHERE Сountry LIKE "USA" Результатом запроса будут все строки содержащие в поле Country значение "USA" . Если проговорить последнюю строку запроса, то она будет звучать так: "Где поле Country равно USA". Ещё одно замечание: в запросам, строки выделяются кавычками. В зависимости от базы данных, кавычки могут быть одинарными или двойными. В Delphi это одинарные кавычки, но я буду использовать в этих статьях двойные, как это предусмотрено стандартом. Я немного поторопился и использовал в запросе ключевое слово LIKE . Это слово идентично знаку "=" (равно), только используется для сравнения строк. Если тебе надо сравнивать числа, то ты должен использовать знак равно (=), а если строки, то оператор LIKE . Давай теперь рассмотрим, как этот запрос будет выглядеть при поиске по числам. Для этого найдём все строки из той же базы, где количество лицензий равно 1. SELECT * FROM User WHERE LecNumber =1

http://www.cydsoft.com/vr-online

26


VR-online Journal (Horrific and VR-Team)

Для программистов №3

В этом случае мы производим поиск по числовому полю, поэтому используем знак равно (=). Результатом запроса будут все строки, содержащие в поле LecNumber значение 1. Во всех запросах я использовал единственный оператор "=" (равно). Но это не значит, что больше ничего нет. Стандарт разрешает использовать следующие операторы: • • • • • •

"=" ">" "<" ">=" "<=" "<>"

Равный Больше Меньше - Больше или равно - Меньше или равно - Неравно

Операторы "больше", "меньше" и др. можно использовать не только с числами, но и со строками. В этом случае буква "А" будет меньше чем "Р". При сравнении строк разного регистра, меньшим оказывается строка в верхнем регистре, например, "А" будет меньше "а" и "Р" будет меньше "а". При сравнении строк, тебе также необходимо использовать кавычки. SELECT * FROM User WHERE LecNumber >1 Результатом этого запроса будет строки, в которых количество лицензий больше 1. Теперь усложним запрос с помощью булевых операторов. В стандарте предусмотрено три булевых оператора: AND (логическое "и"), OR (логическое "или"), NOT (логическое "не").Сразу же рассмотрим пример: SELECT * FROM User WHERE Сountry LIKE "USA" AND LecNumber >1 Результат запроса - все строки содержащие в поле "Сountry" значение "USA" и в поле LecNumber значение больше "1". Если какое-то из этих условий не выполнится, то строка не будет выбрана. SELECT * FROM User WHERE Сountry LIKE "USA" OR LecNumber =1 Результат запроса - все строки содержащие в поле "Сountry" значение "USA" или в поле LecNumber значение "1". Для того, чтобы строка была выбрана, необходимо чтобы хотя бы одно из этих условий выполнилось. SELECT * FROM User WHERE Сountry LIKE "USA" AND NOT LecNumber =1 Результат запроса - все строки содержащие в поле "Сountry" значение "USA" и в поле LecNumber значение не равное "1". Для того, чтобы строка была выбрана, необходимо чтобы оба условия были верны (потому что мы используем оператор "AND").

http://www.cydsoft.com/vr-online

27


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Обрати внимание, что во втором условии "NOT LecNumber =1" оператор "NOT" стоит вначале. Вот именно там он и должен стоять, и не вздумай его совать в середину или даже в конец условия. В принципе, это условие идентично условию "LecNumber <>1", но это не значит, что этот оператор не нужен. Иногда он действительно очень удобен. При использовании булевых операторов ты можешь использовать скобки: SELECT * FROM User WHERE Сountry LIKE "USA" AND (LecNumber =1 OR LecNumber =2) Результат запроса - все строки содержащие в поле "Сountry" значение "USA" и в поле LecNumber значение не равное "1" или "2". Для того, чтобы строка была выбрана, необходимо чтобы условие Сountry LIKE "USA" и условие в скобках были верны. Если ты закончил хотя бы четыре класса, то никаких проблем с пониманием сегодняшнего занятия у тебя не возникло. Если нет, то я тебе сочувствую. Удачи тебе!!! Copyright © Фленов Михаил aka Horrific

http://www.cydsoft.com/vr-online

28


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Геймер: Рисование картинок Давай продвинемся дальше в наших познаниях DirectDraw. Сразу же приготовься и забери исходники на диске. В этом примере я уже не использую контексты GDI, я рисую только средствами DirectDraw. А самое интересное, что я рисую картинкой. Принцип работы программы похож на ту, что мы рассматривали в прошлой статье, поэтому я расскажу только отличия. Хватит болтовни, давай приступим к программированию. Посмотри на рисунок 1. Сегодня ты получишь вот такую прогу.

Рис.1 Пример работы проги Для облегчения проги я использовал библиотеку DDUtils1 . Её ты можешь взять (если ещё не сделал этого) в разделе "Полезности". С чего всё началось? А началось всё с того, что я объявил ещё одну поверхность. Теперь у меня в программе три поверхности: две переключающиеся и одна для хранения BMP файла. После этого, в конце процедуры StartDX я вызываю процедурку GetPicture. procedure TForm1.GetPicture; begin FSecondSurface := DDLoadBitmap(FDirectDraw, '1.bmp', FRect.Left, FRect.Top); if(FSecondSurface = nil) then begin InitFail();

http://www.cydsoft.com/vr-online

29


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Exit; end; end; DDLoadBitmap загружает картинку в поверхность FSecondSurface. Похожая процедура есть в DDUtils1, но я решил переписать её внеся небольшие изменения. Давай посмотрим, что в ней происходит: function DDLoadBitmap(DirectDraw : IDirectDraw2; const BitmapName: string; var Width, Height: integer):IDirectDrawSurface; var Bitmap : HBitmap; BM : Windows.TBitmap; SurfaceDesc: TDDSurfaceDesc; Begin // Пытаемся загрузить картинку Bitmap:= LoadImage(0, PChar(BitmapName), IMAGE_BITMAP, Width, Height, LR_LOADFROMFILE or LR_CREATEDIBSECTION); // Проверяем, получилось ли это? if Bitmap = 0 then Raise Exception.CreateFmt('Unable to load bitmap %s', [ BitmapName ]); //Вытаскиваем из картинки растровые данные GetObject(Bitmap, SizeOf(BM), @BM); //Подготавливаем временную поверхность FillChar(SurfaceDesc, SizeOf(SurfaceDesc), 0); with SurfaceDesc do begin dwSize:= SizeOf(SurfaceDesc); dwFlags:= DDSD_CAPS or DDSD_HEIGHT or DDSD_WIDTH; ddsCaps.dwCaps:= DDSCAPS_OFFSCREENPLAIN; dwWidth:= BM.bmWidth; dwHeight:= BM.bmHeight; end; // Создаём поверхность if DirectDraw.CreateSurface(SurfaceDesc, Result, NIL) <> DD_OK then Raise Exception.Create('CreateSurface failed'); //Копируем картинку на поверхность с помощью процедуры из DDUtils1 DDCopyBitmap(Result, Bitmap, 0, 0, 0, 0); Width:=BM.bmWidth; Height:=BM.bmHeight; if Bitmap <> 0 then DeleteObject(Bitmap); end; Здесь ничего сложного нет, ты можешь сам разобраться. Если тебе лень разбираться, то просто используй эту функцию. В качестве параметров Width и Height возвращается ширина и высота загруженной картинки. Вот и всё. Картинка загружена, переходим к рисованию. Для рисования я использую функцию BltFast. Это самая быстрая функция из серии "рисовальщиков". function BltFast( dwX, dwY: DWORD; // Левая и верхняя позиция на результирующей поверхности. lpDDSrcSurface: IDirectDrawSurface;//Исходная поверхность откуда копироваться const lpSrcRect: TRect; //Область исходной поверхности, куда скопировать dwTrans: DWORD): HResult; stdcall;

http://www.cydsoft.com/vr-online

30


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Эта функция относится к объекту поверхности, поэтому вызывать её надо как ResultSurfase.BltFast(…). Копирование происходит на поверхность ResultSurfase. dwTrans - это флаги, которые определяют параметры копирования. • • • •

DDBLTFAST_DESTCOLORKEY - Прозрачное копирование. В качестве прозрачного цвета используется colorkey результирующей поверхности. DDBLTFAST_NOCOLORKEY - Копирование без прозрачности. DDBLTFAST_SRCCOLORKEY - Прозрачное копирование. В качестве прозрачного цвета используется colorkey источника. DDBLTFAST_WAIT - Если поверхность занята, то функция не генерирует ошибку, а ждёт освобождения поверхности и потом рисует.

Ещё одна интересная функция в программе - InitFail, которая вызывается, если не удалось загрузить картинку: procedure TForm1.InitFail; begin if FDirectDraw <> nil then begin FDirectDraw.FlipToGDISurface; MessageBox(Handle, 'DirectDraw Init FAILED', '', MB_OK ); Close(); end; end; Всё в этой функции тебе знакомо, я просто хотел обратить твоё внимание на то, что функция MessageBox вызывается после FDirectDraw.FlipToGDISurface. Зачем это? Я уже говорил в прошлых статьях, что FDirectDraw.FlipToGDISurface передает управление выводом на экран GDI, и после этого я вывожу сообщение. Если не передать управление на GDI, то сообщение не будет видно, потому что DirectDraw не может отобразить функцию MessageBox. Вот и всё. Сегодня ты научился рисовать растровые данные на поверхности. Это уже половина необходимой информации по DirectDraw для создания игр. Удачи тебе, до встречи в следующем номере. Исходники примера можете взять в файле dx.zip

Copyright © Фленов Михаил aka Horrific

http://www.cydsoft.com/vr-online

31


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Форматы данных: Формат файла PCX PCX - один из самых старейших форматов графических данных, который разработала фирма ZSoft. Если ты решил написать программу, которая должны будет работать с графикой, то поддержка этого формата обязательна. Не смотря на то, что этот формат не позволяет хранить анимацию, как это делает GIF, он всё же получил большое распространение. Практически все графические редакторы поддерживают его, поэтому ты обязан его знать. Как и любой другой графический формат, PCX состоит из заголовка и растровых данных. Заголовок имеет размер 128 байт, а всё остальное в файле - сжатые растровые данные. Для сжатия используется наверно самый простой алгоритм, не считая абсолютно не сжатых данных. Алгоритм очень прост, если в файле используются данные достаточно большого разрешения. Я имею в виду 256 цветов. Когда используется 16 битный цвет или ещё меньше, то растровые данные сохраняются по плоскостям, т.е. каждая цветовая плоскость отдельно. В 256-и цветных картинках, для описания одного пикселя требуется 8 бит, поэтому сжатие происходит последовательно каждого пикселя, без разделения на плоскости. Я буду рассматривать только 256 кодирование. Хватит вступительных слов, давай перейдём к рассмотрению заголовка PCX файла: Смещение 0 1

Условное обозначение Signature Version

Длина 1 1

Описание Обязательно должно быть 10. Это подтверждает, что файл действительно относиться к PCX формату фирмы ZSoft Информация о версии. Возможны значения: 0 – версия 2,5 2 – версия 2,8 с палитрой 3 – версия 2,8 без палитры

2 3

Encoding Bits per Pixel

1 1

4 6 7 10 12

Left Top Width Height HorRes

2 2 2 2 2

14

VerRes

2

http://www.cydsoft.com/vr-online

5 – версия 3,0 PCX кодирование длинными сериями Число бит на пиксель. Я рассматриваю только 8 бит. С плоскостями я не дружу. Левая позиция экрана Верхняя позиция экрана Ширина экрана Высота экрана Горизонтальное разрешение создающего устройства Вертикальное разрешение создающего

32


VR-online Journal (Horrific and VR-Team)

16 64 65 66

Color map Reserved Nplanes Bytes per Line

68

Palette Info

48 1 1 2 2

Для программистов №3 устройства Набор цветовой палитры Оставлено до лучших времён Число цветовых слоёв Число байт на строку в цветовом слое (для PCX-файлов всегда должно быть четным) Как ты должен понимать палитру. Возможны значения: 1 - цветная/черно-белая,

70

Filler

58

2 - градации серого Заполняется нуликами до самого конца заголовка.

Замечание к палитре. Я подразумеваю, что палитра есть, а если это так, то её надо искать в конце файла. Для этого надо перейти в конец файла и оттуда отсчитать 769 (256*3) байт. После этого, со следующей позиции файла начинается палитра. Теперь поговорим о кодировании. Оно происходит довольно просто. Читаешь символ, если он больше чем 192, то значение символа минус192 будет равно количеству повторений следующего символа. Читай следующий символ и повторяй его столько, сколько высчитал на предыдущем этапе. После этого, снова читаешь следующий символ. Если он меньше 192, то это простое значение цвета, и ты можешь смело его выводить на экран. Читай следующий символ и проверяй на соответствие 192. Если чё не понятно, то перечитай заново. Всё очень даже просто и никаких подводных плит. Если ты собрался закодировать PCX файл, то ты можешь нарваться на проблему. Когда будешь кодировать значение цвета, например, 195, то запиши его в файл как пара чисел 193 195. Если ты просто запишешь 195, то при распаковке наткнёшься на проблему, потому что 195 - больше чем 192. Если не понял в чём проблема, то перечитай про распаковку. Если ты запишешь как два числа 193 195, то при распаковке ты встретишь 193 и повторишь символ 195 ровно 193-192 раз, то есть один раз. Почему этот алгоритм эффективен? Да потому что в любой картинке очень много идущих подряд повторяющихся цветов. С помощью этого алгоритма длинные последовательности цветов превращаются в два байта. Всё очень просто и никаких загадок. Если ты не индеец, то этой инфы тебе будет достаточно. Удачи тебе. Скоро увидимся.

Copyright © Фленов Михаил aka Horrific

http://www.cydsoft.com/vr-online

33


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Java для всех Свершилось. Начиная с этого номера, я дам несколько уроков программирования на языке Java. В моё рассмотрение попадут только апплеты, и программировать мы будем только их. Сегодня нам предстоит разобрать по косточкам наш первый апплет. Апплеты - это маленькие программулины, которые тасуются на серверы и ты иногда видишь их внутри своего браузера. Вот простейший апплет, с которого мы начнём изучение: import java.awt.*; import java.applet.*; public class FirstAppl extends Applet { public void paint(Привет с большого будуна) { g.drawString("Hello World!", 10, 5); } } Набери этот текст в любом текстовом редакторе. Теперь эту писанину в файл FirstAppl.java. Далее нужно откомпилировать эту писанину. Для этого подойдёт JDK любой версии, в состав которого входит компилятор javac.exe. Напиши в командной строке javac.exe FirstAppl.java и у тебя на выходе должен появится файл FirstAppl.class. Теперь у тебя есть откомпилированный Java код и нам теперь нужен HTML код, чтобы можно было увидеть результат в браузере. Создай HTML файл и напиши в нём: <аpplet code=" FirstAppl" width=200 height=40> </аррlet> Помести оба этих файла в одну директорию и запусти HTML файл. Результат примитивный, но для первого раза пойдёт, потому что нам ещё предстоит изучить очень много теории. Теперь постараемся разобраться с кодом: import java.awt.*; import java.applet.*; Эти две строчки подключают заголовочные файлы, для того, чтобы мы могли использовать прописанные там функции. java.awt означает, что нужно сначала найти каталог java (поиск идёт в архиве classes.zip, где находятся все заголовочные файлы), потом в нём подкаталог awt, и внутри этого каталога подключить все файлы. О том, что нужны именно все файлы, говорит звёздочка в конце строки. Хочу остановиться и обратить твоё внимание, что Java регистрозависимый язык. Это значить, что java и JaVa - абсолютно разные слова. Далее объявляется класс: public class FirstAppl extends Applet { }

http://www.cydsoft.com/vr-online

34


VR-online Journal (Horrific and VR-Team)

Для программистов №3

Класс - то же самое, что и объект в Delphi. FirstAppl - имя класса. Applet - ключевое слово, которое указывает компилятору на то, что это апплет. Все остальные зарезервированные слова нужно оставлять такими. Вполне возможно, что с ними мы разберёмся позже по мере надобности. Теперь обрати внимание, что мы сохранили код в файл FirstAppl.java. Имя файла и имя главного класса (именно главного, потому что их может быть несколько) в этом файле должны быть одинаковыми. Внутри фигурных скобок у нас объявлена одна процедура: public void paint(Graphics g) { g.drawString("Привет с большого будуна", 10, 5); } Слово public означает тоже самое, что и в Delphi. Дальше идёт тип возвращаемого значения. Void - означает, что такого значения нет. Вообще, в Java как и в С/С++ нет разделения на процедуры и функции, как в Delphi. Здесь только функции, но они не обязательно должны возвращать значения. В нашем случае возвращать ничего не надо, поэтому я поставил void. Дальше идёт имя процедуры - paint, которая будет вызываться при прорисовке апплета. В скобках нам даётся переменная g типа Graphics. В отличии от Delphi (я всё сравниваю с ним, потому что это основной язык журнала) вначале стоит тип переменной, а потом переменная. В фигурных скобках (которые заменяют Begin и End у Delphi) находиться тело процедуры. Здесь у нас только одна процедура: g.drawString("Привет с большого будуна", 10, 5); Она выводит на экран текст, указанный в качестве первого параметра. Второй и третий - положение текста по оси Х и У. С исходным текстом апплеты мы разобрались, теперь перейдём к HTML коду: <applet code=" FirstAppl " width=200 height=40> </applet> Параметр code указывает на имя java-апплета. А далее всё понятно, ширина и высота апплета на HTML странице. Помимо этого можно использовать следующие параметры: ARCHIVE - имя архива, который должен загрузиться перед запуском апплета. В этом архиве могут храниться ресурсы или файлы необходимые апплету. CODEBASE - базовый адрес URL для апплета. ALT - альтернативный текст, который будет виден, если браузер не поддерживает Java. ALIGN, VSPACE, HSPACE - выравнивание апплета на страничке. На сегодня всё. Я постарался сделать первое занятие простым и понятным. В следующем номере мы углубимся в дебри Java. Copyright © Фленов Михаил aka Horrific

http://www.cydsoft.com/vr-online

35


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.