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

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