May 06, 2024, 04:10:33 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


RTSAVE in text mode adds garbage to string

Started by Jerry Muelver, February 17, 2008, 11:22:58 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Jerry Muelver

With the following code, type a word, do Save, save as test.txt. The @RTSAVE command looks clean in the debug message. Then reload file with Open. Do Save, and the messagebox shows garbarge characters appended to the end of the string used in RTSAVE. The file saves clean, but the RTSAVE to a var gets garbaged. I use a string saved from a RichText edit to build a big string, and don't need the appended garbage. I supposed I could use a signal character to mark the end of the contents, then cop off anything longer than that, or maybe get the length of the contents and use that to chop the RTSAVE string, but seems to me that shouldn't be necessary.

'demo of the rich edit control
'Requires EBASIC 1.0 or greater
'Compile as a WINDOWS target

DEF d1:Dialog
DEF textclr,size,weight,bold,flags,ret,retsave:INT
DEF fontname,oldfont,filename,filter,ptext[1600],crlf:STRING
DEF file1:FILE
'the default font properties
fontname = "Arial"
oldfont = fontname
size = 12
weight = 400
'filter for loading/saving files
filter = "Text file (*.txt)|*.txt||"
crlf = chr$(13) + chr$(10)

CREATEDIALOG d1,0,0,587,360,0x80C80080,0,"Rich Edit demo",&Handler
CONTROL d1,@RICHEDIT,"",7,35,570,294,0x50B010C4,1
CONTROL d1,@BUTTON,"",11,9,23,23,0x50000000,2
CONTROL d1,@BUTTON,"A",42,9,23,23,0x50000000,3
CONTROL d1,@BUTTON,"Mod",82,9,23,23,0x50000000,4

DOMODAL d1
END

SUB Handler
SELECT @MESSAGE
CASE @IDINITDIALOG
CENTERWINDOW d1
BEGINMENU d1
MENUTITLE "File"
MENUITEM "Save",0,6
MENUITEM "Load",0,7
MENUITEM "Print",0,11
SEPARATOR
MENUITEM "Quit",0,1
'
MENUTITLE "Edit"
MENUITEM "Undo",0,2
MENUITEM "Cut",0,3
MENUITEM "Copy",0,4
MENUITEM "Paste",0,5
'
MENUTITLE "Format"
MENUITEM "Subscript",0,8
MENUITEM "Superscript",0,9
MENUITEM "Normal",0,10
ENDMENU
'default font and color
CONTROLCMD d1,1,@RTSETDEFAULTFONT,fontname,size,0,0
CONTROLCMD d1,1,@RTSETDEFAULTCOLOR,RGB(0,0,0)
'margins
CONTROLCMD d1,1,@RTSETMARGINS,10,10
'7.5 inch line size
CONTROLCMD d1,1,@RTSETLINEWIDTH,770 * 15
'128K text limit
CONTROLCMD d1,1,@RTSETLIMITTEXT,128000
SETCONTROLCOLOR d1,2,0,RGB(255,0,0)
CASE @IDCONTROL
SELECT @CONTROLID
CASE 2:'Color
textclr = COLORREQUEST(d1,textclr)
CONTROLCMD d1,1,@RTSETSELCOLOR,textclr
SETFOCUS d1,1
CASE 3:'FONT
'flags = 0
fontname = FONTREQUEST(d1,size,weight,flags,textclr,oldfont)
if(len(fontname))
oldfont = fontname
if weight = 700 THEN bold = 1 ELSE bold = 0
CONTROLCMD d1,1,@RTSETSELFONT,fontname,size,bold,flags
CONTROLCMD d1,1,@RTSETSELCOLOR,textclr
SETFOCUS d1,1
endif
case 4
def mod:int
mod=controlcmd(d1,1,@rtgetmodified)
messagebox d1,str$(mod),"hi"
controlcmd d1,1,@rtsetmodified,0
ENDSELECT
CASE @IDMENUPICK
SELECT @MENUNUM
CASE 1:'Quit
CLOSEDIALOG d1,@IDOK
CASE 2:'Undo
CONTROLCMD d1,1,@RTUNDO
CASE 3:'Cut
CONTROLCMD d1,1,@RTCUT
CASE 4:'Copy
CONTROLCMD d1,1,@RTCOPY
CASE 5:'Paste
CONTROLCMD d1,1,@RTPASTE
CASE 6:'SAVE
ret = CONTROLCMD (d1,1,@RTGETMODIFIED)
ret = MESSAGEBOX(d1,"modified = " + str$(ret),"Modified?")
retsave = CONTROLCMD (d1,1,@RTSAVE,ptext,0)
ret = MESSAGEBOX(d1,str$(retsave)+crlf+ptext+"|","Dirty save")

filename = FILEREQUEST("Save file",d1,0,filter,"txt")
if(len(filename))
if(OPENFILE(file1,filename,"W")=0)
CONTROLCMD d1,1,@RTSAVE,file1,0
CLOSEFILE file1
endif
endif
CASE 7:'LOAD
filename = FILEREQUEST("Load file",d1,1,filter,"txt")
if(len(filename))
if(OPENFILE(file1,filename,"R")=0)
CONTROLCMD d1,1,@RTLOAD,file1,0
CLOSEFILE file1
controlcmd d1,1,@rtsetmodified,0
endif
endif
CASE 8:'Subscript
CONTROLCMD d1,1,@RTSETCHAROFFSET,-((size / 2) * 20)
CASE 9:'Superscript
CONTROLCMD d1,1,@RTSETCHAROFFSET,((size / 2) * 20)
CASE 10:'normal
CONTROLCMD d1,1,@RTSETCHAROFFSET,0
CASE 11:'Print
CONTROLCMD d1,1,@RTPRINT,0


ENDSELECT
CASE @IDMENUINIT
'only enable the Undo menu if there is something to..undo
ENABLEMENUITEM d1,2,CONTROLCMD(d1,1, @RTCANUNDO)
ENDSELECT
RETURN
ENDSUB

Ionic Wind Support Team

Zero your string before using with @RTSAVE.

DECLARE IMPORT,RtlZeroMemory(dest AS POINTER,numBytes AS INT)

...
RtlZeroMemory(ptext, 1600)
retsave = CONTROLCMD (d1,1,@RTSAVE,ptext,0)
Ionic Wind Support Team

Jerry Muelver

Thanks, Paul. I never would have figured THAT one out! I implemented the measure-contents, chop-string method with apparent success, but I'm going back in to do the string-zeroing Turley solution immediately.

Ionic Wind Support Team

Good ;)

The streaming functions of the RE controls (how it saves) doesn't terminate the buffer with a NULL.  Zeroing your strings is a good way to be sure the string is properly terminated.

Paul.

Ionic Wind Support Team

Jerry Muelver

Thanks for the explanation, Paul.

I think I see. Loading the string with non-null-terminated content overwrites previous string contents, and may stop short of the length of previous content, leaving the string with some garbage running up to the old string-size null. Letting the string to "" first, instead of "zeroing" it, just puts a null at the first character position, and leaves the old string contents and its null hanging around in memory after the new null. So, you can still get garbage. Zeroing the string wipes all that left-over stuff out before you load from the null-less richtext content, so there's nothing left over to create garbage.