source: oup/current/Tool_BinEdit.pas@ 45

Last change on this file since 45 was 45, checked in by alloc, 18 years ago
File size: 27.2 KB
Line 
1unit Tool_BinEdit;
2interface
3uses
4 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
5 Dialogs, Tool_Template, StdCtrls, ExtCtrls, VirtualTrees, Grids, Wrapgrid,
6 MPHexEditor, VTHeaderPopup, Menus, StrUtils, Clipbrd,
7 Data, Code_OniDataClass, Code_Functions, Code_DataStructures, Code_Exporters;
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, Tool_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;
744begin
745 if VST.FocusedColumn = 3 then
746 begin
747 node := VST.FocusedNode;
748 nodedata := VST.GetNodeData(node);
749
750 if not (nodedata.datatype in [11, 12]) and
751 ((nodedata.DataType < 100) or (nodedata.DataType > 300)) then
752 begin
753 Form_ValueEdit.MakeVarInput(nodedata.Caption, nodedata.offset,
754 nodedata.datatype, nodedata.Value, Self);
755 end
756 else
757 begin
758 if nodedata.DataType = 11 then
759 begin
760 if OniDataConnection.GetRawInfo(fileid, nodedata.offset).raw_size > 0 then
761 Form_Main.open_child('rawedit', fileid);
762 end;
763 if nodedata.DataType = 12 then
764 begin
765 if (StrToInt(nodedata.Value) < OniDataConnection.GetFilesCount) and
766 (StrToInt(nodedata.Value) > 0) and
767 (StrToInt(nodedata.Value) <> fileid) then
768 begin
769 if OniDataConnection.GetFileInfo(StrToInt(nodedata.Value)).Size > 0 then
770 Form_Main.open_child('binedit', StrToInt(nodedata.Value))
771 else
772 ShowMessage('Linked filed is a zero-byte-file');
773 end;
774 end;
775 if (nodedata.DataType >= 100) and (nodedata.DataType <= 300) then
776 begin
777 if Form_Main.open_child('binedit', -1) then
778 begin
779 TForm_BinEdit(Form_Main.ActiveMDIChild).edit_filtername.Text := nodedata.Value;
780 TForm_BinEdit(Form_Main.ActiveMDIChild).check_filtername.Checked := True;
781 TForm_BinEdit(Form_Main.ActiveMDIChild).check_filternameClick(Self);
782 end;
783 end;
784 end;
785
786 end;
787end;
788
789
790
791
792procedure TForm_BinEdit.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
793 Column: TColumnIndex);
794var
795 Data: PNodeData;
796begin
797 Data := VST.GetNodeData(node);
798 if Data.DataType > 0 then
799 begin
800 hex.SelStart := Data.Offset;
801 hex.SelEnd := Data.Offset + GetTypeDataLength(Data.DataType) - 1;
802 end
803 else
804 begin
805 hex.SelStart := Data.Offset;
806 hex.SelEnd := Data.Offset + HexToLong(Data.Value) - 1;
807 end;
808end;
809
810
811
812
813procedure TForm_BinEdit.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
814 Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
815var
816 Data: PNodeData;
817begin
818 Data := Sender.GetNodeData(Node);
819 CellText := '';
820 if TextType = ttNormal then
821 begin
822 case Column of
823 0:
824 CellText := Data.Caption;
825 1:
826 if Data.DataType > 0 then
827 CellText := '0x' + IntToHex(Data.Offset, 8)
828 else if Data.Offset > 0 then
829 CellText := '0x' + IntToHex(Data.Offset, 8);
830 2:
831 if Data.DataType > 0 then
832 CellText := GetDataType(Data.DataType);
833 3:
834 if Data.DataType > 0 then
835 CellText := Data.Value //GetValue(data.DataType, data.Offset)
836 else if Length(Data.Value) > 0 then
837 CellText := IntToStr(HexToLong(Data.Value)) + ' Bytes';
838 4:
839 CellText := Data.Description;
840 end;
841 end;
842end;
843
844
845
846
847procedure TForm_BinEdit.VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex;
848 OldPosition: Integer);
849begin
850 if Sender.Columns.Items[column].Position < 1 then
851 Sender.Columns.Items[column].Position := OldPosition;
852end;
853
854
855
856
857procedure TForm_BinEdit.VTHPopupColumnChange(const Sender: TBaseVirtualTree;
858 const Column: TColumnIndex; Visible: Boolean);
859begin
860 if column = 0 then
861 TVirtualStringTree(Sender).Header.Columns.Items[column].Options :=
862 TVirtualStringTree(Sender).Header.Columns.Items[column].Options + [coVisible];
863end;
864
865
866
867
868procedure TForm_BinEdit.SetNewValue(datatype: Word; offset: LongWord; Value: String);
869var
870 Data: Tdata;
871 value_int: LongWord;
872 value_float: Single;
873 i: Word;
874begin
875 case datatype of
876 1..4:
877 begin
878 value_int := StrToInt(Value);
879 SetLength(Data, datatype);
880 for i := 0 to datatype - 1 do
881 begin
882 Data[i] := value_int mod 256;
883 value_int := value_int div 256;
884 end;
885 end;
886 5..8:
887 begin
888 value_int := StrToInt('$' + Value);
889 SetLength(Data, datatype - 4);
890 for i := 0 to datatype - 5 do
891 begin
892 Data[i] := value_int mod 256;
893 value_int := value_int div 256;
894 end;
895 end;
896 9:
897 begin
898 value_float := StrToFloat(Value);
899 Data := Encode_Float(value_float);
900 end;
901 10:
902 begin
903 value_int := BinToInt(Value);
904 SetLength(Data, 1);
905 Data[0] := value_int;
906 end;
907 10000..65535:
908 begin
909 SetLength(Data, datatype - 10000);
910 for i := 1 to datatype - 10000 do
911 begin
912 if i <= Length(Value) then
913 Data[i - 1] := Ord(Value[i])
914 else
915 Data[i - 1] := 0;
916 end;
917 end;
918 end;
919 for i := 0 to High(Data) do
920 begin
921 if hex.Data[offset + i] <> Data[i] then
922 hex.ByteChanged[offset + i] := True;
923 hex.Data[offset + i] := Data[i];
924 end;
925 hex.Modified := True;
926 hexChange(Self);
927 hex.Repaint;
928end;
929
930
931
932
933procedure TForm_BinEdit.value_viewerDblClick(Sender: TObject);
934var
935 offset: LongWord;
936 datatype: Word;
937 objectname: String;
938 Value: String;
939begin
940 if (value_viewer.Col = 1) and (Length(value_viewer.Cells[1, value_viewer.Row]) > 0) then
941 begin
942 offset := hex.SelStart;
943 if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
944 datatype := 1;
945 if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
946 datatype := 2;
947 if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
948 datatype := 4;
949 if value_viewer.Cells[0, value_viewer.Row] = 'Bitset' then
950 datatype := 10;
951 if value_viewer.Cells[0, value_viewer.Row] = 'Float' then
952 datatype := 9;
953 if value_viewer.Cells[0, value_viewer.Row] = 'Selected length' then
954 Exit;
955 if value_viewer.Cells[0, value_viewer.Row] = 'String' then
956 begin
957 if hex.SelCount > 0 then
958 datatype := 10000 + hex.SelCount
959 else
960 datatype := 10000 + Length(value_viewer.Cells[1, value_viewer.Row]);
961 end;
962 objectname := '';
963 Value := GetValue(datatype, offset);
964 Form_ValueEdit.MakeVarInput(objectname, offset, datatype, Value, Self);
965 end;
966end;
967
968
969
970
971procedure TForm_BinEdit.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
972begin
973 if (Shift = [ssCtrl]) and (Key = 83) then
974 if hex.Modified then
975 if not Save then
976 Exit;
977end;
978
979
980begin
981 AddToolListEntry('binedit', 'Binary .dat-Editor', '');
982end.
Note: See TracBrowser for help on using the repository browser.