kleiner Hex Viewer

Für allgemeine Fragen zur Programmierung mit PureBasic.
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35

kleiner Hex Viewer

Beitrag 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
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Benutzeravatar
Bisonte
Beiträge: 2476
Registriert: 01.04.2007 20:18

Re: kleiner Hex Viewer

Beitrag 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)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
HeX0R
Beiträge: 3070
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: kleiner Hex Viewer

Beitrag 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()
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35

Re: kleiner Hex Viewer

Beitrag 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
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Benutzeravatar
HeX0R
Beiträge: 3070
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: kleiner Hex Viewer

Beitrag 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
Zuletzt geändert von HeX0R am 12.08.2013 17:58, insgesamt 2-mal geändert.
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35

Re: kleiner Hex Viewer

Beitrag von SBond »

super, hat geklappt :D


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


lg
SBond
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Antworten