PB IDE Werkzeug: CodeReplacer (speziell für PureForm-Nutzer)

Anwendungen, Tools, Userlibs und anderes nützliches.
Benutzeravatar
Kurzer
Beiträge: 1614
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

PB IDE Werkzeug: CodeReplacer (speziell für PureForm-Nutzer)

Beitrag von Kurzer »

Folgendes IDE Werkzeug ist aus der Not heraus entstanden.

Kurz zur Motivation des ganzen:
Ich erstelle meine Fensteroberflächen sehr gern mit dem leider nicht mehr supporteten Form-Designer "PureForm" von Gnozal. Mit dem integrierten Designer von PureBasic komme ich irgendwie nicht klar.

Nun ist es leider so, dass PureForm nicht mehr in jedem Fall gültigen Code für die aktuellen PB Versionen erzeugt. Da PureForm diesbezüglich nicht anpassbar ist und Gnozal alle Daten in PureForm verschlüsselt hat, gibt es eigentlich nur eine Möglichkeit, wenn man bei PureForm bleiben möchte. Man muss den erzeugten GUI Sourcecode jedes mal anpassen.
Damit ich das nicht immer manuell machen muss, habe ich ein Werkzeug dafür geschrieben (was man sicherlich auch für andere Zwecke nutzen kann).

Das Tool liest die entsprechende Quellcodedatei ein, führt darin Stringersetzungen aus und scheibt die bearbeitete Datei unter dem gleichen Namen wieder auf Platte. Die originale Quellcodedatei wird dabei unter dem alten Namen + ".bak" gesichert.

In meinem Fall ersetzt es also veraltete GUI Befehle mit den aktuellen Befehlen von PB 5.x. Die Ersetzungen sind in einer externen Datei definiert und somit erweiterbar.

Ich habe das Tool so eingerichtet, dass es im aktuellen Projekt- oder Quellcodeordner die Datei "GUI.pbi" bearbeitet. Ich nenne meine GUI-Includes immer so, aber der Dateiname ist ja in der Werkzeugkonfiguration anpassbar. Die genaue Einrichtung in der IDE sieht so aus - die Ausführung habe ich mir auf den Shortcut ALT+C gelegt.

Bild

Das Tool (ich habe es CodeReplacer.exe genannt) liegt bei mir im PureBasic-Verzeichnis. Dazu gehört dann noch eine Datei, die die Ersetzungen enthält. Das ganze sieht dann in etwa so aus:

Bild

Der Inhalt der Datei könnte so aussehen:

Code: Alles auswählen

# ; <- This first, single character defines the delimiter and must be the very first character in this file!

; After the definition of the delimiter you can add comments using the ; char.
; All text after the first ";" in a line will be ignored

; Also empty lines or lines with only "space" character will be ignored
; The replacement definition-lines must have the following format: 
; The string to be replaced followed by the delimiter and the replacestring. Please use no spaces, except they are needed part of the strings.

; All strings must be encoded in ASCII format!

Frame3DGadget(#FrameGadget(
Das allererste Zeichen in dieser Datei stellt das Trennzeichen dar mit dem "alter String" und "neuer String" getrennt werden. Im Beispiel oben ist das die #.
Danach können sofort die Zeilen mit den Ersetzungen kommen, die in folgendem Format vorliegen müssen:

Code: Alles auswählen

AlterString Trennzeichen NeuerString
Alles ohne Leerzeichen, direkt aneinander gehängt.
Im Beispiel oben haben wir also
Alter String = Frame3DGadget(
Tennzeichen = #
Neuer String = FrameGadget(

In der Praxis sieht das bei mir dann so aus, dass ich in PureForm etwas an der GUI.pbi ändere (aslo den Code aus PureForm speichere), dann wechsel ich in die PB IDE in einen Tab, in dem mein Projekt offen ist und drücke dann ALT+C.
Es erscheint dann kurz das Infofenster und die GUI-Datei ist an die aktuelle PB Version angepasst. Ggf. meldet PB dann noch, dass die Datei extern verändert wurde und ob sie neu eingelesen werden soll.

Das Tool erzeugt bei jedem Lauf eine Backupdatei des Quellcodes der bearbeitet wird.

Bild

Aber Vorsicht, das passiert immer. Wenn man also zweimal hintereinander die gleiche Datei bearbeiten lässt, dann hat man sich das Backup natürlich übergebügelt und beide Dateien haben den selben Inhalt.

So, viel geschwafelt... jetzt folgt code. :)

CodeReplacer:

Code: Alles auswählen

EnableExplicit

Enumeration 
	#InFile
	#OutFile
	#DefinitionsFile
EndEnumeration

Structure Replace
	OldString.s
	NewString.s
EndStructure

Global.i iNumOfParams, iBeginOfComment, iFormat = #PB_Ascii
Global.s sInFile, sDefinitionsFile, sDelimiter, sLine, sInFileBody, sError

iNumOfParams = CountProgramParameters()

If iNumOfParams = 2
	If OpenWindow(0, #PB_Ignore, #PB_Ignore, 400, 50, "CodeReplacer by Kurzer", #PB_Window_Tool|#PB_Window_ScreenCentered) = 0
		sError = "Das Infofenster konnte nicht ge÷ffnet werden."
		;sError = "Can't open the Infowindow."
		Goto ErrorWindow
	EndIf
	; Parameter abfragen / Get the parameters
	sInFile=Trim(Trim(ProgramParameter(0), " "), ",")
	sDefinitionsFile=Trim(Trim(ProgramParameter(1), " "), ",")
	
	; Status im Fenster anzeigen / Show status in the window
	TextGadget(0, 5, 5, 390, 40, "Verarbeite Codedatei '" + sInFile + "'", #PB_Text_Center) 
	;TextGadget(0, 5, 5, 390, 40, "Processing sourcefile '" + sInFile + "'", #PB_Text_Center) 
	While WindowEvent() : Wend
	
	; Definitionsfile ÷ffnen / Open Definitionfile
	If ReadFile(#DefinitionsFile, sDefinitionsFile, #PB_File_SharedRead) = 0
		sError = "Die Ersetzungsdatei kann nicht ge÷ffnet werden: '" + sDefinitionsFile + "'"
		;sError = "Can't open the file with replacements '" + sDefinitionsFile + "'"
		Goto ErrorDefinitionFile
	EndIf
	
	; Trennzeichen lesen / Read the delimiter
	sDelimiter = Left(ReadString(#DefinitionsFile, #PB_Ascii), 1)
	If sDelimiter ="" 
		sError = "Es ist kein Trennzeichen gefunden!" 
		;sError = "No Delimiter is defined!" 
		Goto ErrorDelimiter
	EndIf
	
	; Ersetzungsliste f³llen / Fill the ReplacementList
	NewList ReplaceList.Replace()
	While Not Eof(#DefinitionsFile)
		sLine = ReadString(#DefinitionsFile, #PB_Ascii) 
		iBeginOfComment = FindString(sLine, ";")
		
		If iBeginOfComment = 1 Or Trim(sLine) = ""
			Goto NextLine
		ElseIf iBeginOfComment > 1
			sLine = Left(sLine, iBeginOfComment)
		EndIf
		
		If AddElement(ReplaceList()) = 0
			sError = "Nicht genug Speicherplatz f³r die ReplaceListe vorhanden" 
			;sError = "Not enough memory for the replacement list" 
			Goto ErrorReplaceList
		EndIf
		ReplaceList()\OldString = StringField(sLine, 1, sDelimiter)
		ReplaceList()\NewString = StringField(sLine, 2, sDelimiter)
		NextLine:
	Wend
	
	If ListSize(ReplaceList()) = 0
		sError = "Es sind keine Ersetzungen definiert worden in Datei '" + sDefinitionsFile + "'"
		;sError = "No replacements are defined in file '" + sDefinitionsFile + "'"
		Goto ErrorReplaceList
	EndIf
	
	; Codedatei einlesen / Reading the sourcefile
	If ReadFile(#InFile, sInFile, #PB_File_SharedRead) = 0
		sError = "Die Codedatei kann nicht ge÷ffnet werden: '" + sInFile + "'"
		;sError = "Can't open the sourcefile '" + sInFile + "'"
		Goto ErrorInFile
	EndIf
	
	; Die komplette Datei in einen String lesen / Read the whole file into a string
	iFormat = ReadStringFormat(#InFile)
	sInFileBody = ReadString(#InFile, iFormat|#PB_File_IgnoreEOL) 
	CloseFile(#InFile)
	
	If sInFileBody = ""
		sError = "Fehler beim Lesen der Codedatei '" + sInFile + "'"
		;sError = "Error while reading the sourcefile '" + sInFile + "'"
		Goto ErrorInFile
	EndIf
	
	; Alle Ersetzungen im String durchf³hren / Perform all replacements within string	
	; Es wird die Gross-/Kleinschreinbung beachtet / The search/replace-action is casesensitiv!
	ForEach ReplaceList()
		sInFileBody = ReplaceString(sInFileBody, ReplaceList()\OldString, ReplaceList()\NewString, #PB_String_CaseSensitive)
	Next
	
	; Originale Codedatei sichern / Making a backup of the original sourcefile
	DeleteFile(sInFile + ".bak")
	RenameFile(sInFile, sInFile + ".bak")
	
	; Neue Codedatei erzeugen / Creating a new the sourcefile
	If OpenFile(#OutFile, sInFile) = 0
		sError = "Die Codedatei kann nicht f³r den Schreibzugriff ge÷ffnet werden: '" + sInFile + "'"
		;sError = "Can't open the sourcefile for writing '" + sInFile + "'"
		Goto ErrorInFile
	EndIf
	
	WriteString(#OutFile, sInFileBody, iFormat)
	
	CloseFile(#DefinitionsFile)
	CloseFile(#OutFile)
	FreeList(ReplaceList())
	
	; Eine kurze Pause, damit man den Text im Fenster lesen kann / A short delay so one can read the text in the window
	Delay(500)
	FreeGadget(0)
	CloseWindow(0)
	Goto Exit
EndIf

MessageRequester("Hinweis", "Dieses Programm ben÷tigt 2 Parameter:"+#LF$+#CR$+#LF$+#CR$+"  1) Die zu bearbeitende Quellcodedatei"+#LF$+#CR$+"  2) Die Datei mit den Ersetzungsstrings")
;MessageRequester("Hinweis", "This program needs two parameters:"+#LF$+#CR$+#LF$+#CR$+"  1) The sourcefile to be processed"+#LF$+#CR$+"  2) the file with the replacement strings")
Goto Exit

ErrorInFile:
ErrorReplaceList:
FreeList(ReplaceList())

ErrorDelimiter:
CloseFile(#DefinitionsFile)

ErrorDefinitionFile:
CloseWindow(0)

ErrorWindow:
MessageRequester("Fehler", sError)

Exit:
End
Das Programm benötigt zwei Parameter:
CodeReplacer "Pfad und Name der QuellcodeDatei" "Pfad und Name der Datei mit den Ersetzungen"

Also:
- Sourcecode oben zu einer "CodeReplacer.exe" kompilieren
- Ersetzungsdatei erstellen
- CodeReplacer.exe und Ersetzungsdatei in ein Verzeichnis für PB Tools kopieren
- CodeReplacer als Werkzeug einrichten und dabei den von Dir benutzten Dateinamen für die von PureForm erzeugte Includedatei angeben.
Zuletzt geändert von Kurzer am 28.11.2015 22:40, insgesamt 1-mal geändert.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2023: 56 Jahre.
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: PB IDE Werkzeug: CodeReplacer (speziell für PureForm-Nut

Beitrag von RSBasic »

Gute Idee :allright:
Ich nutze zwar kein PureForm, weil ich meine Benutzeroberfläche wie in alten Zeiten selber schreibe und ich damit am besten klar komme, aber vielleicht verwende ich dein Tool für andere Zwecke.
Aber für die anderen PureForm-Nutzer ist dein Tool bestimmt sehr nützlich.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Antworten