Seite 1 von 1

kleiner Hex Viewer

Verfasst: 12.08.2013 04:45
von SBond
Hi Leute,

habe mal wieder ein kleines Problem...
Ich habe mir mal quick and dirty einen kleinen Hex-Viewer geschrieben. Ich will damit nur kleine Dateien (<10KB) betrachten. Irgendwelche Funktionen wie kopieren oder bearbeiten des Inhaltes sind nicht vorgesehen. Das öffnen und darstellen klappt soweit ganz gut. Das einzige, was mich noch stört ist die ASCII-Ansicht. Gibt es eine Möglichkeit, dass jedes Zeichen eine feste Breite bekommt? Ich habe mal 2 Screenshots von meinem Hex Viewer und einen richtigen Hex-Editor gemacht. Ich denke so kann man die Unterschiede am besten sehen. Ich bin mir nicht sicher ob ich einfach nur eine bestimmte Schriftart brauche.



Mein Tool:
Bild

richtiger Hex-Editor:
Bild

Code: Alles auswählen

; Achtung: quick and dirty Code  ;)

DateiName$		= OpenFileRequester("Datei wählen", StandardDatei$, Pattern$, PatternPosition)
Dateigroesse.q 	= FileSize(DateiName$)
Datei  			= ReadFile(#PB_Any, DateiName$)

If Datei = 0
	End
EndIf


OpenWindow(0, 0, 0, 700, 525, "irgend so ein Hex-Kram", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(1, 10, 10, 680, 505, "Offset", 80, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection| #PB_ListIcon_GridLines)

For x = 1 To 16 Step 1
	AddGadgetColumn(1, x, Hex(x-1), 28)
Next

AddGadgetColumn(1, 17, "ASCII", 120)

For x = 0 To Dateigroesse Step 16
	AddGadgetItem(1, -1, RSet(Hex(x), 6, "0"))
Next

X_Pos=1
Y_Pos=0

While Eof(Datei) = 0
	
	If X_Pos > 16
		X_Pos = 1
		Y_Pos + 1
		Text$=""
		Text2$=""	
	EndIf
	
	SetGadgetItemText(1, Y_Pos, RSet(Hex(ReadAsciiCharacter(Datei)), 2, "0"), X_Pos)
	
	Text$=	GetGadgetItemText(1, Y_Pos, X_Pos)
	Wert=	Val("$"+Text$)
	Text2$=	Text2$ + Chr(Wert)
	SetGadgetItemText(1, Y_Pos, Text2$, 17)
	
	X_Pos + 1
	
Wend

Center.LV_COLUMN\mask=#LVCF_FMT
Center\fmt=#LVCFMT_RIGHT
SendMessage_(GadgetID(1), #LVM_SETCOLUMN,0,@Center)
SendMessage_(SendMessage_(GadgetID(1),#LVM_GETHEADER,0,0),#WM_SETFONT,LoadFont(0,"",9,#PB_Font_Bold),1)
SetGadgetItemColor(1, -1, #PB_Gadget_BackColor, $DDDDDD, 0)


For x = 1 To 16 Step 1
	SetGadgetItemColor(1, -1, #PB_Gadget_FrontColor, $FF0000, x)
Next


Repeat
	
	Event = WaitWindowEvent()
	
Until Event = #PB_Event_CloseWindow
CloseFile(Datei)

eventuell kennt ja jemand die Lösung ;)

lg
SBond

Re: kleiner Hex Viewer

Verfasst: 12.08.2013 06:17
von Bisonte
Einen "fixedwidth" Font benutzen ;)

So wie es die IDE als Default macht z.B. : hier war es glaub ich Courier New... (ich z.B. nutze Consolas)

Code: Alles auswählen

; Achtung: quick and dirty Code  ;)

LoadFont(0, "Consolas", 12) ; oder was auch immer als Grösse....
DateiName$      = OpenFileRequester("Datei wählen", StandardDatei$, Pattern$, PatternPosition)
Dateigroesse.q    = FileSize(DateiName$)
Datei           = ReadFile(#PB_Any, DateiName$)

If Datei = 0
   End
EndIf


OpenWindow(0, 0, 0, 700, 525, "irgend so ein Hex-Kram", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(1, 10, 10, 680, 505, "Offset", 80, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection| #PB_ListIcon_GridLines)

SetGadgetFont(1, FontID(0)) ; <-- und hier den Font setzen
For x = 1 To 16 Step 1
   AddGadgetColumn(1, x, Hex(x-1), 28)
Next

AddGadgetColumn(1, 17, "ASCII", 120)

For x = 0 To Dateigroesse Step 16
   AddGadgetItem(1, -1, RSet(Hex(x), 6, "0"))
Next

X_Pos=1
Y_Pos=0

While Eof(Datei) = 0
   
   If X_Pos > 16
      X_Pos = 1
      Y_Pos + 1
      Text$=""
      Text2$=""   
   EndIf
   
   SetGadgetItemText(1, Y_Pos, RSet(Hex(ReadAsciiCharacter(Datei)), 2, "0"), X_Pos)
   
   Text$=   GetGadgetItemText(1, Y_Pos, X_Pos)
   Wert=   Val("$"+Text$)
   Text2$=   Text2$ + Chr(Wert)
   SetGadgetItemText(1, Y_Pos, Text2$, 17)
   
   X_Pos + 1
   
Wend

Center.LV_COLUMN\mask=#LVCF_FMT
Center\fmt=#LVCFMT_RIGHT
SendMessage_(GadgetID(1), #LVM_SETCOLUMN,0,@Center)
SendMessage_(SendMessage_(GadgetID(1),#LVM_GETHEADER,0,0),#WM_SETFONT,LoadFont(0,"",9,#PB_Font_Bold),1)
SetGadgetItemColor(1, -1, #PB_Gadget_BackColor, $DDDDDD, 0)


For x = 1 To 16 Step 1
   SetGadgetItemColor(1, -1, #PB_Gadget_FrontColor, $FF0000, x)
Next


Repeat
   
   Event = WaitWindowEvent()
   
Until Event = #PB_Event_CloseWindow
CloseFile(Datei)

Re: kleiner Hex Viewer

Verfasst: 12.08.2013 11:23
von HeX0R
Hier mal ein bisschen weniger "quick and dirty":

Code: Alles auswählen

EnableExplicit

Structure _BYTES_
	b.b[16]
EndStructure

Procedure main()
	Protected FileName$, FileID, x, i, Event, Center.LV_COLUMN, R._BYTES_
	Protected Line.s, Ascii.s

	LoadFont(0, "courier new", 9) ; oder was auch immer als Grösse....
	FileName$ = OpenFileRequester("Datei wählen", "", "", 0)
	FileID    = ReadFile(#PB_Any, FileName$)

	If FileID

		OpenWindow(0, 0, 0, 730, 525, "irgend so ein Hex-Kram", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
		ListIconGadget(1, 10, 10, 710, 505, "Offset", 80, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection | #PB_ListIcon_GridLines)
		SetGadgetFont(1, FontID(0)) ; <-- und hier den Font setzen
		For x = 1 To 16
			AddGadgetColumn(1, x, Hex(x - 1), 28)
		Next
		AddGadgetColumn(1, 17, "ASCII", 150)

		While Eof(FileID) = 0
			Line  = RSet(Hex(Loc(FileID)), 8, "0") + #LF$
			Ascii = ""
			x     = ReadData(FileID, @R, 16)
			For i = 0 To x - 1
				If R\b[i] >= 0 And R\b[i] < 32
					;nicht darstellbare Zeichen
					Ascii + "."
				Else
					Ascii + Chr(R\b[i])
				EndIf
				Line + RSet(Hex(R\b[i], #PB_Byte), 2, "0") + #LF$
			Next i
			If x < 16
				For i = x To 15
					Line + #LF$
				Next i
			EndIf
			AddGadgetItem(1, -1, Line + Ascii)
		Wend
		CloseFile(FileID)

		Center\mask = #LVCF_FMT
		Center\fmt  = #LVCFMT_RIGHT
		SendMessage_(GadgetID(1), #LVM_SETCOLUMN, 0, @Center)
		SetGadgetItemColor(1, -1, #PB_Gadget_BackColor, $DDDDDD, 0)
		For x = 1 To 16
			SetGadgetItemColor(1, -1, #PB_Gadget_FrontColor, $FF0000, x)
		Next


		Repeat

			Event = WaitWindowEvent()

		Until Event = #PB_Event_CloseWindow
	EndIf

EndProcedure

main()

Re: kleiner Hex Viewer

Verfasst: 12.08.2013 13:39
von SBond
Super, vielen Dank euch beiden ^^
das hilft mir weiter *freu*


Edit:

Ein Problem ist mir doch noch aufgefallen:
Ich möchte diesen Hex-Viewer in ein bestehendes Projekt einbinden, das als Unicode-Exe kompiliert wird.
Dadurch ändert sich aber die Ansicht des Textes. Ist es möglich den Text als ASCII-Zeichensatz anzeigen zu lassen?


Links: Unicode-Executable
Rechts: standard EXE (so soll die Ansicht sein)
Bild

habe es noch mit verschiedenen Schriftarten versucht, aber leider erfolglos :(
wisst ihr weiter?

lg
SBond

Re: kleiner Hex Viewer

Verfasst: 12.08.2013 17:37
von HeX0R
Ändere

Code: Alles auswählen

Ascii + Chr(R\b[i])
in

Code: Alles auswählen

Ascii + PeekS(@R\b[i], 1, #PB_Ascii)
Wird so aber vermutlich bei fetten Dateien merklich langsamer.

Ich dachte erst ein Ändern der Struktur in .a würde genügen, allerdings scheinen die Unicode-Zeichen zwischen 128 und 160 andere zu sein, als die Ascii-Zeichen.
Um das Ganze nicht unnötig zu verkomplizieren habe ich es eben mit der PeekS-Variante umgesetzt.

[Edit]
Hier noch die etwas schnellere Variante mit einer Look-Up-Tabelle:

Code: Alles auswählen

EnableExplicit

Structure _BYTES_
	b.a[16]
EndStructure

Procedure main()
	Protected FileName$, FileID, x, i, Event, Center.LV_COLUMN, R._BYTES_
	Protected Line.s, Ascii.s
	
	LoadFont(0, "lucida console", 9) ; oder was auch immer als Grösse....
	FileName$ = OpenFileRequester("Datei wählen", "", "", 0)
	FileID    = ReadFile(#PB_Any, FileName$)

	If FileID

		OpenWindow(0, 0, 0, 730, 525, "irgend so ein Hex-Kram", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
		ListIconGadget(1, 10, 10, 710, 505, "Offset", 80, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection | #PB_ListIcon_GridLines)
		SetGadgetFont(1, FontID(0)) ; <-- und hier den Font setzen
		For x = 1 To 16
			AddGadgetColumn(1, x, Hex(x - 1), 28)
		Next
		AddGadgetColumn(1, 17, "ASCII", 150)

		While Eof(FileID) = 0
			Line  = RSet(Hex(Loc(FileID)), 8, "0") + #LF$
			Ascii = ""
			x     = ReadData(FileID, @R, 16)
			For i = 0 To x - 1
				If R\b[i] >= 0 And R\b[i] < 32
					;nicht darstellbare Zeichen
					Ascii + "."
				CompilerIf #PB_Compiler_Unicode
				ElseIf R\b[i] > 127 And R\b[i] < 160
					Ascii + Chr(PeekI(?SwopAsciiCharacters + (R\b[i] - 128) * SizeOf(Integer)))
				CompilerEndIf	
				Else
					Ascii + Chr(R\b[i])
				EndIf
				Line + RSet(Hex(R\b[i], #PB_Byte), 2, "0") + #LF$
			Next i
			If x < 16
				For i = x To 15
					Line + #LF$
				Next i
			EndIf
			AddGadgetItem(1, -1, Line + Ascii)
		Wend
		CloseFile(FileID)

		Center\mask = #LVCF_FMT
		Center\fmt  = #LVCFMT_RIGHT
		SendMessage_(GadgetID(1), #LVM_SETCOLUMN, 0, @Center)
		SetGadgetItemColor(1, -1, #PB_Gadget_BackColor, $DDDDDD, 0)
		For x = 1 To 16
			SetGadgetItemColor(1, -1, #PB_Gadget_FrontColor, $FF0000, x)
		Next


		Repeat

			Event = WaitWindowEvent()

		Until Event = #PB_Event_CloseWindow
	EndIf

EndProcedure

main()

End

DataSection
	SwopAsciiCharacters:
	Data.i 8364, 129, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 141, 381, 143
	Data.i 144, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 157, 382, 376
EndDataSection

Re: kleiner Hex Viewer

Verfasst: 12.08.2013 17:56
von SBond
super, hat geklappt :D


vielen vielen Dank :mrgreen:
Ich wäre bestimmt nicht so schnell auf die Lösung gekommen.


lg
SBond