Page 1 of 2

Whats the size limitation for the StringGadget gadget?

Posted: Mon Jul 26, 2004 6:53 pm
by GeoTrail
Guess there is a size limitation for how big a text file can be when it is added to a StringGadget. When I try to add a 115 kb text file to the gadget my program crash.

Is there any way to get around this?

Posted: Mon Jul 26, 2004 7:02 pm
by Beach
64K is the limit.. Here is a thread that shows a way around it thanks to Mr. Fr34k :)

viewtopic.php?t=9186&highlight=64k+stringgadget

Posted: Mon Jul 26, 2004 7:06 pm
by GeoTrail
Thanks Beach.
Do I add SendMessage_(GadgetID(#String), #EM_LIMITTEXT, NewSize, 0) right after the gadget was created, or after the window has been called?

Posted: Mon Jul 26, 2004 7:19 pm
by Beach
I believe you can do it any time after the Gadget itself is created. I have used this technique before but I do not remember the sequence. Sorry.

Posted: Mon Jul 26, 2004 7:49 pm
by GeoTrail
I tried this

Code: Select all

StringGadgetSize.l = 104857600
SendMessage_(GadgetID(#Editor_0), #EM_LIMITTEXT, StringGadgetSize.l, 0)
but doesn't seem to have any effect. The program crashes when reading files bigger than 64 KB.

104857600 is just a test. Tried a lower number but had no effect.

Posted: Mon Jul 26, 2004 9:34 pm
by upnorth
For String Gadget:
SendMessage_(GadgetID(#String), #EM_LIMITTEXT, NewSize, 0)

For Editor Gadget:
SendMessage_(GadgetID(#Editor), #EM_EXLIMITTEXT, 0, NewSize)

You need to change your #EM_LIMITTEXT to #EM_EXLIMITTEXT and the last 2 parameters for the Editor Gadget are 0, Newsize not Newsize, 0

Hope this helps.

Posted: Mon Jul 26, 2004 9:49 pm
by GeoTrail
Well, when I first made the window dialog, I made it with a EditorGadget, but then I tried changing it to a StringGadget which I'm using now. Just didn't change the enumeration name.

Code: Select all

StringGadgetSize.l = 1048576
    If CreateGadgetList(WindowID())
      StringGadget(#Editor_0, 10, 30, 570, 430, "", #PB_String_MultiLine | #PB_String_ReadOnly)
      SetGadgetFont(#Editor_0, FontID1)
      SendMessage_(GadgetID(#Editor_0), #EM_LIMITTEXT, StringGadgetSize.l, 0)
    EndIf
That's how the string gadget code looks like.

And it's still not working :(

Posted: Mon Jul 26, 2004 9:56 pm
by freak
Do you read the file into on single string?
There is a limit of 64k for a PB string. So you'll have to either work with
a memory buffer, but that means you can't use PB commands to fill in the
Gadget, or your read the file line by line and fill the EditorGadget with
AddGadgetItem()

Timo

Posted: Mon Jul 26, 2004 10:00 pm
by GeoTrail
I've written a procedure that uses memory buffer to read the content of the text files.

Code: Select all

Procedure GetText(File$)
  Result = ReadFile(0, File$) : Debug "Result: "+Str(Result)
  Length = Lof() : Debug "Length of file: "+Str(Length)
  *MemoryBuffer = AllocateMemory(Length)
  LengthRead = ReadData(*MemoryBuffer, Length) : Debug "Length read: "+Str(LengthRead)
  Text.s = PeekS(*MemoryBuffer, LengthRead) : Debug "Text.s: "+Text
  SetGadgetText(#Editor_0, RTrim(Text))
  SetWindowTitle(#Window_0, AppName + " - " + GetFilePart(File$))
EndProcedure
I added RTrim because some files adds weird symbols to the StringGadget. Could that have something to do with the app crashing?

Posted: Mon Jul 26, 2004 10:40 pm
by GPI
All strings are limited, so PeekS() too....

Posted: Mon Jul 26, 2004 10:41 pm
by upnorth
I believe that PB's StringGadget is actually what Microsoft calls an Edit Control. According to Microsoft a single line Edit Control is limited to 32k and a multiline Edit Control is limited to 64K See this link:

http://msdn.microsoft.com/library/defau ... itctls.asp

However, I have been able to put a few megs of text in a PB EditorGadget after resetting the limit on it as shown above. The EditorGadget is actually a Microsoft Richedit Control I believe.

Posted: Mon Jul 26, 2004 11:11 pm
by GeoTrail
GPI, are there any other way I can get this done then?

upnorth, Not sure if the link worked. Just saw a page with lots of lines of links on it.

I just tried added the gadget resize code right above the code that inserts the content into the gadget but it still crashes

Code: Select all

Procedure GetText(File$) ; Procedure to read file content into buffer
  Result = ReadFile(0, File$) ; because of PB's 64 K string limit.
  Length = Lof() ; Get length of file for AllocateMemory.
  *MemoryBuffer = AllocateMemory(Length) ; Set buffer size.
  LengthRead = ReadData(*MemoryBuffer, Length) ; Read file to buffer.
  Text.s = PeekS(*MemoryBuffer, LengthRead) ; Add content of buffer to string.
  SendMessage_(GadgetID(#Editor_0), #EM_LIMITTEXT, StringGadgetSize.l, 0)
  SetGadgetText(#Editor_0, RTrim(Text.s))
  SetWindowTitle(#Window_0, AppName + " - " + GetFilePart(File$))
EndProcedure
This also doesn't work:

Code: Select all

Procedure GetText(File$) ; Procedure to read file content into buffer
  Result = ReadFile(0, File$) ; because of PB's 64 K string limit.
  Length = Lof() ; Get length of file for AllocateMemory.
  *MemoryBuffer = AllocateMemory(Length) ; Set buffer size.
  LengthRead = ReadData(*MemoryBuffer, Length) ; Read file to buffer.
  ;Text.s = PeekS(*MemoryBuffer, LengthRead) ; Add content of buffer to string.
  SendMessage_(GadgetID(#Editor_0), #EM_LIMITTEXT, StringGadgetSize.l, 0)
  ;SetGadgetText(#Editor_0, RTrim(Text.s))
  SetGadgetText(#Editor_0, PeekS(*MemoryBuffer, LengthRead))
  SetWindowTitle(#Window_0, AppName + " - " + GetFilePart(File$))
EndProcedure
Now I tried changing the StringGadget to a EditGadget

Code: Select all

Procedure GetText(File$) ; Procedure to read file content into buffer
  Result = ReadFile(0, File$) ; because of PB's 64 K string limit.
  Length = Lof() ; Get length of file for AllocateMemory.
  *MemoryBuffer = AllocateMemory(Length) ; Set buffer size.
  LengthRead = ReadData(*MemoryBuffer, Length) ; Read file to buffer.
  ;Text.s = PeekS(*MemoryBuffer, LengthRead) ; Add content of buffer to string.
  ;SendMessage_(GadgetID(#Editor_0), #EM_LIMITTEXT, StringGadgetSize.l, 0)
  SendMessage_(GadgetID(#Editor_0), #EM_EXLIMITTEXT, 0, StringGadgetSize)
  ;SetGadgetText(#Editor_0, RTrim(Text.s))
  SetGadgetText(#Editor_0, PeekS(*MemoryBuffer, LengthRead))
  SetWindowTitle(#Window_0, AppName + " - " + GetFilePart(File$))
EndProcedure
and still it crashes :(

Posted: Mon Jul 26, 2004 11:33 pm
by upnorth
I suggest you try ReadString() to read a line at a time from the file and AddGadgetItem() to add those lines to the EditorGadget one at a time. This should avoid the problem of trying to transfer the entire file at once.

I can confirm that the EditorGadget will hold a few megs at least as I have cut and pasted that much into one.

I can look into this more when I get home from work.

Posted: Mon Jul 26, 2004 11:40 pm
by fweil
Have a look at this ...

Code: Select all

Enumeration
  #Window_0
  #Editor_0
EndEnumeration

#MAX_STRING_LENGTH = $1000000

Structure StringBytes
 Bytes.b[#MAX_STRING_LENGTH]
EndStructure

Global AppName.s

Procedure ManipulationBufferSize(Bytes)
  PBStringBase.l = 0
  PBMemoryBase.l = 0
  !MOV Eax, dword [PB_StringBase]
  !MOV [Esp+4],Eax
  !MOV Eax, dword [PB_MemoryBase]
  !MOV [Esp+8],Eax
  HeapReAlloc_(PBMemoryBase, #GMEM_ZEROINIT, PBStringBase, Bytes)
  !MOV dword [PB_StringBase],Eax
  Debug "ManipulationBufferSize : max length of string set to : " + Str(Bytes)
  ProcedureReturn Bytes
EndProcedure

Procedure GetText(File$) ; Procedure to read file content into buffer 
  If ReadFile(0, File$)
      LengthOfFile = Lof()
      Text.s = Space(LengthOfFile)
      *Buffer.StringBytes = @Text
      ReadData(*Buffer, LengthOfFile)
      CloseFile(0)
  EndIf
  Debug Len(Text)
  SetGadgetText(#Editor_0, Text)
  SetWindowTitle(#Window_0, AppName + " - " + GetFilePart(File$)) 
EndProcedure

ManipulationBufferSize(#MAX_STRING_LENGTH)
  AppName = "EditorGadget"
  FileName.s = "C:\RECUP\Frw\Bible\BibleJNDdoc-Bible.txt"
  If OpenWindow(#Window_0,0,0,322,150,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,AppName) And CreateGadgetList(WindowID(0)) 
    EditorGadget (#Editor_0,8,8,306,133,#PB_Container_Raised) 
    GetText(FileName)
    Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow 
  EndIf 

..

Posted: Tue Jul 27, 2004 12:28 am
by NoahPhense
omg.. all this code.. someone finalize this thing and I'll make a library out
of it. So we don't have to have this conversation (again)..

- np