source: oup/releases/0.33a/Tools/BinEdit.pas@ 347

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