source: oup/releases/0.22a/Unit8_binedit.pas@ 368

Last change on this file since 368 was 22, checked in by alloc, 18 years ago
File size: 16.8 KB
Line 
1UNIT Unit8_binedit;
2INTERFACE
3USES
4 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
5 Dialogs, Wrapgrid, StdCtrls, Grids, StrUtils, MPHexEditor, ExtCtrls,
6 Unit3_data, Unit2_functions, Unit9_data_structures, Unit4_exporters;
7
8TYPE
9 TForm8 = Class(TForm)
10 Splitter1: TSplitter;
11 panel_data: TPanel;
12 hex: TMPHexEditor;
13 Splitter2: TSplitter;
14 structs: TWrapGrid;
15 panel_files: TPanel;
16 list: TListBox;
17 panel_extension: TPanel;
18 lbl_filter: TLabel;
19 combo_extension: TComboBox;
20 Bevel1: TBevel;
21 panel_imexport: TPanel;
22 btn_export: TButton;
23 btn_import: TButton;
24 opend: TOpenDialog;
25 saved: TSaveDialog;
26 value_viewer: TWrapGrid;
27 Splitter3: TSplitter;
28{ PROCEDURE structsGetEditText(Sender: TObject; ACol, ARow: Integer; var Value: string);
29 PROCEDURE structsSetEditText(Sender: TObject; ACol, ARow: Integer; const Value: string);
30 PROCEDURE structsKeyPress(Sender: TObject; var Key: Char);
31} PROCEDURE FormActivate(Sender: TObject);
32 PROCEDURE btn_importClick(Sender: TObject);
33 PROCEDURE btn_exportClick(Sender: TObject);
34 PROCEDURE panel_imexportResize(Sender: TObject);
35 FUNCTION Save:Boolean;
36 PROCEDURE FormClose(Sender: TObject; var Action: TCloseAction);
37 PROCEDURE combo_extensionClick(Sender: TObject);
38 PROCEDURE panel_extensionResize(Sender: TObject);
39 FUNCTION GetValue(datatype:Word; offset:LongWord):String;
40 PROCEDURE WriteStructureInfos(structinfoid:Integer);
41 PROCEDURE hexSelectionChanged(Sender: TObject);
42 PROCEDURE hexChange(Sender: TObject);
43 PROCEDURE panel_dataResize(Sender: TObject);
44 PROCEDURE structsClick(Sender: TObject);
45 PROCEDURE FormResize(Sender: TObject);
46 PROCEDURE ClearStructViewer;
47 PROCEDURE listClick(Sender: TObject);
48 PROCEDURE FormCloseQuery(Sender: TObject; var CanClose: Boolean);
49 PROCEDURE FormCreate(Sender: TObject);
50 PROCEDURE Recreatelist;
51 PROCEDURE ClearValues;
52 PROCEDURE WriteValues;
53 PRIVATE
54 PUBLIC
55 END;
56
57VAR
58 Form8: TForm8;
59
60IMPLEMENTATION
61{$R *.dfm}
62USES Unit1_main;
63VAR
64 fileid:LongWord;
65
66FUNCTION IntToBin(value:Byte):String;
67 VAR i:Byte;
68 BEGIN
69 Result:='';
70 FOR i:=7 DOWNTO 0 DO BEGIN
71 Result:=Result+IntToStr((value SHR i) AND $01);
72 END;
73 END;
74
75FUNCTION TForm8.GetValue(datatype:Word; offset:LongWord):String;
76 VAR
77 data:Tdata;
78 i:Word;
79 BEGIN
80 CASE datatype OF
81 1: Result:=IntToStr(hex.data[offset]);
82 2: Result:=IntToStr(hex.data[offset]+hex.data[offset+1]*256);
83 3: Result:=IntToStr(hex.data[offset]+hex.data[offset+1]*256+hex.data[offset+2]*256*256);
84 4: Result:=IntToStr(hex.data[offset]+hex.data[offset+1]*256+hex.data[offset+2]*256*256+hex.data[offset+3]*256*256*256);
85 5: Result:='0x'+IntToHex(hex.data[offset],2);
86 6: Result:='0x'+IntToHex(hex.data[offset]+hex.data[offset+1]*256,4);
87 7: Result:='0x'+IntToHex(hex.data[offset]+hex.data[offset+1]*256+hex.data[offset+2]*256*256,6);
88 8: Result:='0x'+IntToHex(hex.data[offset]+hex.data[offset+1]*256+hex.data[offset+2]*256*256+hex.data[offset+3]*256*256*256,8);
89 9: BEGIN
90 SetLength(data,4);
91 data[0]:=hex.data[offset];
92 data[1]:=hex.data[offset+1];
93 data[2]:=hex.data[offset+2];
94 data[3]:=hex.data[offset+3];
95 Result:=FloatToStr(Decode_Float(data));
96 END;
97 10: Result:=IntToBin(hex.data[offset]);
98 10000..65535: BEGIN
99 Result:='';
100 FOR i:=1 TO datatype-10000 DO BEGIN
101 IF hex.Data[offset+i-1]>=32 THEN
102 Result:=Result+Chr(hex.Data[offset+i-1])
103 ELSE
104 Result:=Result+'.';
105 END;
106 END;
107 END;
108 END;
109
110PROCEDURE TForm8.WriteStructureInfos(structinfoid:Integer);
111 VAR
112 i:Byte;
113 BEGIN
114 IF structinfoid>=0 THEN BEGIN
115 structs.Enabled:=True;
116 WITH structure_infos[structinfoid] DO BEGIN
117 Self.structs.RowCount:=Length(entries)+1;
118 FOR i:=1 TO Length(entries) DO BEGIN
119 Self.structs.Cells[0,i]:=entries[i-1].name;
120 Self.structs.Cells[1,i]:='0x'+IntToHex(entries[i-1].offset,6);
121 Self.structs.Cells[2,i]:=GetDataType(entries[i-1].datatype);
122 IF entries[i-1].datatype>10000 THEN
123 Self.structs.Cells[3,i]:='*String*#HINT:'+GetValue(entries[i-1].datatype,entries[i-1].offset)+'#'
124 ELSE
125 Self.structs.Cells[3,i]:=GetValue(entries[i-1].datatype,entries[i-1].offset);
126 Self.structs.Cells[4,i]:=entries[i-1].description;
127 END;
128 END;
129 END;
130 END;
131
132PROCEDURE TForm8.ClearValues;
133 VAR
134 i:Byte;
135 BEGIN
136 FOR i:=1 TO value_viewer.RowCount-1 DO BEGIN
137 value_viewer.Cells[1,i]:='';
138 END;
139 END;
140
141PROCEDURE TForm8.WriteValues;
142 VAR
143 i,j:Byte;
144 data:Tdata;
145 str:String;
146 BEGIN
147 FOR i:=1 TO value_viewer.RowCount-1 DO BEGIN
148 IF value_viewer.Cells[0,i]='1 byte, unsigned' THEN BEGIN
149 IF (hex.SelCount=1) OR (hex.SelCount=0) THEN
150 value_viewer.Cells[1,i]:=IntToStr(hex.Data[hex.SelStart])
151 ELSE
152 value_viewer.Cells[1,i]:='';
153 END;
154 IF value_viewer.Cells[0,i]='2 bytes, unsigned' THEN BEGIN
155 IF (hex.SelCount=2) OR (hex.SelCount=0) THEN
156 value_viewer.Cells[1,i]:=IntToStr( hex.Data[hex.SelStart]+hex.Data[hex.SelStart+1]*256 )
157 ELSE
158 value_viewer.Cells[1,i]:='';
159 END;
160 IF value_viewer.Cells[0,i]='4 bytes, unsigned' THEN BEGIN
161 IF (hex.SelCount=4) OR (hex.SelCount=0) THEN
162 value_viewer.Cells[1,i]:=IntToStr( hex.Data[hex.SelStart]+hex.Data[hex.SelStart+1]*256+hex.Data[hex.SelStart+2]*256*256+hex.Data[hex.SelStart+3]*256*256*256 )
163 ELSE
164 value_viewer.Cells[1,i]:='';
165 END;
166 IF value_viewer.Cells[0,i]='Bitset' THEN BEGIN
167 IF (hex.SelCount<=8) THEN BEGIN
168 IF hex.SelCount=0 THEN BEGIN
169 SetLength(data,1);
170 data[0]:=hex.Data[hex.SelStart];
171 END ELSE BEGIN
172 SetLength(data,hex.SelCount);
173 FOR j:=0 TO hex.SelCount-1 DO
174 data[j]:=hex.Data[hex.SelStart+j];
175 END;
176 value_viewer.Cells[1,i]:=DataToBin(data);
177 END ELSE
178 value_viewer.Cells[1,i]:='';
179 END;
180 IF value_viewer.Cells[0,i]='Float' THEN BEGIN
181 IF (hex.SelCount=4) OR (hex.SelCount=0) THEN BEGIN
182 SetLength(data,4);
183 FOR j:=0 TO 3 DO
184 data[j]:=hex.Data[hex.SelStart+j];
185 value_viewer.Cells[1,i]:=FloatToStr(Decode_Float(data));
186 END ELSE
187 value_viewer.Cells[1,i]:='';
188 END;
189 IF value_viewer.Cells[0,i]='Selected length' THEN BEGIN
190 value_viewer.Cells[1,i]:=IntToStr(hex.SelCount)+' bytes';
191 END;
192 IF value_viewer.Cells[0,i]='String' THEN BEGIN
193 j:=0;
194 str:='';
195 IF hex.SelCount=0 THEN BEGIN
196 WHILE hex.Data[hex.SelStart+j]>0 DO BEGIN
197 str:=str+Char(hex.Data[hex.SelStart+j]);
198 Inc(j);
199 END;
200 END ELSE BEGIN
201 FOR j:=1 TO hex.SelCount DO
202 str:=str+Char(hex.Data[hex.SelStart+j-1]);
203 END;
204 value_viewer.Cells[1,i]:=str;
205 END;
206 END;
207 END;
208
209PROCEDURE TForm8.Recreatelist;
210 VAR
211 i:LongWord;
212 exts:TStringList;
213 BEGIN
214 combo_extension.Items.Clear;
215 combo_extension.Items.Add('_All files_ ('{+IntToStr(dat_header.Files)}+')');
216 exts:=GetExtensionsList;
217 FOR i:=0 TO High(exts) DO
218 combo_extension.Items.Add(exts[i]);
219 combo_extension.ItemIndex:=0;
220 combo_extensionClick(Self);
221 END;
222
223PROCEDURE TForm8.FormCreate(Sender: TObject);
224 BEGIN
225 Self.Caption:='';
226 fileid:=0;
227 structs.ColCount:=5;
228 structs.RowCount:=2;
229 structs.FixedRows:=1;
230 structs.Cells[0,0]:='Name';
231 structs.Cells[1,0]:='Offset';
232 structs.Cells[2,0]:='Type';
233 structs.Cells[3,0]:='Value';
234 structs.Cells[4,0]:='Description';
235 structs.ColWidths[0]:=75;
236 structs.ColWidths[1]:=60;
237 structs.ColWidths[2]:=75;
238 structs.ColWidths[3]:=75;
239 value_viewer.ColCount:=2;
240 value_viewer.RowCount:=8;
241 value_viewer.FixedRows:=1;
242 value_viewer.Cells[0,0]:='Type';
243 value_viewer.Cells[1,0]:='Value';
244 value_viewer.Cells[0,1]:='1 byte, unsigned';
245 value_viewer.Cells[0,2]:='2 bytes, unsigned';
246 value_viewer.Cells[0,3]:='4 bytes, unsigned';
247 value_viewer.Cells[0,4]:='Bitset';
248 value_viewer.Cells[0,5]:='Float';
249 value_viewer.Cells[0,6]:='String';
250 value_viewer.Cells[0,7]:='Selected length';
251 value_viewer.ColWidths[0]:=100;
252 Self.panel_dataResize(Self);
253 END;
254
255FUNCTION TForm8.Save:Boolean;
256 VAR
257 mem:TMemoryStream;
258 data:Tdata;
259 BEGIN
260 CASE MessageBox(Self.Handle,PChar('Save changes to file '+GetFileInfo(fileid).FileName+'?'),PChar('Data changed...'),MB_YESNOCANCEL) OF
261 IDYES: BEGIN
262 mem:=TMemoryStream.Create;
263 hex.SaveToStream(mem);
264 mem.Seek(0,soFromBeginning);
265 SetLength(data,mem.Size);
266 mem.Read(data[0],mem.Size);
267 mem.Free;
268 UpdateDatFile(fileid,data);
269 Result:=True;
270 END;
271 IDNO: Result:=True;
272 IDCANCEL: BEGIN
273 Result:=False;
274 END;
275 END;
276 END;
277
278PROCEDURE TForm8.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
279 BEGIN
280 IF hex.Modified THEN BEGIN
281 IF NOT Save THEN CanClose:=False;
282 END;
283 END;
284
285PROCEDURE TForm8.listClick(Sender: TObject);
286 VAR
287 mem:TMemoryStream;
288 data:Tdata;
289 i:LongWord;
290 BEGIN
291 IF hex.Modified THEN BEGIN
292 IF NOT Save THEN BEGIN
293 FOR i:=0 TO list.Count-1 DO BEGIN
294 IF StrToInt(MidStr(list.Items.Strings[i],1,5))=fileid THEN BEGIN
295 list.ItemIndex:=i;
296 Exit;
297 END;
298 END;
299 END;
300 END;
301 Self.ClearStructViewer;
302 fileid:=StrToInt(MidStr(list.Items.Strings[list.ItemIndex],1,5));
303 data:=LoadDatFile(fileid);
304 IF Length(data)>0 THEN BEGIN
305 mem:=TMemoryStream.Create;
306 mem.Write(data[0],Length(data));
307 mem.Seek(0,soFromBeginning);
308 hex.LoadFromStream(mem);
309 mem.Free;
310 WriteStructureInfos(GetStructureInfoId(GetFileInfo(fileid).Extension));
311 END;
312 END;
313
314PROCEDURE TForm8.ClearStructViewer;
315 VAR
316 x:Word;
317 BEGIN
318 structs.RowCount:=2;
319 FOR x:=0 TO structs.ColCount-1 DO structs.Cells[x,1]:='';
320 structs.Enabled:=False;
321 END;
322
323PROCEDURE TForm8.FormResize(Sender: TObject);
324 BEGIN
325 IF Self.Width>=650 THEN BEGIN
326 END ELSE Self.Width:=650;
327 IF Self.Height>=450 THEN BEGIN
328 END ELSE Self.Height:=450;
329 END;
330
331PROCEDURE TForm8.structsClick(Sender: TObject);
332 VAR
333 offset:LongWord;
334 length:Byte;
335 BEGIN
336 IF structs.Row>0 THEN BEGIN
337 offset:=structure_infos[GetStructureInfoId(GetFileInfo(fileid).extension)].entries[structs.Row-1].offset;
338 length:=GetTypeDataLength(structure_infos[GetStructureInfoId(GetFileInfo(fileid).extension)].entries[structs.Row-1].datatype);
339 hex.SelStart:=offset;
340 hex.SelEnd:=offset+length-1;
341{ IF structs.Cells[structs.Col,0]='Value' THEN
342 IF structure_infos[GetStructureInfoId(dat_files[fileid].Extension)].entries[structs.Row-1].datatype<=10 THEN
343 structs.Options:=structs.Options+[goEditing]
344 ELSE
345 structs.Options:=structs.Options-[goEditing];
346} END;
347 END;
348
349PROCEDURE TForm8.panel_dataResize(Sender: TObject);
350 BEGIN
351 structs.ColWidths[4]:=structs.Width-structs.ColWidths[0]-structs.ColWidths[1]-structs.ColWidths[2]-structs.ColWidths[3]-28;
352 value_viewer.ColWidths[1]:=value_viewer.Width-value_viewer.ColWidths[0]-28;
353 END;
354
355PROCEDURE TForm8.hexChange(Sender: TObject);
356 BEGIN
357 ClearValues;
358 IF hex.DataSize>0 THEN BEGIN
359 WriteStructureInfos(GetStructureInfoId(GetFileInfo(fileid).Extension));
360 WriteValues;
361 END;
362 END;
363
364PROCEDURE TForm8.hexSelectionChanged(Sender: TObject);
365 VAR
366 selstart:Integer;
367 i,j:Word;
368 BEGIN
369 FOR i:=1 TO structs.RowCount-1 DO BEGIN
370 FOR j:=0 TO structs.ColCount-1 DO BEGIN
371 structs.CellColors[j,i]:=clWhite;
372 structs.CellFontColors[j,i]:=clBlack;
373 END;
374 END;
375 IF hex.DataSize>0 THEN BEGIN
376 selstart:=hex.SelStart;
377 IF GetStructureInfoId(GetFileInfo(fileid).Extension)>=0 THEN BEGIN
378 WITH structure_infos[GetStructureInfoId(GetFileInfo(fileid).Extension)] DO BEGIN
379 FOR i:=0 TO High(entries) DO BEGIN
380 IF ((selstart-entries[i].offset)<GetTypeDataLength(entries[i].datatype)) AND ((selstart-entries[i].offset)>=0) THEN BEGIN
381 FOR j:=0 TO structs.ColCount-1 DO BEGIN
382 structs.CellColors[j,i+1]:=clBlue;
383 structs.CellFontColors[j,i+1]:=clWhite;
384 END;
385 structs.Row:=i+1;
386 END;
387 END;
388 END;
389 END;
390 WriteValues;
391 END;
392 END;
393
394PROCEDURE TForm8.panel_extensionResize(Sender: TObject);
395 BEGIN
396 combo_extension.Width:=panel_extension.Width-5;
397 END;
398
399PROCEDURE TForm8.combo_extensionClick(Sender: TObject);
400 VAR
401 Extension:String[4];
402 files:TStringList;
403 i:LongWord;
404 BEGIN
405 Extension:=MidStr(combo_extension.Items.Strings[combo_extension.ItemIndex],1,4);
406 list.Items.Clear;
407 IF Extension='_All' THEN
408 files:=GetFilesList('','',True)
409 ELSE
410 files:=GetFilesList(extension,'',True);
411 IF Length(files)>0 THEN
412 FOR i:=0 TO High(files) DO
413 list.Items.Add(files[i]);
414 END;
415
416PROCEDURE TForm8.FormClose(Sender: TObject; var Action: TCloseAction);
417 BEGIN
418 Action:=caFree;
419 Form1.close_window(Self.Name);
420 END;
421
422PROCEDURE TForm8.panel_imexportResize(Sender: TObject);
423 BEGIN
424 btn_import.Width:=panel_imexport.Width-8;
425 btn_export.Width:=panel_imexport.Width-8;
426 END;
427
428PROCEDURE TForm8.btn_exportClick(Sender: TObject);
429 BEGIN
430 saved.Filter:='Files of matching extension (*.'+GetFileInfo(fileid).Extension+')|*.'+dat_files[fileid].Extension+'|All files|*.*';
431 saved.DefaultExt:=GetFileInfo(fileid).Extension;
432 IF saved.Execute THEN BEGIN
433 ExportDatFile(fileid,saved.FileName);
434 END;
435 END;
436
437PROCEDURE TForm8.btn_importClick(Sender: TObject);
438 VAR
439 data:Tdata;
440 fs:TFileStream;
441 BEGIN
442 opend.Filter:='Files of matching extension (*.'+GetFileInfo(fileid).Extension+')|*.'+dat_files[fileid].Extension+'|All files|*.*';
443 IF opend.Execute THEN BEGIN
444 fs:=TFileStream.Create(opend.FileName,fmOpenRead);
445 IF fs.Size<>hex.DataSize THEN BEGIN
446 ShowMessage('Can''t import '+ExtractFilename(opend.FileName)+
447 ', file has to have same size as file in .dat.'+CrLf+
448 'Size of file in .dat: '+FormatFileSize(hex.datasize)+CrLf+
449 'Size of chosen file: '+FormatFileSize(fs.Size));
450 END ELSE BEGIN
451{ SetLength(data,fs.Size);
452 fs.Read(data[0],fs.Size);
453 fs.Free;
454 fs:=TFileStream.Create(dat_filename,fmOpenReadWrite);
455 fs.Seek(dat_files[fileid].dataddr,soFromBeginning);
456 fs.Write(data[0],Length(data));
457} END;
458 fs.Free;
459 listClick(Self);
460 END;
461 END;
462
463PROCEDURE TForm8.FormActivate(Sender: TObject);
464 BEGIN
465 Form1.SetActiveWindow(Self.Name);
466 END;
467{
468PROCEDURE TForm8.structsKeyPress(Sender: TObject; VAR Key: Char);
469 VAR
470 dt:Byte;
471 BEGIN
472 IF structs.EditorMode THEN BEGIN
473 dt:=structure_infos[GetStructureInfoId(dat_files[fileid].Extension)].entries[structs.Row-1].datatype;
474 CASE dt OF
475 1..4: BEGIN
476 IF NOT (Key IN [#8,#13,#27,'0'..'9']) THEN Key:=#0;
477 END;
478 5..8: BEGIN
479 IF NOT (Key IN [#8,#13,#27,'0'..'9','A'..'F','a'..'f']) THEN Key:=#0;
480 IF Key IN ['a'..'f'] THEN Key:=UpCase(Key);
481 IF NOT (Key IN [#8,#13,#27]) AND ( Length(structs.Cells[structs.Col,structs.Row])>=2*(dt-4) ) THEN Key:=#0;
482 END;
483 9: BEGIN
484 IF (Key IN ['.']) AND (Pos('.',structs.Cells[structs.Col,structs.Row])>0) THEN Key:=#0;
485 IF NOT (Key IN [#8,#13,#27,'0'..'9','.','-']) THEN Key:=#0;
486 END;
487 10: BEGIN
488 IF NOT (Key IN [#8,#13,#27,'0'..'1']) THEN Key:=#0;
489 IF NOT (Key IN [#8,#13,#27]) AND ( Length(structs.Cells[structs.Col,structs.Row])>=8 ) THEN Key:=#0;
490 END;
491 END;
492 END;
493 END;
494
495PROCEDURE TForm8.structsSetEditText(Sender: TObject; ACol, ARow: Integer; CONST Value: string);
496 BEGIN
497 IF NOT TWrapGrid(Sender).EditorMode THEN
498 ShowMessage('['+IntToStr(ACol)+'|'+IntToStr(ARow)+']='+Value);
499 END;
500
501PROCEDURE TForm8.structsGetEditText(Sender: TObject; ACol, ARow: Integer; var Value: string);
502 BEGIN
503 IF structs.EditorMode THEN
504 ShowMessage('EditorMode - '+Value)
505 ELSE
506 ShowMessage('NOT EditorMode - '+Value);
507 END;
508}
509END.
Note: See TracBrowser for help on using the repository browser.