Catch RTF from editor gadget
- Joakim Christiansen
- Addict
- Posts: 2452
- Joined: Wed Dec 22, 2004 4:12 pm
- Location: Norway
- Contact:
Catch RTF from editor gadget
I need to be able to catch the RTF from my editor gadget and put it inside another editor gadget.
I like logic, hence I dislike humans but love computers.
- Thorsten1867
- Addict
- Posts: 1372
- Joined: Wed Aug 24, 2005 4:02 pm
- Location: Germany
Hilft dir speichern und laden weiter?
Code: Select all
Procedure StreamFileIn_Callback(hFile, pbBuff, cb, pcb)
ProcedureReturn ReadFile_(hFile, pbBuff, cb, pcb, 0)!1
EndProcedure
Procedure StreamFileOut_Callback(hFile, pbBuff, cb, pcb)
ProcedureReturn WriteFile_(hFile, pbBuff, cb, pcb, 0)!1
EndProcedure
Procedure Editor_Load(EGid.l, File.s)
Protected StreamData.EDITSTREAM
Protected FileID.l
FileID = ReadFile(#PB_Any, File)
If FileID
StreamData\dwCookie = FileID(FileID)
StreamData\dwError = #Null
StreamData\pfnCallback = @StreamFileIn_Callback()
If UCase(GetExtensionPart(File)) = "RTF"
SendMessage_(GadgetID(EGid), #EM_STREAMIN, #SF_RTF, @StreamData)
Else
SendMessage_(GadgetID(EGid), #EM_STREAMIN, #SF_TEXT, @StreamData)
EndIf
CloseFile(FileID)
EndIf
EndProcedure
Procedure Editor_Save(EGid.l,File.s)
Protected StreamData.EDITSTREAM
Protected FileID.l
If File <> ""
FileID = CreateFile(#PB_Any, File)
If FileID
StreamData\dwCookie = FileID(FileID)
StreamData\dwError = #Null
StreamData\pfnCallback = @StreamFileOut_Callback()
If UCase(GetExtensionPart(File)) = "RTF"
SendMessage_(GadgetID(EGid), #EM_STREAMOUT, #SF_RTF, @StreamData)
Else
SendMessage_(GadgetID(EGid), #EM_STREAMOUT, #SF_TEXT, @StreamData)
EndIf
CloseFile(FileID)
EndIf
Else
ProcedureReturn 0
EndIf
EndProcedure
Translated with http://www.DeepL.com/Translator
Download of PureBasic - Modules
Download of PureBasic - Programs
[Windows 11 x64] [PB V5.7x]
Download of PureBasic - Modules
Download of PureBasic - Programs
[Windows 11 x64] [PB V5.7x]
- Thorsten1867
- Addict
- Posts: 1372
- Joined: Wed Aug 24, 2005 4:02 pm
- Location: Germany
Or try it with the clipboard:
Code: Select all
Procedure EditorGadgetSelectAll(Gadget_ID)
; Select the whole Text of the EditorGadget
RangeAll.CHARRANGE\cpMin = 0
RangeAll\cpMax = -1
ProcedureReturn SendMessage_(GadgetID(Gadget_ID),#EM_EXSETSEL,0,@RangeAll) ; Select All
EndProcedure
Procedure EditorGadgetCOPY(Gadget_ID)
ProcedureReturn SendMessage_(GadgetID(Gadget_ID), #WM_COPY, 0, 0)
EndProcedure
Procedure EditorGadgetPASTE(Gadget_ID)
ProcedureReturn SendMessage_(GadgetID(Gadget_ID), #EM_PASTESPECIAL, 0, 0)
EndProcedure
Translated with http://www.DeepL.com/Translator
Download of PureBasic - Modules
Download of PureBasic - Programs
[Windows 11 x64] [PB V5.7x]
Download of PureBasic - Modules
Download of PureBasic - Programs
[Windows 11 x64] [PB V5.7x]
- Joakim Christiansen
- Addict
- Posts: 2452
- Joined: Wed Dec 22, 2004 4:12 pm
- Location: Norway
- Contact:
Thank you for your help, but I needed something a little different.
So I just put together some shit:
It also work with:
So I don't need the Editor_SetRTF() actually.
So I just put together some shit:
Code: Select all
Procedure GetRTFCallback(dwCookie.l,pbBuff.l,cb.l,*pcb)
CopyMemory(pbBuff,dwCookie,cb)
EndProcedure
Procedure SetRTFCallback(dwCookie.l,pbBuff.l,cb.l,*pcb)
PokeS(pbBuff,PeekS(dwCookie))
EndProcedure
Procedure Editor_GetRTF(Gadget.l,Adress.l)
Protected Stream.EDITSTREAM
Stream\dwCookie = Adress
Stream\pfnCallback = @GetRTFCallback()
SendMessage_(GadgetID(Gadget),#EM_STREAMOUT,#SF_RTF,@Stream)
EndProcedure
Procedure Editor_SetRTF(Gadget.l,Adress.l)
Protected Stream.EDITSTREAM
Stream\dwCookie = Adress
Stream\pfnCallback = @SetRTFCallback()
SendMessage_(GadgetID(Gadget),#EM_STREAMIN,#SF_RTF,@Stream)
EndProcedure
Code: Select all
*MyString = AllocateMemory(200)
;Copy it to buffer
Editor_GetRTF(#Editor,*MyString)
ClearGadgetItemList(#Editor) ;Clear the gadget
;Write the buffer
Editor_SetRTF(#Editor,*MyString)
Code: Select all
SetGadgetText(#Editor,PeekS(*MyString))
I like logic, hence I dislike humans but love computers.
Joakim, it is possible that Windows will not send all the rtf content to your GetRTFCallback() procedure in one go. It is quite possible (and very probable!) that it will call the function repeatedly, each time sending just a fraction of the total content.
Each time the callback is called, the 'cb' variable holds the number of bytes which Windows sends to your procedure (if zero then the transfer is complete and you must return non-zero to complete the process). You should place the actual number of bytes transferred each time in the address pointed to by *pcb. Of course, you should also update the address of your memory buffer to write to each time.
In fact I've just tested some very similar code that I use and the corresponding callback was called twice on a particular gadget whose rtf content I saved.
Each time the callback is called, the 'cb' variable holds the number of bytes which Windows sends to your procedure (if zero then the transfer is complete and you must return non-zero to complete the process). You should place the actual number of bytes transferred each time in the address pointed to by *pcb. Of course, you should also update the address of your memory buffer to write to each time.
In fact I've just tested some very similar code that I use and the corresponding callback was called twice on a particular gadget whose rtf content I saved.
I may look like a mule, but I'm not a complete ass.
- Joakim Christiansen
- Addict
- Posts: 2452
- Joined: Wed Dec 22, 2004 4:12 pm
- Location: Norway
- Contact:
So it would have to be something like this?
Do you know any easy way of just getting the size of all the data that will be sendt?
Then I could just do:
Code: Select all
Procedure.l GetRTFCallback(dwCookie.l,pbBuff.l,cb.l,*pcb.LONG)
Static Length.l
Debug 1
If cb = 0
Length = 0 ;reset
Else
CopyMemory(pbBuff,dwCookie+Length,cb)
Length + cb
EndIf
*pcb\l = cb
ProcedureReturn 0
EndProcedure
Then I could just do:
Code: Select all
Define *Buffer = AllocateMemory(GetRTFSize())
GetRTF(#Editor,*Buffer)
I like logic, hence I dislike humans but love computers.
The following ensures that windows stops calling the callback when all the data is transferred:
This is more or less what I use.
Code: Select all
Procedure.l GetRTFCallback(dwCookie.l,pbBuff.l,cb.l,*pcb.LONG)
Protected result
Static Length.l
CopyMemory(pbBuff,dwCookie+Length,cb)
Length + cb
*pcb\l = cb
If cb = 0
result=1 ;All done! Returning 1 will cancel further calls to this proc.
EndIf
ProcedureReturn result
EndProcedure
I don't think so. Since editor gadgets can embed OLE objects (such as images, Excel sheets etc.) determining the actual size of the rtf content before streaming would be extremely difficult. Besides which, the editor gadget does not hold it's content in rtf format internally and only converts it when we stream the contents out as you are doing.Do you know any easy way of just getting the size of all the data that will be sendt?
I may look like a mule, but I'm not a complete ass.
- Joakim Christiansen
- Addict
- Posts: 2452
- Joined: Wed Dec 22, 2004 4:12 pm
- Location: Norway
- Contact:
- Joakim Christiansen
- Addict
- Posts: 2452
- Joined: Wed Dec 22, 2004 4:12 pm
- Location: Norway
- Contact:
- Joakim Christiansen
- Addict
- Posts: 2452
- Joined: Wed Dec 22, 2004 4:12 pm
- Location: Norway
- Contact:
Well, here is the final result:
I did much testing, even with large files (75kb).
And here cb never returns 0, and if it does it should enough to just copy that to *pcb and it will end properly.
Maybe you need the Result = 1 stuff on other computers but I didn't need it.
But it's all there commented away if you need it.
Code: Select all
Global RTFLength
Procedure.l GetRTFCallback(dwCookie.l,pbBuff.l,cb.l,*pcb.LONG)
;Protected Result.l
;If cb = 0
;Result = 1
;Else
CopyMemory(pbBuff,dwCookie+RTFLength,cb)
RTFLength + cb
;EndIf
*pcb\l = cb
ProcedureReturn 0;Result
EndProcedure
Procedure.l GetRTFLenCallback(dwCookie.l,pbBuff.l,cb.l,*pcb.LONG)
RTFLength + cb
*pcb\l = cb
ProcedureReturn 0
EndProcedure
Procedure GetRTF(Gadget.l,Adress.l)
Protected Stream.EDITSTREAM
Stream\dwCookie = Adress
Stream\pfnCallback = @GetRTFCallback()
RTFLength = 0
SendMessage_(GadgetID(Gadget),#EM_STREAMOUT,#SF_RTF,@Stream)
EndProcedure
Procedure.l GetRTFLen(Gadget.l)
Protected Stream.EDITSTREAM
Stream\pfnCallback = @GetRTFLenCallback()
RTFLength = 0
SendMessage_(GadgetID(Gadget),#EM_STREAMOUT,#SF_RTF,@Stream)
ProcedureReturn RTFLength
EndProcedure
FreeMemory(*Buffer)
*Buffer = AllocateMemory(GetRTFLen(#Editor))
GetRTF(#Editor,*Buffer)
ClearGadgetItemList(#Editor)
SetGadgetText(#Editor,PeekS(*Buffer))
And here cb never returns 0, and if it does it should enough to just copy that to *pcb and it will end properly.
Maybe you need the Result = 1 stuff on other computers but I didn't need it.
But it's all there commented away if you need it.

I like logic, hence I dislike humans but love computers.