Hello!
I've seen your code and here are some points you have to consider:
- HGui was build to create app with a GUIs using an hierarchical structure where everything starts from a root display, what you are doing is a bit of an hack but I'll help you to figure out how to use what you need

- The
:InputBoxNew() is an helper function that is used to quickly build a window on a living HGui app already defined, that's why using
:Free() or
:Close() methods it quits you app, HGui sees that the :InputBox() is the last opened window and terminate the application.
To avoid this problem there is a function used to switch this behaviour:
HGui.SetQuitOnLastWindow(value) -> Replace value with
False and you app will not be terminated.
But there is another problem: for HGui the InputBox window is the first display you opened (because it counts HGui windows) and the problem is in the
HGui.Window:New(), precisely in this code fragment:
Code: Select all
;===[ BUILD PROCESS ]========================================================
; Check if we are building the first window
Local first_window = IIf(TB.Count(HGui.Windows) = 0, True, False)
If first_window ;::::::::::::::::::::::::::::::::::::::::::: FIRST WINDOW :::
NewWin.private.HWId = 1
...
That explains why your display 1 is destroyed and used by the InputBox().
---
Now let's see how you can use the InputBox without going mad 
---
Solution (I think it's the best if your app can tolerate windows)
1) The
@DISPLAY command is used to initialize the display but it will be changed by HGui because it needs to initialize its stuff:
Code: Select all
main_window = HGui.Window:new(
{ title = "TEST",
name = "main",
position = { x = #CENTER, y = #CENTER },
size = { w = 800, h = 600 },
; Let's attach a confirmation requester when the user
; closes the main window clicking on the close gadget.
flags = { AutoClose = False },
events = { OnClose = Function(msg)
Local answer = SystemRequest("ARE YOU SURE?",
"Do you want to quit?",
"Yes|No")
If answer = 1 Then End
EndFunction
}
})
Since this is the first display it is the number 1, always.
2) Using the above code the InputBox will not destroy anymore your display, so there is no need to use the open/close display trick in
p_callback(Gadget) function which becames:
Code: Select all
Function p_callback(Gadget)
If gadget.Result.Cancel
SystemRequest("Cancelled", "You pressed Cancel!", "OK")
Else
SystemRequest("Text saved to file", "Saved to file:\n"..Gadget.Result.text, "OK")
StringToFile(Gadget.Result.text, "test.txt")
EndIf
Gadget.Result.Window:free()
EndFunction
3) InputBox() is a non-blocking method, this means that in this specific example you don't need to pause your current intervals or disable DoubleBuffer(), you just need to modify the
p_displaySomething() adding a
SelectDisplay():
Code: Select all
Function p_displaysomething()
SelectDisplay( 1, True)
xpos = Rnd(750)+1
ypos = Rnd(580)+1
xsize = Rnd(400)+1
ysize = Rnd(300)+1
Box(xpos, ypos, xsize, ysize, GetRandomColor())
SetFont(#SERIF, 24)
TextOut(550, 20, "CLICK HERE TO TEST")
Flip
EndFunction
Last thing: if you need a scroll bar for your text you can duplicate the :InputBox() method and create a new one that supports a scrollbar, drop me a line if you need help with that.
Your final program is not much different from your original one:
Code: Select all
@DISPLAY {Title = "HGUI test", Width = 800, Height = 600}
@INCLUDE "+Includes.hws"
@INCLUDE #INC_HGUI
BeginDoubleBuffer()
SetFillStyle(#FILLCOLOR)
main_window = HGui.Window:new(
{ title = "TEST",
name = "main",
position = { x = #CENTER, y = #CENTER },
size = { w = 800, h = 600 },
bgcolor = #RED,
; Let's attach a confirmation requester when the user
; closes the main window clicking on the close gadget.
flags = { AutoClose = False },
events = { OnClose = Function(msg)
Local answer = SystemRequest("ARE YOU SURE?",
"Do you want to quit?",
"Yes|No")
If answer = 1 Then End
EndFunction
}
})
Function p_displaysomething()
SelectDisplay( 1, True)
xpos = Rnd(750)+1
ypos = Rnd(580)+1
xsize = Rnd(400)+1
ysize = Rnd(300)+1
Box(xpos, ypos, xsize, ysize, GetRandomColor())
SetFont(#SERIF, 24)
TextOut(550, 20, "CLICK HERE TO TEST")
Flip
EndFunction
Function p_HandlerFunc(msg)
Switch(msg.Action)
Case "OnMouseDown":
xpos = MouseX()
ypos = MouseY()
If xpos > 600 And ypos < 100
p_inputbox
EndIf
Case "CloseWindow":
Wait(50)
End
EndSwitch
EndFunction
Function p_inputbox()
; EndDoubleBuffer()
; ClearInterval(1)
If Exists("test.txt")
OpenFile(1, "test.txt")
While Not Eof(1)
string$ = string$.."\n"..ReadLine(1)
Wend
CloseFile(1)
string$ = StripStr(string$)
Else
string$ = "Edit this"
EndIf
HGui.SetQuitOnLastWindow(False)
myWin = HGui.Window:InputBoxNew(
{ text = string$,
ok = "Ok",
cancel = { "Cancel" },
callbackOk = p_callback,
callbackCancel = p_callback,
;callbackClose = p_callback,
;--- some standard window's tags ---
size = { w = 600, h = 300 },
title = "The HGui Input Box...",
name = "inputBox1"
})
If HGui.windowExists("inputBox1")
myWin:Set({ title = "Textbox"}, True)
EndIf
EndFunction
Function p_callback(Gadget)
If gadget.Result.Cancel
SystemRequest("Cancelled", "You pressed Cancel!", "OK")
Else
SystemRequest("Text saved to file", "Saved to file:\n"..Gadget.Result.text, "OK")
StringToFile(Gadget.Result.text, "test.txt")
EndIf
Gadget.Result.Window:free()
EndFunction
main_window:render()
InstallEventHandler({ OnMouseDown = p_HandlerFunc, OnCloseWindow = p_HandlerFunc })
SetInterval(1, p_displaysomething, 100)
Repeat
WaitEvent()
Forever
---
Now that you use HGui to initialize you display have a look at all the things it has for you, you may be get rid of some of you event handlers and use the inbuilt ones, here is what the HGui window has to offer:
Code: Select all
/*---------------------------------------------------------
winObject = HGui.Window:new(options)
Create a new HGui window.
-----------------------------------------------------------
INPUT
options : A table used to override default values.
title : Window's title.
name : Unique window's name, if you omit this argument an unique name will be assigned to the window for you.
vsync : True|False
position : Window's position in the host screen.
x : Horizontal position (pixels). Defaults to #CENTER.
y : Vertical position (pixels). Defaults to #CENTER.
size : Window's size
w : Width in pixels. Defaults to 320.
h : Height in pixels. Defaults to 200.
sizemax : Maximum size the window can be resized to. Defaults to the host screen size.
w : Width in pixels. Defaults to 320.
h : Height in pixels. Defaults to 200.
sizemin : Minimum size the window can be resize to. Defaults to <size>.
w : Width in pixels. Defaults to 320.
h : Height in pixels. Defaults to 200.
cacheroot : Cache root gadget (True|False)
bgcolor : Background color
background : Image file name used to fill the background
bgtexture : Image file used as tile to fill the background
bggradient : Table used to define a multi-color gradient to fill the background
type : Gradient type : #LINEAR, #RADIAL, #CONICAL
angle : Gradient angle in degrees
colors : Gradient colors definition, it's atable composed by pairs [color]-[position]. Color is an RBG color value and position is a number in the 0-1 range. Note that the first color must have the position 0 and the last one the position 1.
hotkeys : A table with window's action hotkeys
hide : A key associated to the window:hide() method
show : A key associated to the window:show() method
activate : A key associated to the window:activate() method
close : A key associated to the window:close() method
open : A key associated to the window:open() method
customhotkeys : A table with custom hotkeys you can assign with your own function, each definition is a subtable with the following items:
qualifier : Key qualifier (LCONTROL, RCONTROL, etc...)
key : Assigned key
event : Event (OnKeyDown, ...)
callback : Callback function
flags : Window's flags
resizeable : Resizeable window? (True|False)
closeable : Closeable window? (True|False)
moveable : Moveable window? (True|False)
borderless : Borderless window? (True|False)
modal : Modal window? (True|False)
hidefromtaskbar : Hide from the taskbar (True|False)
hideable : Hideable window? (True|False)
autoclose : <False> to receive the event but to keep the window opened, you have to close it in your callback function.
events : Callback functions table
onclose : Called when the window is closed (passed params: eventMessage, windowObject)
onmove : Called when the window is move
onactivate : Called when the window get the focus
ondeactivate : Called when the window lost the focus
onhide : Called when the window is hided
onshow : Called when the window is showed
onsize : Called when the window is resized
ondrop : Called when a file is dropped into the window
dontopen : TRUE to create the window without opening
contextual : Contextual menu (same structure as .menu field)
menu : Top menu definition, please have a look at :menuSet() method for detailed informations.
OUTPUT
winObject : The window object created or FALSE if an error has occured.
---------------------------------------------------------*/
The alternative to this is to dynamically create the TextBox in the first display, but I think that the above method is simpler and requires less code modification.
Sorry for the very long post

Let me know if it's all fine!
Fabio