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

Page 1

VR-online JOURNAL For real programmers Фленов Михаил & VR-Team VR-online для программистов №1

Delphi: Нестандартные окна .........................................................................................................3 Delphi: Плавающие окна .............................................................................................................10 Delphi (графика): Вывод текста под углом ...............................................................................13 Delphi (графика): Прозрачные картинки ...................................................................................19 Delphi (Базы данных): Создание первой базы данных ............................................................21 Delphi (Базы данных): Фильтрация............................................................................................28 WinSock: Введение ......................................................................................................................31 Форматы файлов: Графический формат GIF ............................................................................36 OpenGL: Точка, точка, запятая...................................................................................................39

Copyright: VR-online Journal http://www.vr-online.ru


VR-online Journal (Фленов Михаил & VR Team)

Мы рады представить вам первый номер нашего электронного журнала для программистов, хакеров и администраторов. Здесь мы регулярно будем выкладывать статьи по программированию, сетям, ОС, программам, железу и обо всём, что касается компьютера. Форма общения в журнале - свободная. Это значит, что не будет всяких официальных почестей и желательно, чтобы общения происходили на «ТЫ». Это не означает неуважение, это означает равенство между возрастами и знаниями между нами и читателями. Мы постараемся рассказывать как можно более понятно и расписывать каждую мелочь. Надеюсь, что вам журнал понравится. А если это так, то приходи на наш сайт http://www.vr-online.ru и приводи своих друзей . Если у тебя возник вопрос, то задавай его лучше на форуме нашего сайта. Почта проверяется не регулярно и на форуме ты получишь ответ на много быстрее. Количество разделов в нашем журнале будет постоянно увеличиваться и возможно, что со временем мы превратимся в полноценный электронный журнал с постоянными разделами. Несмотря на достаточную популярность VR-online, на данный момент разделы не постоянны. Это проблема любого проекта построенного на чистом энтузиазме и не приносящего дохода. Наш проект тоже пока не приносит нам денег, но мы надеемся на вечную жизнь для VR-online.

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

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

INFO: ИДЕЯ И РЕАЛИЗАЦИЯ: Флёнов Михаил (Horrific) ГРАФИКА: Фленов Михаил, tr4sh VR-Team: Crazy_Script, Del, Demogorgon, Fighter, Mish!, Negus, Spider NE, tr4sh, Ramzes, Shy Hulud INTERNET: WWW: http://www.vr-online.ru E-MAIL: vr_online@cydsoft.com ДИЗАЙН САЙТА: tr4sh КОДИНГ САЙТА: Mish!

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

Свои комментарии и пожелания по поводу журнала ты также можешь оставить на форуме нашего сайта. Фленов Михаил aka Horrific

http://www.vr-online.ru

2


VR-online Journal (Фленов Михаил & VR Team)

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

Delphi: Нестандартные окна С первого же номера, я начну публиковать уроки Delphi. Сразу скажу, что уроки будут для начинающих, а не для чайников. Поэтому если ты чайник, то иди копать траншеи, программирование не для тебя. Почему я очень часто использую именно этот язык? Ответ прост. С помощью Delphi можно очень быстро создавать любые приложения и в то же время это очень мощная среда разработки. Программист, пишущий на Delphi, ни чем не ограничен, он может создавать приложения любой сложности. Для обучения по моим статьям тебе лучше всего прикупить Delphi 5.0. Если такой нет, то может подойти и 4-я и даже 3-я версии. Я не буду писать всякую чушь, типа обзоров возможностей, обзоров компонент. Мы сразу перейдём к разработке работающих приложений, и во время работы познакомимся с мелочами. С первого же занятия ты убедишься в мощности Delphi. Каждый мой урок будет полезен как начинающему, так и программисту со стажем. Наше первое приложение. Для начала запусти Delphi. Если ты не знаешь, как это делать, то иди копать траншеи. После запуска перед тобой откроется новый проект. Вот именно с ним мы и начнём работать. Теперь выполняй следующие действия: 1. Поставь на форму кнопку. 2. Создай для неё событие "OnClick". 3. Напиши в этой процедуре "Close;" - закрытие окна.

Рис 1. Object Inspector

http://www.vr-online.ru

3


VR-online Journal (Фленов Михаил & VR Team)

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

Для создания события тебе надо выделить объект, событие которого тебя интересует, потом перейти в окно "Object Inspector" (рис 1). Выбрать закладку "Events" и дважды щёлкнуть там по событию. У тебя должны получиться вот такая процедура: procedure TForm1.Button1Click(Sender: TObject); begin Close; end; По нажатию кнопки форма закроется. Никаких "Halt" в твоей программе не должно быть. Все окна закрываются только через "Close()". Кстати, кнопку расположи так, как показано на рисунке 2. Зачем? Узнаешь позже, просто сделай, как я говорю.

Рис 2. Расположение кнопки "Выход" Теперь снова выдели кнопку и в "Object Inspector" у свойства "Caption" напиши "Выход". Маленькое приложение готово. Ты можешь запустить его с помощью меню "Run" и посмотреть, что у нас получилось. А у нас пока ещё ничего не получилось. Потерпи ещё пять минут, и у нас будет на что смотреть. Теперь переходи в окно текста программы и ищи объявления public:. Объявления бывают трёх типов: private, public и protected. Во время уроков мы будем пользоваться первыми двумя. Теперь в private напиши следующее: private { Private declarations } FormRgn,EllipseRgn:HRGN; Во второй строке идёт комментарий. Комментарий - это любой текст (хоть матершина), он не влияет на работу программы, ты их пишешь для себя, а я для тебя, обращай на них внимание. Комментарии оформляются в фигурные кавычки {}. Всё, что находится между ними - это комментарий. Тут может быть хоть несколько строк. Второй способ оформления - это двойной слеш "//". Всё, что находиться в этой строке после двойного слеша - комментарий. В этом случае следующая строка уже не будет комментарием.

http://www.vr-online.ru

4


VR-online Journal (Фленов Михаил & VR Team)

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

Теперь для главной формы создай событие "OnCreate". Для этого достаточно дважды щёлкнуть по главной форме и Delphi создаст процедуру FormCreate . В ней напиши следующее: procedure TForm1.FormCreate(Sender: TObject); begin FormRgn:= CreateEllipticRgn(0,0,Width,Height); SetWindowRgn(Handle,FormRgn,True); end; У тебя должен получиться вот такой текст: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } FormRgn,EllipseRgn:HRGN; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin FormRgn:=CreateEllipticRgn(0,0,Width,Height); SetWindowRgn(Handle,FormRgn,True); end; procedure TForm1.Button1Click(Sender: TObject); begin Close; end; end. Вот теперь запусти то, что у нас получилось. У тебя должно получиться окно похожее на моё окно (см. Рис 3). Я надеюсь, теперь понятно, почему мы именно так расположили кнопку закрытия окна.

http://www.vr-online.ru

5


VR-online Journal (Фленов Михаил & VR Team)

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

Рис 3. Пример выполнения программы Теперь рассмотрим подробнее, что мы тут натворили. CreateEllipticRgn( NLeftRect:Integer, nTopRect:Integer, nRightRect:Integer, nBottomRect:Integer ): HRGN;

//Левая позиция // Верхняя // Правая // Нижняя

Эта процедура создаёт регион в виде эллипса. SetWindowRgn( HWnd: HWND, HRgn: HRGN, BRedraw:Boolean ):Integer;

// Указатель на нашу форму // Предварительно созданный регион // Флаг перерисовки окна

Эта процедура привязывает созданный нами регион с нашей формой. Со всеми параметрами вроде понятно, я только обращу внимание на bRedraw , этот флаг должен быть true. Если ты этого не сделаешь, то твой регион ну будет прорисован. Теперь я приведу ещё две функции, а пример мы посмотрим чуть позже. CreateRectRgn ( nLeftRect:Integer, nTopRect:Integer, nRightRect:Integer, nBottomRect:Integer ): HRGN;

// // // //

Левая позиция Верхняя Правая Нижняя

Эта функция похожа на CreateEllipticRgn . Она также создаёт регион, но уже квадратный.

CombineRgn(

http://www.vr-online.ru

6


VR-online Journal (Фленов Михаил & VR Team) HrgnDest: HRGN, hrgnSrc1: HRGN, hrgnSrc2: HRGN, fnCombineMode:Integer ) :Integer;

// // // //

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

Указатель на результирующий регион Указатель на регион 1 Указатель на регион 2 Метод объединения

Эта функция комбинирует два региона из hrgnSrc1 и hrgnSrc2 и помещает результат в HrgnDest . fnCombineMode - метод комбинирования, который может быть: RGN_AND, RGN_COPY, RGN_DIFF, RGN_OR или RGN_XOR. Теперь подправим нашу программу с учётом новых функций. Для этого, нужно изменить процедуру FormCreate . procedure TForm1.FormCreate(Sender: TObject); begin FormRgn:=CreateEllipticRgn(0,0,Width,Height); EllipseRgn:=CreateRectRgn(round(Width/4),round(Height/4), round(3*Width/4),round(3*Height/4)); CombineRgn(FormRgn,FormRgn,EllipseRgn,RGN_DIFF); SetWindowRgn(Handle,FormRgn,True); end; После запуска ты сможешь увидеть прозрачное окно (Рис 4.).

Рис 4. Пример выполнения программы Вот так, мы с первого урока научились создавать нестандартные окна. Комбинируя различными параметрами изученных нами функций, ты сможешь добиться достаточно хороших эффектов. И напоследок немного теории. Мы использовали в наших функциях Width и Height - это ширина и высота нашего окна. Откуда они взялись? Для этого нужно понимать объёктность. Delphi - это объектно-ориентированный язык. Вот именно об объёктах мы сейчас немного поговорим. В самом начале текста программы есть строка TForm1 = class(TForm) . Она означает, что класс TForm1 происходит от TForm. Такой класс унаследует себе все свойства

http://www.vr-online.ru

7


VR-online Journal (Фленов Михаил & VR Team)

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

предка (TForm), и может добавлять свои. Вот именно у предка и есть такие свойства как Width и Height . Мы просто пользовались ими. И напоследок магическая точка с запятой (;). Она ставиться в конце каждого оператора, как разделитель. Например, ты хочешь присвоить переменной F значение 5, а переменной W значение 4. Ты должен записать это так F:=5; W:=4;. Как видишь, точка с запятой ставиться в конце каждого выражения и служит их разделителем. Единственное, когда не надо ставить ;, так это перед словом else. Есть такая конструкция: if условие then Операция 1 //Здесь точка с запятой не нужна, потому что следом идёт else else оператор 2; Происходящее здесь звучит очень просто: Если условие выполнено то выполнить Операция 1 иначе выполнить оператор 2; Например: if i>0 then i:=5 else i:=10 На первый раз тебе будет достаточно этих знаний. В будущем мы будем постоянно сталкиваться с объектами, поэтому со временем ты пополнишь свой багаж знаний. Если ты что-то не понял, не огорчайся. Со временем всё станет ясно. Попробуй просто поиграть с текстом программы. Москва тоже не сразу строилась. Все исходные коды описанного здесь примера, находятся в файле coolwin.zip Copyright © Фленов Михаил aka Horrific

http://www.vr-online.ru

8


VR-online Journal (Фленов Михаил & VR Team)

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

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

http://www.vr-online.ru

9


VR-online Journal (Фленов Михаил & VR Team)

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

Delphi: Плавающие окна Мы продолжаем учиться программировать. И снова я покажу, что достаточно сложные на первый взгляд вопросы решаются очень легко. Сегодня ты научишься заставлять окна плавать. Плавать они будут не в бассейне, а по экрану, наше окно можно будет перетащить за любую его часть. А самое главное, мы рассмотрим аж два способа решения этой задачи. Сначала рассмотрим тот, что попроще. Для этого создайте новый проект. В разделе private новой формы напишите: procedure WMNCHitTest(var M: TWMNCHitTest); message wm_NCHitTest; Теперь нажми клавиши Ctrl+Alt+C , после этого Delphi создаст пустую процедуру: procedure TForm1.WMNCHitTest(var M: TWMNCHitTest); begin end; Внутри неё напиши следующее: inherited; if M.Result = htClient then M.Result := htCaption; Теперь запусти программу и попробуй перетащить окно за форму. Получилось? Это хорошо, теперь рассмотрим, что мы для этого сделали. Самое первое, это мы объявили процедуру - обработчик для события HitTest. Это событие происходит, когда тестируется щёлчок мышки по окну. Это событие мы объявляли не так как предыдущие (через Object Inspector), а вручную как обычную процедуру. О том, что это обработчик события говорит надпись в объявлении после точки с запятой: message wm_NCHitTest. Внутри обработчика события мы вызываем предка с помощью inherited; , чтобы сначала он обработал это событие. А после этого мы проверяем следующее: если щелчок был по форме, то мы заставляем Microsoft думать, что щелчок был по заголовку окна. Всё очень просто. Взгляни ещё раз на этот код, и ты это поймёшь. Теперь мы сделаем тоже самое вторым способом. Он немного тяжелее, но зато он позволяет перетаскивать окна за любой компонент. Приготовь новый проект, мы начинаем. В объявлении private напиши следующее: private { Private declarations } OldX, OldY, OldLeft,

http://www.vr-online.ru

10


VR-online Journal (Фленов Михаил & VR Team)

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

OldTop : Integer; ScreenDC : HDC; MoveRect : TRect; Dragging : Boolean;

Создай на форме из палитры компонентов TPanel (рис 1.) и создай для неё обработчик события OnMouseDown . В этой процедуре напиши следующее:

Рис 1. Форма procedure TForm1.Panel1MouseDown(Sender: TObject; Button:TMouseButton;Shift:TShiftState;X,Y:Integer); Begin if Button = mbLeft then begin ScreenDC := GetDC(0); OldX := X; // сохраняем Х координату щелчка OldY := Y; // сохраняем Y координату щелчка OldLeft := X; // сохраняем Х координату щелчка OldTop := Y; // сохраняем Y координату щелчка MoveRect := BoundsRect; // сохраняем размеры и положение окна DrawFocusRect(ScreenDC, MoveRect); // Рисуем рамочку окна. Dragging := True; // Начинаем перемещение. end; end;

Процедура нам передаёт параметр Button , в котором хранится значение нажатой кнопки мыши (возможны значения mbLeft, mbRight и mbMiddle). В первой строчке мы проверяем, нажата ли левая кнопка. Если это была левая, то мы начинаем приготовления к перетаскиванию окна. Практически всё ты сможешь понять по комментариям, но некоторые вещи я объясню. GetDC создаёт контекст устройства к указанному в скобках окну, и записывает это, в объявленную нами переменную ScreenDC. В качестве параметра мы передаём ноль, а не ссылку на окно. В этом случае мы получим контекст рисования на всём экране. Контекст устройства - это нечто похожее на Canvas, только второй имеет больше возможностей и более удобен в работе. DrawFocusRect эта функция рисует рамочку на контексте, переданном в качестве первого параметра, и размерами, переданными в качестве второго параметра. В качестве размера мы передаём текущее положение экрана. Теперь нужно создать обработчик события OnMouseMove (когда переместили мышку). Внутри обработчика напиши следующее:

http://www.vr-online.ru

11


VR-online Journal (Фленов Михаил & VR Team)

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

if Dragging then begin //Если происходит перемещение то …. DrawFocusRect(ScreenDC,MoveRect); OldX := X; // Сохраняем новое положение экрана OldY := Y; // Сохраняем новое положение экрана MoveRect := Rect(Left+OldX-OldLeft,Top+OldY-OldTop, Left+Width+OldX-OldLeft,Top+Height+OldY-OldTop); DrawFocusRect(ScreenDC,MoveRect); end; Первый вызов процедуры DrawFocusRect рисует рамку поверх предыдущей. Это нужно для того, чтобы стереть её. Если дважды вывести рамку в одном и том же месте, то результат будет нулевым. Затем сохраняются новое положение окна, переданные нам обработчиком. Далее вычисляются новые размеры рамки, и записываются в MoveRect . И снова вызывается DrawFocusRect , которая рисует рамку в новом положении окна. Теперь создаём обработчик события OnMouseUp (когда отпустили мышку) и записываем следующее: if Button = mbLeft then begin // Если это была левая кнопка DrawFocusRect(ScreenDC,MoveRect); //Стираем рамку Left := Left+X-OldLeft; //Устанавливаем новое левое положение окна Top := Top+Y-OldTop; //Устанавливаем новое верхнее положение окна ReleaseDC(0,ScreenDC); // Уничтожаем контекст устройства Dragging := False; // Перемещение закончено. end; Всё, что здесь происходит ты сможешь разобраться по комментариям. Скажу только, что когда мы создавали контекст устройства (GetDC), мы выделили память. Любую память нужно освобождать после использования, для этого мы воспользовались процедурой ReleaseDC. Исходники примера находятся в файле floatwin.zip. Copyright © Фленов Михаил aka Horrific

http://www.vr-online.ru

12


VR-online Journal (Фленов Михаил & VR Team)

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

Delphi (графика): Вывод текста под углом Ты уже получил начальные знания о Delphi, и наверно уже смог написать свою первую прогу с помощью статьи "Язык программирования Delphi. Нестандартные окна". Сейчас мы продолжим уроки с обучения работы с графикой. Во всех книгах по Delphi обучение начинается с программы "Hello world", а графика рассматривается в конце книги как сложный материал. Наша цель научиться программировать, а не поздороваться с миром. Сейчас ты убедишься, что ничего сложного в графике нет.

Рис 1. Пример выполнения программы На рисунке 1 ты можешь увидеть пример работы программы. Вот именно это и будет делать наша прога. Если ты ещё не вышел из прошлого проекта, то создай новый. Для этого выбери меню File и нажми пункт New Application . Теперь создай обработчик события OnCreate . В этой процедуре напиши следующее: procedure TForm1.FormCreate(Sender: TObject); begin index:=0; end; Index - это у нас будет счётчик, но его ещё надо объявить, поэтому иди в объявления private и напиши следующее:

http://www.vr-online.ru

13


VR-online Journal (Фленов Михаил & VR Team)

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

private { Private-Deklarationen } index:Integer; cl:Boolean; Теперь мы познакомимся с типами данных Delphi. Мы объявили с тобой две переменные: index и cl . Первая из них - это целое, знаковое число. Вторая - это буленовское, и может принимать значения TRUE или FALSE . Основные приготовление закончены, и мы можем переходить непосредственно к программированию. Создай обработчик события для главной формы OnMouseDown . Для этого в Object Inspector нужно перейти в закладку Events и дважды щёлкнуть по этому событию. procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var // Ключевое слово, после которого идут объявления A: Integer; // Объявление переменной А - целое число. begin A := Random(3600); CanvasSetAngle(Canvas, A / 10); Canvas.TextOut(X, Y, FormatFloat('##0.0', A/10)+'°'); end; Рассмотрим, что у нас получилось. Обрати внимание, что после имени процедуры я написал слово VAR . После этого слова идут объявления переменных, которые будут видны только в этой процедуре и создаются при входе, а уничтожаются после выхода из процедуры. Все объявления, которые мы делали после слов private и public видны во всех процедурах типа Имя_Класса.Имя_Процедуры . Тут есть свои нюансы, которые мы рассмотрим по мере надобности. Теперь рассмотрим текст процедуры. В первой строчке мы используем функцию Random , она возвращает случайное значение, но не больше чем число указанное в скобках. В нашем случае - это 3600. Вторую строчку я опущу, а рассмотрим сразу третью. Canvas.TextOut - выводит текст на форме. Canvas - это свойство формы, которое отвечает за всё, что рисуется на ней. TextOut - выводит текст в Canvas. procedure TextOut( X, Y: Integer; // X, Y позиция текста. const Text: string //Текст, который будет нарисован ); В качестве текста я опять использовал процедуру: FormatFloat. Эта процедура переводит число с запятой (вещественное, или так сказать дробное) с учётом формата. function FormatFloat( const Format: string; // Строка формата Value: Extended // Число ): string; В нашем случае эта функция возвращает строку и прибавляет к этой строке значок градуса.

http://www.vr-online.ru

14


VR-online Journal (Фленов Михаил & VR Team)

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

Теперь возвращаемся ко второй строке. CanvasSetAngle - этой процедуры ещё нет, мы её должны написать. Я сейчас приведу весь текст программы, а потом мы рассмотрим эту процедуру отдельно.

unit Textrot1; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type TForm1 = class(TForm) procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Timer1Timer(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private-Deklarationen } index:Integer; cl:Boolean; public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.DFM} procedure CanvasSetAngle(C: TCanvas; A: Single); var LogRec: TLOGFONT; // Объявляем переменную логического шрифта begin GetObject(C.Font.Handle,SizeOf(LogRec),Addr(LogRec)); LogRec.lfEscapement := Trunc(A*10); LogRec.lfOrientation := Trunc((A+10) * 100); C.Font.Handle := CreateFontIndirect(LogRec); end; procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var A: Integer; begin A := Random(3600); CanvasSetAngle(Canvas, A / 10); Canvas.TextOut(x, Y, FormatFloat('##0.0', A/10)+'°'); end; procedure TForm1.Timer1Timer(Sender: TObject); begin end; procedure TForm1.FormCreate(Sender: TObject);

http://www.vr-online.ru

15


VR-online Journal (Фленов Михаил & VR Team)

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

begin index:=0; Canvas.Brush.Style:=bsClear; end; end. В качестве параметров мы передаём процедуре Canvas и угол разворота текста. Угол разворота - имеет значение Single - что означает вещественное (дробное). До этого имя процедур вместо нас писал Delphi. Эту процедуру тебе придётся вписывать своими руками, поэтому познакомимся с ней поближе. procedure - зарезервированное слово, процедура. CanvasSetAngle - имя процедуры Дальше в скобках идут параметры, передаваемые в процедуру. Это означает, что у нас есть какое-то значение, мы его отдаём процедуре, которая может с ним работать. Обрати внимание, что это единственная процедура не выглядящая как Имя_Класса.Имя_Процедуры . Это означает, что наша процедура не относиться к классу TForm1 . Я очень часто использую слово функция. Функция - это процедура, которая возвращает какое-то значение. Её объявление будет выглядеть как: function HHH (Передаваемые параметры):Тип; function - зарезервированное слово, функция. HHH - имя процедуры Тип - Тип возвращаемого значение. Например "integer". Теперь перейдём к содержимому процедуры. Рассмотрим по частям первую строчку. GetObject //Это функция возвращает информацию о графическом объекте C.Font.Handle // Объект на который нужно получить значение. SizeOf(LogRec)// Передаем размер возвращаемого значения Addr(LogRec)// Передаём адрес возвращаемого значения С помощью этой функции, мы получаем информацию о шрифте, используемом нами для рисования. Вторая и третья строчки этой процедуры изменяют значения полученной информации. Четвёртая функция записывает изменённую информацию. Запусти получившееся приложение, и пощёлкай по форме мышкой. Когда наиграешься, закрой программу и я продолжу. Теперь поставь на форме Timer , который находиться в закладке System . Создай для таймера обработчик события OnTimer и напиши в нём следующее: procedure TForm1.Timer1Timer(Sender: TObject); begin CanvasSetAngle(Canvas, index); Canvas.TextOut(100, 100, 'CyD Soft'); index:=index+45; if index>=360 then begin index:=0; if cl then Canvas.Font.Color:=clBlack else

http://www.vr-online.ru

16


VR-online Journal (Фленов Михаил & VR Team)

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

Canvas.Font.Color:=clRed; cl:=not cl; end; end; Вот уже и закончился очередной урок программирования. На прощанье я напомню, что если ты что-то не понял, не огорчайся. Со временем всё станет ясно. В этой статье я тебе рассказал многое из того, что не говорил в прошлой. Я даю тебе информацию постепенно. Если я дам тебе сразу всё, то ты всё равно не запомнишь. Все исходные коды описанного здесь примера, находятся в файле cooltext.zip Copyright © Фленов Михаил aka Horrific

http://www.vr-online.ru

17


VR-online Journal (Фленов Михаил & VR Team)

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

Реклама в журнале 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.vr-online.ru

18


VR-online Journal (Фленов Михаил & VR Team)

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

Delphi (графика): Прозрачные картинки

Мы продолжаем изучение программирования графики на Delphi. Сегодня у нас будет маленький примерчик, но очень удаленький. Прозрачность картинки очень часто обсуждается на различных конференциях, поэтому я решил объяснить эту проблему всем. Как всегда, нам понадобиться запустить Delphi и создать новый проект. Теперь поставь на форму из палитры компонентов Additional компонент TImage . Теперь дважды щёлкни по его свойству Picture . Перед тобой появиться стандартный диалог выбора файла, выбери любой bmp файл, и нажимай "ОК". У тебя должно получиться нечто похожее на рисунок 1.

Рис 1. Форма Теперь щёлкни по форме и создай для неё обработчик события OnPaint . Это событие отвечает за прорисовку экрана, и вызывается каждый раз когда окно нуждается в прорисовке. Вспомни пример из прошлого номера, в котором мы рисовали поворачивающийся текст, программа работает прекрасно, но как только мы свернём её и восстановим заново, всё исчезнет. Мы должны сами восстанавливать содержимое экрана, и делать это надо именно в обработчике OnPaint . Поэтому этот пример мы сделаем по всем правилам. В созданной процедуре FormPaint напиши следующее: procedure TForm1.FormPaint(Sender: TObject); begin Canvas.Brush.Color:=Color; Canvas.BrushCopy(Rect(0,0,Image1.Width,Image1.Height), Image1.Picture.Bitmap, Rect(0,0,Image1.Width,Image1.Height), Image1.Picture.Bitmap.Canvas.Pixels[1,1]); end;

Теперь можешь запустить программу и посмотреть результат. Неплохо? Давай рассмотрим, что же мы писали, чтобы добиться этого.

http://www.vr-online.ru

19


VR-online Journal (Фленов Михаил & VR Team)

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

Рис 2. Результат работы программы Canvas.Brush.Color:=Color; Как ты уже знаешь, Canvas отвечает за то, что будет нарисовано в окне. Поэтому, чтобы что-то нарисовать прямо на форме, мы рисуем это здесь. У него есть свойство Brush, в котором хранятся параметры кисти, используемой при закрашивании. Мы изменяем только один параметр у этой кисти - цвет, которому мы присваиваем цвет формы. Взглянём на эту запись вот так: Область_рисования_формы.Кисть.Цвет:=Цвет_формы. Теперь перейдём ко второй строке. Она кажется немного сложной, но это только на первый взгляд. Поэтому рассмотрим всё по частям. М используем процедуру BrushCopy у уже знакомого Canvas . Эта процедура копирует на Canvas картинку.

procedure BrushCopy( const Dest: TRect; Bitmap: TBitmap; const Source: TRect; Color: TColor);

// // // //

Область приёмника Картинка которая будет копироваться Область источника Прозрачный цвет

Область приёмника объявлена как TRect, который имеет вид TRect = (Left, Top, Right, Bottom: Integer); . Что находиться в скобках, я думаю пояснять не надо. То же самое и с областью источника. В качестве картинки мы передаём Bitmap из TImage . Прозрачный цвет будет заменяться на цвет кисти, который мы задали в первой строке. В качестве прозрачного цвета я использовал цвет пикселя в позиции [1,1] из картинки TImage. На это указывает запись Image1.Picture.Bitmap.Canvas.Pixels[1,1] . Я её запишу немного по другому: TImage1.Его_картинка.Bitmap.Область_рисования.Пиксел[1_по_оси_X, 1_по оси_Y] Вот и всё. Жди следующего урока. Исходники примера находятся в файле transp.zip.

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

http://www.vr-online.ru

20


VR-online Journal (Фленов Михаил & VR Team)

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

Delphi (Базы данных): Создание первой базы данных Я уже устал говорить, что Delphi это мощный язык программирования. Я повторюсь, потому что работа с базами данных стала действительно простой только с появлением этого мощного языка программирования. Я научу тебя эффективно работать с базами Paradox, которые отличаются большими возможностями и высокой производительностью. Для создания первой базы данных тебе понадобиться запустить Database Desktop, который входит в поставку с Delphi. После запуска выполни следующие действия:

Рис 1. Создание новой таблицы 1. Выбери меню File затем New и наконец Table 2. В появившемся окне, выбери из списка Paradox 7 . 3. Нажми "OK".

http://www.vr-online.ru

21


VR-online Journal (Фленов Михаил & VR Team)

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

Перед тобой откроется окно как на рисунке 1. Можно сказать, что первая база данных готова. Теперь ты должен заполнить её поля, но сначала рассмотрим появившийся перед нами диалог. 1. Первая колонка - это номер по порядку. Database Desktop генерирует его автоматически и изменять ты его не можешь. 2. Имя поля. Здесь ты можешь называть свои поля как угодно. 3. Тип поля. Щёлкни в этой колонке правой кнопкой мыши и перед тобой появиться меню со всеми допустимыми типами, тебе необходимо только выбрать нужный. 4. Размер. Это размер поля. Не у всех типов полей можно менять размер, у большинства он задан жёстко. Размер в основном меняется у строковых типов (Alpha), бинарных (binary) и др. 5. Ключ. Если ты дважды щёлкнешь по этой колонке, то текущее поле станет ключевым, то есть по умолчанию по нему будет отсортирована вся таблица. Ключевыми могут быть только первые поля, то есть второе поле сможет быть ключевым только вместе с первым. Без ключевого поля невозможно добавлять новые записи в таблицу. В качестве примера возьмём классический пример - приём заказов. Самое главное, это правильно представить себе и создать структуру базы данных. В нашем случае будет вестись учёт следующих полей: • • • • •

ФИО Покупатель Адрес Дата заказа товара Наименование заказанного товара Количество заказанного товара

Теперь нужно продумать структуру. Если создать все эти поля в одной таблице, то будет не совсем эффективно. Если один и тот же покупатель возьмёт два товара, то у обеих строчек 1-е и 2-е поле будут содержать одинаковые данные. Будет лучше, если мы вынесем первые два поля в отдельную таблицу. Итак, наша база данных будет состоять из двух таблиц. В первой будут следующие поля (после тире стоит тип поля, а в скобках размер): • • •

Ключ 1 - autoincrement ФИО Покупатель - alpha (размер 50) Адрес - alpha (размер 50)

И соответственно 2-я: • • • • •

Ключ 1 - autoincrement Ключ 2 - Integer Дата заказанного товара - date Наименование заказанного товара - alpha (размер 20) Количество заказанного товара - Integer

"Ключ 1" - это будет уникальное ключевое поле в обеих таблицах, поэтому поставь им значок ключевого. "Ключ 2" во второй таблице будет связан с "Ключ 1" из первой. Создай эти таблицы. Первую назови mast.db , а вторую child.db . После того, как создашь вторую таблицу, ты должен сделать "Ключ 2" во второй таблице индексным, чтобы можно было связать две таблицы с помощью этого поля. Для

http://www.vr-online.ru

22


VR-online Journal (Фленов Михаил & VR Team)

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

этого нужно Для этого нужно из меню Table выбрать пункт Restructure . Перед тобой должно открыться вот такое окно:

Рис 2. Table Restructure Перед тобой откроется окно как на рисунке 2. В выпадающем списке Table properties выбери Secondary Indexes и нажми кнопку Define . Выбери свой второй ключ и перемести его в список Indexed fields . Можешь нажимать "OK". У тебя запросят имя индекса, введи, например hhh и снова жми "OK". После этого сохраняй таблицу. Индексы готовы, теперь перейдём к последнему этапу подготовки базы. Запусти SQL Explorer.

http://www.vr-online.ru

23


VR-online Journal (Фленов Михаил & VR Team)

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

Рис 3. SQL Explorer Из меню Object нужно выбрать пункт New . Database driver name должен быть STAMDART . Жми "ОК". Это создаст новый Alias. Переименуй его в "Sales1". Теперь в правой половине окна щёлкни по строке PATH. Перед тобой откроется окно выбора директории. Выбери ту, где находятся созданные нами таблицы и нажми "ОК". Для сохранения того, что ты навоял, выбери из меню Object пункт Apply . Вот теперь мы готовы писать собственно программу. Поэтому сделай перерыв и после этого запускай Delphi. Создай новый проект. Помести на него из палитры компонент "Data Access" два "DataSource" и два "TTable". Для первого "DataSource" установи свойство "DataSet" в Table1 , а у второго "Table2" . Теперь у Table1 измени следующие свойства (желательно в такой последовательности): • • •

В "DatabaseName" выставь Sales1 (это Alias, который мы создали в SQL Explorer) "TableName" выставь в "mast.db". Если ты всё правильно сделал, то имя этой базы будет в выпадающем списке этой строки. "Active" выставь в TRUE .

То же самое сделай и с Table2, только в "TableName" выставь "child.db". После того как ты всё это сделаешь, из палитры компонент "DataControls" поставь на форму два "DBGrid". В свойстве "DataSource" у одной из них выставь DataSource1 , а у другой DataSource2 . Постарайся расположить компоненты, как на рисунке 4.

http://www.vr-online.ru

24


VR-online Journal (Фленов Михаил & VR Team)

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

Рис 4. Расположения компонентов на форме Уже можно запустить программу и убедиться, что всё работает. Но всё ещё не очень красиво, ведь таблицы ещё не связаны, и никому не нужно видеть ключи, да и подписи на английском. Щёлкни по "Table2", здесь у тебя должна находиться "child.db". В свойстве "MasterSource" выставь DataSource1 . После этого дважды щёлкни в поле "MasterFields", перед тобой откроется окно как на рис.5. В верхнем списке (Available Indexes) выбери имя, которое ты задал, когда индексировал Key2, в данном случае это "hhh". Теперь выдели Key2 в левом окне и Key1 в правом и нажми кнопку "Add". Нажимай "ОК" и снова ставь в свойствах этой таблицы "Active" в "true".

Рис 5. Окно связывания таблиц Теперь дважды щёлкни по "Table2". Перед тобой откроется окошко (на рисунке 4 справа вытянутое окно с заголовком "Form1.Table2"). В этом окне щёлкни правой кнопкой мыши, и в появившемся меню выбери Add All Fields . После этого, все имена таблицы будут добавлены в это окно. В свойствах Key1 и Key2 установи "Visible" в FALSE . В свойстве поля "Data" установи "DisplayFormat" в dddddd , а "EditMask" в 99/99/9999 . У всех полей свойство "DisplayLabel" отвечает за имя отображающее в компонентах это поле, поэтому напиши здесь у всех нормальные русские именна.

http://www.vr-online.ru

25


VR-online Journal (Фленов Михаил & VR Team)

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

После того, как закончишь с этой таблицей, проделай подобные операции со второй. Твоё первое приложение работающее с базой данных готово. Мы сегодня создали не совсем простенькое приложение, и при этом не написали ни одной строчки кода. В следующем номере я продолжу тебя знакомить с возможностями Delphi при программировании баз данных Все исходные коды описанного здесь примера, находятся в файле database.zip Copyright © Фленов Михаил aka Horrific

http://www.vr-online.ru

26


VR-online Journal (Фленов Михаил & VR Team)

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

Программирование в 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.vr-online.ru

27


VR-online Journal (Фленов Михаил & VR Team)

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

Delphi (Базы данных): Фильтрация Для сегодняшнего занятия нам понадобиться проект, созданный на прошлом занятии (см. прошлый номер). Открой этот проект. Теперь сделаем наш проект покрасивее, для этого выполни следующее: 1. Установи на форму из палитры Win32 компонент TToolBar. 2. Выставь свойство Align у DBGrid1 в alTop , а у DBGrid2 в alClient . 3. Установи на форму из палитры Additional компонент TSplitter. 4. Выставь свойство Align у TSplitter в alTop . 5. Теперь устанавливаем поверх ToolBar1 компонент TEdit. Align - выравнивание, т.е. по какой стороне формы будет выравнивание. После этих манипуляций у тебя должно получится нечто похожее на рисунок 1.

Рис 1. Форма Теперь создай событие OnChange для Edit1, это событие происходит каждый раз, когда пользователь вводит текст в Edit1. В созданной процедуре напиши следующее: if Edit1.Text<>'' then begin Table1.Filtered:=true;

http://www.vr-online.ru

28


VR-online Journal (Фленов Михаил & VR Team)

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

Table1.Filter:=DBGrid1.SelectedField.FieldName+ '='''+Edit1.Text+'*'''; end else Table1.Filtered:=false; Здесь мы использовали конструкцию типа if Условие then Действие1 else Действие 2 Суть здесь такая: Если "условие" действительно, то выполнить "Действие 1", иначе выполнить "Действие 2". Действие должно быть только одно, если больше, то их нужно записать между парой "Begin" и "End", как "Действие 1" в нашем примере. Теперь перейдём непосредственно к рассмотрению примера. Первая строка проверяет, есть ли текст в Edit1. Если да, то выполняется "действие 1", которое состоит из двух строчек. В первой я говорю, что Table1 фильтрованная. Это означает, что видимыми будут только те строки, которые удовлетворяют условию, записанному в свойстве Filter у Table1. В следующей строке я создаю это условие. DBGrid1.SelectedField.FieldName означает выделенную колонку в DBGrid1, т.е. фильтр будет устанавливаться относительно выделенного поля. Edit1.Text+'*' - звёздочка в этом выражении означает любые символы. Это значит, если в Edit1 будет введены буквы "Аб", то показываться будут все строки начинающиеся на "Аб". Если не поставить звёздочку, то будут выведены только строки равные "Аб", а строка с "Абв" уже не выведется. В качестве "действия 2" условия, я отменяю фильтрацию. Теперь, как это будет выглядеть в общем: Если введён какой-нибудь символ, то установить фильтр. Если ничего не введено, то удалить фильтр, что покажет все строки. Это самый простой способ поиска необходимых строк. В качестве фильтра можно использовать выражения типа: Имя_Колонки1='Параметр' AND Имя_Колонки2='Параметр' В этом случае, фильтрация будет проходить сразу по двум полям, то есть выводиться будут только те строки, которые удовлетворят сразу двум условиям. Запусти программу и попробуй поиграть с вводом в Edit1. Только эффект будет, если у тебя введены строки в базу данных. На фильтрацию влияют настройки свойства FilterOption у Table1. Дважды щёлкни по этому свойству в Object Inspector . и перед тобой откроется два свойства: • •

foCaseInsensitive - сравнивать без учёта регистра. Если это свойство = true, то строки "абв" и "АБВ" будут одинаковыми, иначе они будут разными. foNoPartialCompare - Если этот параметр = true, то звёздочка "*", которую мы использовали, работать не будет.

Вот ты и познакомился с фильтрацией. Ты пока потренируй свои возможности, а я подумаю о чём тебе рассказать в следующем номере.

http://www.vr-online.ru

29


VR-online Journal (Фленов Михаил & VR Team)

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

А напоследок я расскажу о некоторых возможностях Database Desktop , которые я опустил до лучших времён в прошлой статье. Так вот, эти лучшие времена настали.

Рис 2. Database Desktop • • • •

Minimum Value - минимальное значение параметра. Maximum Value - максимальное значение параметра. Default Value - значение параметра по умолчанию. Этим значением будет заполняться поле при создании новой строки. Picture - Маска, которая показывает, как должно выглядеть поле. Для её назначения используй кнопку Assist

На сегодня хватит, а то у тебя голова вскипит. Исходники примера находятся в файле database.zip.

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

http://www.vr-online.ru

30


VR-online Journal (Фленов Михаил & VR Team)

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

WinSock: Введение Интернет всё больше входит в нашу жизнь. Мы его используем как средство общения, средство получения информации, средство развлечения и т.д. Из всего этого следует, что для работы с ним необходимо множество программ и на рынке их очень много, но существует три наиболее распространённые ситуации, когда не возможно ими воспользоваться: • • •

не хватает денег на приобретение лицензионной копии; работа стандартной программы не устраивает по своим возможностям и удобству; необходимой программы просто нет.

Первый пункт для нашей страны не особо актуален, ведь в любом городе существуют рынки, на которых за смешную цену можно купить диск, полный программ не только для работы с интернетом, но и для работы с текстом, графикой и т.д. Второй и третий пункт в нашей стране встречается более чаще, поэтому программист начинает писать сам программку, в которой будут реализованы те или иные функции для работы с интернетом. Ты, конечно же, можешь сказать, что существует ещё одна причина - деньги. Если ты так считаешь, и взялся читсть мою книгу только для этого, то не теряй времени зря, лучше займись чем-нибудь другим. Если ты пишешь программу только ради денег, то ты не сможешь получить от неё нужного эффекта. Начинать писать программу можно только в том случае, если ты действительно видишь, что твоя будущая программа необходима. Теперь встаёт вопрос: "Как писать?". Вот на этот вопрос мы и постараемся ответить. Несколько десятков лет назад, существовало множество методов для взаимодействия компьютеров между собой, но такое разнообразие привело к проблеме несовместимости программного обеспечения, поэтому программисты пришли к выводу, что необходимо стандартизировать процесс связи компьютеров по сети. Одним из шагов, на пути стандартизации было появление протоколов, но они каждым программистом реализовывались по разному. В целях создания универсального метода взаимодействия процессов на основе использования многоуровневых сетевых протоколов был разработан механизм, получивший название "sockets" (в дальнейшем "гнёзда"). За счёт стандартизации, этот способ уступает по гибкости потоковому механизму, но возможностей, которые дают гнёзда больше чем достаточно. В этой книге мы рассмотрим основные аспекты применения гнёзд, основы некоторых протоколов и, конечно же, напишем какую-нибудь программку для работы с гнёздами, я сам ещё не знаю какую. Первое знакомство: Все люди как люди, а Microsoft пошла своим путём и немного по-своему реализовала гнёзда. Функции для работы с гнёздами расположены в файле Winsock.dll. Если ваш

http://www.vr-online.ru

31


VR-online Journal (Фленов Михаил & VR Team)

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

компьютер настроен для работы в сети, то этот файл должен находиться в директории Windows, если вы не нашли этого файла, то скорей всего ваша сеть сконфигурирована не правильно или у вас шоловливые руки, которые стёрли этот файл. К достоинствам гнёзд можно отнести: • •

Программирование гнёзд, для различных платформ практически не отличается; Возможна связь процессов находящихся на разных машинах и на разных платформах;

Реализация гнёзд в библиотеке Winsock.dll схожа с библиотеками UNIX систем, но в данной книге основной упор будет делаться на библиотеку Microsoft, в которой достаточно много различий, поэтому документация на UNIX систему вам поможет, но не силько.

Рисунок 1. Связь через гнёзда происходит как на сервере, так и на клиенте через три уровня: гнёзд, протоколов и устройств. Уровень гнезд выполняет функции интерфейса между обращениями к операционной системе (системным функциям) и средствами низких уровней, уровень протоколов содержит модули, обеспечивающие взаимодействие процессов (на рисунке показаны протоколы TCP и IP), а уровень устройств содержит драйверы, управляющие сетевыми устройствами (драйвер сетевой карты, модема). Уровень протоколов зависит от конфигурации операционной системы, я не зря указал TCP/IP так как он является транспортным протоколом сети интернет протоколом. Гнёзда позволяют связываться двум процессам как внутри одной машины, так и нескольким машинам через сеть. Процессы взаимодействуют между собой по схеме клиент-сервер: сервер ждёт сигнала от гнезда, а клиенты обращаются к серверу через гнездо которое моет находится как на этом компьютере, так и на другом. Библиотека winsock обеспечивает связь между клиентом и сервером, передавая и принимая данные от клиента к серверу и обратно. Гнезда бывают двух типов: виртуальный канал или потоковое гнездо и дейтаграмма. Виртуальный канал обеспечивает надежную доставку данных с сохранением исходной последовательности. Дейтаграммы не гарантируют надежную доставку с сохранением уникальности и последовательности, но они более экономны в использовании ресурсов, поскольку для них не требуются сложные установочные операции. В дальнейшем при рассмотрении функций Winsock я не буду останавливаться на данной теме, поэтому тебе необходимо сейчас понять различие между датаграммами и виртуальным каналом, потому что они программируются немного по разному. Основным отличием является инициализация и функции посылки и приёма информации.

http://www.vr-online.ru

32


VR-online Journal (Фленов Михаил & VR Team)

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

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

Протоколы : Наиболее распространённым является протокол TCP/IP. Этот протокол используют во всём мире для объединения компьютеров в сети, он также является основным протоколом в сети Internet. Термин TCP/IP охватывает целую кучу протоколов, прикладные программы и даже саму сеть. Наиболее распространёнными протоколами семейства TCP/IP являются FTP, UDP, TELNET и др. Рассмотрим протокол TCP немного подробнее. TCP занимает в многоуровневой архитектуре протоколов нишу непосредственно над протоколом Internet, который позволяет протоколу TCP отправлять и получать сегменты информации переменной длины, заключенные в оболочку Internet датаграмм. Internet датаграмма предоставляет средства для адресации отправителя и получателя сегментов TCP в различных сетях. Протокол Internet также осуществляет любую фрагментацию и сборку сегментов TCP, необходимую для осуществления передачи и доставки через множество сетей и промежуточных шлюзов. Когда информация слишком большая, и не может быть передана одним пакетом, то протокол Internet разбивает информацию на пакеты, пересылает процессу-клиенту, а при приёме собирает в одно целое. Протокол Internet также обработывает информацию о приоритете, классификации безопасности, а также осуществляет разграничение TCP сегментов (необходимая информация берётся из заголовка, который мы рассмотрим ниже). Так что данная информация может быть передана напрямую через множество сетей. Для большей наглядности вышесказанного рассмотри следующий рисунок, он показывает четыре уровня TCP.

Передача TCP сегментов осуществляется в виде Internet датаграмм. Заголовок датаграммы в Internet протоколе имеет несколько информационных полей, включая адреса отправляющего и принимающего хост компьютеров. Заголовок TCP следует за Internet заголовком и дополняет его информацией, специфической для TCP протокола. Это позволяет использовать на уровне хост-компьютеров всех протоколов семейства TCP. Одним из существенных недостатков пакетной передачи данных - большое количество служебной информации. К служебной информации я отношу заголовки протоколов. Так, например, при отправке одного пакета данных по протоколу TCP, вы отправляете вместе с данными два заголовка - заголовок протокола TCP и заголовок протокола Internnet.

http://www.vr-online.ru

33


VR-online Journal (Фленов Михаил & VR Team)

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

Формат TCP заголовка: Тебе не обязательно вникать и запоминать в структуру заголовка, потому что работа с Winsock позволяет работать с гнёздами на более высоком уровне. Протокол TCP используют тогда, когда необходима гарантированная доставка информации. Соединение между процессом-сервером и процессом-клиентом образуют виртуальный канал, который обеспечивает гарантированность доставки пакетов. Виртуальный канал требует дополнительных ресурсов, как на машине-клиенте, так и на машине-сервере. Этот канал является дуплексным (пакеты могут направляться в обоих направлениях). Протокол TCP немного медленней UDP, так как для обеспечения надёжности передачи пакетов, необходимы подтверждения об успешной доставке пакета. Если в течении определённого периода (таймаут) не пришло подтверждение об успешной доставки пакета, происходит повторная передача данных. Ты можешь сказать, что это слишком медленно, ждать пока сервер подтвердит каждый пакет, но клиент не делает этого. Протокол организован с использованием упреждающей отправки пакетов. Это значит, что процесс-клиент имеет право отправить определённое количество пакетов, не дожидаясь подтверждения их доставки. Если сервер присылает уведомление об ошибке приёма одного из пакетов, то процесс-клиент повторяет отправку данного пакета, и продолжает отправку следующих, пока снова не приедёт сообщение об ошибке или не выйдет время (таймаут). Точно так же происходит передача и в обратную сторону. Для начала, тебе этих знаний больше чем достаточно, поэтому, я думаю, можно переходить к рассмотрению функций библиотеки WinSock, что мы и сделаем в следующем номере Copyright © Фленов Михаил aka Horrific

http://www.vr-online.ru

34


VR-online Journal (Фленов Михаил & VR Team)

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

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

http://www.vr-online.ru

35


VR-online Journal (Фленов Михаил & VR Team)

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

Форматы файлов: Графический формат GIF Если ты путешествуешь в Internet, то не раз видел анимацию выполненную с использованием GIF файлов. Этот формат стал одним из распространённых в сети Internet. И всё это благодаря своим достоинствам: • • •

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

На время написания этой статьи, на страничке этого журнала все картинки были созданы с помощью CyD GIF Studio Pro и хранились в GIF формате. По степени сжатия, с GIF файлами могут конкурировать только JPG (JPEG). Но вторые сжимаются с потерей качества, и при высокой степени сжатия эти потери очень сильно ощутимы. Поэтому JPEG используют только для хранения больших картинок, не требовательных к качеству. Для начала посмотрим на рисунок 1. На нём представлена структура GIF файла. Обрати внимание, что дескриптор изображения, локальная палитра и растровые данные могут повторяться сколько угодно раз. Как раз это свойство и позволяет создавать анимированные изображения. При изучении статьи ты должен внимательно следить за дескрипторами о которых я говорю. Ты не должен путать дескриптор изображения и дескриптор экрана. Теперь рассмотрим всё по порядку. Сигнатура файла. В различной литературе здесь может использоваться разные обозначения, но я привык именно к такому. Сигнатура - это подпись файла, которая подтверждает, что это действительно GIF файл. Размер сигнатуры равен 6 байтам. Я не знаю зачем так много, но видимо так надо. На Рис 1. Структура GIF файла данный момент сигнатура может иметь два значения: GIF89a или GIF87a . Первые три байта говорят, что перед нами файл формата GIF. Вторые три байта показывают версию файла. Дескриптор экрана . Здесь хранятся общие параметры для хранящихся в файле изображений. Здесь определены размеры изображения, существование таблицы цветов и их глубина. На рисунке 2 представлена схема дескриптора экрана. Как ты можешь видеть, все поля имеют размер в один байт.

http://www.vr-online.ru

36


VR-online Journal (Фленов Михаил & VR Team)

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

Первый и второй байт это ширина, а второй и третий - высота. Ширина и высота логического экрана могут быть больше размеров физического. Как в этом случае будет высвечиваться изображение, будет зависеть от программы реализующей этот формат. В пятом байте хранится сразу несколько параметров 1. М (1 бит) если равен единице, то после дескриптора идёт глобальная таблица цветов. 2. cr (3 бита) если к этому значению прибавить 1, то получается число битов цветового разрешения. Рис 2. Дескр. экрана. 3. Следующий бит всегда равен нулю. 4. pixel (3 бита) Если прибавить единицу, то получим число бит/пиксель. Диапазон значений от 0 до 7, то есть если мы прибавим "1" то получим максимальную глубину цвета в 256 цветов. В наше время это уже маловато, но что поделаешь. Формат разрабатывался более десяти лет назад. После этого идёт фон (1-й байт) - индекс цвета в глобальной таблице цветов (если её нет, то значение берётся из палитры, используемой по умолчанию) используемый в качестве фона. Последний байт нулевой, т.е. зарезервирован до лучших времён. Глобальная палитра Глобальная палитра может и не существовать. О её существовании говорит поле "М" в пятом байте дескриптора экрана. Эта палитра может быть связана со всеми изображениями или с некоторыми из них. Число элементов палитры равно 2 в степени (число бит/пиксел). Каждый элемент состоит из трёх байтов: интенсивность красного, зелёного и синего. Дескриптор изображения - определяет расположение и размеры внутри пространства описанного в дескрипторе экрана. Помимо этого, здесь хранятся флаги присутствия локальной палитры (если её нет, то используется глобальная) и последовательность высвечивания пикселов. Структура дескриптора изображения показана на рисунке 3. Рассмотрим подробнее: • • • • • •

1-й байт - это разделитель изображений (шестнадцатеричная 0x2C). 2-й и 3-й байт. Начало изображения в пикселах относительно левого края экрана. 4-й и 5-й байт. Начало изображения в пикселах относительно верхнего края экрана. 6-й и 7-й байт. Ширина изображения в пикселах. 8-й и 9-й байт. Высота изображения в пикселах. 10-й байт. Хранит флаги изображения: Рис 3. Дескр. изображ. o М=1 (1 бит) означает что есть локальная палитра, иначе используется глобальная, а значение pixel этого байта игнорируется. o I=0 (1 бит) означает, что растровые данные отформатированы в последовательном порядке, иначе данные переплетены. o Далее идут три бита нулевых. o pixel (3 бит), если прибавить 1, то получим число бит/пиксель.

http://www.vr-online.ru

37


VR-online Journal (Фленов Михаил & VR Team)

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

Локальная палитра как и глобальная является необязательной. Её присутствие зависит от бита "М" в 10-м байте дескриптора изображения. Эта палитра относиться только к последующим растровым данным. На остальные изображения она не влияет. После отображения растровых данных таблицу цветов и число бот на пиксел нужно вернуть у состоянию, описанному в дескрипторе экрана. Растровые данные Формат растровых данных определён как серия значений индексов в цветовой палитре. Пикселы хранятся слева на право последовательно по строкам. Если бит "I" в 10-м байте дескриптора изображения равен нулю, то данные записываются последовательно, сверху вниз. Иначе происходит четырёхпроходная запись данных. Сперва записывается каждая восьмая строка, начиная с первой. Потом каждая 8-я, начиная с 5-й строки. На 3-м этапе записывается каждая четвёртая, и на последнем этапе записывается каждая 2-я строка. Растровые данный сжимаются по алгоритму сжатия LZW. Терминатор Шестнадцатеричное 0х3В означает конец изображения. Если в файле только одно изображение, то это конец файла. Если изображений несколько, то после терминатора начинается следующее изображение. С основными составляющими структуры мы познакомились, но на этом осмотр формата GIF фала не заканчивается. Этот формат был тщательно продуман, и в него были заложены механизмы, позволяющие расширять возможности формата. Для этого был введён Расширенный блок GIF . Расширенный блок может находиться как перед дескриптором изображения, так и после изображения, н перед терминатором. Расширенный блок состоит из: • • • •

(1 байт) Идентификатор расширенного блока - 00100001 (1 байт) Функциональный код (1 байт) Байт счётчик Данные

Байт счётчик и данные могут повторяться много раз, происходит это, пока не встретиться нулевой байт счётчик. И это ещё не всё. В следующем номере мы познакомимся с алгоритмом сжатия LZW, с помощью которого сжимаются GIF файлы. Copyright © Фленов Михаил aka Horrific

http://www.vr-online.ru

38


VR-online Journal (Фленов Михаил & VR Team)

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

OpenGL: Точка, точка, запятая Начиная с этго номера, мы начинаем знакомиться с OpenGL. Как и все другие занятия, это сразу же начнётся с реального примера. Посмотри на рисунок 1. Вот такая у нас получится программа.

Рис 1. Пример работы программы Для того, чтобы использовать функции OpenGL тебе понадобится подключить два файла: GL и GLU. Для этого напиши имена этих файлов в разделе Uses в начале файла. Оба этих файла ты можешь забрать вместе с исходниками в конце статьи. Начинаем программировать. Для начала нам понадобиться две переменные. Их ты должен объявить в разделе private private { Private declarations } DC:HDC; hrc:HGLRC; Теперь создай обработчик события OnCreate . В нём нужно написать следующее: DC:=GetDC(Handle); PixelFormat; hrc:=wglCreateContext(DC); wglMakeCurrent(DC,hrc); В первой строчке мы получаем контекст рисования на форме, и сохраняем его в созданной нами переменной DC. Во второй строке мы вызываем процедуру, которая будет устанавливать формат пиксела. Эту процедуру мы напишем чуть позже. Третья строка на основе контекста формы создаёт OpenGL контекст рисования. И последняя строка делает OpenGL контекст активным. Теперь перейдём к процедуре PixelFormat . В разделе private , после объявленных нами переменных объяви процедуру.

http://www.vr-online.ru

39


VR-online Journal (Фленов Михаил & VR Team)

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

procedure PixelFormat; Теперь нажми Ctrl+Alt+C после этого Delphi создаст пустую процедуру и переместит тебя в неё. В ней нужно написать следующее: procedure TForm1.PixelFormat; var nPixelFormat:Integer; pfd:TPixelFormatDescriptor; begin FillChar(pfd,Sizeof(pfd),0);

// заполняем структуру pfd нулями.

pfd.nSize:=sizeof(pfd); // Заполняем размер структуры. pfd.nVersion:=1; //Версия pfd.dwFlags:=PFD_DOUBLEBUFFER+PFD_SUPPORT_OPENGL+ PFD_DRAW_TO_WINDOW; //Флаги контекста pfd.iPixelType:=PFD_TYPE_RGBA; //Тип цвета pfd.cColorBits:=24; //Количество цветов pfd.cAlphaBits:=64; pfd.cAccumBits:=64; pfd.cDepthBits:=32; pfd.cStencilBits:=64; pfd.iLayerType:=PFD_MAIN_PLANE; nPixelFormat:=ChoosePixelFormat(DC,@pfd); if nPixelFormat<>0 then SetPixelFormat(DC,nPixelFormat,@pfd); end; Самое интересное для нас это флаги: • • •

PFD_DOUBLEBUFFER - при рисовании будет использована двойная буферизация. PFD_SUPPORT_OPENGL - Этот флаг говорит, что окно будет поддерживать OpenGL PFD_DRAW_TO_WINDOW - Этот флаг говорит, что рисование будет происходить в окне.

С остальным ты разберёшься сам по комментариям. А теперь небольшое замечание: параметры pfd.cColorBits, pfd.cAlphaBits и так далее можно назначать хоть 128. В этом случае OpenGL создаст максимально близкий по возможностям к этим значениям контекст. ChoosePixelFormat -запрашиваем формат пиксела. В качестве первого параметра мы передаём контекст устройства в котором собираемся рисовать. Второй параметр структура, которую мы уже заполнили. В этой структуре хранятся данные о запрашиваемом нами формате пиксела. Если возвращаемое значение не равно нулю, то всё в порядке. SetPixelFormat - устанавливает запрошенный нами формат пиксела. Переходим к последнему этапу подготовки к рисованию. Создай обработчик события OnPaint , в нём нужно написать следующее: glMatrixMode(GL_PROJECTION); // Устанавливаем матрицу glLoadIdentity( ); // Загружаем единичную матрицу if width <= height then glOrtho (-2, 2, -2*height/width, 2*height/width, -10.0, 10.0)

http://www.vr-online.ru

40


VR-online Journal (Фленов Михаил & VR Team)

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

else glOrtho (-2*width/height, 2*width/height, -2, 2, -10.0, 10.0); glViewport(0, 0, width, height); //Область видимости на форме Со всем, что здесь происходит ты разберёшься по комментариям, я только объясню действие функции glOrtho. Эта процедура устанавливает область отсечения. Все точки выходящие за эту область будут отсечены. glOrtho( GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble );

left, //Левая позиция right, //Правая bottom, //Нижняя top, //Верхняя near, //Ближняя far //Дальняя

Теперь мы готовы к рисованию с помощью OpenGL. В обработчике OnPaint мы напишем следующее: var ps:TPaintStruct; begin BeginPaint(Handle,ps); //Начало рисования glClearColor(1,0.5,0.5,1); //Выставляем цвет фона glClear(GL_COLOR_BUFFER_BIT); // Очищаем нарисованное ранее glPointSize(10);

//Выставляем размер точки

glColor3f (0.0, 1.0, 0.0); glBegin(GL_POINTS); glVertex3f(1.25,1.25,0); glVertex3f(-1.25,-1.25,0); glEnd;

//Выбираем цвет для рисования // рисуем две точки

glEnable(GL_POINT_SMOOTH); glBegin(GL_POINTS); glColor3f (1.0, 0.0, 0.0); glVertex3f(1.25,-1.25,0); glVertex3f(-1.25,1.25,0); glEnd;

//Включаем режим сглаживания // рисуем ещё две точки

glColor3f (0.0, 0.0, 1.0); glBegin(GL_LINES); glVertex3f(1.0,-1.0,0); glVertex3f(-1.0,1.0,0); glVertex3f(1,1,0); glVertex3f(-1,-1,0); glEnd; glFlush(); swapBuffers(dc); EndPaint(Handle,ps); end;

//Рисуем две линии

//Конец рисования OpenGL //Вывести буфер на экран //Конец рисования

Я постарался написать комментарии, чтобы ты мог разобраться с тем, что здесь происходит. Рисование всех объектов начинается с glBegin. В скобках мы передаём значение, указывающее на тип объекта который будет рисоваться. Например:

http://www.vr-online.ru

41


VR-online Journal (Фленов Михаил & VR Team)

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

glBegin(GL_POINTS); // рисуем две точки glVertex3f(1.25,1.25,0); // Положение точки 1 glVertex3f(-1.25,-1.25,0);// Положение точки 2 glEnd; Эта конструкция рисует одну точку. glVertex3f(x,y,z) - точка в позиции X,Y,Z. glEnable - включает и выключает специальные режимы рисования. Мы использовали эту функцию, чтобы включить сглаживание, после чего наши точки стали круглыми. Конструкция glBegin(GL_LINES) - нарисовала две линии (из первой точки во вторую и из третей в четвёртую). В конструкции GL_LINES должно быть чётное число точек. Если будет три точки, то третья точка отбрасывается. Замечания к цвету. Цвет задаётся с помощью функции glColor3f (интенсивность красного, интенсивность зелёного, интенсивность синего). Интенсивность цвета изменяется от нуля до 1. Это не совсем привычно для нас, ведь мы привыкли, что цвет изменяется от 0 до 255, но к этому ты быстро привыкнешь. После рисования нужно уничтожить всё, что мы намудрили. Для этого в обработчике события OnDistroy напиши: wglMakeCurrent(0,0); wglDeleteContext(hrc); ReleaseDC(handle,DC); Первая программа на OpenGL готова. В следующем номере я продолжу тебя знакомить с программированием на OpenGL с использованием Delphi. И пусть все те, кто считает Delphi не пригодным для этого, гниют в аду. Исходник примера находится в файле opengl.zip Copyright © Фленов Михаил aka Horrific

http://www.vr-online.ru

42


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