RTF aus EditorGadget in String speichern

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Hyper
Beiträge: 194
Registriert: 19.04.2005 19:14

RTF aus EditorGadget in String speichern

Beitrag von Hyper »

Hallo Gefährten,

guten Abend. Ich habe eine Frage zum Thema RTF.

Ich möchte den Inhalt eines EditorGadgets mit Formatierungen
a) in einen String speichern und später
b) aus dem String heraus anzeigen.

Was funktioniert, ist b) das Einstellen der Strings in den Editor:

Code: Alles auswählen

; Aus dem Forum:
OpenWindow(0, 200, 200, 400, 200,"EditorGadget", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget)
CreateGadgetList(WindowID(0))
EditorGadget(0, 0, 0, WindowWidth(0), WindowHeight(0))

text$ = "{\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fmodern\fprq1\fcharset0 Courier New;}{\f1\fswiss\fprq2\fcharset0 Arial;}{\f2\fswiss\fprq2\fcharset0 Verdana;}}"
text$ = text$ + "{\colortbl ;\red255\green0\blue0;\red0\green128\blue0;\red0\green0\blue255;\red0\green0\blue0;}"
text$ = text$ + "\viewkind4\uc1\pard\f0\fs20 normal \cf1 rot\cf0  \cf2 gr\'fcn\cf0  \b fett\b0  \cf3\b fettblau \cf0\b0 normal\par "
text$ = text$ + "Zeilenumbruch \f1 Arial, \f2\fs28 Verdana\fs20 , \f0 Courier New\cf4\par "
text$ = text$ + "}"

SetGadgetText(0, text$) 
Bleibt noch a) in einen String speichern

Code: Alles auswählen

 Text$ = GetGadgetText( 0 ) 

funktioniert nicht, der Text wird ohne jede Formatierung in den String übernommen. Im Forum habe ich bislang nur Codes gefunden, um den Text direkt in eine Datei zu schieben. Ich bräuchte sozusagen ein:

Code: Alles auswählen

 Text$ = GetGadgetTextRTF( 0 ) 
Hat da jemand etwas zur Hand?
PB 5.72
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

>> Im Forum habe ich bislang nur Codes gefunden, um den Text direkt in eine Datei zu schieben.

na supi, ob Datei oder Speicher ist doch ejal...


ob es aber in nen einfachen String geht, hängt davon ab, wie RTF codiert ist.
wenn da Nuller drin vorkommen können, die fälschlich als Terminator interpretiert werden könnten,
kannst du es nicht als String speichern, no chance.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Hyper
Beiträge: 194
Registriert: 19.04.2005 19:14

Beitrag von Hyper »

Hallo Kaeru Gaman,

sorry, ich verstehe das nicht. Ich habe doch oben den Text auch aus einem String. Man muss ihn doch da auch wieder hineinbekommen, oder?
PB 5.72
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

den Text bekommst du ja auch in einen String, wie du selber geschrieben hast,

Code: Alles auswählen

Text$ = GetGadgetText( 0 ) 
und dann eben, völlig folgerichtig,
>> der Text wird ohne jede Formatierung in den String übernommen.

Text hat kein Format, sondern nur auseinanderfolgende Buchstaben. das ist ein String. eine Zeichenkette.

RTF enthält eben nicht nur Text, sondern auch Format-Daten.
Formatdaten können nun mal auch Zeichen enthalten, die als reiner Text etwas völlig anderes bedeuten.

deswegen kannst du sehr wahrscheinlich RTF nicht als String speichern,
und selbst wenn, kannst du den nicht als String debuggen oder irgendwo einfügen, dass man das Format sehen würde.

also musst du den in einen dafür reservierten Speicherbereich schreiben,
und auch von dort wieder als Rohdaten in das Editorgadget bringen,
nicht per SetGadgetText.

... und dafür hast du doch die Routine.
ob du es nun direkt in eine Datei schreibst oder in einen dafür allocierten Speicher, ist unerheblich.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
HeX0R
Beiträge: 3042
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:

Beitrag von HeX0R »

Code: Alles auswählen

Procedure Editor_StreamCallback(dwCookie, *pbBuff, cb, *pcb.LONG)
	Shared MyEditorResult.s

	MyEditorResult + PeekS(*pbBuff, cb)
	*pcb\l = cb

	ProcedureReturn 0
EndProcedure

Procedure.s GetGadgetTextRTF(Gadget)
	Protected stream.EDITSTREAM
	Shared MyEditorResult.s

	stream\pfnCallback = @Editor_StreamCallback()
	SendMessage_(GadgetID(Gadget), #EM_STREAMOUT, #SF_RTF | #SFF_PLAINRTF, @stream)
	
	ProcedureReturn MyEditorResult
EndProcedure

; Aus dem Forum:
OpenWindow(0, 200, 200, 400, 200,"EditorGadget", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget)
EditorGadget(0, 0, 0, WindowWidth(0), WindowHeight(0))

text$ = "{\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fmodern\fprq1\fcharset0 Courier New;}{\f1\fswiss\fprq2\fcharset0 Arial;}{\f2\fswiss\fprq2\fcharset0 Verdana;}}"
text$ = text$ + "{\colortbl ;\red255\green0\blue0;\red0\green128\blue0;\red0\green0\blue255;\red0\green0\blue0;}"
text$ = text$ + "\viewkind4\uc1\pard\f0\fs20 normal \cf1 rot\cf0  \cf2 gr\'fcn\cf0  \b fett\b0  \cf3\b fettblau \cf0\b0 normal\par "
text$ = text$ + "Zeilenumbruch \f1 Arial, \f2\fs28 Verdana\fs20 , \f0 Courier New\cf4\par "
text$ = text$ + "}"

SetGadgetText(0, text$)

While WaitWindowEvent() ! 16 : Wend
Debug GetGadgetTextRTF(0)
Benutzeravatar
Hyper
Beiträge: 194
Registriert: 19.04.2005 19:14

Beitrag von Hyper »

Hallo HeX0R,

vielen Dank! Muss für heut leider Schluss machen, aber ich teste es schnellstmöglich!
PB 5.72
Benutzeravatar
Hyper
Beiträge: 194
Registriert: 19.04.2005 19:14

Beitrag von Hyper »

Hallo HeXOR,

Dein Code funktioniert sehr gut! Vielen Dank!! Allerdings bekomme ich beim Einbau in meinem Programm einen Syntax Error bei

Code: Alles auswählen

Procedure Editor_StreamCallback(dwCookie, *pbBuff, cb, *pcb.LONG) 
Hier bin ich noch am Knobeln, waran das liegt.
PB 5.72
Benutzeravatar
Hyper
Beiträge: 194
Registriert: 19.04.2005 19:14

Re: RTF aus EditorGadget in String speichern

Beitrag von Hyper »

Hallo HeXOR,

war easy, hat nur die Deklaration der Inputparameter gefehlt. So klappt es:

Code: Alles auswählen

Procedure Editor_StreamCallback(dwCookie.l, *pbBuff.l, cb.l, *pcb.Long) 
Ich habe für den mehrfachen Aufruf der Prozedur noch eine Variablen-Initialisierung von MyEditorResult eingebaut:

Code: Alles auswählen

Procedure.s GetGadgetTextRTF(Gadget.l) 
  Protected stream.EDITSTREAM 
  Shared MyEditorResult.s 
  
  MyEditorResult     = ""         ; ++ Hyper
  
  stream\pfnCallback = @Editor_StreamCallback() 
  SendMessage_(GadgetID(Gadget), #EM_STREAMOUT, #SF_RTF | #SFF_PLAINRTF, @stream) 
  
  ProcedureReturn MyEditorResult 
EndProcedure
Muss MyEditorResult unbedingt global sein?
PB 5.72
Rokur
Beiträge: 167
Registriert: 29.12.2005 09:58
Computerausstattung: Intel Core2 Quad (4x2,4 GHz), 4096 MB RAM, GForce 8800GTX 786 MB
Windows XP 32 Bit, PureBasic 4.40 (x86)

Re: RTF aus EditorGadget in String speichern

Beitrag von Rokur »

Hyper hat geschrieben:Muss MyEditorResult unbedingt global sein?
MyEditorResult ist doch nicht global sondern shared. :?
WinXP 32 Bit, PureBasic 4.40 (x86)
Benutzeravatar
HeX0R
Beiträge: 3042
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: RTF aus EditorGadget in String speichern

Beitrag von HeX0R »

Hyper hat geschrieben:Hallo HeXOR,

war easy, hat nur die Deklaration der Inputparameter gefehlt. So klappt es:

Code: Alles auswählen

Procedure Editor_StreamCallback(dwCookie.l, *pbBuff.l, cb.l, *pcb.Long) 
Also daran kanns nicht gelegen haben, wenn man den Variablen keine Typenbezeichnung spendiert, wird eben der Standard genommen. Seit PB 4.2 oder 4.3 soll man das eh wenn möglich ohne Typenbezeichnung machen (oder .i), wegen der x64 Kompatibilität.
Hyper hat geschrieben:Muss MyEditorResult unbedingt global sein?
Nun, wie Rokur bereits bemerkte ist die Variable nicht global, sondern shared.
Allerdings ist vermutlich beides in deinem Fall nicht ganz nützlich.

Man kann es aber auch anders machen:

Code: Alles auswählen

Structure _CALLBACK_COOKIE_
	*Buffer
	Pos.l
EndStructure

Procedure Editor_StreamCallback(*dwCookie._CALLBACK_COOKIE_, *pbBuff, cb, *pcb.LONG)

	If *dwCookie\Pos + cb > MemorySize(*dwCookie\Buffer)
		*dwCookie\Buffer = ReAllocateMemory(*dwCookie\Buffer, *dwCookie\Pos + cb + SizeOf(CHARACTER))
	EndIf
	CopyMemory(*pbBuff, *dwCookie\Buffer + *dwCookie\Pos, cb)
	*dwCookie\Pos + cb
	*pcb\l = cb

	ProcedureReturn 0
EndProcedure

Procedure.s GetGadgetTextRTF(Gadget)
	Protected stream.EDITSTREAM, CC._CALLBACK_COOKIE_, Result.s

	CC\Buffer = AllocateMemory(2048)
	CC\Pos    = 0

	stream\pfnCallback = @Editor_StreamCallback()
	stream\dwCookie    = @CC
	SendMessage_(GadgetID(Gadget), #EM_STREAMOUT, #SF_RTF | #SFF_PLAINRTF, @stream)

	Result = PeekS(CC\Buffer, MemorySize(CC\Buffer))
	FreeMemory(CC\Buffer)
	ProcedureReturn Result
EndProcedure

; Aus dem Forum:
OpenWindow(0, 200, 200, 400, 200, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
EditorGadget(0, 0, 0, WindowWidth(0), WindowHeight(0))

text$ = "{\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fmodern\fprq1\fcharset0 Courier New;}{\f1\fswiss\fprq2\fcharset0 Arial;}{\f2\fswiss\fprq2\fcharset0 Verdana;}}"
text$ = text$ + "{\colortbl ;\red255\green0\blue0;\red0\green128\blue0;\red0\green0\blue255;\red0\green0\blue0;}"
text$ = text$ + "\viewkind4\uc1\pard\f0\fs20 normal \cf1 rot\cf0  \cf2 gr\'fcn\cf0  \b fett\b0  \cf3\b fettblau \cf0\b0 normal\par "
text$ = text$ + "Zeilenumbruch \f1 Arial, \f2\fs28 Verdana\fs20 , \f0 Courier New\cf4\par "
text$ = text$ + "}"

SetGadgetText(0, text$)

While WaitWindowEvent() ! 16 : Wend
Debug GetGadgetTextRTF(0)
Antworten