source: oup/current/Tool_RawEdit.pas @ 43

Last change on this file since 43 was 43, checked in by alloc, 17 years ago

DevTree 0.33a.

File size: 26.0 KB
Line 
1unit Tool_RawEdit;
2
3interface
4
5uses
6  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7  Dialogs, Wrapgrid, StdCtrls, Grids, StrUtils, MPHexEditor, ExtCtrls, Clipbrd,
8  Data, Code_Functions, Code_DataStructures, Code_Exporters, Code_OniDataClass,
9  Menus, Math;
10
11type
12  TForm_RawEdit = class(TForm)
13    Splitter1: TSplitter;
14    panel_data: TPanel;
15    hex:   TMPHexEditor;
16    Splitter2: TSplitter;
17    value_viewer: TWrapGrid;
18    value_viewer_context: TPopupMenu;
19    value_viewer_context_copy: TMenuItem;
20    value_viewer_context_copyashex: TMenuItem;
21    value_viewer_context_copyasdec: TMenuItem;
22    value_viewer_context_copyasfloat: TMenuItem;
23    value_viewer_context_copyasbitset: TMenuItem;
24    value_viewer_context_copyasstring: TMenuItem;
25    panel_files: TPanel;
26    opend: TOpenDialog;
27    saved: TSaveDialog;
28    panel_imexport: TPanel;
29    btn_export: TButton;
30    btn_import: TButton;
31    group_file: TGroupBox;
32    list:  TListBox;
33    panel_extension: TPanel;
34    lbl_filter: TLabel;
35    combo_extension: TComboBox;
36    edit_filtername: TEdit;
37    check_filtername: TCheckBox;
38    GroupBox1: TGroupBox;
39    list_offset: TListBox;
40    Splitter4: TSplitter;
41    procedure hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
42    procedure list_offsetClick(Sender: TObject);
43    procedure LoadRaw(raw_info: TRawInfo);
44    procedure LoadFileNames;
45    procedure check_filternameClick(Sender: TObject);
46    procedure combo_extensionClick(Sender: TObject);
47    procedure panel_extensionResize(Sender: TObject);
48    procedure listClick(Sender: TObject);
49    procedure Recreatelist;
50
51    procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
52    procedure value_viewerDblClick(Sender: TObject);
53    procedure value_viewer_context_copyClick(Sender: TObject);
54    procedure value_viewerMouseDown(Sender: TObject; Button: TMouseButton;
55      Shift: TShiftState; X, Y: Integer);
56    procedure value_viewer_contextPopup(Sender: TObject);
57    procedure btn_importClick(Sender: TObject);
58    procedure btn_exportClick(Sender: TObject);
59    procedure panel_imexportResize(Sender: TObject);
60    function Save: Boolean;
61    procedure FormClose(Sender: TObject; var Action: TCloseAction);
62    function GetValue(datatype: Word; offset: LongWord): String;
63    procedure hexSelectionChanged(Sender: TObject);
64    procedure hexChange(Sender: TObject);
65    procedure panel_dataResize(Sender: TObject);
66    procedure FormResize(Sender: TObject);
67    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
68    procedure FormCreate(Sender: TObject);
69    procedure ClearValues;
70    procedure WriteValues;
71    procedure SetNewValue(datatype: Word; offset: LongWord; Value: String);
72    procedure listMouseDown(Sender: TObject; Button: TMouseButton;
73      Shift: TShiftState; X, Y: Integer);
74  private
75    fileid:     LongWord;
76    dat_offset: LongWord;
77    fileid_opened, dat_offset_opened: LongWord;
78  public
79  end;
80
81var
82  Form_RawEdit: TForm_RawEdit;
83
84implementation
85
86{$R *.dfm}
87
88uses Main, Helper_ValueEdit;
89
90
91
92
93procedure TForm_RawEdit.LoadRaw(raw_info: TRawInfo);
94var
95  i:    LongWord;
96  Data: Tdata;
97  mem:  TMemoryStream;
98begin
99  if hex.Modified then
100  begin
101    if not Save then
102    begin
103      Exit;
104    end;
105  end;
106  if list_offset.Count = 0 then
107  begin
108    for i := 0 to list.Count - 1 do
109    begin
110      if OniDataConnection.ExtractFileID(list.Items.Strings[i]) = raw_info.src_id then
111      begin
112        list.ItemIndex := i;
113        listClick(Self);
114        Break;
115      end;
116    end;
117    for i := 0 to list_offset.Count - 1 do
118    begin
119      if MidStr(list_offset.Items.Strings[i], 3, 8) = IntToHex(raw_info.src_offset, 8) then
120      begin
121        list_offset.ItemIndex := i;
122        Break;
123      end;
124    end;
125  end;
126  SetLength(Data, raw_info.raw_size);
127  OniDataConnection.LoadRawFile(raw_info.src_id, raw_info.src_offset, @Data[0]);
128  if Length(Data) > 0 then
129  begin
130    hex.DataSize := 0;
131    hex.DataSize := raw_info.raw_size;
132    for i := 0 to High(Data) do
133      hex.Data[i] := Data[i];
134    //WriteStructureInfos(GetStructureInfoId(GetFileInfo(fileid).Extension));
135    //      structs.Height:=structs.RowCount*20;
136    //      IF structs.Height>120 THEN structs.Height:=120;
137    hexSelectionChanged(Self);
138    fileid_opened     := raw_info.src_id;
139    dat_offset_opened := raw_info.src_offset;
140    hex.Modified      := False;
141  end
142  else
143  begin
144    ClearValues;
145    hex.DataSize := 0;
146  end;
147end;
148
149
150
151
152procedure TForm_RawEdit.Recreatelist;
153var
154  i:     LongWord;
155  exts:  TStringArray;
156  Count: LongWord;
157begin
158  combo_extension.Items.Clear;
159  combo_extension.Items.Add('_All files_ ('{+IntToStr(dat_header.Files)} + ')');
160  exts := OniDataConnection.GetExtensionsList;
161  for i := 0 to High(RawListHandlers) do
162  begin
163    Count := Length(OniDataConnection.GetFilesList(RawListHandlers[i].Ext, '', True));
164    combo_extension.Items.Add(RawListHandlers[i].ext + ' (' + IntToStr(Count) + ')');
165  end;
166  //    FOR i:=0 TO High(exts) DO
167  //      combo_extension.Items.Add(exts[i]);
168  combo_extension.ItemIndex := 0;
169  combo_extensionClick(Self);
170end;
171
172
173
174
175procedure TForm_RawEdit.LoadFileNames;
176var
177  Extension: String;
178  no_zero_bytes: Boolean;
179  pattern: String;
180  files: TStringArray;
181  i: LongWord;
182begin
183  Extension := MidStr(combo_extension.Items.Strings[combo_extension.ItemIndex], 1, 4);
184  pattern   := '';
185  if check_filtername.Checked then
186    pattern := edit_filtername.Text;
187  if Extension = '_All' then
188  begin
189    Extension := '';
190    for i := 0 to High(RawListHandlers) do
191    begin
192      if Length(Extension) > 0 then
193        Extension := Extension + ',';
194      Extension := Extension + RawListHandlers[i].Ext;
195    end;
196  end;
197
198  files := OniDataConnection.GetFilesList(extension, pattern, True);
199  list.Items.Clear;
200  if Length(files) > 0 then
201    for i := 0 to High(files) do
202      list.Items.Add(files[i]);
203  list_offset.Items.Clear;
204end;
205
206
207
208
209procedure TForm_RawEdit.panel_extensionResize(Sender: TObject);
210begin
211  combo_extension.Width := panel_extension.Width - 5;
212  edit_filtername.Width := panel_extension.Width - 5;
213end;
214
215
216
217
218procedure TForm_RawEdit.combo_extensionClick(Sender: TObject);
219begin
220  LoadFileNames;
221end;
222
223
224
225
226procedure TForm_RawEdit.check_filternameClick(Sender: TObject);
227begin
228  edit_filtername.Enabled := not check_filtername.Checked;
229  LoadFileNames;
230end;
231
232
233
234
235procedure TForm_RawEdit.listClick(Sender: TObject);
236var
237  mem:  TMemoryStream;
238  Data: Tdata;
239  i:    LongWord;
240  offsets: TRawList;
241begin
242  if hex.Modified then
243  begin
244    if not Save then
245    begin
246      Exit;
247    end;
248  end;
249  ClearValues;
250  hex.DataSize := 0;
251  fileid := OniDataConnection.ExtractFileID(list.Items.Strings[list.ItemIndex]);
252  list_offset.Enabled := True;
253  if OniDataConnection.GetFileInfo(fileid).size > 0 then
254  begin
255    offsets := OniDataConnection.GetRawList(fileid);
256    list_offset.Items.Clear;
257    if Length(offsets) > 0 then
258    begin
259      for i := 0 to High(offsets) do
260      begin
261        list_offset.Items.Add('0x' + IntToHex(offsets[i].src_offset, 8) +
262          ', ' + IntToStr(offsets[i].raw_size) + ' bytes');
263      end;
264    end
265    else
266    begin
267      list_offset.Enabled := False;
268    end;
269  end
270  else
271  begin
272    list_offset.Enabled := False;
273  end;
274end;
275
276
277
278
279procedure TForm_RawEdit.listMouseDown(Sender: TObject; Button: TMouseButton;
280  Shift: TShiftState; X, Y: Integer);
281var
282  pt: TPoint;
283begin
284  pt.X := x;
285  pt.Y := y;
286  list.ItemIndex := list.ItemAtPos(pt, true);
287  if list.ItemIndex > -1 then
288    Self.listClick(Self);
289end;
290
291procedure TForm_RawEdit.list_offsetClick(Sender: TObject);
292var
293  i: LongWord;
294  raw_info: TRawInfo;
295begin
296  ClearValues;
297  dat_offset := StrToInt('$' + MidStr(
298    list_offset.Items.Strings[list_offset.ItemIndex], 3, 8));
299  LoadRaw(OniDataConnection.GetRawInfo(fileid, dat_offset));
300end;
301
302
303
304
305function IntToBin(Value: Byte): String;
306var
307  i: Byte;
308begin
309  Result := '';
310  for i := 7 downto 0 do
311  begin
312    Result := Result + IntToStr((Value shr i) and $01);
313  end;
314end;
315
316
317
318
319function TForm_RawEdit.GetValue(datatype: Word; offset: LongWord): String;
320var
321  Data: Tdata;
322  i:    Word;
323begin
324  case datatype of
325    1:
326      Result := IntToStr(hex.Data[offset]);
327    2:
328      Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256);
329    3:
330      Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256);
331    4:
332      Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] *
333        256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256);
334    5:
335      Result := '0x' + IntToHex(hex.Data[offset], 2);
336    6:
337      Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256, 4);
338    7:
339      Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 +
340        hex.Data[offset + 2] * 256 * 256, 6);
341    8:
342      Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 +
343        hex.Data[offset + 2] * 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256, 8);
344    9:
345    begin
346      SetLength(Data, 4);
347      Data[0] := hex.Data[offset];
348      Data[1] := hex.Data[offset + 1];
349      Data[2] := hex.Data[offset + 2];
350      Data[3] := hex.Data[offset + 3];
351      Result  := FloatToStr(Decode_Float(Data));
352    end;
353    10:
354      Result := IntToBin(hex.Data[offset]);
355    11:
356      Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 +
357        hex.Data[offset + 2] * 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256, 8);
358    10000..65535:
359    begin
360      Result := '';
361      for i := 1 to datatype - 10000 do
362      begin
363        if hex.Data[offset + i - 1] >= 32 then
364          Result := Result + Chr(hex.Data[offset + i - 1])
365        else
366          Result := Result + '.';
367      end;
368    end;
369  end;
370end;
371
372
373
374
375procedure TForm_RawEdit.ClearValues;
376var
377  i: Byte;
378begin
379  for i := 1 to value_viewer.RowCount - 1 do
380  begin
381    value_viewer.Cells[1, i] := '';
382  end;
383end;
384
385
386
387
388procedure TForm_RawEdit.WriteValues;
389var
390  i, j:  Byte;
391  Data:  Tdata;
392  str:   String;
393  Value: LongWord;
394begin
395  for i := 1 to value_viewer.RowCount - 1 do
396  begin
397    if value_viewer.Cells[0, i] = '1 byte, unsigned' then
398    begin
399      if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not
400        ((hex.SelStart + 1) > hex.DataSize) then
401      begin
402        Value := hex.Data[hex.SelStart];
403        value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 2);
404      end
405      else
406        value_viewer.Cells[1, i] := '';
407    end;
408    if value_viewer.Cells[0, i] = '2 bytes, unsigned' then
409    begin
410      if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not
411        ((hex.SelStart + 2) > hex.DataSize) then
412      begin
413        Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256;
414        value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 4);
415      end
416      else
417        value_viewer.Cells[1, i] := '';
418    end;
419    if value_viewer.Cells[0, i] = '4 bytes, unsigned' then
420    begin
421      if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
422        ((hex.SelStart + 4) > hex.DataSize) then
423      begin
424        Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 +
425          hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256;
426        value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 8);
427      end
428      else
429        value_viewer.Cells[1, i] := '';
430    end;
431    if value_viewer.Cells[0, i] = 'Bitset' then
432    begin
433      if (hex.SelCount <= 8) then
434      begin
435        if hex.SelCount = 0 then
436        begin
437          SetLength(Data, 1);
438          Data[0] := hex.Data[hex.SelStart];
439        end
440        else
441        begin
442          SetLength(Data, hex.SelCount);
443          for j := 0 to hex.SelCount - 1 do
444            Data[j] := hex.Data[hex.SelStart + j];
445        end;
446        value_viewer.Cells[1, i] := DataToBin(Data);
447      end
448      else
449        value_viewer.Cells[1, i] := '';
450    end;
451    if value_viewer.Cells[0, i] = 'Float' then
452    begin
453      if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
454        ((hex.SelStart + 4) > hex.DataSize) then
455      begin
456        SetLength(Data, 4);
457        for j := 0 to 3 do
458          Data[j] := hex.Data[hex.SelStart + j];
459        value_viewer.Cells[1, i] := FloatToStr(Decode_Float(Data));
460      end
461      else
462        value_viewer.Cells[1, i] := '';
463    end;
464    if value_viewer.Cells[0, i] = 'Selected length' then
465    begin
466      value_viewer.Cells[1, i] := IntToStr(hex.SelCount) + ' bytes';
467    end;
468    if value_viewer.Cells[0, i] = 'String' then
469    begin
470      j   := 0;
471      str := '';
472      if hex.SelCount = 0 then
473      begin
474        while (hex.Data[hex.SelStart + j] > 0) and ((hex.SelStart + j) < hex.DataSize) do
475        begin
476          if hex.Data[hex.selstart + j] >= 32 then
477            str := str + Char(hex.Data[hex.SelStart + j])
478          else
479            str := str + '.';
480          Inc(j);
481        end;
482      end
483      else
484      begin
485        for j := 0 to hex.SelCount - 1 do
486          if hex.Data[hex.selstart + j] >= 32 then
487            str := str + Char(hex.Data[hex.SelStart + j])
488          else if hex.Data[hex.selstart + j] > 0 then
489            str := str + '.'
490          else
491            Break;
492      end;
493      value_viewer.Cells[1, i] := str;
494    end;
495  end;
496end;
497
498
499
500
501procedure TForm_RawEdit.FormCreate(Sender: TObject);
502begin
503  Self.Caption := '';
504  fileid     := 0;
505  value_viewer.ColCount := 2;
506  value_viewer.RowCount := 8;
507  value_viewer.FixedRows := 1;
508  value_viewer.Cells[0, 0] := 'Type';
509  value_viewer.Cells[1, 0] := 'Value';
510  value_viewer.Cells[0, 1] := '1 byte, unsigned';
511  value_viewer.Cells[0, 2] := '2 bytes, unsigned';
512  value_viewer.Cells[0, 3] := '4 bytes, unsigned';
513  value_viewer.Cells[0, 4] := 'Bitset';
514  value_viewer.Cells[0, 5] := 'Float';
515  value_viewer.Cells[0, 6] := 'String';
516  value_viewer.Cells[0, 7] := 'Selected length';
517  value_viewer.ColWidths[0] := 100;
518  hex.Height := panel_data.Height - 190;
519  Self.panel_dataResize(Self);
520  //
521  value_viewer.Font.Charset := AppSettings.CharSet;
522  //
523end;
524
525
526
527
528function TForm_RawEdit.Save: Boolean;
529var
530  mem:  TMemoryStream;
531  Data: Tdata;
532  i:    LongWord;
533begin
534  case MessageBox(Self.Handle, PChar('Save changes to .raw-part of file ' +
535      OniDataConnection.GetFileInfo(fileid).FileName + '?'), PChar('Data changed...'),
536      MB_YESNOCANCEL) of
537    idYes:
538    begin
539      mem := TMemoryStream.Create;
540      hex.SaveToStream(mem);
541      mem.Seek(0, soFromBeginning);
542      SetLength(Data, mem.Size);
543      mem.Read(Data[0], mem.Size);
544      mem.Free;
545      OniDataConnection.UpdateRawFile(fileid_opened, dat_offset_opened,
546        Length(Data), @Data[0]);
547      hex.Modified := False;
548      for i := 0 to hex.Datasize - 1 do
549        hex.ByteChanged[i] := False;
550      Result := True;
551    end;
552    idNo:
553      Result := True;
554    idCancel:
555    begin
556      Result := False;
557    end;
558  end;
559end;
560
561
562
563
564procedure TForm_RawEdit.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
565begin
566  if hex.Modified then
567  begin
568    if not Save then
569      CanClose := False;
570  end;
571end;
572
573
574
575
576procedure TForm_RawEdit.FormResize(Sender: TObject);
577begin
578  if Self.Width >= 650 then
579  begin
580  end
581  else
582    Self.Width := 650;
583  if Self.Height >= 450 then
584  begin
585  end
586  else
587    Self.Height := 450;
588end;
589
590
591
592
593procedure TForm_RawEdit.panel_dataResize(Sender: TObject);
594begin
595  value_viewer.ColWidths[1] := value_viewer.Width - value_viewer.ColWidths[0] - 28;
596end;
597
598
599
600
601procedure TForm_RawEdit.hexChange(Sender: TObject);
602begin
603  ClearValues;
604  if hex.DataSize > 0 then
605  begin
606{      WriteStructureInfos(GetStructureInfoId(GetFileInfo(fileid).Extension));
607      WriteValues;
608}    end;
609end;
610
611
612
613
614procedure TForm_RawEdit.hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
615var
616  temps: String;
617begin
618  if (Shift = [ssCtrl]) and (Key = Ord('C')) then
619  begin
620    if hex.SelCount > 0 then
621    begin
622      if hex.InCharField then
623        Clipboard.AsText := hex.SelectionAsText
624      else
625        Clipboard.AsText := hex.SelectionAsHex;
626    end;
627  end;
628  if (Shift = [ssCtrl]) and (Key = Ord('V')) then
629  begin
630{      temps:=Clipboard.AsText;
631      IF hex.SelStart+Length(temps)>hex.DataSize THEN
632        SetLength(temps, hex.DataSize-hex.SelStart);
633      hex.Sel
634      hex.SelCount:=Length(temps);
635      hex.ReplaceSelection(temps,Length(temps));
636}    end;
637end;
638
639
640
641
642procedure TForm_RawEdit.hexSelectionChanged(Sender: TObject);
643var
644  selstart: Integer;
645  i, j:     Word;
646begin
647{    FOR i:=1 TO structs.RowCount-1 DO BEGIN
648      FOR j:=0 TO structs.ColCount-1 DO BEGIN
649        structs.CellColors[j,i]:=clWhite;
650        structs.CellFontColors[j,i]:=clBlack;
651      END;
652    END;
653}    if hex.DataSize > 0 then
654  begin
655{      selstart:=hex.SelStart;
656      IF GetStructureInfoId(GetFileInfo(fileid).Extension)>=0 THEN BEGIN
657        WITH structure_infos[GetStructureInfoId(GetFileInfo(fileid).Extension)] DO BEGIN
658          FOR i:=0 TO High(entries) DO BEGIN
659            IF ((selstart-entries[i].offset)<GetTypeDataLength(entries[i].datatype)) AND ((selstart-entries[i].offset)>=0) THEN BEGIN
660              FOR j:=0 TO structs.ColCount-1 DO BEGIN
661                structs.CellColors[j,i+1]:=clBlue;
662                structs.CellFontColors[j,i+1]:=clWhite;
663              END;
664              structs.Row:=i+1;
665            END;
666          END;
667        END;
668      END;
669}      WriteValues;
670  end;
671end;
672
673
674
675
676procedure TForm_RawEdit.FormClose(Sender: TObject; var Action: TCloseAction);
677begin
678  Action := caFree;
679end;
680
681
682
683
684procedure TForm_RawEdit.panel_imexportResize(Sender: TObject);
685begin
686  btn_import.Width := panel_imexport.Width - 8;
687  btn_export.Width := panel_imexport.Width - 8;
688end;
689
690
691
692
693procedure TForm_RawEdit.btn_exportClick(Sender: TObject);
694var
695  fs: TFileStream;
696begin
697  saved.Filter     := 'Files of matching extension (*.' + OniDataConnection.GetFileInfo(
698    fileid).Extension + ')|*.' + OniDataConnection.GetFileInfo(fileid).Extension +
699    '|All files|*.*';
700  saved.DefaultExt := OniDataConnection.GetFileInfo(fileid).Extension;
701  if saved.Execute then
702  begin
703    fs := TFileStream.Create(saved.FileName, fmCreate);
704    hex.SaveToStream(fs);
705    fs.Free;
706  end;
707end;
708
709
710
711
712procedure TForm_RawEdit.btn_importClick(Sender: TObject);
713var
714  Data: Tdata;
715  fs:   TFileStream;
716begin
717  opend.Filter := 'Files of matching extension (*.' + OniDataConnection.GetFileInfo(
718    fileid).Extension + ')|*.' + OniDataConnection.GetFileInfo(fileid).Extension +
719    '|All files|*.*';
720  if opend.Execute then
721  begin
722    fs := TFileStream.Create(opend.FileName, fmOpenRead);
723    if fs.Size <> hex.DataSize then
724    begin
725      ShowMessage('Can''t import ' + ExtractFilename(opend.FileName) +
726        ', file has to have same size as file in .dat.' + CrLf +
727        'Size of file in .dat: ' + FormatFileSize(hex.datasize) + CrLf +
728        'Size of chosen file: ' + FormatFileSize(fs.Size));
729    end
730    else
731    begin
732      hex.LoadFromStream(fs);
733      hex.Modified := True;
734    end;
735    fs.Free;
736  end;
737end;
738
739
740
741
742procedure TForm_RawEdit.value_viewer_contextPopup(Sender: TObject);
743var
744  i: Byte;
745begin
746  for i := 0 to value_viewer_context.Items.Count - 1 do
747    value_viewer_context.Items.Items[i].Visible := False;
748  with value_viewer do
749  begin
750    if (Col = 1) and (Row > 0) and (Length(Cells[Col, Row]) > 0) then
751    begin
752      if Pos(' byte', Cells[0, Row]) = 2 then
753      begin
754        value_viewer_context.Items.Find('Copy to &clipboard').Visible := True;
755        value_viewer_context.Items.Find('Copy to clipboard (as &dec)').Visible := True;
756        value_viewer_context.Items.Find('Copy to clipboard (as &hex)').Visible := True;
757      end;
758      if Pos('Float', Cells[0, Row]) = 1 then
759        value_viewer_context.Items.Find('Copy to clipboard (as &float)').Visible := True;
760      if Pos('Bitset', Cells[0, Row]) = 1 then
761        value_viewer_context.Items.Find(
762          'Copy to clipboard (as &bitset)').Visible := True;
763      if Pos('String', Cells[0, Row]) = 1 then
764        value_viewer_context.Items.Find(
765          'Copy to clipboard (as &string)').Visible := True;
766      if Pos('Selected length', Cells[0, Row]) = 1 then
767        value_viewer_context.Items.Find('Copy to &clipboard').Visible := True;
768    end;
769  end;
770end;
771
772
773
774
775procedure TForm_RawEdit.value_viewerMouseDown(Sender: TObject; Button: TMouseButton;
776  Shift: TShiftState; X, Y: Integer);
777var
778  ACol, ARow: Integer;
779begin
780  if Button = mbRight then
781  begin
782    value_viewer.MouseToCell(x, y, ACol, ARow);
783    if ARow > 0 then
784    begin
785      value_viewer.Col := ACol;
786      value_viewer.Row := ARow;
787    end;
788  end;
789end;
790
791
792
793
794procedure TForm_RawEdit.value_viewer_context_copyClick(Sender: TObject);
795var
796  i:     Byte;
797  Name:  String;
798  Value: LongWord;
799begin
800  Name := TMenuItem(Sender).Name;
801  if Pos('asstring', Name) > 0 then
802  begin
803    Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
804  end
805  else if Pos('asfloat', Name) > 0 then
806  begin
807    Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
808  end
809  else if Pos('asbitset', Name) > 0 then
810  begin
811    Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
812  end
813  else if (Pos('ashex', Name) > 0) or (Pos('asdec', Name) > 0) then
814  begin
815    if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
816    begin
817      if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not
818        ((hex.SelStart + 1) > hex.DataSize) then
819        Value := hex.Data[hex.SelStart];
820    end;
821    if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
822    begin
823      if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not
824        ((hex.SelStart + 2) > hex.DataSize) then
825        Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256;
826    end;
827    if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
828    begin
829      if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
830        ((hex.SelStart + 4) > hex.DataSize) then
831        Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 +
832          hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256;
833    end;
834    if Pos('asdec', Name) > 0 then
835    begin
836      Clipboard.AsText := IntToStr(Value);
837    end
838    else
839    begin
840      if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
841        Clipboard.AsText := '0x' + IntToHex(Value, 2);
842      if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
843        Clipboard.AsText := '0x' + IntToHex(Value, 4);
844      if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
845        Clipboard.AsText := '0x' + IntToHex(Value, 8);
846    end;
847  end
848  else
849  begin
850    Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
851  end;
852end;
853
854
855
856
857procedure TForm_RawEdit.SetNewValue(datatype: Word; offset: LongWord; Value: String);
858var
859  Data: Tdata;
860  value_int: LongWord;
861  value_float: Single;
862  i: Word;
863begin
864  case datatype of
865    1..4:
866    begin
867      value_int := StrToInt(Value);
868      SetLength(Data, datatype);
869      for i := 0 to datatype - 1 do
870      begin
871        Data[i]   := value_int mod 256;
872        value_int := value_int div 256;
873      end;
874    end;
875    5..8:
876    begin
877      value_int := StrToInt('$' + Value);
878      SetLength(Data, datatype - 4);
879      for i := 0 to datatype - 5 do
880      begin
881        Data[i]   := value_int mod 256;
882        value_int := value_int div 256;
883      end;
884    end;
885    9:
886    begin
887      value_float := StrToFloat(Value);
888      Data := Encode_Float(value_float);
889    end;
890    10:
891    begin
892      value_int := BinToInt(Value);
893      SetLength(Data, 1);
894      Data[0] := value_int;
895    end;
896    10000..65535:
897    begin
898      SetLength(Data, datatype - 10000);
899      for i := 1 to datatype - 10000 do
900      begin
901        if i <= Length(Value) then
902          Data[i - 1] := Ord(Value[i])
903        else
904          Data[i - 1] := 0;
905      end;
906    end;
907  end;
908  for i := 0 to High(Data) do
909  begin
910    if hex.Data[offset + i] <> Data[i] then
911      hex.ByteChanged[offset + i] := True;
912    hex.Data[offset + i] := Data[i];
913  end;
914  hex.Modified := True;
915  hexChange(Self);
916  hex.Repaint;
917end;
918
919
920
921
922procedure TForm_RawEdit.value_viewerDblClick(Sender: TObject);
923var
924  offset:     LongWord;
925  datatype:   Word;
926  objectname: String;
927  Value:      String;
928begin
929  if (value_viewer.Col = 1) and (Length(value_viewer.Cells[1, value_viewer.Row]) > 0) then
930  begin
931    offset := hex.SelStart;
932    if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
933      datatype := 1;
934    if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
935      datatype := 2;
936    if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
937      datatype := 4;
938    if value_viewer.Cells[0, value_viewer.Row] = 'Bitset' then
939      datatype := 10;
940    if value_viewer.Cells[0, value_viewer.Row] = 'Float' then
941      datatype := 9;
942    if value_viewer.Cells[0, value_viewer.Row] = 'Selected length' then
943      Exit;
944    if value_viewer.Cells[0, value_viewer.Row] = 'String' then
945    begin
946      if hex.SelCount > 0 then
947        datatype := 10000 + hex.SelCount
948      else
949        datatype := 10000 + Length(value_viewer.Cells[1, value_viewer.Row]);
950    end;
951    objectname := '';
952    Value      := GetValue(datatype, offset);
953    Form_ValueEdit.MakeVarInput(objectname, offset, datatype, Value, Self);
954  end;
955end;
956
957
958
959
960procedure TForm_RawEdit.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
961begin
962  if (Shift = [ssCtrl]) and (Key = 83) then
963    if hex.Modified then
964      if not Save then
965        Exit;
966end;
967
968end.
Note: See TracBrowser for help on using the repository browser.