source: oup/current/Tools/BinEdit.pas@ 112

Last change on this file since 112 was 111, checked in by alloc, 18 years ago
File size: 27.2 KB
Line 
1unit BinEdit;
2interface
3uses
4 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
5 Dialogs, Template, StdCtrls, ExtCtrls, VirtualTrees, Grids, Wrapgrid,
6 MPHexEditor, VTHeaderPopup, Menus, StrUtils, Clipbrd,
7 Data, TypeDefs, ConnectionManager, Buttons;
8
9type
10 TForm_BinEdit = class(TForm_ToolTemplate)
11 hex: TMPHexEditor;
12 Splitter2: TSplitter;
13 value_viewer: TWrapGrid;
14 VST: TVirtualStringTree;
15 Splitter3: TSplitter;
16 value_viewer_context: TPopupMenu;
17 value_viewer_context_copy: TMenuItem;
18 value_viewer_context_copyasdec: TMenuItem;
19 value_viewer_context_copyasfloat: TMenuItem;
20 value_viewer_context_copyasbitset: TMenuItem;
21 value_viewer_context_copyasstring: TMenuItem;
22 value_viewer_context_copyashex: TMenuItem;
23 VTHPopup: TVTHeaderPopupMenu;
24 procedure FormCreate(Sender: TObject);
25 procedure NewFile(fileinfo: TFileInfo);
26
27 procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
28 procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
29
30 procedure hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
31 procedure hexSelectionChanged(Sender: TObject);
32 procedure hexChange(Sender: TObject);
33
34 procedure LoadDat(_fileid: Integer);
35 function Save: Boolean;
36 function GetValue(datatype: Word; offset: Integer): String;
37 procedure SetNewValue(datatype: Word; offset: Integer; Value: String);
38
39 procedure WriteStructureInfos;
40 procedure ClearStructViewer;
41 procedure VSTDblClick(Sender: TObject);
42 procedure VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
43 Column: TColumnIndex);
44 procedure VTHPopupColumnChange(const Sender: TBaseVirtualTree;
45 const Column: TColumnIndex; Visible: Boolean);
46 procedure VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex;
47 OldPosition: Integer);
48 procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
49 Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
50
51 procedure ClearValues;
52 procedure WriteValues;
53 procedure value_viewerDblClick(Sender: TObject);
54 procedure value_viewer_context_copyClick(Sender: TObject);
55 procedure value_viewerMouseDown(Sender: TObject; Button: TMouseButton;
56 Shift: TShiftState; X, Y: Integer);
57 procedure value_viewer_contextPopup(Sender: TObject);
58 private
59 fileid: Integer;
60 ConID: Integer;
61 public
62 end;
63
64var
65 Form_BinEdit: TForm_BinEdit;
66
67implementation
68
69uses ValueEdit, Main, Functions, DatStructureLoader{, RawEdit};
70{$R *.dfm}
71
72type
73 PNodeData = ^TNodeData;
74
75 TNodeData = record
76 Caption: String;
77 Offset: LongInt;
78 DataType: Word;
79 Value: String;
80 Description: String;
81 end;
82
83
84
85procedure TForm_BinEdit.FormCreate(Sender: TObject);
86begin
87 inherited;
88 Self.OnNewFileSelected := NewFile;
89
90 Self.Caption := '';
91 fileid := 0;
92 VST.NodeDataSize := SizeOf(TNodeData);
93 value_viewer.ColCount := 2;
94 value_viewer.RowCount := 8;
95 value_viewer.FixedRows := 1;
96 value_viewer.FixedCols := 1;
97 value_viewer.Cells[0, 0] := 'Type';
98 value_viewer.Cells[1, 0] := 'Value';
99 value_viewer.Cells[0, 1] := '1 byte, unsigned';
100 value_viewer.Cells[0, 2] := '2 bytes, unsigned';
101 value_viewer.Cells[0, 3] := '4 bytes, unsigned';
102 value_viewer.Cells[0, 4] := 'Bitset';
103 value_viewer.Cells[0, 5] := 'Float';
104 value_viewer.Cells[0, 6] := 'String';
105 value_viewer.Cells[0, 7] := 'Selected length';
106 value_viewer.ColWidths[0] := 120;
107 value_viewer.ColWidths[1] := 1000;
108// hex.Height := content.Height - 215;
109 //
110 value_viewer.Font.Charset := AppSettings.CharSet;
111 VST.Font.Charset := AppSettings.CharSet;
112 hex.Translation := tkAsIs;
113 hex.Font.Charset := AppSettings.CharSet;
114 //
115end;
116
117procedure TForm_BinEdit.NewFile(fileinfo: TFileInfo);
118begin
119 LoadDat(fileinfo.ID);
120end;
121
122
123
124
125function AddVSTEntry(AVST: TCustomVirtualStringTree; ANode: PVirtualNode;
126 ARecord: TNodeData): PVirtualNode;
127var
128 Data: PNodeData;
129begin
130 Result := AVST.AddChild(ANode);
131 Data := AVST.GetNodeData(Result);
132 AVST.ValidateNode(Result, False);
133 Data^ := ARecord;
134end;
135
136
137
138
139procedure TForm_BinEdit.LoadDat(_fileid: Integer);
140var
141 mem: TMemoryStream;
142 Data: TByteData;
143begin
144 if ConID <> -1 then
145 begin
146 if hex.Modified then
147 begin
148 if not Save then
149 begin
150 Self.SelectFileID(ConnectionID, FileID);
151 Exit;
152 end;
153 end;
154 end;
155 if _fileid >= 0 then
156 begin
157 fileid := _fileid;
158 ConID := ConnectionID;
159 if ConManager.Connection[ConID].ExtractFileIDOfName(filelist.Items.Strings[filelist.ItemIndex]) <> fileid then
160 Self.SelectFileID(ConnectionID, fileid);
161 Self.ClearStructViewer;
162 mem := nil;
163 ConManager.Connection[ConID].LoadDatFile(fileid, TStream(mem));
164 hex.LoadFromStream(mem);
165 mem.Free;
166 ClearValues;
167 WriteStructureInfos;
168 end
169 else
170 begin
171 fileid := _fileid;
172 ConID := -1;
173 Self.ClearStructViewer;
174 ClearValues;
175 hex.DataSize := 0;
176 end;
177end;
178
179
180
181function TForm_BinEdit.GetValue(datatype: Word; offset: Integer): String;
182var
183 Data: TByteData;
184 i: Word;
185 floatformat: TFormatSettings;
186begin
187 floatformat.DecimalSeparator := '.';
188 case datatype of
189 1:
190 Result := IntToStr(hex.Data[offset]);
191 2:
192 Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256);
193 3:
194 Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256);
195 4:
196 Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] *
197 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256);
198 5:
199 Result := '0x' + IntToHex(hex.Data[offset], 2);
200 6:
201 Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256, 4);
202 7:
203 Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 +
204 hex.Data[offset + 2] * 256 * 256, 6);
205 8:
206 Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 +
207 hex.Data[offset + 2] * 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256, 8);
208 9:
209 begin
210 SetLength(Data, 4);
211 Data[0] := hex.Data[offset];
212 Data[1] := hex.Data[offset + 1];
213 Data[2] := hex.Data[offset + 2];
214 Data[3] := hex.Data[offset + 3];
215 Result := FloatToStr(Decode_Float(Data), floatformat);
216 end;
217 10:
218 Result := IntToBin(hex.Data[offset]);
219 11:
220 Result := '0x' + IntToHex(ConManager.Connection[ConID].GetRawInfo(fileid, offset).RawAddr, 8);
221 12:
222 Result := FormatNumber(hex.Data[offset + 1] + hex.Data[offset + 2] * 256 +
223 hex.Data[offset + 3] * 256 * 256, 5, '0');
224 13:
225 Result := IntToStr(hex.Data[offset]);
226 14:
227 Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256);
228 15:
229 Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256);
230 16:
231 Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] *
232 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256);
233 17:
234 Result := IntToStr((hex.Data[offset + 3]) div 2);
235 100..300:
236 begin
237 Result := '';
238 for i := 1 to datatype - 100 do
239 begin
240 if hex.Data[offset + i - 1] >= 32 then
241 Result := Result + Chr(hex.Data[offset + i - 1])
242 else
243 Break;
244 end;
245 end;
246 1000..9999:
247 begin
248 Result := '';
249 for i := 1 to datatype - 1000 do
250 begin
251 if hex.Data[offset + i - 1] >= 32 then
252 Result := Result + Chr(hex.Data[offset + i - 1])
253 else
254 Result := Result + '.';
255 end;
256 end;
257 10000..65535:
258 begin
259 Result := '';
260 for i := 1 to datatype - 10000 do
261 begin
262 if hex.Data[offset + i - 1] >= 32 then
263 Result := Result + Chr(hex.Data[offset + i - 1])
264 else
265 Result := Result + '.';
266 end;
267 end;
268 end;
269end;
270
271
272
273
274procedure TForm_BinEdit.WriteStructureInfos;
275var
276 i, j: Integer;
277 pdata: PNodeData;
278 Data: TNodeData;
279 node: PVirtualNode;
280 structs: TStructDef;
281begin
282 VST.BeginUpdate;
283 if VST.RootNodeCount = 0 then
284 begin
285 structs := LoadStructureDefinition(ConID, fileid);
286 if structs.Data then
287 begin
288 if Length(structs.Global) > 0 then
289 begin
290 for i := 0 to High(structs.Global) do
291 begin
292 Data.Caption := structs.Global[i].Name;
293 Data.Offset := structs.Global[i].offset;
294 Data.DataType := structs.Global[i].datatype;
295 Data.Value := GetValue(structs.Global[i].datatype, structs.Global[i].offset);
296 Data.Description := structs.Global[i].description;
297 AddVSTEntry(VST, nil, Data);
298 end;
299 end;
300 if Length(structs.Subs) > 0 then
301 begin
302 for i := 0 to High(structs.Subs) do
303 begin
304 with structs.Subs[i] do
305 begin
306 if Length(Entries) > 0 then
307 begin
308 if Pos('#', SubName) > 0 then
309 begin
310 Data.Offset := HexToLong(MidStr(SubName, Pos('#', SubName) + 1, 8));
311 Data.Value :=
312 MidStr(SubName, PosEx('#', SubName, Pos('#', SubName) + 1) + 1, 8);
313 Data.Caption := MidStr(SubName, 1, Pos('#', SubName) - 1);
314 Data.Description := SubDesc;
315 end
316 else
317 begin
318 Data.Caption := SubName;
319 Data.Description := SubDesc;
320 Data.Offset := 0;
321 Data.Value := '';
322 end;
323 Data.DataType := 0;
324 node := AddVSTEntry(VST, nil, Data);
325 Data.Description := '';
326 for j := 0 to High(Entries) do
327 begin
328 Data.Caption := Entries[j].Name;
329 Data.Offset := Entries[j].offset;
330 Data.DataType := Entries[j].datatype;
331 Data.Value := GetValue(Entries[j].datatype, Entries[j].offset);
332 Data.Description := Entries[j].description;
333 AddVSTEntry(VST, node, Data);
334 end;
335 end;
336 end;
337 end;
338 end;
339 end;
340 if VST.RootNodeCount > 0 then
341 VST.FocusedNode := VST.GetFirst;
342 end
343 else
344 begin
345 Node := VST.GetFirst;
346 while Assigned(Node) do
347 begin
348 pdata := VST.GetNodeData(Node);
349 if pdata.DataType > 0 then
350 pdata.Value := GetValue(pdata.Datatype, pdata.Offset);
351 Node := VST.GetNext(Node);
352 end;
353 end;
354 VST.EndUpdate;
355end;
356
357
358
359
360procedure TForm_BinEdit.ClearValues;
361var
362 i: Byte;
363begin
364 for i := 1 to value_viewer.RowCount - 1 do
365 begin
366 value_viewer.Cells[1, i] := '';
367 end;
368end;
369
370
371
372
373procedure TForm_BinEdit.WriteValues;
374var
375 i, j: Integer;
376 Data: TByteData;
377 str: String;
378 Value: Integer;
379 floatformat: TFormatSettings;
380begin
381 floatformat.DecimalSeparator := '.';
382 for i := 1 to value_viewer.RowCount - 1 do
383 begin
384 if value_viewer.Cells[0, i] = '1 byte, unsigned' then
385 begin
386 if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not
387 ((hex.SelStart + 1) > hex.DataSize) then
388 begin
389 Value := hex.Data[hex.SelStart];
390 value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 2);
391 end
392 else
393 value_viewer.Cells[1, i] := '';
394 end;
395 if value_viewer.Cells[0, i] = '2 bytes, unsigned' then
396 begin
397 if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not
398 ((hex.SelStart + 2) > hex.DataSize) then
399 begin
400 Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256;
401 value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 4);
402 end
403 else
404 value_viewer.Cells[1, i] := '';
405 end;
406 if value_viewer.Cells[0, i] = '4 bytes, unsigned' then
407 begin
408 if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
409 ((hex.SelStart + 4) > hex.DataSize) then
410 begin
411 Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 +
412 hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256;
413 value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 8);
414 end
415 else
416 value_viewer.Cells[1, i] := '';
417 end;
418 if value_viewer.Cells[0, i] = 'Bitset' then
419 begin
420 if (hex.SelCount <= 8) then
421 begin
422 if hex.SelCount = 0 then
423 begin
424 SetLength(Data, 1);
425 Data[0] := hex.Data[hex.SelStart];
426 end
427 else
428 begin
429 SetLength(Data, hex.SelCount);
430 for j := 0 to hex.SelCount - 1 do
431 Data[j] := hex.Data[hex.SelStart + j];
432 end;
433 value_viewer.Cells[1, i] := DataToBin(Data);
434 end
435 else
436 value_viewer.Cells[1, i] := '';
437 end;
438 if value_viewer.Cells[0, i] = 'Float' then
439 begin
440 if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
441 ((hex.SelStart + 4) > hex.DataSize) then
442 begin
443 SetLength(Data, 4);
444 for j := 0 to 3 do
445 Data[j] := hex.Data[hex.SelStart + j];
446 value_viewer.Cells[1, i] := FloatToStr(Decode_Float(Data), floatformat);
447 end
448 else
449 value_viewer.Cells[1, i] := '';
450 end;
451 if value_viewer.Cells[0, i] = 'Selected length' then
452 begin
453 value_viewer.Cells[1, i] := IntToStr(hex.SelCount) + ' bytes';
454 end;
455 if value_viewer.Cells[0, i] = 'String' then
456 begin
457 j := 0;
458 str := '';
459 if hex.SelCount = 0 then
460 begin
461 while (hex.Data[hex.SelStart + j] > 0) and ((hex.SelStart + j) < hex.DataSize) do
462 begin
463 if hex.Data[hex.selstart + j] >= 32 then
464 str := str + Char(hex.Data[hex.SelStart + j])
465 else
466 str := str + '.';
467 Inc(j);
468 end;
469 end
470 else
471 begin
472 for j := 0 to hex.SelCount - 1 do
473 if hex.Data[hex.selstart + j] >= 32 then
474 str := str + Char(hex.Data[hex.SelStart + j])
475 else if hex.Data[hex.selstart + j] > 0 then
476 str := str + '.'
477 else
478 Break;
479 end;
480 value_viewer.Cells[1, i] := str;
481 end;
482 end;
483end;
484
485
486
487
488function TForm_BinEdit.Save: Boolean;
489var
490 mem: TMemoryStream;
491 i: Integer;
492begin
493 case MessageBox(Self.Handle, PChar('Save changes to file ' +
494 ConManager.Connection[ConID].GetFileInfo(fileid).Name + '?'), PChar('Data changed...'),
495 MB_YESNOCANCEL + MB_ICONQUESTION) of
496 idYes:
497 begin
498 mem := TMemoryStream.Create;
499 hex.SaveToStream(mem);
500 mem.Seek(0, soFromBeginning);
501 ConManager.Connection[ConID].UpdateDatFile(fileid, mem);
502 mem.Free;
503 hex.Modified := False;
504 for i := 0 to hex.Datasize - 1 do
505 hex.ByteChanged[i] := False;
506 Result := True;
507 end;
508 idNo:
509 Result := True;
510 idCancel:
511 begin
512 Result := False;
513 end;
514 end;
515end;
516
517
518
519
520procedure TForm_BinEdit.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
521begin
522 if hex.Modified then
523 begin
524 if not Save then
525 CanClose := False;
526 end;
527end;
528
529
530
531
532procedure TForm_BinEdit.ClearStructViewer;
533begin
534 VST.Clear;
535end;
536
537
538
539
540
541
542procedure TForm_BinEdit.hexChange(Sender: TObject);
543begin
544 ClearValues;
545 if hex.DataSize > 0 then
546 begin
547 WriteStructureInfos;
548 WriteValues;
549 end;
550end;
551
552
553
554
555procedure TForm_BinEdit.hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
556//var
557// temps: String;
558begin
559 if (Shift = [ssCtrl]) and (Key = Ord('C')) then
560 begin
561 if hex.SelCount > 0 then
562 begin
563 if hex.InCharField then
564 Clipboard.AsText := hex.SelectionAsText
565 else
566 Clipboard.AsText := hex.SelectionAsHex;
567 end;
568 end;
569 if (Shift = [ssCtrl]) and (Key = Ord('V')) then
570 begin
571{ temps:=Clipboard.AsText;
572 IF hex.SelStart+Length(temps)>hex.DataSize THEN
573 SetLength(temps, hex.DataSize-hex.SelStart);
574 hex.Sel
575 hex.SelCount:=Length(temps);
576 hex.ReplaceSelection(temps,Length(temps));
577} end;
578end;
579
580
581
582
583procedure TForm_BinEdit.hexSelectionChanged(Sender: TObject);
584var
585 selstart: Integer;
586 node: PVirtualNode;
587 pdata: PNodeData;
588begin
589 if hex.DataSize > 0 then
590 begin
591 WriteValues;
592 selstart := hex.SelStart;
593 if VST.RootNodeCount > 0 then
594 begin
595 Node := VST.GetFirst;
596 while Assigned(Node) do
597 begin
598 pdata := VST.GetNodeData(Node);
599 if pdata.DataType > 0 then
600 begin
601 if ((selstart - pdata.Offset) < GetDataTypeLength(pdata.DataType)) and
602 ((selstart - pdata.Offset) >= 0) then
603 begin
604 VST.FocusedNode := Node;
605 VST.Selected[Node] := True;
606 Break;
607 end;
608 end;
609 Node := VST.GetNext(Node);
610 end;
611 end;
612 end;
613end;
614
615
616
617
618procedure TForm_BinEdit.value_viewer_contextPopup(Sender: TObject);
619var
620 i: Byte;
621begin
622 for i := 0 to value_viewer_context.Items.Count - 1 do
623 value_viewer_context.Items.Items[i].Visible := False;
624 with value_viewer do
625 begin
626 if (Col = 1) and (Row > 0) and (Length(Cells[Col, Row]) > 0) then
627 begin
628 if Pos(' byte', Cells[0, Row]) = 2 then
629 begin
630 value_viewer_context.Items.Find('Copy to &clipboard').Visible := True;
631 value_viewer_context.Items.Find('Copy to clipboard (as &dec)').Visible := True;
632 value_viewer_context.Items.Find('Copy to clipboard (as &hex)').Visible := True;
633 end;
634 if Pos('Float', Cells[0, Row]) = 1 then
635 value_viewer_context.Items.Find('Copy to clipboard (as &float)').Visible := True;
636 if Pos('Bitset', Cells[0, Row]) = 1 then
637 value_viewer_context.Items.Find(
638 'Copy to clipboard (as &bitset)').Visible := True;
639 if Pos('String', Cells[0, Row]) = 1 then
640 value_viewer_context.Items.Find(
641 'Copy to clipboard (as &string)').Visible := True;
642 if Pos('Selected length', Cells[0, Row]) = 1 then
643 value_viewer_context.Items.Find('Copy to &clipboard').Visible := True;
644 end;
645 end;
646end;
647
648
649
650
651procedure TForm_BinEdit.value_viewerMouseDown(Sender: TObject; Button: TMouseButton;
652 Shift: TShiftState; X, Y: Integer);
653var
654 ACol, ARow: Integer;
655begin
656 if Button = mbRight then
657 begin
658 value_viewer.MouseToCell(x, y, ACol, ARow);
659 if ARow > 0 then
660 begin
661 value_viewer.Col := ACol;
662 value_viewer.Row := ARow;
663 end;
664 end;
665end;
666
667
668
669
670procedure TForm_BinEdit.value_viewer_context_copyClick(Sender: TObject);
671var
672 Name: String;
673 Value: Integer;
674begin
675 Name := TMenuItem(Sender).Name;
676 if Pos('asstring', Name) > 0 then
677 begin
678 Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
679 end
680 else if Pos('asfloat', Name) > 0 then
681 begin
682 Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
683 end
684 else if Pos('asbitset', Name) > 0 then
685 begin
686 Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
687 end
688 else if (Pos('ashex', Name) > 0) or (Pos('asdec', Name) > 0) then
689 begin
690 if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
691 begin
692 if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not
693 ((hex.SelStart + 1) > hex.DataSize) then
694 Value := hex.Data[hex.SelStart];
695 end;
696 if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
697 begin
698 if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not
699 ((hex.SelStart + 2) > hex.DataSize) then
700 Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256;
701 end;
702 if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
703 begin
704 if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
705 ((hex.SelStart + 4) > hex.DataSize) then
706 Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 +
707 hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256;
708 end;
709 if Pos('asdec', Name) > 0 then
710 begin
711 Clipboard.AsText := IntToStr(Value);
712 end
713 else
714 begin
715 if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
716 Clipboard.AsText := '0x' + IntToHex(Value, 2);
717 if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
718 Clipboard.AsText := '0x' + IntToHex(Value, 4);
719 if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
720 Clipboard.AsText := '0x' + IntToHex(Value, 8);
721 end;
722 end
723 else
724 begin
725 Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
726 end;
727end;
728
729
730
731
732procedure TForm_BinEdit.VSTDblClick(Sender: TObject);
733var
734 node: PVirtualNode;
735 nodedata: PNodeData;
736 form: TForm_ToolTemplate;
737begin
738 if VST.FocusedColumn = 3 then
739 begin
740 node := VST.FocusedNode;
741 nodedata := VST.GetNodeData(node);
742
743 if not (nodedata.datatype in [11, 12]) and
744 ((nodedata.DataType < 100) or (nodedata.DataType > 300)) then
745 begin
746 Form_ValueEdit.MakeVarInput(nodedata.Caption, nodedata.offset,
747 nodedata.datatype, nodedata.Value, Self);
748 end
749 else
750 begin
751 if nodedata.DataType = 11 then
752 begin
753 if ConManager.Connection[ConID].GetRawInfo(fileid, nodedata.offset).RawSize > 0 then
754 Form_Main.open_child('rawedit', ConID, fileid);
755 end;
756 if nodedata.DataType = 12 then
757 begin
758 if (StrToInt(nodedata.Value) < ConManager.Connection[ConID].GetFileCount) and
759 (StrToInt(nodedata.Value) > 0) and
760 (StrToInt(nodedata.Value) <> fileid) then
761 begin
762 if ConManager.Connection[ConID].GetFileInfo(StrToInt(nodedata.Value)).Size > 0 then
763 Form_Main.open_child('binedit', ConID, StrToInt(nodedata.Value))
764 else
765 ShowMessage('Linked filed is a zero-byte-file');
766 end;
767 end;
768 if (nodedata.DataType >= 100) and (nodedata.DataType <= 300) then
769 begin
770 form := Form_Main.open_child('binedit', ConID, -1);
771 if Assigned(form) then
772 form.SetFileFilters(nodedata.Value, '', False);
773 end;
774 end;
775
776 end;
777end;
778
779
780
781
782procedure TForm_BinEdit.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
783 Column: TColumnIndex);
784var
785 Data: PNodeData;
786begin
787 Data := VST.GetNodeData(node);
788 if Data.DataType > 0 then
789 begin
790 hex.SelStart := Data.Offset;
791 hex.SelEnd := Data.Offset + GetDataTypeLength(Data.DataType) - 1;
792 end
793 else
794 begin
795 hex.SelStart := Data.Offset;
796 hex.SelEnd := Data.Offset + HexToLong(Data.Value) - 1;
797 end;
798end;
799
800
801
802
803procedure TForm_BinEdit.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
804 Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
805var
806 Data: PNodeData;
807begin
808 Data := Sender.GetNodeData(Node);
809 CellText := '';
810 if TextType = ttNormal then
811 begin
812 case Column of
813 0:
814 CellText := Data.Caption;
815 1:
816 if Data.DataType > 0 then
817 CellText := '0x' + IntToHex(Data.Offset, 8)
818 else if Data.Offset > 0 then
819 CellText := '0x' + IntToHex(Data.Offset, 8);
820 2:
821 if Data.DataType > 0 then
822 CellText := GetDataType(Data.DataType);
823 3:
824 if Data.DataType > 0 then
825 CellText := Data.Value //GetValue(data.DataType, data.Offset)
826 else if Length(Data.Value) > 0 then
827 CellText := IntToStr(HexToLong(Data.Value)) + ' Bytes';
828 4:
829 CellText := Data.Description;
830 end;
831 end;
832end;
833
834
835
836
837procedure TForm_BinEdit.VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex;
838 OldPosition: Integer);
839begin
840 if Sender.Columns.Items[column].Position < 1 then
841 Sender.Columns.Items[column].Position := OldPosition;
842end;
843
844
845
846
847procedure TForm_BinEdit.VTHPopupColumnChange(const Sender: TBaseVirtualTree;
848 const Column: TColumnIndex; Visible: Boolean);
849begin
850 if column = 0 then
851 TVirtualStringTree(Sender).Header.Columns.Items[column].Options :=
852 TVirtualStringTree(Sender).Header.Columns.Items[column].Options + [coVisible];
853end;
854
855
856
857
858procedure TForm_BinEdit.SetNewValue(datatype: Word; offset: Integer; Value: String);
859var
860 Data: TByteData;
861 value_int: LongWord;
862 value_float: Single;
863 i: Word;
864begin
865 case datatype of
866 1..4:
867 begin
868 value_int := StrToInt(Value);
869 SetLength(Data, datatype);
870 for i := 0 to datatype - 1 do
871 begin
872 Data[i] := value_int mod 256;
873 value_int := value_int div 256;
874 end;
875 end;
876 5..8:
877 begin
878 value_int := StrToInt('$' + Value);
879 SetLength(Data, datatype - 4);
880 for i := 0 to datatype - 5 do
881 begin
882 Data[i] := value_int mod 256;
883 value_int := value_int div 256;
884 end;
885 end;
886 9:
887 begin
888 value_float := StrToFloat(Value);
889 Data := Encode_Float(value_float);
890 end;
891 10:
892 begin
893 value_int := BinToInt(Value);
894 SetLength(Data, 1);
895 Data[0] := value_int;
896 end;
897 10000..65535:
898 begin
899 SetLength(Data, datatype - 10000);
900 for i := 1 to datatype - 10000 do
901 begin
902 if i <= Length(Value) then
903 Data[i - 1] := Ord(Value[i])
904 else
905 Data[i - 1] := 0;
906 end;
907 end;
908 end;
909 for i := 0 to High(Data) do
910 begin
911 if hex.Data[offset + i] <> Data[i] then
912 hex.ByteChanged[offset + i] := True;
913 hex.Data[offset + i] := Data[i];
914 end;
915 hex.Modified := True;
916 hexChange(Self);
917 hex.Repaint;
918end;
919
920
921
922
923procedure TForm_BinEdit.value_viewerDblClick(Sender: TObject);
924var
925 offset: Integer;
926 datatype: Word;
927 objectname: String;
928 Value: String;
929begin
930 if (value_viewer.Col = 1) and (Length(value_viewer.Cells[1, value_viewer.Row]) > 0) then
931 begin
932 offset := hex.SelStart;
933 if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
934 datatype := 1;
935 if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
936 datatype := 2;
937 if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
938 datatype := 4;
939 if value_viewer.Cells[0, value_viewer.Row] = 'Bitset' then
940 datatype := 10;
941 if value_viewer.Cells[0, value_viewer.Row] = 'Float' then
942 datatype := 9;
943 if value_viewer.Cells[0, value_viewer.Row] = 'Selected length' then
944 Exit;
945 if value_viewer.Cells[0, value_viewer.Row] = 'String' then
946 begin
947 if hex.SelCount > 0 then
948 datatype := 10000 + hex.SelCount
949 else
950 datatype := 10000 + Length(value_viewer.Cells[1, value_viewer.Row]);
951 end;
952 objectname := '';
953 Value := GetValue(datatype, offset);
954 Form_ValueEdit.MakeVarInput(objectname, offset, datatype, Value, Self);
955 end;
956end;
957
958
959
960
961procedure TForm_BinEdit.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
962begin
963 if (Shift = [ssCtrl]) and (Key = 83) then
964 if hex.Modified then
965 if not Save then
966 Exit;
967end;
968
969
970begin
971 AddToolListEntry('binedit', 'Binary .dat-Editor', '');
972end.
Note: See TracBrowser for help on using the repository browser.