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

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