tak jak w Hex Workshop

0

nie widzialem tematu na forum ktory by mi to wyjasnil a moze go przegapilem wiec pytam jak moge otworzyc dowolny plik wczytac go np. do memo i zeby byl w tym memo wyswietlony tak jak w Hex Workshop czyli sam kog hex ??? pozdrawiam mam nadzieje ze ktos mnie troszke zrozumial i mi pomoze

0

Już tepiej w TStringGrid - po prostu wczytujesz kolejne bajty i przeliczasz ich wartości na hexy ( IntToHex(Bajt,2); ), po czym wstawiasz to tabelki, po 16 bajtów na wiersz...

0
procedure TForm1.HexadecimalExecute(FileName: String);
var
  Chars, Ln : String;
  I : Integer;
  HF : File of Byte;
  B, J : Byte;
  Text : TStrings;
begin
  Text := TStringList.Create;

    AssignFile(HF, FileName);
    FileMode := 0;
    try
      Reset(HF);
    except
      MessageBox(0, 'Nie można otworzyć pliku.', 'Błąd', MB_ICONERROR);
      Exit;
    end;

    Screen.Cursor := crHourGlass;
    Application.ProcessMessages;

    I := 0;
    while not Eof(HF) do
    begin
      Ln := Format('%.8x |', [I * 16]);
      Chars := ' | ';
      for J := 0 to 15 do
      begin
        if not Eof(HF) then
        begin
          Read(HF, B);
          Chars := Chars + Chr(B);
          Ln := Ln + Format(' %.2x', [B]);
        end
        else
          Ln := Ln + '   ';
      end;
      Text.Add(Ln + Chars);
      Inc(I);
    end;
    CloseFile(HF);

    SynEdit.Lines.Clear;
    SynEdit.Lines := Text;

    Text.Free;
    Screen.Cursor := crDefault;


end;

Najlepiej działa to z SynEditem, ale po paru przeróbkach (np. usuwanie #10#13, zmiana czionki na regularną itp) bedzie działało w pełni poprawnie również w Memo. Dla pliku 1MB konwersja trwa (na moim kompie 1GHz, 256RAM) ok. 7 sek, zapis do SynEdit - ok. 40 msec. Niestety zapis do Memo trwa o wiele dłużej. Dlatego też w profesjonalnych edytorach hexów wczytywanie odbywa się dynamicznie-wczytywane jest jedynie ta częsc pliku która jest aktualnie przegladana/edytowana.

PS. Kod może ne jest doskonały, ale za to mój własny :-)

0

Najlepiej to odwzorować plik w pamięci (CreateFileMapping) i do komponentu takego np. jak napisał autor odpowiedzi pierwszej, wczytaywać po kawałku - jakiś odcinek bajtów żeby zapełniał tylko widoczną część komponentu. Dlatego lepiej jest robić tak, gdyż jak wczytasz jakiś ogromny plik całkowicie to przy wolniejszym kompie może się zawiesić. Tak właśnie robi tez HexWorkshop.

0

Jak uzyc tej procedury ktora jest wyzej, zeby przy otwieraniu pliku za pomoca OpenDialog <ort>Od razu </ort>plik byl zamieniony na postac szesnastkowa i byl wyswietlony w oknie RichEdit? Z gory wielkie dzieki

0

To najszybsze, co wymyśliłem do wczytania całego (jednak całego ;P ) pliku [Form1, Button1, Memo1, OpenDialog1]:

procedure TForm1.Button1Click(Sender: TObject);
var hFile:THandle;
    hMem:THandle;
    Size:DWORD;
    i:DWORD;
    b:^byte;
    s:string;
    z:string;
    l:byte;
    c:byte;
    x,y:char;
label p1ok;
label p2ok;
begin
b:=nil;
if OpenDialog1.Execute then
  begin
  hFile:=CreateFile(pChar(OpenDialog1.FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if (hFile <> NULL) then
    begin
    Size:=GetFileSize(hFile, nil);
    hMem:=CreateFileMapping(hFile, nil, PAGE_READONLY, 0, 0, nil);
    if (hMem <> NULL) then
      begin
      b:=MapViewOfFile(hMem, FILE_MAP_READ, 0, 0, 0);
      if (b<>nil) then
        begin
        i:=size;
        l:=0;
        s:='';
        z:='';
        while (i>0) do
          begin
          dec(i);
          asm
            push eax
            push ebx
            mov ebx, b
            mov ah, [ebx]
            push ax
            shr ah, 4
            add ah, '0'
            cmp ah, '9'
            jle p1ok
            add ah, 'A'-10-'0'
          p1ok:
            mov x, ah
            pop ax
            and ah, 0Fh
            add ah, '0'
            cmp ah, '9'
            jle p2ok
            add ah, 'A'-10-'0'
          p2ok:
            mov y, ah
            pop ebx
            pop eax
          end;
          s:=s+' '+x+y;
          inc(l);
          if l>31 then
            begin
            z:=z+s+#13#10;
            s:='';
            l:=0;
            end;
          inc(b);
          end;
        Memo1.Lines.Add(z);
        UnmapViewOfFile(b);
        end;
        CloseHandle(hMem);
      end;
    CloseHandle(hFile);
    end;
  end;
end;

Tak na prawdę ten asembler w środku do konwersji bin->hex nie jest niezbędny (tak się bawiłem :D ), ale jak chcesz się zająć tworzeniem czegość a'la HexWorkshop, to bez tego może być ciężko się obejść. Jak chesz otrzymać dużą szybkość, elementy interfejsu (tutaj Memo1) odświeżaj jak najrzadziej (oczywiście sensownie z punktu widzenia użytkownika).

To już banalnie prosto dopasować do RichEdit'a.

1 użytkowników online, w tym zalogowanych: 0, gości: 1