ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/oup/current/Tools/BinEdit.pas
Revision: 104
Committed: Tue Feb 20 22:03:11 2007 UTC (18 years, 7 months ago) by alloc
Content type: text/x-pascal
Original Path: oup/rewrite/Tools/BinEdit.pas
File size: 28028 byte(s)
Log Message:

File Contents

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