скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Создание CGI счётчика в Delphi




Когда нормальный человек, уезжая из дома одевает на жену пояс верности, веб-дизайнер ставит на нее счетчик...

Если Вы программируете в Delphi и, хотели бы, чтобы Ваш любимый компилятор поучавствовал в создании Вашей веб-странички, то можно начать с маленькой, но довольно важной части веб-проекта - счётчика. Обычно, счётчик выглядит как кнопка на странице. В данном случае это JPEG картинка, генерируемая на лету.

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

Для начала давайте посмотрим - как этот счётчик может выглядеть:

Вызывается счётчик тэгом IMG примерно так:


<img src="http://ww5.borland.com/ scripts/CounterCGI.exe?FileName=Article">

CGI скрипт так же может получать определённый набор параметров:

  • Txt e.g. "You are visitor %d today, and %d ever."
  • FontName e.g. "Courier"
  • FontColor e.g. "clGreen" or "$404040"
  • BackgroundColor e.g. "clYellow" or "$808080"

А вот так выглядит вызов скрипта с несколькими параметрами:


http://ww5.borland.com/scripts/CounterCGI.exe?FileName=Article&BackgroundColor=$808080&FontColor=$404040&FontName=Courier

Итак, давайте разбираться с кодом.

Начать создавать новое CGI приложение следует с выбора File | New | Web Server Application | CGI stand-alone executable. После этого Вы получите чистый Web модуль. Добавьте новый TWebActionItem в подсвеченном свойстве действий (Actions) в TWebModule, нажав на Add Item. Затем двойным щелчком на событие OnAction создайте обработчик действия.

Изображение JPEG, получается как снимок изображения с TPanel, с TMemo внитри него. Таким способом легче придать 3D вид счётчику. Для начала нам необходимо добавить следующую строку в раздел implementation:


implementation

uses
  ExtCtrls, StdCtrls, Controls, Forms, Graphics, JPEG;

Теперь, мы определим некоторые основные процедуры, которые будут использоваться в коде. GetPaths будет обеспечивать нас двумя жизненно важными путями. Первый путь будет указывать где хранится сам скрипт по отношению к корневой директории web сервера (т.е. относительный путь). Скорее всего это будет "scripts" или "cgi-bin" в зависимости от того, куда Вы его положите. Второй - это локальный путь в Windows. Он может выглядеть как "C:\InetPub". Для нас важны оба пути, чтобы обеспечить переносимость CGI скрипта из директории в директорию и с одного сервера на другой.


procedure GetPaths(Request: TWebRequest; var ScriptPath, LocalPath: string);
var
  ScriptFileName: string;
begin
  ScriptPath := Request.ScriptName;
  ScriptFileName := ExtractFileName(ParamStr(0));
  // Убираем EXE/DLL имя, чтобы получить путь
  Delete(ScriptPath, Pos(ScriptFileName, ScriptPath) - 1, Length(ScriptFileName) + 1);
  // Убираем главную косую
  Delete(ScriptPath,1,1);

  LocalPath := ExtractFilePath(ParamStr(0));
  // Удаление ScriptPath даёт нам корневой путь
  Delete(LocalPath, Pos(ScriptPath, LocalPath) - 1, Length(ScriptPath) + 1);
end;

Процедура SetVariable будет использоваться для инициализации нужных нам переменных.


procedure SetVariable(var S : string; const Value, default: string);
begin
  S := Value;
  if S = '' then
    S := default;
end;

Вся суть CGI скрипта заключается в событие OnAction. Давайте рассмотрим его по шагам.


procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);

Сперва объявим некоторые локальные переменные.


var
  ScriptPath, LocalPath, FileName, Txt, FontColor,
  BackgroundColor, FontName, FontSize: string;
  Today, LastEver, Ever, LastToday: Integer;
  LastDate: TDate;
  MS: TMemoryStream;
  Panel: TPanel;
  Memo: TMemo;
  Bitmap: TBitmap;
  Form: TForm;
  fp: TextFile;

Теперь вызовем GetPaths, чтобы выяснить путь к скрипту, а так же локальный путь. В данном примере мы будем помещать наши счётчики в директорию "counters". Физический путь будет выглядеть примерно так "C:\InetPub\counters".


begin
  GetPaths(Request, ScriptPath, LocalPath);
  LocalPath := LocalPath + 'counters\';

Затем, мы получаем все параметры, переданные вместе с вызовом скрипта. Параметры поступают к нам через свойство Request.QueryFields. Обратите внимание, что если какой-то параметр не был передан, то SetVariable устанавливает его по умолчанию.


with Request.QueryFields do
begin
  FileName := LocalPath+Values['FileName']+'.txt';
  SetVariable(Txt,Values['Txt'],'You are visitor %d today, and %d ever.');
  SetVariable(FontName,Values['FontName'],'Arial');
  SetVariable(FontSize,Values['FontSize'],'10');
  SetVariable(FontColor,Values['FontColor'],'clWhite');
  SetVariable(BackgroundColor,Values['BackgroundColor'],'clBlack');
end;

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


try
  // Write a new empty counter file if it doesn't exist
  if not FileExists(FileName) then
  begin
    AssignFile(fp, FileName);
    Rewrite(fp);
    WriteLn(fp, 0);
    WriteLn(fp, Date);
    WriteLn(fp, 0);
    CloseFile(fp);
  end;

Итак, файл существует. Естевственно, если мы создали его, что счётчик будет равен 0, иначе будем считывать старые значения, и зменять их, если необходимо. Обратите внимание , на то, как мы отслеживаем общее число посещение и посещений за день.


// Читаем старые значения счётчика
AssignFile(fp,FileName);
Reset(fp);
ReadLn(fp,LastEver);
Ever := LastEver+1;
ReadLn(fp,LastDate);
ReadLn(fp,LastToday);
if Date = LastDate then
  Today := LastToday+1
else
  Today := 1;
CloseFile(fp);

И в заключении, надо записать новые значения в файл, содержащий данные счётчика.


// Записываем новые значения счётчика
AssignFile(fp, FileName);
Rewrite(fp);
WriteLn(fp, Ever);
WriteLn(fp, Date);
WriteLn(fp, Today);
CloseFile(fp);

Теперь приступим к созднию того, что в конечном итоге будет называться JPEG. Для начала сделаем невидимым TForm которая содержит TPanel и TMemo. Так же устанавливаем FontName и FontSize.


Form := TForm.Create(nil);
with Form.Font do
begin
  name := FontName;
  Size := StrToInt(FontSize);
end;

Удостоверимся в том, что текст, который мы помещаем в memo контрол, содержит значения счётчика, считанные из файла.


Txt := Format(Txt, [Today, Ever]);

Далее мы создаём панель. Ширина и высота будут определяться шириной текста, который мы помещаем в неё. Так же устанавливаем скашивание для 3D эффекта.


Panel := TPanel.Create(nil);
with Panel do
begin
  BevelInner := bvRaised;
  BevelOuter := bvLowered;
  Parent := Form;
  Width := Form.Canvas.TextWidth(Txt) + 9;
  Height := Form.Canvas.TextHeight(Txt) + 9;
end;

Помещаем memo в панель, и устанавливаем её ширину и высоту, а так же цвет, который указан в BackgroundColor.


Memo := TMemo.Create(nil);
with Memo do
begin
  Top := 2;
  Left := 2;
  Width := Panel.Width-5;
  Height := Panel.Height-5;
  Alignment := taCenter;
  Color := StringToColor(BackgroundColor);
  BorderStyle := bsNone;
  Parent := Panel;
end;

Теперь необходимо сделать изображение эелемента управления, который мы создали. Для этого создаём TBitmap и закрашеваем его панелью. За одно рисуем текст на битмапе.


Bitmap := TBitmap.Create;
with Bitmap do
begin
  Width := Panel.Width-1;
  Height := Panel.Height-1;
  Canvas.Lock;
  Panel.PaintTo(Canvas.Handle,0,0);
  Canvas.Unlock;
  Canvas.Brush.Style := bsClear;
  with Canvas.Font do
  begin
    name := FontName;
    Size := StrToInt(FontSize);
    Color := StringToColor(FontColor);
  end;
  Canvas.TextOut(4,3,Txt);
end;

Затем преобразовываем bitmap в JPEG. JPEG будет записан в memory stream. Этот поток будет связан с браузером и передаваться посетителю странички в виде картинки.


with Response do
begin
  MS := TMemoryStream.Create;
  with TJPEGImage.Create do
  begin
    CompressionQuality := 75;
    Assign(Bitmap);
    SaveToStream(MS);
    Free;
  end;
  ContentType := 'image/jpeg';
  MS.Position := 0;
  SendResponse;
  SendStream(MS);
end;

Освобождаем ресурсы:


Panel.Free;
Bitmap.Free;
Form.Free;

На всякий случай обрабатываем исключительные ситуации


except
  on E: Exception do
    Response.Content := E.message;
  end;
  Handled := True;
end;

Вот собственно и всё. Наслаждайтесь счётчиком, сделанным в Delphi 5 :)






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook