Chameleon/Writers.pas
Nikolaos Georgiou a5cf23eda4 Add 'pas/' from commit '71642f0773f3b21b1e6bcdfcfdbdb186b6c8f78c'
git-subtree-dir: pas
git-subtree-mainline: 6d5784cc4089eeb4864244cd4951b1aa66b4e90e
git-subtree-split: 71642f0773f3b21b1e6bcdfcfdbdb186b6c8f78c
2021-05-29 07:57:12 +02:00

191 lines
4.1 KiB
ObjectPascal

unit Writers;
{$MODE Delphi}
interface
uses Windows, SysUtils, Classes, Graphics;
type
TTextWriter = class
private
FStream: TStream;
FIdent: cardinal;
FWriteIdent: boolean;
procedure WriteIdent;
public
constructor Create(AStream: TStream);
constructor CreateFile(const FileName: string);
destructor Destroy; override;
procedure NewLine;
procedure Write(const str: string);
procedure WriteLn(const str: string);
procedure WriteString(const str: string);
property Ident: cardinal read FIdent write FIdent;
property Stream: TStream read FStream;
end;
TDfmWriter = class(TTextWriter)
procedure WriteBinaryAsText(Input: TStream);
procedure WriteBoolProp(const Name: string; Value: boolean);
procedure WriteColorProp(const Name: string; Value: TColor);
procedure WriteCustomProp(const Name, Value: string);
procedure WriteIntProp(const Name: string; Value: integer);
procedure WriteStringProp(const Name, Value: string);
procedure WritePlacement(wnd, parent: HWND);
end;
implementation
constructor TTextWriter.Create(AStream: TStream);
begin
inherited Create;
FStream := AStream;
FIdent := 0;
FWriteIdent := True;
end;
constructor TTextWriter.CreateFile(const FileName: string);
begin
inherited Create;
FStream := TFileStream.Create(FileName, fmCreate);
FIdent := 0;
FWriteIdent := True;
end;
destructor TTextWriter.Destroy;
begin
FStream.Free;
inherited;
end;
procedure TTextWriter.WriteIdent;
var
s: string;
i: integer;
begin
if FWriteIdent then
begin
if FIdent > 0 then
begin
s := '';
for i := 1 to FIdent do
s := s + ' ';
FStream.Write(s[1], FIdent);
end;
FWriteIdent := False;
end;
end;
procedure TTextWriter.Write(const str: string);
begin
WriteIdent;
FStream.Write(str[1], Length(str));
end;
procedure TTextWriter.WriteLn(const str: string);
begin
Write(str);
NewLine;
end;
procedure TTextWriter.WriteString(const str: string);
begin
Write(Chr(Length(str)) + str);
end;
procedure TTextWriter.NewLine;
const
crlf: array [0..1] of char = #13#10;
begin
FStream.Write(crlf[0], 2);
FWriteIdent := True;
end;
procedure TDfmWriter.WriteBoolProp(const Name: string; Value: boolean);
const
s: array [False..True] of string = ('False', 'True');
begin
WriteCustomProp(Name, s[Value]);
end;
procedure TDfmWriter.WriteColorProp(const Name: string; Value: TColor);
begin
WriteCustomProp(Name, ColorToString(Value));
end;
procedure TDfmWriter.WriteCustomProp(const Name, Value: string);
begin
WriteLn(Name + ' = ' + Value);
end;
procedure TDfmWriter.WriteIntProp(const Name: string; Value: integer);
begin
WriteCustomProp(Name, IntToStr(Value));
end;
procedure TDfmWriter.WriteStringProp(const Name, Value: string);
begin
WriteCustomProp(Name, '''' + Value + '''');
end;
procedure BinToHex(Binary, Text: PChar; Count: integer);
const
HexChars: array[0..15] of char = '0123456789ABCDEF';
var
I: integer;
begin
for I := 0 to Count - 1 do
begin
Text^ := HexChars[(byte(Binary[I]) and $F0) shr 4];
Inc(Text);
Text^ := HexChars[(byte(Binary[I]) and $0F)];
Inc(Text);
end;
end;
procedure TDfmWriter.WriteBinaryAsText(Input: TStream);
const
BytesPerLine = 32;
var
MultiLine: boolean;
I: integer;
Count: longint;
Buffer: array[0..BytesPerLine - 1] of char;
Text: array[0..BytesPerLine * 2 - 1] of char;
begin
Count := Input.Size;
MultiLine := Count > BytesPerLine;
while Count > 0 do
begin
if MultiLine then
NewLine;
if Count >= BytesPerLine then
I := BytesPerLine
else
I := Count;
Input.Read(Buffer, I);
BinToHex(Buffer, Text, I);
Write(Text);
Dec(Count, I);
end;
end;
procedure TDfmWriter.WritePlacement(wnd, parent: HWND);
var
R: TRect;
begin
GetWindowRect(wnd, R);
if IsWindow(parent) then
begin
Windows.ScreenToClient(parent, R.TopLeft);
Windows.ScreenToClient(parent, R.BottomRight);
end;
WriteIntProp('Left', R.Left);
WriteIntProp('Top', R.Top);
WriteIntProp('Width', R.Right - R.Left);
WriteIntProp('Height', R.Bottom - R.Top);
end;
end.