В данной статье я опишу как создать приложение с поддержкой скинов. Скин будет состоять всего из одного файла и его нельзя будет открыть графическими редакторами. В скине будут описаны координаты положения объектов (например кнопок). То есть каждый скин будет уникален.
Нам понадобится написать два приложения: первое будет создавать скин, а вторая будет грузить его, всмысле это и будет программа спользующая скин. Начнем с первой программы. Для начала поясню, как я хочу чтобы все это работало. Будем создавать файл и в него писать информацию в следующей последовательности: некоторые данные о самом скине (далее разберем поподробнее) и сами графические файлы, один за другим. Приступим. Объявим тип: Type TSkins = Record SkinName: string[255]; sze: array [1..3] of Int64; crd: array [1..3] of TPoint; end; Объявленный массив sze - это массив размеров файлов, для облегчения последующей загрузки скина. А массив crd - это координаты объекта.
Добавим следующую строчку в глобальную секцию var: sk: TSkins; Нам понадобится определять размеры файла. Напишем функцию, которая будет возвращать размер файла: Function GetFileSize(FileName: String): Longint; var FS: TFileStream; begin FS := TFileStream.Create(FileName, fmOpenRead); Result := FS.Size; FS.Free; end; Напишем процедуру добавления файла к скину: Procedure AddToFile(s:string; F:TFileStream); var L:Longint; F1:TFileStream; begin F1:=TFileStream.Create(S, fmOpenRead); L:=F1.Size;
F.CopyFrom(F1, L);
F1.Free; end;
Теперь по нажатию на кнопку будем создавать скин: procedure TForm1.Button1Click(Sender: TObject); var fs:TFileStream; begin sk.SkinName:='www.DelphiDevelop.ru' ;
Sk.sze[1] := GetFileSize('fone.bmp' ); Sk.sze[2] := GetFileSize('2.bmp' ); Sk.sze[3] := GetFileSize('3.bmp' );
Sk.crd[1] := Point(0,0); Sk.crd[2] := Point(50,50); Sk.crd[3] := Point(50,90);
FS:=TFileStream.Create('SkinName.skin' , fmCreate);
FS.WriteBuffer(sk, SizeOF(sk)); AddToFile('fone.bmp' , FS); AddToFile('2.bmp' , FS); AddToFile('3.bmp' , FS);
FS.Free; end; Естественно в папке с этой программой должны быть четыре BMP файла с названиями: fone.bmp, 2.bmp, 3.bmp, 4.bmp Запускаем приложение жмем кнопку и появляется файл SkinName.skin. Конечно программу для создания скина можно сделать и лучше, например указывать какой файл грузить и куда создавать готовый файл скина. Итак, файл создали осталось его загрузить. Создайте новое приложение и точно также добавьте: Type TSkins = Record SkinName: string[255]; sze: array [1..3] of Int64; crd: array [1..3] of TPoint; end; Еще нужно добавить это в глобальную секцию var: sk: TSkins; Напишем процедуру которая будет загружать из файла-скина нужную графику: Procedure ReadSkinsFile(F:TFileStream; si:int64; crd:TPoint;img:Timage); var F1:TMemoryStream; begin F1:=TMemoryStream.Create;
F1.CopyFrom(F, Si);
F1.Position:=0; Img.Picture.Bitmap.LoadFromStream(F1);
img.Left:=crd.X; img.Top:=crd.Y;
F1.Free; end; F - будет передаваться читаемый файл; si - размер файла; crd - координаты. Будем тутже изменять положение Image; img - в какой TImage будет грузиться графика. Выложим кнопку на форму и по клику по ней напишем: procedure TForm1.Button1Click(Sender: TObject); var fs:TFileStream; begin FS:=TFileStream.Create('SkinName.skin' , fmOpenRead); FS.ReadBuffer(sk, SizeOF(sk));
Label1.Caption:=sk.SkinName;
ReadSkinsFile(FS, sk.sze[1], sk.crd[1], Image1); ReadSkinsFile(FS, sk.sze[2], sk.crd[2], Image2); ReadSkinsFile(FS, sk.sze[3], sk.crd[3], Image3); FS.Free; end; Также необходимо выложить 3 TImage и 1 TLabel и не забудьте скопировать в папку с программой сам файл скина, иначе будет возникать ошибка. Запускаем программу, нажимаем на кнопку и в Image грузится графика. Обратите внимание, что массив нужно будет увеличить если графических файлов используется больше чем 3.
Конечно можно сделать обработку разнообразных ошибок но это уже другая история. Также можно сделать чтобы при наведении на кнопку она "загоралась". Это также уже вне этой статьи. Скачать исходник [21,4 Кб] Приведу полный код первой программы (создает скин): unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, xpman;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private public end;
Type TSkins = Record SkinName: String[255]; sze: array [1..3] of Int64; crd: array [1..3] of TPoint; end;
var Form1: TForm1; sk: TSkins;
implementation
{$R *.dfm}
Function GetFileSize(FileName: String): Longint; var FS: TFileStream; begin FS := TFileStream.Create(FileName, fmOpenRead); Result := FS.Size; FS.Free; end;
Procedure AddToFile(s:string; F:TFileStream); var L:Longint; F1:TFileStream; begin F1:=TFileStream.Create(S, fmOpenRead); L:=F1.Size;
F.CopyFrom(F1, L);
F1.Free; end;
procedure TForm1.Button1Click(Sender: TObject); var fs:TFileStream; begin sk.SkinName:='www.CodeLab.3dn.ru' ;
Sk.sze[1] := GetFileSize('fone.bmp' ); Sk.sze[2] := GetFileSize('2.bmp' ); Sk.sze[3] := GetFileSize('3.bmp' );
Sk.crd[1] := Point(0,0); Sk.crd[2] := Point(50,50); Sk.crd[3] := Point(50,90);
FS:=TFileStream.Create('SkinName.skin' , fmCreate);
FS.WriteBuffer(sk, SizeOF(sk)); AddToFile('fone.bmp' , FS); AddToFile('2.bmp' , FS); AddToFile('3.bmp' , FS);
FS.Free; end;
end.
Код второй программы (которая загружает скин): unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, xpman;
type TForm1 = class(TForm) Button1: TButton; Image1: TImage; Image2: TImage; Image3: TImage; Label1: TLabel; procedure Button1Click(Sender: TObject); private public end;
Type TSkins = Record SkinName: String[255]; sze: array [1..3] of Int64; crd: array [1..3] of TPoint; end;
var Form1: TForm1; sk: TSkins;
implementation
{$R *.dfm}
Procedure ReadSkinsFile(F:TFileStream; si:int64; crd:TPoint; img:Timage); var F1:TMemoryStream; begin F1:=TMemoryStream.Create;
F1.CopyFrom(F, Si);
F1.Position:=0; Img.Picture.Bitmap.LoadFromStream(F1);
img.Left:=crd.X; img.Top:=crd.Y;
F1.Free; end;
procedure TForm1.Button1Click(Sender: TObject); var fs:TFileStream; begin FS:=TFileStream.Create('SkinName.skin' , fmOpenRead); FS.ReadBuffer(sk, SizeOF(sk));
Label1.Caption:=sk.SkinName;
ReadSkinsFile(FS, sk.sze[1], sk.crd[1], Image1); ReadSkinsFile(FS, sk.sze[2], sk.crd[2], Image2); ReadSkinsFile(FS, sk.sze[3], sk.crd[3], Image3);
FS.Free; end;
end.
|