Page 1 of 2
HTML GUI (PB 4.10+)
Posted: Wed Jun 20, 2007 1:09 pm
by Rescator
This is a rather rough example but interesting anyway.
Quickly explained it acts almost like a About window/box but uses the webgadget,
the window can be closed normally or by clicking a inline close link.
Hopefully this gives you an idea on how to make a HTML GUI.
If your program is fully HTML GUI driven it would be best to have the window loop in the main program loop instead, this example was just a test.
This example also passes the html directly, it may be better to use local html gui files for GUI's with larger html "pages".
I also want to thank the PB Team for adding the callback as that is the key to making a HTML GUI as it allows custom things like "cmd:close"
Code: Select all
EnableExplicit
Procedure.l AboutHtml_NavigationCallback(gadget,url$)
Protected window.l
If url$="cmd:close"
window=GetGadgetData(gadget)
If IsWindow(window)
CloseWindow(window)
EndIf
ProcedureReturn #False
EndIf
ProcedureReturn #True
EndProcedure
Procedure.l AboutHtml(title$,msg$,width.l=400,height.l=300,parent.l=#Null)
Protected window.l,flags.l,web.l,button.l,result.l=#False,parentid.l=#Null,event.l
flags=#PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_Invisible
If parent
flags|#PB_Window_WindowCentered
Else
flags|#PB_Window_ScreenCentered
EndIf
If parent
parentid=WindowID(parent)
EndIf
window=OpenWindow(#PB_Any,#PB_Ignore,#PB_Ignore,width,height,title$,flags,parentid)
If window
If CreateGadgetList(WindowID(window))
web=WebGadget(#PB_Any,0,0,WindowWidth(window),WindowHeight(window),"")
If web
SetGadgetItemText(web,#PB_Web_HtmlCode,msg$)
SetGadgetData(web,window)
SetGadgetAttribute(web,#PB_Web_NavigationCallback,@AboutHtml_NavigationCallback())
HideWindow(window,#False)
Repeat
If IsWindow(window) ;We must check as it may have been closed in the callback
event=WaitWindowEvent()
Else
event=#PB_Event_CloseWindow ;If window is gone we must quit the loop
EndIf
Until event=#PB_Event_CloseWindow
result=#True
EndIf
EndIf
If IsWindow(window)
CloseWindow(window)
EndIf
EndIf
ProcedureReturn result
EndProcedure
;A simple example
AboutHtml("Test","<a href="+#DQUOTE$+"cmd:close"+#DQUOTE$+">Close Window</a>")
PS! If others have alternative or improved examples please post those in this thread so it's easier for beginners to find them using the forum search

Posted: Wed Jun 20, 2007 1:18 pm
by srod
Interesting.
I've never used a web gadget for much of anything really, but that's pretty cool and very instructive.
Thanks.
Posted: Wed Jun 20, 2007 1:18 pm
by Num3
Eheheh
I'm working on this too, using javascript and forms with data...
I'll clean up the code later and post a form example!
Posted: Wed Jun 20, 2007 1:19 pm
by dracflamloc
cool tip =)
Posted: Wed Jun 20, 2007 1:45 pm
by Inf0Byt3
Hi! I made this too a while ago. Let me find that old code and i'll post it here

.
Posted: Wed Jun 20, 2007 1:54 pm
by netmaestro
Fabulous, the possibilities get very cool indeed! Thanks for posting.
Posted: Wed Jun 20, 2007 2:09 pm
by Rescator
Looking forward to that Num3, as it seems the navigationcallback do not catch any GET forms? (intentional or a slip by the PB team? *looks at freak*)
Posted: Wed Jun 20, 2007 2:26 pm
by Inf0Byt3
Take a look here. Remember i made this code way back so it could be unusable.
Screenshot:
Download here:
File:1->
HTMLMenu.rar

Posted: Wed Jun 20, 2007 2:36 pm
by Rescator
My apologies to the PB Team, GET forms work. (I've yet to test POST forms but I doubt they work)
I modified my previous example to display the form/GET query in a messagebox. Using normal PB string functions it should be easy to parse this.
HTML based GUI programs is now definably a possibility, and assuming that Linux and Mac will behave the same way, cross platform HTML GUI apps may get popular indeed
Code: Select all
EnableExplicit
Procedure.l AboutHtml_NavigationCallback(gadget,url$)
Protected window.l
Debug url$
If url$="cmd:close"
window=GetGadgetData(gadget)
If IsWindow(window)
CloseWindow(window)
EndIf
ProcedureReturn #False
ElseIf Left(url$,8)="cmd:data"
MessageRequester("GET",Right(url$,Len(url$)-8))
ProcedureReturn #False
EndIf
ProcedureReturn #True
EndProcedure
Procedure.l AboutHtml(title$,msg$,width.l=400,height.l=300,parent.l=#Null)
Protected window.l,flags.l,web.l,button.l,result.l=#False,parentid.l=#Null,event.l
flags=#PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_Invisible
If parent
flags|#PB_Window_WindowCentered
Else
flags|#PB_Window_ScreenCentered
EndIf
If parent
parentid=WindowID(parent)
EndIf
window=OpenWindow(#PB_Any,#PB_Ignore,#PB_Ignore,width,height,title$,flags,parentid)
If window
If CreateGadgetList(WindowID(window))
web=WebGadget(#PB_Any,0,0,WindowWidth(window),WindowHeight(window),"")
If web
SetGadgetItemText(web,#PB_Web_HtmlCode,msg$)
SetGadgetData(web,window)
SetGadgetAttribute(web,#PB_Web_NavigationCallback,@AboutHtml_NavigationCallback())
HideWindow(window,#False)
SetActiveGadget(web)
Repeat
If IsWindow(window) ;We must check as it may have been closed in the callback
event=WaitWindowEvent()
Else
event=#PB_Event_CloseWindow ;If window is gone we must quit the loop
EndIf
Until event=#PB_Event_CloseWindow
result=#True
EndIf
EndIf
If IsWindow(window)
CloseWindow(window)
EndIf
EndIf
ProcedureReturn result
EndProcedure
AboutHtml("Test","<html><body><a href="+#DQUOTE$+"cmd:close"+#DQUOTE$+">Close Window</a> <form action="+#DQUOTE$+"cmd:data"+#DQUOTE$+" method="+#DQUOTE$+"get"+#DQUOTE$+"><textarea name="+#DQUOTE$+"message"+#DQUOTE$+" rows="+#DQUOTE$+"17"+#DQUOTE$+" cols="+#DQUOTE$+"77"+#DQUOTE$+" title="+#DQUOTE$+"Message"+#DQUOTE$+"></textarea><input class="+#DQUOTE$+"button"+#DQUOTE$+" type="+#DQUOTE$+"submit"+#DQUOTE$+" name="+#DQUOTE$+"submit"+#DQUOTE$+" value="+#DQUOTE$+"Submit"+#DQUOTE$+"></form></body></html>",800,600)
Posted: Wed Jun 20, 2007 2:49 pm
by Num3
Beat me to it rescator

nice job
Here's a slighty tweaker version with URL decode incorporated
Code: Select all
Procedure Hex2Dec(HexNumber.s)
Structure OneByte
a.b
EndStructure
*t.OneByte = @HexNumber
result.l = 0
While *t\a <> 0
If *t\a >= '0' And *t\a <= '9'
result = (result << 4) + (*t\a - 48)
ElseIf *t\a >= 'A' And *t\a <= 'F'
result = (result << 4) + (*t\a - 55)
ElseIf *t\a >= 'a' And *t\a <= 'f'
result = (result << 4) + (*t\a - 87)
Else
result = (result << 4) + (*t\a - 55)
EndIf
*t + 1
Wend
ProcedureReturn result
EndProcedure
Procedure.s URL_Decode(string.s)
out.s=""
For a=1 To Len(string.s)
c$=Mid(string.s,a,1)
If c$="%"
k$=Mid(string.s,a+1,2)
out.s+ Chr(Hex2Dec(k$))
a+2
ElseIf c$="+"
out.s+" "
Else
out.s+c$
EndIf
Next
ProcedureReturn out
EndProcedure
Procedure.l AboutHtml_NavigationCallback(Gadget,Url$)
Protected window.l
Debug Url$
If Url$="cmd:close"
window=GetGadgetData(Gadget)
If IsWindow(window)
CloseWindow(window)
End
EndIf
ProcedureReturn #False
ElseIf Left(Url$,8)="cmd:data"
dat$=StringField(Url$,1,"&")
MessageRequester("GET",URL_Decode(dat$))
ProcedureReturn #False
EndIf
ProcedureReturn #True
EndProcedure
Procedure.l AboutHtml(title$,msg$,width.l=400,height.l=300,parent.l=#Null)
Protected window.l,flags.l,web.l,button.l,result.l=#False,parentid.l=#Null,Event.l
flags=#PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_Invisible
If parent
flags|#PB_Window_WindowCentered
Else
flags|#PB_Window_ScreenCentered
EndIf
If parent
parentid=WindowID(parent)
EndIf
window=OpenWindow(#PB_Any,#PB_Ignore,#PB_Ignore,width,height,title$,flags,parentid)
If window
If CreateGadgetList(WindowID(window))
web=WebGadget(#PB_Any,0,0,WindowWidth(window),WindowHeight(window),"")
If web
SetGadgetItemText(web,#PB_Web_HtmlCode,msg$)
SetGadgetData(web,window)
SetGadgetAttribute(web,#PB_Web_NavigationCallback,@AboutHtml_NavigationCallback())
HideWindow(window,#False)
SetActiveGadget(web)
Repeat
If IsWindow(window) ;We must check as it may have been closed in the callback
Event=WaitWindowEvent()
Else
Event=#PB_Event_CloseWindow ;If window is gone we must quit the loop
EndIf
Until Event=#PB_Event_CloseWindow
result=#True
EndIf
EndIf
If IsWindow(window)
CloseWindow(window)
EndIf
EndIf
ProcedureReturn result
EndProcedure
AboutHtml("Test","<html><body><a href="+#DQUOTE$+"cmd:close"+#DQUOTE$+">Close Window</a> <form action="+#DQUOTE$+"cmd:data"+#DQUOTE$+" method="+#DQUOTE$+"get"+#DQUOTE$+"><textarea name="+#DQUOTE$+"message"+#DQUOTE$+" rows="+#DQUOTE$+"10"+#DQUOTE$+" cols="+#DQUOTE$+"40"+#DQUOTE$+" title="+#DQUOTE$+"Message"+#DQUOTE$+"></textarea><input class="+#DQUOTE$+"button"+#DQUOTE$+" type="+#DQUOTE$+"submit"+#DQUOTE$+" name="+#DQUOTE$+"submit"+#DQUOTE$+" value="+#DQUOTE$+"Submit"+#DQUOTE$+"></form></body></html>",800,600)
Posted: Wed Jun 20, 2007 6:10 pm
by Rescator
Nice, ironically I was fiddling away with my own code and did a urldecode as well, but I went a step further to something more practical.
(I love PHP so I took inspiration from that)
This example will take all form fields and put them into a associative list.
Allowing easy ForEach handling of the form fields.
I'm not entirely happy with the url decode and var/arg parsing,
it can probably be tightened up and optimized a bit.
And I probably forgot to check a few things so this GET handling code is not adviced for server use as it currently is.
But for HTML GUI apps it should be ok as those surf locally only so...
PS! This code should work ok with both Unicode and ANSI.
EDIT: forgot a ClearList()
Code: Select all
EnableExplicit
Structure _Form_List_Structure
var$
arg$
EndStructure
Global NewList FormResult._Form_List_Structure()
Procedure.l UrlDecodeToFormResultList(text$)
Protected result$,len.l,*pos.character,a.l,b.l,v.l
ClearList(FormResult())
len=@text$+(Len(text$)*SizeOf(character))
*pos=@text$
v=#False
While *pos<len
If *pos\c=43 ;+
result$+" "
ElseIf (*pos\c=63) Or (*pos\c=38) ;? or &
If v=#True
FormResult()\arg$=result$
result$=""
EndIf
AddElement(FormResult())
v=#False
ElseIf *pos\c=61 ;=
If v=#False
FormResult()\var$=result$
result$=""
EndIf
v=#True
ElseIf *pos\c=37 ;%
*pos+SizeOf(character)
If *pos\c<58 And *pos\c>47 ;0-9
a=*pos\c-48
ElseIf *pos\c<71 And *pos\c>64 ;A-F
a=*pos\c-55
ElseIf *pos\c<103 And *pos\c>96 ;a-f
a=*pos\c-87
Else
a=0
EndIf
*pos+SizeOf(character)
If *pos\c<58 And *pos\c>47 ;0-9
b=*pos\c-48
ElseIf *pos\c<71 And *pos\c>64 ;A-F
b=*pos\c-55
ElseIf *pos\c<103 And *pos\c>96 ;a-f
b=*pos\c-87
Else
b=0
EndIf
result$+Chr((a<<4)+b)
Else
result$+Chr(*pos\c)
EndIf
*pos+SizeOf(character)
Wend
If Len(result$)>0
If v=#True
FormResult()\arg$=result$
Else
AddElement(FormResult())
FormResult()\var$=result$
EndIf
EndIf
a=CountList(FormResult())
ProcedureReturn a
EndProcedure
Procedure.l AboutHtml_NavigationCallback(gadget,url$)
Protected window.l,get$,msg$
Debug url$
If url$="cmd:close"
window=GetGadgetData(gadget)
If IsWindow(window)
CloseWindow(window)
EndIf
ProcedureReturn #False
ElseIf Left(url$,8)="cmd:data"
get$=Right(url$,Len(url$)-8)
If UrlDecodeToFormResultList(get$)
ForEach FormResult()
msg$+FormResult()\var$+"="+FormResult()\arg$+#LF$
Next
MessageRequester("GET",msg$)
EndIf
ProcedureReturn #False
EndIf
ProcedureReturn #True
EndProcedure
Procedure.l AboutHtml(title$,msg$,width.l=400,height.l=300,parent.l=#Null)
Protected window.l,flags.l,web.l,button.l,result.l=#False,parentid.l=#Null,event.l
flags=#PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_Invisible
If parent
flags|#PB_Window_WindowCentered
Else
flags|#PB_Window_ScreenCentered
EndIf
If parent
parentid=WindowID(parent)
EndIf
window=OpenWindow(#PB_Any,#PB_Ignore,#PB_Ignore,width,height,title$,flags,parentid)
If window
If CreateGadgetList(WindowID(window))
web=WebGadget(#PB_Any,0,0,WindowWidth(window),WindowHeight(window),"")
If web
SetGadgetItemText(web,#PB_Web_HtmlCode,msg$)
SetGadgetData(web,window)
SetGadgetAttribute(web,#PB_Web_NavigationCallback,@AboutHtml_NavigationCallback())
HideWindow(window,#False)
SetActiveGadget(web)
Repeat
If IsWindow(window) ;We must check as it may have been closed in the callback
event=WaitWindowEvent()
Else
event=#PB_Event_CloseWindow ;If window is gone we must quit the loop
EndIf
Until event=#PB_Event_CloseWindow
result=#True
EndIf
EndIf
If IsWindow(window)
CloseWindow(window)
EndIf
EndIf
ProcedureReturn result
EndProcedure
AboutHtml("Test","<html><body><a href="+#DQUOTE$+"cmd:close"+#DQUOTE$+">Close Window</a> <form action="+#DQUOTE$+"cmd:data"+#DQUOTE$+" method="+#DQUOTE$+"get"+#DQUOTE$+" enctype="+#DQUOTE$+"application/x-www-form-urlencoded;charset=utf-8"+#DQUOTE$+"><textarea name="+#DQUOTE$+"message"+#DQUOTE$+" rows="+#DQUOTE$+"17"+#DQUOTE$+" cols="+#DQUOTE$+"77"+#DQUOTE$+" title="+#DQUOTE$+"Message"+#DQUOTE$+"></textarea><input class="+#DQUOTE$+"button"+#DQUOTE$+" type="+#DQUOTE$+"submit"+#DQUOTE$+" name="+#DQUOTE$+"submit"+#DQUOTE$+" value="+#DQUOTE$+"Submit"+#DQUOTE$+"></form></body></html>",800,600)
Posted: Thu Jun 21, 2007 6:15 am
by fsw
Can't test the code right now, just wanted to mention that long time ago I played with something similar. IIRC the name of the HTML GUI was HARMONIA.
Posted: Thu Jun 21, 2007 9:26 pm
by utopiomania
The possibility to do html based GUI's in PB has been talked about here for ages, and if 4.1 now
can trap a navigate event, get the url and cancel, its great news indeed
A bit off topic, but if you save the code below as a for example 'program.hta' to your
desktop and dblclick it, it will run as an app in the MS html application host (mshta.exe).
Means that you can develop apps using only Notepad and Windows (with IE >5.5)
Code: Select all
<head>
<title></title>
<meta http-equiv = "msThemeCompatible" content="yes">
<! html application: >
<hta:application
applicationname = ""
icon = "notepad.exe"
border = "thin"
scroll = "no"
contextMenu = "no"
innerBorder = "no"
singleinstance = "yes"
windowstate = "normal"
navigable = "yes"
selection = "no"
version = ""
>
<! application functions: >
<script language = "vbscript">
sub window_onLoad
window.resizeTo 600, 400
window.moveTo 200, 100
end sub
sub button1_onClick
self.close
end sub
sub button1_onMouseOver
button1.value = "<< Prev"
button1.style.cursor = "hand"
end sub
sub button1_onMouseOut
button1.value = "Next >>"
end sub
sub button1_onFocus
button1.value = "<< Prev"
end sub
</script>
</head>
<! application user interface: >
<body style = "filter:progid:dxImageTransform.microsoft.gradient
(gradientType = 0, startColorStr = '#ffffff', endColorStr = '#4080ff')">
<span style = "position:absolute; left:20; top:55">
Type some important letters here:</span>
<input id = "text1" type = "text" title = "yes, type here"
style = "position:absolute; left:20; top:80; width:555; height:22">
<hr style = "position:absolute; left:20; top:310; width:560; height:1; color:#c0c0c0">
<input id = "button1" type = "button" value = "Next >>"
style = "position:absolute; left:480; top:330; width:100; height:25; cursor:hand">
</body>
Posted: Thu Jun 21, 2007 9:49 pm
by Pantcho!!
Ok this is weird.
I run the code i have a window with webgadget and a title and thats it.
And yes running PB 4.10 installed over a PB 4.02 directory.

:roll:
Posted: Thu Jun 21, 2007 10:26 pm
by rsts
Pantcho!! wrote:Ok this is weird.
I run the code i have a window with webgadget and a title and thats it.
And yes running PB 4.10 installed over a PB 4.02 directory.

:roll:
Me too. Thought maybe that was it
cheers