-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathWriters.pas
190 lines (167 loc) · 4.06 KB
/
Writers.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
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.