[GUI] Use HTML and CSS for your GUIs!

Put simple Tips and Tricks that are not entire Tutorials in this forum
User avatar
joedf
Posts: 8937
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

[GUI] Use HTML and CSS for your GUIs!

16 Sep 2014, 14:03

This has already been done. The autohotkey installer is an example. This is just a post to shed some light on this.
To achieve this, we are using an ActiveX Control. More precisely, we are going to "pseudo-integrate" InternetExplorer into our GUI.

TLDR: (too long, didn't read)
For those who don't feel like learning all of it (even though it's not hard), I've made a library to simplify your lives.
Webapp.ahk:
Check it out: https://autohotkey.com/boards/viewtopic.php?f=6&t=21516 :)

Neutron.ahk
or perhaps, even more advanced and powerful is GeekDude's new Neutron.ahk:
https://www.autohotkey.com/boards/viewtopic.php?f=6&t=76865

Otherwise, keep reading ;)


Here's an example script, i wrote a while ago. It is pretty much self-explanatory.
ScreenShot

Code: Select all

;activex gui - test  joedf - 2014/07/04
#SingleInstance, off
OnExit,OnExit

MYAPP_PROTOCOL:="myapp"

HTML_page =
( Ltrim Join
<!DOCTYPE html>
<html>
	<head>
		<style>
			body{font-family:sans-serif;background-color:#dde4ec;}
			#title{font-size:36px;}
			#corner{font-size:10px;position:absolute;top:8px;right:8px;}
			p{font-size:16px;background-color:#efefef;border:solid 1px #666;padding:4px;}
			#footer{text-align:center;}
		</style>
	</head>
	<body>
		<div id="title">Lorem Ipsum</div>
		<div id="corner">Welcome!</div>
		<p>The standard Lorem Ipsum passage, used since the 1500s</p>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
		<p id="footer">
			<a href="%MYAPP_PROTOCOL%://msgbox/hello">Click me for a MsgBox</a>&nbsp;-&nbsp;
			<a href="NOPE://msgbox/hello">Click me for nothing</a>&nbsp;-&nbsp;
			<a href="%MYAPP_PROTOCOL%://soundplay/ding">Click me for a ding sound!</a>
		</p>
	</body>
</html>
)

Gui Add, ActiveX, x0 y0 w640 h480 vWB, Shell.Explorer  ; The final parameter is the name of the ActiveX component.
WB.silent := true ;Surpress JS Error boxes
Display(WB,HTML_page)
ComObjConnect(WB, WB_events)  ; Connect WB's events to the WB_events class object.
Gui Show, w640 h480
return

GuiClose:
ExitApp

OnExit:
	FileDelete,%A_Temp%\*.DELETEME.html ;clean tmp file
ExitApp

class WB_events
{
	;for more events and other, see http://msdn.microsoft.com/en-us/library/aa752085
	
	NavigateComplete2(wb) {
		wb.Stop() ;blocked all navigation, we want our own stuff happening
	}
	DownloadComplete(wb, NewURL) {
		wb.Stop() ;blocked all navigation, we want our own stuff happening
	}
	DocumentComplete(wb, NewURL) {
		wb.Stop() ;blocked all navigation, we want our own stuff happening
	}
	
	BeforeNavigate2(wb, NewURL)
	{
		wb.Stop() ;blocked all navigation, we want our own stuff happening
		;parse the url
		global MYAPP_PROTOCOL
		if (InStr(NewURL,MYAPP_PROTOCOL "://")==1) { ;if url starts with "myapp://"
			what := SubStr(NewURL,Strlen(MYAPP_PROTOCOL)+4) ;get stuff after "myapp://"
			if InStr(what,"msgbox/hello")
				MsgBox Hello world!
			else if InStr(what,"soundplay/ding")
				SoundPlay, %A_WinDir%\Media\ding.wav
		}
		;else do nothing
	}
}

Display(WB,html_str) {
	Count:=0
	while % FileExist(f:=A_Temp "\" A_TickCount A_NowUTC "-tmp" Count ".DELETEME.html")
		Count+=1
	FileAppend,%html_str%,%f%
	WB.Navigate("file://" . f)
}
The trick is using "invalid" urls and catch them, then execute some code.

Now let's investigate "code-direction" : In the above example, we see how we make the "webpage" execute some functions.
In this next example, we are going to read the contents of textbox and then change its contents. >Read & Write<
Webpage >> AHK
AHK >> WebPage

In this second example, we see that we can actually use DOM to access & change things, just like javascript! ;)
A thing to note is that, here we are not using invalid links to our advantage, but we are directly handling the "connected" events for the buttons.
ScreenShot

Code: Select all

;activex gui 2 - test  joedf - 2014/09/19
#SingleInstance, off
OnExit,OnExit

HTML_page =
( Ltrim Join
<!DOCTYPE html>
<html>
	<head>
		<style>
			body{font-family:sans-serif;background-color:#1A1A1A;color:white}
			#title{font-size:36px;}
			input{margin:4px;Border: 2px white solid;background-color:black;color:white;}
			p{font-size:16px;border:solid 1px #666;padding:4px;}
			#footer{text-align:center;}
		</style>
	</head>
	<body>
		<div id="title">Hello World</div>
		<textarea rows="4" cols="70" id="MyTextBox">1234567890-=\ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$^&*()_+|~</textarea>
		<p id="footer">
			<input type="button" id="MyButton1" value="Show Content in AHK MsgBox">
			<input type="button" id="MyButton2" value="Change Content with AHK">
			<input type="button" id="MyButton3" value="Greetings from AHK">
		</p>
	</body>
</html>
)

Gui Add, ActiveX, x0 y0 w640 h480 vWB, Shell.Explorer  ; The final parameter is the name of the ActiveX component.
WB.silent := true ;Surpress JS Error boxes
Display(WB,HTML_page)

;Wait for IE to load the page, before we connect the event handlers
while WB.readystate != 4 or WB.busy
	sleep 10

;Use DOM access just like javascript!
MyButton1 := wb.document.getElementById("MyButton1")
MyButton2 := wb.document.getElementById("MyButton2")
MyButton3 := wb.document.getElementById("MyButton3")
ComObjConnect(MyButton1, "MyButton1_") ;connect button events
ComObjConnect(MyButton2, "MyButton2_")
ComObjConnect(MyButton3, "MyButton3_")
Gui Show, w640 h480
return

GuiClose:
ExitApp
OnExit:
	FileDelete,%A_Temp%\*.DELETEME.html ;clean tmp file
ExitApp

; Our Event Handlers
MyButton1_OnClick() {
	global wb
	MsgBox % wb.Document.getElementById("MyTextBox").Value
}
MyButton2_OnClick() {
	global wb
	FormatTime, TimeString, %A_Now%, dddd MMMM d, yyyy HH:mm:ss
	data := "AHK Version " A_AhkVersion " - " (A_IsUnicode ? "Unicode" : "Ansi") " " (A_PtrSize == 4 ? "32" : "64") "bit`nCurrent time: " TimeString
	wb.Document.getElementById("MyTextBox").value := data
}
MyButton3_OnClick() {
	MsgBox Hello world!
}
;------------------
Display(WB,html_str) {
	Count:=0
	while % FileExist(f:=A_Temp "\" A_TickCount A_NowUTC "-tmp" Count ".DELETEME.html")
		Count+=1
	FileAppend,%html_str%,%f%
	WB.Navigate("file://" . f)
}
Now that we know how to access the DOM, we can basically almost anything the web has to offer (...or at least what IE has to offer ;) ) Just learn some basic DOM-handling and/or javascript and there you go! ;)
Important links:
http://ahkscript.org/docs/commands/GuiControls.htm#ActiveX
http://ahkscript.org/boards/viewtopic.php?f=5&t=4449

DON'T BE SHY TO POST ANY COMMENTS, QUESTIONS OR IDEAS! :cookie:

Hoping to see some nice GUIs! ;)
Cheers! :D
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: [GUI] Use HTML and CSS for your GUIs!

17 Sep 2014, 06:40

useful! thanks.
User avatar
joedf
Posts: 8937
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: [GUI] Use HTML and CSS for your GUIs!

19 Sep 2014, 16:04

Thank you guest3456 & tmplinshi!
--
Added Example 2 :D
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
Grendahl
Posts: 170
Joined: 30 Sep 2013, 08:21

Re: [GUI] Use HTML and CSS for your GUIs!

24 Sep 2014, 15:12

Example 2 throws an error at me. Line# 38/39/40
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: [GUI] Use HTML and CSS for your GUIs!

25 Sep 2014, 04:05

Grendahl wrote:Example 2 throws an error at me. Line# 38/39/40
same here
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: [GUI] Use HTML and CSS for your GUIs!

25 Sep 2014, 06:40

Grendahl wrote:Example 2 throws an error at me. Line# 38/39/40
Particularly these lines:

Code: Select all

ComObjConnect(MyButton1, "MyButton1_") ;connect button events
ComObjConnect(MyButton2, "MyButton2_")
ComObjConnect(MyButton3, "MyButton3_")
What error are you getting? AHK version?
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: [GUI] Use HTML and CSS for your GUIs!

25 Sep 2014, 06:43

Code: Select all

---------------------------
test.ahk
---------------------------
Error:  No valid COM object!

	Line#
	005: HTML_page = <!DOCTYPE html><html><head><style>body{font-family:sans-serif;background-color:#1A1A1A;color:white}#title{font-size:36px;}input{margin:4px;Border: 2px white solid;background-color:black;color:white;}p{font-size:16px;border:solid 1px #666;padding:4px;}#footer{text-align:center;}</style></head><body><div id="title">Hello World</div><textarea rows="4" cols="70" id="MyTextBox">1234567890-=\ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$^&*()_+|~</textarea><p id="footer"><
	030: Gui,Add,ActiveX,x0 y0 w640 h480 vWB,Shell.Explorer
	031: WB.silent := true  
	032: Display(WB,HTML_page)  
	035: MyButton1 := wb.document.getElementById("MyButton1")
	036: MyButton2 := wb.document.getElementById("MyButton2")
	037: MyButton3 := wb.document.getElementById("MyButton3")
--->	038: ComObjConnect(MyButton1, "MyButton1_")  
	039: ComObjConnect(MyButton2, "MyButton2_")  
	040: ComObjConnect(MyButton3, "MyButton3_")  
	041: Gui,Show,w640 h480
	042: Return
	045: ExitApp
	047: FileDelete,%A_Temp%\*.DELETEME.html
	048: ExitApp

Continue running the script?
---------------------------
是(Y)   否(N)   
---------------------------
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: [GUI] Use HTML and CSS for your GUIs!

25 Sep 2014, 06:55

Can you check with MsgBox % ComObjType(MyButton1, "name"). Also check if the temp files are successfully written/created. Put a MsgBox(to halt execution) below Display(WB,HTML_page) then check your A_Temp folder. What version of IE do you have installed?
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: [GUI] Use HTML and CSS for your GUIs!

25 Sep 2014, 07:02

MsgBox % ComObjType(MyButton1, "name") displays "DispHTMLInputElement". I'm using IE8.

Code: Select all

Display(WB,HTML_page)
MsgBox, hi
The MsgBox, hi will fix the error :P . So the reason was haven't wait the page loading finished. I think joedf's computer is super fast. :mrgreen:

Code: Select all

Display(WB,HTML_page)

while WB.readystate != 4 or WB.busy
    sleep 10
Thanks, Coco.
User avatar
joedf
Posts: 8937
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: [GUI] Use HTML and CSS for your GUIs!

25 Sep 2014, 09:34

Whoops, I did not get the chance to check the error out :P Thanks, coco :D
@tmplinshi my computer has fast I/O :P I'll update the example with your fix some time today. :)
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
Sjc1000_

Re: [GUI] Use HTML and CSS for your GUIs!

18 Oct 2014, 03:58

( i can't log in atm, but its worth me posting here )

There is an alternative way to using the Shell.Explorer.
You can use MSHTML.
It supports click / double click and hover events.
Though, If i remember correctly it doesn't allow CSS3. But 2 is good enough for AHK GUI's right? ;)

I have an example http://www.autohotkey.com/board/topic/1 ... orts-gifs/ here.
Im up for getting back into AHK for this exact thing, if you want to collab on something maybe we can get some wicked stuff goin on.
User avatar
joedf
Posts: 8937
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: [GUI] Use HTML and CSS for your GUIs!

18 Oct 2014, 12:28

Wow, Datz cool! CSS3 animations in ahk, never thought of that.. Hover events, ... Awesome! :D Sure, just send me a PM if you get any cool ideas to work on! ;)
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
Sjc1000
Posts: 39
Joined: 02 Oct 2013, 02:07

Re: [GUI] Use HTML and CSS for your GUIs!

04 Nov 2014, 19:34

I had an idea about making a GUI class, one that uses MSHTML or Shell.Explorer. Maybe we could collab on this?
Please find me on the IRC if you have any questions, I'm never on the forum anymore.
User avatar
joedf
Posts: 8937
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: [GUI] Use HTML and CSS for your GUIs!

04 Nov 2014, 22:33

Great Idea! Sure!
What to call it? wGUI? WebUI? AHK-webkit?
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
geek
Posts: 1051
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: [GUI] Use HTML and CSS for your GUIs!

04 Nov 2014, 22:46

I did a bit of mucking around with a class for html controls a while back. IIRC the weirdness of embedded IE (and the inconsistency between doctypes and stuff) caused me to drop the project. You can probable strip out the FixIE call, that's just what I use to force it to act like newer IE versions instead of like IE7 or whatever it uses by default

Code: Select all

#Persistent
ComObjError(0)
FixIE(True, "0")

html =
(
<style id="Style">
	button {
		background-color: #CCF;
		border-color: black;
		border-radius: 0.5em;
		border-width: 1px;
		box-shadow: 3px 3px 0.5em 0em #888;
	}
	p {
		font-family: monospace;
	}
</style>
<button id="MyButton" label="MyLabel">This is a button</button>
<button label="Reset">Reset CSS</button>
<p id="MyText">This is some text</p>
)

x := new HtmlControl(html, "w500 h500")
;Gui, Show
return

MyLabel:
;ToolTip, % ++count
Count++
x.MyText := "Some more text: " Count
return

Reset:
x.Style.Sheet.cssText := ""
return

GuiClose:
ExitApp
return

class HtmlControl
{
	__New(html, Options="", Title="")
	{
		global wb
		
		;Gui, Add, ActiveX, vWB %Options%, Shell.Explorer
		
		wb := ComObjCreate("InternetExplorer.Application")
		;wb.FullScreen := true
		wb.Visible := true
		wb.AddressBar := false
		ComObjConnect(wb, new this.IEHandler())
		wb.Navigate("about:blank")
		while wb.readystate != 4
			sleep, 50
		wb.document.Write("<!DOCTYPE html><html><title>" A_ScriptName "</title><body>" html "</body></html>")
		
		Buttons := wb.document.getElementsByTagName("BUTTON")
		while Button := Buttons.Item(A_Index-1)
		{
			this.Buttons[A_Index] := Button
			ComObjConnect(Button, new this.ButtonHandler())
		}
		;MsgBox, % ComObjType(wb, "Name")
		
		this.wb := wb
	}
	
	__Set(Name, Value)
	{
		if this.wb
		{
			Element := this.wb.document.getElementByID(Name)
			if Element
				return Element.InnerText := Value
		}
	}
	
	__Get(Name)
	{
		if (Name != "wb" && this.wb)
		{
			Element := this.wb.document.getElementByID(Name)
			if Element
				return Element
		}
	}
	
	__Delete()
	{
		this.wb.Quit()
	}
	
	class IEHandler
	{
		onQuit(p*)
		{
			SetTimer, GuiClose, -0
		}
	}
	
	class ButtonHandler
	{
		onClick(Button)
		{
			Label := Button.GetAttribute("Label")
			if IsLabel(Label)
				SetTimer, %Label%, -0
		}
	}
}
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: [GUI] Use HTML and CSS for your GUIs!

05 Nov 2014, 09:36

I've been working on Shell.Explorer wrapper, still a work-in-progress, but already functional. Personally, I plan to use it as a lib script for another project, an AHK version of node-webkit
Some current features:
  • IWebBrowser2, window, document, elements, collection/list objects are wrapped in their respective classes.
  • Built-in support for TranslateAccelerator( to allow common IE shortcuts such as Ctrl+C)
  • Support for FEATURE_BROWSER_EMULATION, if you have IE9+, you can take advantage of the new HTML5 features
  • + more :)
It's not yet final in its current form but the interface design should allow me to expand/alter it easily.
I'll post it formally in the forum once the next AHK release includes the support for passing AHK objects to COM API's since I still need to do some tests and redesigns..
User avatar
joedf
Posts: 8937
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: [GUI] Use HTML and CSS for your GUIs!

05 Nov 2014, 10:08

I suggest we just Make a repo under AhkScript, so we can contribute together :)
I can't currently, since I don't have access to a computer/Laptop for the next 4-5 or so days, I'm not sure yet. :P
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
deoauto
Posts: 4
Joined: 21 Mar 2015, 21:54

Re: [GUI] Use HTML and CSS for your GUIs!

22 Mar 2015, 14:44

hello all, :)
especially to joedf for creating this interesting thread with helpful examples. I am quite new to autohotkey, its been less than a week since I started using it extensively. The idea of having HTML as GUI sounds really "revolutionary" to me (the end of boring GUI)... until it can't take me any further due to the limitation of shell.explorer issues. I have tried the FixIE() method in this forum and creating Autohotkey.exe registry in FEATURE_BROWSER_EMULATION, as well as adding <meta http-equiv="X-UA-Compatible" content="IE=9"> in my html file. It seems that after changing registry values to support Internet Explorer 8+ (capability to display css border-radius, showing .svg picture files.. ) it looks cool and good except the function to fire autohotkey commands using the following statement.

Code: Select all

coordmode, mouse, screen
mousegetpos theX, theY
Gui destroy ; destroy previously opened gui

Gui add, activeX, w110 h70 vTest, D:\htmgui.html
Gui +LastFound +AlwaysOnTop -Caption +ToolWindow  
CustomColor = EEAA99 
Gui, Color, %CustomColor%
WinSet, TransColor, %CustomColor% 255 
test.silent := true 
while test.readyState != 4 or test.busy
    sleep 100

divs := test.document.getElementById("div1")
ComObjConnect(divs, "divs_")
Gui, Show, x%theX% y%theY%, divclick_tester

divs_onClick(){
	soundbeep
  	msgbox ThumbsUp!
  	gui destroy
}
Note that
* if IE8+ support registry NOT YET added, the code works but style border-radius will not show
* if IE8+ support registry ADDED, border-radius will show but divs := test.document.getElementById("div1") will not work and returns "Error: 0x8000402 - No such interface supported". However if divs := test.document is used instead, clicking anywhere in the document area will fire successfully.

Can someone shed light on this? is there something I'm missing? how do I make .getElementById("div1") works again?

my htmgui.html file content

Code: Select all

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=9"> 
<title>Html Gui</title>
</head>

<body style="margin:0px; padding:0px; overflow:hidden; background-color:#EEAA99;">

<div style="position: relative; display: inline-block; width:100px; height:20px; text-align:center; margin: 0 auto; background-color:#09F; border: 1px solid black; border-radius:5px; cursor:pointer; overflow:hidden;" id="div1">

<a id="ahkbuttonic" style="text-decoration: none; cursor:crosshair;overflow:hidden;">Show!</a>

</div>

</body>
</html>
Btw this is my first post! :D hope to be part of autohotkey community.

Return to “Tips and Tricks (v1)”

Who is online

Users browsing this forum: No registered users and 16 guests