wtf GUI Frameworks... rant I guess

Everything else that doesn't fall into one of the other PB categories.
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by Zach »

I might stick with your previous example :oops:
In this particular case, the editor gadget will always be read-only, and will always output text generated as RTF formatted, so having the check in there won't be necessary to me. But perhaps it will help someone else 8)

I do have one question though, I noticed in the compiler check there is a call to AllocateMemory() but I don't see any calls to free that memory later. Given that this is a procedure that is designed to print loads and loads of text to a box over time, wouldn't that result in a memory leak or something? Excuse my ignorance :!: I know this likely won't affect me, as I won'y be compiling under older versions anymore, but figured I would ask

mk-soft wrote:The RichEdit control has a check on the text "{\rtf".
If this text is recognized at the beginning, the text is interpreted as UTF8 and translated by Control.
Otherwise, the text is interpreted as Unicode text.

Update v1.03

Code: Select all

;-TOP

; *****************************************************************************
; AddTextRTF by mk-soft, v1.03, 25.03.2018

CompilerIf #PB_Compiler_Version < 550
  Procedure UTF8(Text.s)
    Protected *mem = AllocateMemory(StringByteLength(Text, #PB_UTF8) + 1)
    If *mem
      PokeS(*mem, Text, -1, #PB_UTF8)
    EndIf
    ProcedureReturn *mem
  EndProcedure
CompilerEndIf

Procedure AddTextRTF(Gadget, Text.s , NewLine=#True)
  If Left(Text, 5) <> "{\rtf "
    Text = "{\rtf " + Text + "}"
  EndIf
  CompilerIf #PB_Compiler_Unicode
    Protected hEdit = GadgetID(Gadget)
    Protected ndx = GetWindowTextLength_(hEdit)
    Protected *szBuffer = UTF8(Text)
    Protected hFocus = GetFocus_()
    If ndx And NewLine
      AddGadgetItem(Gadget, -1, "")
    EndIf
    SetFocus_(hEdit);
    SendMessage_(hEdit, #EM_SETSEL, ndx, ndx)
    SendMessage_(hEdit, #EM_REPLACESEL, 0, *szBuffer)
    SetFocus_(hFocus);
    FreeMemory(*szBuffer)
  CompilerElse
    AddGadgetItem(Gadget, -1 , Text)
  CompilerEndIf
EndProcedure

; *****************************************************************************
Image
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: wtf GUI Frameworks... rant I guess

Post by mk-soft »

After using the new functions UTF8(Text) and Ascii(Text) you have to free the memory yourself with FreeMemory(*mem).

This also happens in my code

These new features are available since version v5.50
The Procedure is only required for older versions.

P.S. Version 1.01 to Version 1.03
The only difference to the previous code is that the code now sets the identifier "{\rtf ... }" automatically if required.

Ups.
Small Bugfix...
Update v1.04

Code: Select all

;-TOP

; *****************************************************************************
; AddTextRTF by mk-soft, v1.04, 25.03.2018

CompilerIf #PB_Compiler_Version < 550
  Procedure UTF8(Text.s)
    Protected *mem = AllocateMemory(StringByteLength(Text, #PB_UTF8) + 1)
    If *mem
      PokeS(*mem, Text, -1, #PB_UTF8)
    EndIf
    ProcedureReturn *mem
  EndProcedure
CompilerEndIf

Procedure AddTextRTF(Gadget, Text.s , NewLine=#True)
  If Left(Text, 5) <> "{\rtf"
    Text = "{\rtf " + Text + "}"
  EndIf
  CompilerIf #PB_Compiler_Unicode
    Protected hEdit = GadgetID(Gadget)
    Protected ndx = GetWindowTextLength_(hEdit)
    Protected *szBuffer = UTF8(Text)
    Protected hFocus = GetFocus_()
    If ndx And NewLine
      AddGadgetItem(Gadget, -1, "")
    EndIf
    SetFocus_(hEdit);
    SendMessage_(hEdit, #EM_SETSEL, ndx, ndx)
    SendMessage_(hEdit, #EM_REPLACESEL, 0, *szBuffer)
    SetFocus_(hFocus);
    FreeMemory(*szBuffer)
  CompilerElse
    AddGadgetItem(Gadget, -1 , Text)
  CompilerEndIf
EndProcedure

; *****************************************************************************
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by Zach »

Hi MK. I didn't see your update before I tried to discern what was doing what in the code, but anyway I took some time to try and comment it myself without relying too much on MSDN and google.

Keeping in mind some of your changes aren't in here.. How close did I get ? :lol:

I'm planning to modify it slightly. I won't need the RTF check because my own <tag> to RTF converter function will take care of that, also I gotta disable the Newline functionality as for the purposes of my game, this would not be the correct place to implement line spaces. Under my old code, I implemented that via the navigation / screen printing system. Having the code here insert a linebreak all the time defeats some of the formatting, and specifying new line yes or no on every call to this function would be inefficient IMHO.

I suppose my only puzzling question is why there needs to be code for getting the window handle and setting focus (would PB have done this internally under my old code?) Would any of this focus grabbing code interfere with the user actively typing into the input box, or hitting hotkeys on the keyboard while the editor gadget is actively updating??

Also, can you explain to me how I might be able to hide the caret when the editor gadget is being manipulated by the user? I mean, still allow them to click somewhere and highlight text to copy etc. but hide the caret itself so it doesn't sit there blinking afterwards.

Code: Select all

Procedure AddTextRTF(Gadget, Text.s)                              ;// pass the Gadget name and text to be inserted.
  CompilerIf #PB_Compiler_Unicode
    Protected hEdit = GadgetID(Gadget)                            ;// Create a handle for the gadget to be modified
    Protected ndx = GetWindowTextLength_(hEdit)                   ;// Index the size of all the text in the editor gadget
    Protected *szBuffer = UTF8(Text)                              ;// Create a Pointer to the RTF text to be added, converted to UTF8 format
    Protected hFocus = GetFocus_()                                ;// Get a handle to the current window with keyboard focus
    If ndx
      AddGadgetItem(Gadget, -1, "")                               ;// Add a new line  (to prepare for new inserted text?)
    EndIf
    SetFocus_(hEdit);                                             ;// Set the focus to the editor gadget
    SendMessage_(hEdit, #EM_SETSEL, ndx, ndx)                     ;// Set the caret to the last line of the editor gadget
    SendMessage_(hEdit, #EM_REPLACESEL, 0, *szBuffer)             ;// Inserts the new text into the editor gadget
    SetFocus_(hFocus);                                            ;// Sets focus to the previously acquired window handlde (why???)
    FreeMemory(*szBuffer)                                         ;// Free the memory used by the Pointer
  CompilerElse
    AddGadgetItem(Gadget, -1 , Text)
  CompilerEndIf
EndProcedure
Image
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by Zach »

I just noticed a glaring bug I did not originally pick up on. This is present in all versions of the new code I am using and I'm not sure how to fix it.
There seems to be a problem with line returns. As illustrated in the linked image below.

It is not adding the line return after the room title, the room description begins on the same line, and then it adds the line return AFTER the room description, resulting in a single space break for some reason.
I thought maybe it had to do with the check for an ndex value so I removed the check for that but still no dice. The single space break is happening because as mentioned before, the line return that should come after the room title, is for some reason being applied after the room description - which also has a linebreak added. I tested this by changing NewLine=0 on the room description call and it remove the single space, but still added the line break properly.

I couldn't trace what was going on in the debugger visually (the window wouldn't draw/update until all AddTextRTF() items had been processed ).
The previous non-unicode code does not suffer from this issue

Image

edit: So far the only fix I've found is to comment out any checks for adding blank lines, etc from the AddTextRTF() Procedure, and as a test I modified the ProcedureReturn value

Code: Select all

ProcedureReturn header + input + "\line" + footer
So I guess the correct thing to do here would be to rewrite both stuff, possibly combining both procedures into a single one, with an optional value check (like flags that don't have to be specified) that defaults to a \line being inserted unless specifically told not to when called. The idea is this procedure will be called by several different PrintToScreen type Procedures, each with their own formatting requirements, etc. I feel this Procedure as a whole needs to be designed purely as an "format and then insert this RTF text and a \line break" and do nothing else with regards to logic checks for additional breaks or paragraph breaking, etc

Image
I could line break different rooms as you navigate by calling the AddTextRTF Procedure from a function designed to print rooms as you navigate, (called as part of any response to use movement or look commands).
That's kind of how I had it setup under the old code I lost.
I could even do something like give the user the option to echo input to the screen, and have it function as a breaking point between large blocks of text instead.

Image
Image
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: wtf GUI Frameworks... rant I guess

Post by mk-soft »

I had the focus setting from the example of MSDN. But it probably works without setting the focus.

Link: https://support.microsoft.com/de-de/hel ... it-control

Now NewLine standard is not active and I use the extension "\line" now too.

Code: Select all

;-TOP

; *****************************************************************************
; AddTextRTF by mk-soft, v1.05, 27.03.2018

CompilerIf #PB_Compiler_Version < 550
  Procedure UTF8(Text.s)
    Protected *mem = AllocateMemory(StringByteLength(Text, #PB_UTF8) + 1)
    If *mem
      PokeS(*mem, Text, -1, #PB_UTF8)
    EndIf
    ProcedureReturn *mem
  EndProcedure
CompilerEndIf

Procedure AddTextRTF(Gadget, Text.s , NewLine=#False)
  If Left(Text, 5) <> "{\rtf"
    Text = "{\rtf " + Text + "}"
  EndIf
  If NewLine
    Text = Left(Text, Len(text) - 1) + "\line}" 
  EndIf
  CompilerIf #PB_Compiler_Unicode
    Protected hEdit = GadgetID(Gadget)
    Protected ndx = GetWindowTextLength_(hEdit)
    Protected *szBuffer = UTF8(Text)
    SendMessage_(hEdit, #EM_SETSEL, ndx, ndx)
    SendMessage_(hEdit, #EM_REPLACESEL, 0, *szBuffer)
    FreeMemory(*szBuffer)
  CompilerElse
    AddGadgetItem(Gadget, -1 , Text)
  CompilerEndIf
EndProcedure

; *****************************************************************************
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by Zach »

Thanks for that update MK. I'm off to work but maybe I'll have something to show for all this tomorrow, my day off 8)
Image
Post Reply