 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Fri Dec 21, 2007 5:14 pm Post subject: HTMLText 1.01 - Write HTML style text to a GUI |
|
|
This is just a quick demonstration to see if there's any interest in me continuing the function:
| Code: | | <fGeorgia><w100>Light text in Georgia</w></f><w1000>Heaviest text </w>Normal Text <u><i><b>This is underlined, italic and bold </b></i></u><cff0000><d>This is red and Deleted</d></c> |
The idea is to allow html style coding to write text to a window, as it is very annoying having to write so many complex lines just to write a simple sentence that contains different colours, weights, sizes etc.
Usage:
| Code: | | HTMLText(x, y, Text, Gui) |
x and y positions in the gui specified as the last parameter, and wrap text you wish to have tags with:
Colour: <cff0000></c>
Size: <s20></s> ; Not implemented.
Weight: <w400></w>
Bold: <b></b>
Italic: <i></i>
Delete/Strikeout: <d></d>
Underline: <u></u>
Font: <fArial></f>
Note:
- You must close tags in the order they were opened.
So, this is incorrect:
| Code: | | <b><i>Bold+Italic</b></i> |
This is correct:
| Code: | | <b><i>Bold+Italic</i></b> |
- you may not enclose a tag with the same tag.
ie
| Code: | | <b>Here is <b>some</b> text</b> |
| Code: | ; c = Colour
; s = Size
; w = Weight (max 1000)
; b = Bold
; i = Italic
; d = Delete/Strikeout
; u = Underline
; f = Font
#SingleInstance Force
Text = Normal <fImpact><w100>Light text </w></f><w1000>Heaviest text </w>Normal Text <u><i><b>This is underlined, italic and bold </b></i></u><cff0000><d>This is red and Deleted</d></c>
HTMLText(10, 10, Text, 2)
Gui, 2: Add, Text, x10 y+10, Not part of the function
Gui, 2: Show, AutoSize
Return
HTMLText(x, y, Text, Gui=1)
{
AllText := Text
Tags := "<c[0-9a-fA-F]+?>,<s[0-9]+?>,<w[0-9]+?>,<b>,<i>,<d>,<u>,<f.+?>"
StringSplit, Tag, Tags, `,
Loop
{
Loop
{
;Gui, %Gui%: Font, s17
FirstPos := ""
Loop, %Tag0%
{
Pos := RegExMatch(Text, Tag%A_Index%, Test)
If ((Pos) && (Pos < FirstPos)) || (!FirstPos)
FirstPos := Pos
}
Pos := FirstPos
If (Pos) && (Pos != 1)
{
If !Started
{
Gui, %Gui%: Add, Text, x%x% y%y%, % SubStr(Text, 1, Pos-1) ;%
EndTrim += Pos-1
StringTrimLeft, Text, Text, % Pos-1 ;%
Started := 1
}
Else
{
Gui, %Gui%: Add, Text, x+0 yp+0, % SubStr(Text, 1, Pos-1) ;%
EndTrim += Pos-1
StringTrimLeft, Text, Text, % Pos-1 ;%
}
}
Else If (Pos) && (Pos = 1)
{
ETag := SubStr(Text, 2, 1)
Pos := RegExMatch(Text, "<" ETag ".+?" ETag ">", Text, 1)
If !Length
{
EndTrim += StrLen(Text)
Length := 1
}
If ETag in b,i,d,u
{
StringReplace, Text, Text, <%ETag%>,, All
StringReplace, Text, Text, </%ETag%>,, All
If (Etag = "b")
Gui, %Gui%: Font, Bold
If (Etag = "i")
Gui, %Gui%: Font, Italic
If (Etag = "d")
Gui, %Gui%: Font, Strike
If (Etag = "u")
Gui, %Gui%: Font, Underline
}
If ETag in c,w,f
{
Pos := RegExMatch(Text, "<" ETag "(.+?)>(.+?)</" ETag ">", Text, 1)
If (Etag = "c")
Gui, %Gui%: Font, c%Text1%
If (Etag = "w")
Gui, %Gui%: Font, w%Text1%
If (Etag = "f")
Gui, %Gui%: Font,, %Text1%
Text := Text2
}
}
Else
{
If !Length
EndTrim += StrLen(Text)
If !Started
{
Gui, %Gui%: Add, Text, x%x% y%y%, %Text%
Started := 1
}
Else
Gui, %Gui%: Add, Text, x+0 yp+0, %Text%
Length := ""
Break
}
}
Gui, %Gui%: Font
StringTrimLeft, AllText, AllText, %EndTrim%
Text := AllText
Length := EndTrim := ""
If !Text
Break
}
}
Esc::ExitApp |
Newer version:
Thought i may as well just update this code with the version I had last. There were still things to add, but I havent got round to doing it. The following code allows wrapping, but you cant specify a new line. Also using different sized text may make the texts appear at different heights as they could have different baselines. This is the same with using different fonts:
| Code: | ; c = Colour
; s = Size
; w = Weight (max 1000)
; b = Bold
; i = Italic
; d = Delete/Strikeout
; u = Underline
; f = Font
#SingleInstance Force
SetBatchLines -1
Text =
(
<ce5460f>Colour: </c><c7d1cba>This can be specified</c><c456745> using the c tag.</c>
<s14>Size: </s><s6>Different</s>sizes can be specified <s16>easily</s> using the s tag.
<w1000>Weight:</w><w100>Different</w>weights can be specified <w800>easily</w>using the w tag.
<b>Bold: </b>The b tag can be used for <b>bold</b>text.
<i>Italic: </i>The i tag can be used for <i>italic</i>text.
<d>Delete:</d> The d tag can be used for <d>deleted</d>text.
<u>Underline:</u> The u tag can be used for <u>underlined</u>text.
<fComic Sans MS>Font:</f>Different <fGaramond>fonts</f> can be specified with the f tag.
)
HTMLText("x10 y40 w400", Text, 2)
Gui, 2: Show, AutoSize
Return
;###########################################################################
HTMLText(Options, Text, Gui=1)
{
RestoreDHW := A_DetectHiddenWindows
DetectHiddenWindows, On
Gui, %Gui%: +LastFound
hwnd := WinExist()
Gui, %Gui%: Default
RegExMatch(Options, "x([0-9]+)", x)
RegExMatch(Options, "y([0-9]+)", y)
RegExMatch(Options, "w([0-9]+)", w)
x := x1, y := y1, w := w1
StringReplace, Text, Text, `n,, All
Loop
{
ControlGetPos, XPos, YPos, Width, Height, Static%A_Index%, ahk_id %hwnd%
If !(Width || Height)
{
CN := A_Index-1
Break
}
}
AllText := Text
Tags := "<c[0-9a-fA-F]+?>,<s[0-9]+?>,<w[0-9]+?>,<b>,<i>,<d>,<u>,<f.+?>"
StringSplit, Tag, Tags, `,
Loop
{
Loop
{
FirstPos := ""
Loop, %Tag0%
{
Pos := RegExMatch(Text, Tag%A_Index%, Test)
If ((Pos) && (Pos < FirstPos)) || (!FirstPos)
FirstPos := Pos
}
Pos := FirstPos
If (Pos) && (Pos != 1)
{
IntText := SubStr(Text, 1, Pos-1)
StringSplit, IntText, IntText, % " " ;%
GoSub, AddText
If !Length
EndTrim += Pos-1
StringTrimLeft, Text, Text, % Pos-1 ;%
Started := 1
}
Else If (Pos) && (Pos = 1)
{
ETag := SubStr(Text, 2, 1)
Pos := RegExMatch(Text, "<" ETag ".+?</" ETag ">", Text, 1)
If !Length
EndTrim += StrLen(Text)
Length := 1
If ETag in b,i,d,u
{
StringReplace, Text, Text, <%ETag%>,, All
StringReplace, Text, Text, </%ETag%>,, All
If (Etag = "b")
Gui, %Gui%: Font, Bold
If (Etag = "i")
Gui, %Gui%: Font, Italic
If (Etag = "d")
Gui, %Gui%: Font, Strike
If (Etag = "u")
Gui, %Gui%: Font, Underline
}
If ETag in c,w,f,s
{
Pos := RegExMatch(Text, "<" ETag "(.+?)>(.+?)</" ETag ">", Text, 1)
If (Etag = "c")
Gui, %Gui%: Font, c%Text1%
If (Etag = "w")
Gui, %Gui%: Font, w%Text1%
If (Etag = "f")
Gui, %Gui%: Font,, %Text1%
If (Etag = "s")
Gui, %Gui%: Font, s%Text1%
Text := Text2
}
}
Else
{
StringSplit, IntText, Text, % " " ;%
If !Length
EndTrim += StrLen(Text)
GoSub, AddText
Started := 1
Break
}
}
Gui, %Gui%: Font
StringTrimLeft, AllText, AllText, %EndTrim%
Text := AllText
Length := EndTrim := ""
If !Text
Break
}
DetectHiddenWindows, %RestoreDHW%
Return, 0
;###########################################################################
AddText:
Loop, %IntText0%
{
CN++
Gui, %Gui%: Add, Text, % ((A_Index = 1) && (!Started)) ? "x" x " y" y : "x+0 yp+0", % (A_Index != IntText0) ? IntText%A_Index% " " : IntText%A_Index%
GuiControlGet, Pos, Pos, Static%CN%
If (PosH != OldPosH) && (OldPosH)
{
NewY := OldPosY+OldPosH > PosY+PosH ? PosY+(OldPosH-PosH) : PosY-(PosH-OldPosH)
GuiControl, Move, Static%CN%, % "y" NewY ;%
Gui, %Gui%: Add, Text, % "x" PosX+PosW " y" NewY " w" 0 " h" PosH ;%
CN++
}
OldPosX := PosX, OldPosY := PosY, OldPosW := PosW, OldPosH := PosH
If (PosW+PosX > x+w) || (IntText%A_Index% = "<l>")
{
y += 40
GuiControl, Move, Static%CN%, x%x% y%y%
Gui, %Gui%: Add, Text, % "x" x+PosW " y" y " w" 0 ;%
CN++
}
}
Return
}
Esc::ExitApp |
Last edited by tic on Sat Mar 22, 2008 9:29 am; edited 15 times in total |
|
| Back to top |
|
 |
Andreone
Joined: 20 Jul 2007 Posts: 257 Location: Paris, France
|
Posted: Fri Dec 21, 2007 6:49 pm Post subject: |
|
|
Good idea
I just played with your code and I made few changes:
- adding ", isn't it?" add the end of your displayed sentence (your version lost the ?)
- the loop can be exited sooner
- If Pos are not needed
- IntermediateText := SubStr(Text, 1, (Pos ? Pos-1 : StrLen(Text))) is coded once
| Code: | Text := "This text can have <b>bold</b> or non-<b>bold</b> text. It's <b>easy peasy!</b>, isn't it?"
HTMLText(10, 10, Text)
Gui, 1: Show, AutoSize
Return
HTMLText(x, y, Text, Gui=1)
{
Loop
{
Gui, Font
Pos := RegExMatch(Text, "<b>(.+?)</b>", Bold, 1)
IntermediateText := SubStr(Text, 1, (Pos ? Pos-1 : StrLen(Text)))
If IntermediateText
{
If !Started
{
Gui, %Gui%: Add, Text, x%x% y%y%, %IntermediateText%
Started := 1
}
Else
{
Gui, %Gui%: Add, Text, x+0 yp+0, %IntermediateText%
}
}
; no more html text, quit loop now
If !Pos
Break
Gui, Font, Bold
If !Started
{
Gui, %Gui%: Add, Text, x%x% y%y%, % Bold1
Started := 1
}
Else
Gui, %Gui%: Add, Text, x+0 yp+0, % Bold1
StringTrimLeft, Text, Text, % Pos+StrLen(Bold)-1
}
} |
But you put yourself into troubles: what about italic, underline, font size and font colors?
Edited: you should also make a screenshot of the gui. It's always nice to have a visual example when dealing with guis. |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Fri Dec 21, 2007 7:07 pm Post subject: |
|
|
| Code: | | - IntermediateText := SubStr(Text, 1, (Pos ? Pos-1 : StrLen(Text))) is coded once |
yes i would definitely do that, but it was just an example functionality, non optimised.
| Quote: | | - adding ", isn't it?" add the end of your displayed sentence (your version lost the ?) |
it doesnt for me. it works fine
| Quote: | | But you put yourself into troubles: what about italic, underline, font size and font colors? |
Heh, yeh it will be troublesome, but doable i think. ill have to think about it if enough people are interested and then write it all up. |
|
| Back to top |
|
 |
Andreone
Joined: 20 Jul 2007 Posts: 257 Location: Paris, France
|
Posted: Fri Dec 21, 2007 7:18 pm Post subject: |
|
|
| tic wrote: | | Quote: | | - adding ", isn't it?" add the end of your displayed sentence (your version lost the ?) | it doesnt for me. it works fine | You're right. It was a bug I introduced myself (and corrected ) while I was tinkering your script.
| Quote: | | Heh, yeh it will be troublesome, but doable i think. ill have to think about it if enough people are interested and then write it all up. | You already have one vote!  |
|
| Back to top |
|
 |
Titan
Joined: 11 Aug 2004 Posts: 5390 Location: /b/
|
Posted: Fri Dec 21, 2007 7:28 pm Post subject: |
|
|
Great work! I would recommend you use the re: "i)<\s*(b|strong)\b[^>]*>(?'1'.+?)<\s*/\1\s*>". _________________
 |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Fri Dec 21, 2007 7:30 pm Post subject: |
|
|
probably the best way i can think of to add all the other functionalities is to:
Take the first <
Then find what html code it is ie <b>
Then find the corresponding closing brace </b> along with all the text in between. ie:
| Code: | | <b><i>Italic+Bold</i>Just Bold</b> |
Then take out the italic part:
| Code: | | <b><i>Italic+Bold</i></b> |
and then the bold part:
and join them together.
Stringtrim all of that out and continue.
Its gonna be very hard, but im sure it can be done and will be very useful when finished. |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Sat Dec 22, 2007 1:37 am Post subject: |
|
|
This code does not need optimising. I am still in the process of adding functionality and will leave optimisation until the end as it often hinders the readability of the code.
This has all the font properties added apart from setting size:
| Code: | ; c = Colour
; s = Size
; w = Weight (max 1000)
; b = Bold
; i = Italic
; d = Delete/Strikeout
; u = Underline
; f = Font
#SingleInstance Force
Text = <fGeorgia><w100>Light text in Georgia </w></f><w1000>Heaviest text </w>Normal Text <u><i><b>This is underlined, italic and bold </b></i></u><cff0000><d>This is red and Deleted</d></c>
HTMLText(10, 10, Text, 2)
Gui, 2: Add, Text, x10 y+10, Not part of the function
Gui, 2: Show, AutoSize
Return
HTMLText(x, y, Text, Gui=1)
{
AllText := Text
Loop
{
Loop
{
Pos := InStr(Text, "<")
If (Pos) && (Pos != 1)
{
If !Started
{
Gui, %Gui%: Add, Text, x%x% y%y%, % SubStr(Text, 1, Pos-1) ;%
EndTrim += Pos-1
StringTrimLeft, Text, Text, % Pos-1 ;%
Started := 1
}
Else
{
Gui, %Gui%: Add, Text, x+0 yp+0, % SubStr(Text, 1, Pos-1) ;%
EndTrim += Pos-1
StringTrimLeft, Text, Text, % Pos-1 ;%
}
}
Else If (Pos) && (Pos = 1)
{
ETag := SubStr(Text, 2, 1)
Pos := RegExMatch(Text, "<" ETag ".+?" ETag ">", Text, 1)
If !Length
{
EndTrim += StrLen(Text)
Length := 1
}
If ETag in b,i,d,u
{
StringReplace, Text, Text, <%ETag%>,, All
StringReplace, Text, Text, </%ETag%>,, All
If (Etag = "b")
Gui, %Gui%: Font, Bold
If (Etag = "i")
Gui, %Gui%: Font, Italic
If (Etag = "d")
Gui, %Gui%: Font, Strike
If (Etag = "u")
Gui, %Gui%: Font, Underline
}
If ETag in c,w,f
{
Pos := RegExMatch(Text, "<" ETag "(.+?)>(.+?)</" ETag ">", Text, 1)
If (Etag = "c")
Gui, %Gui%: Font, c%Text1%
If (Etag = "w")
Gui, %Gui%: Font, w%Text1%
If (Etag = "f")
Gui, %Gui%: Font,, %Text1%
Text := Text2
}
}
Else
{
If !Length
EndTrim += StrLen(Text)
If !Started
{
Gui, %Gui%: Add, Text, x%x% y%y%, %Text%
Started := 1
}
Else
Gui, %Gui%: Add, Text, x+0 yp+0, %Text%
Length := ""
Break
}
}
Gui, %Gui%: Font
StringTrimLeft, AllText, AllText, %EndTrim%
Text := AllText
Length := EndTrim := ""
If !Text
Break
}
}
Esc::ExitApp |
A note is that you may not use the < or > symbol currently and also you must strictly follow html style coding patterns. ie you cannot do:
| Code: | | <i><b>hello</i></b> |
You must close tags in the order they were opened:
| Code: | | <i><b>hello</b></i> |
I will add the ability to specify a width and text will be wrapped accordingly, and will also add the ability to specify font and size. There may be many bugs and that is why i have not updated this to the top post. Please inform me of all of them.
Enjoy
Last edited by tic on Sat Dec 22, 2007 5:23 pm; edited 1 time in total |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4078 Location: Pittsburgh
|
Posted: Sat Dec 22, 2007 5:00 pm Post subject: |
|
|
Very useful!
I’d also had use of super/subscripts, if possible. They are useful in describing algorithms, adding footnotes, etc. If we had fractions, long sqrt signs (covering a whole expression) professional looking help screens could be popped up, without using richedit or IE controls. |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Sat Dec 22, 2007 5:21 pm Post subject: |
|
|
Glad I got your seal of approval Lasz
| Quote: |
professional looking help screens could be popped up, without using richedit or IE controls. |
I completely agree. I think it looks "tacky" using richedit/ie... controls as it doesnt look flush with the gui. It just looks stuck on.
I have found myself several times writing a credits gui or something similar in my programs, ie Amun, and found it more than annoying to switch continually between bold, italic and normal text, and that doesnt even include all the other styles im not using.
I am just adding in now the ability to use < and > without it destroying the persons script, and then will move on to the user being able to specify a width for the control, which might prove troublesome
The problem is that i would need to know the width of the next word before it was created! If I knew afterwards then I could wrap back round, but this would be inaccurate, as the previous word would have already exceeded its allocated width. The only way I can think to properly do this, (and i probably wont use this method though) is to actually create the whole thing first, read all the widths, and then create it again, once knowing the calculated widths
As you can see any help with ideas will be very helpful! |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Sat Dec 22, 2007 6:09 pm Post subject: |
|
|
| Using < and > no longer ruins coding, and can be used as long as they do not have the letter c,s,w,b,i,d,u,f directly to the right of a < |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Sat Dec 22, 2007 11:19 pm Post subject: |
|
|
I dont have any idea how to get the heights and widths of the text before its added, so I didnt want to do this, but may have to.....
does anyone know how to find the 1st gui that doesnt exist.
ie... My program is already using Gui, 1 through to Gui, 5
So I want to find what is the 1st number of a gui thats not being used, so i want to find the number 6.
Any ideas?
Edit:
Or is there a way to create a gui (like you would normally Gui, 99:Add, text) except that it wouldnt intefere with any exisitng guis, so basically can a gui be created that isnt gui 1-99 but is something else?
It just needs to be created and then immediately destroyed, without even showing it. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2739 Location: Australia, Qld
|
Posted: Sun Dec 23, 2007 12:12 am Post subject: |
|
|
| tic wrote: | | So I want to find what is the 1st number of a gui thats not being used, so i want to find the number 6. |
| Code: | Loop, 99
{
Gui, %A_Index%:+LastFoundExist
ifWinNotExist
{
N := A_Index
break
}
}
Msgbox %N% |
| Quote: | | Unlike other options, LastFoundExist is recognized only when no other options appear on the same line. +LastFoundExist is the same as +LastFound except that the window is not created if it does not already exist. The main use for this is to detect whether a particular GUI window exists. |
|
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2739 Location: Australia, Qld
|
Posted: Sun Dec 23, 2007 3:51 am Post subject: |
|
|
| tic wrote: | | I think it looks "tacky" using richedit/ie... controls as it doesnt look flush with the gui. It just looks stuck on. |
I disagree.
Uses two IE controls (GuiAddHtml) and a Text control. The second IE control has text and an image.
| Code: | GuiAddHtml(html, Options="") ; (only positioning options should be used)
{
IE_Init()
Gui, +LastFound
if ! RegExMatch(Options, "(?<!\S)W(\d+)", w)
w1 := 100
ie := IE_Add(WinExist(), 0, 0, w1, 100)
WinSet, ExStyle, -0x200, % "ahk_id " COM_AtlAxGetContainer(ie)
IE_LoadURL(ie, "about:blank")
doc := IE_Document(ie)
COM_Invoke(doc, "write", html)
COM_Invoke(doc, "close")
body := COM_Invoke(doc, "body")
if !(w && RegExMatch(Options, "(?<!\S)H\d+"))
{
; Wait up to one second for document to load, in case images were specified.
Loop 10 {
if COM_Invoke(doc, "readyState") = "complete"
break
Sleep, 100
}
; body.offsetHeight seems to simply be the height of the control,
; so use the bottom of the lowest element.
h := 0
all := COM_Invoke(body, "all")
Loop % COM_Invoke(all, "length") {
item := COM_Invoke(all, "item", A_Index-1)
x := COM_Invoke(item, "clientLeft") + COM_Invoke(item, "offsetLeft")
+ COM_Invoke(item, "offsetWidth")
y := COM_Invoke(item, "clientTop") + COM_Invoke(item, "offsetTop")
+ COM_Invoke(item, "offsetHeight")
if (y > h)
h := y
if (x > w1)
w1 := x
COM_Release(item)
}
COM_Release(all)
}
COM_Release(body)
COM_Release(doc)
Gui, Add, Text, W%w1% H%h% %Options% hwndhtext Hidden, guihtml%ie%
GuiControlGet, t, Pos, guihtml%ie%
IE_Move(ie, tX, tY, tW, tH)
return ie
} |
The default width is 100, though it will be expanded automatically if necessary. Height is calculated automatically (if not specified), and a hidden Text control is added to allow the next added control to be positioned automatically.
Example usage:
| Code: | ; Get COLOR_3DFACE (default GUI colour.)
SetFormat, Integer, H
bgc := DllCall("GetSysColor","int",15)
bgc := bgc >> 16 | bgc & 0xFF00 | (bgc & 0xFF) << 16
bgc := SubStr("000000" SubStr(bgc, 3), -5)
SetFormat, Integer, D
html =
(
<body bgcolor="#%bgc%" scroll="no" style="margin: 0">
... html content ...<br>
</body>
)
GuiAddHtml(html, "W135")
Gui, Show |
The <br> is necessary (in the example) because the auto-sizing code only considers elements descended from body (i.e. not raw text directly contained by the body element.)
Edit: I forgot to mention - GuiAddHtml requires IE.ahk and COM.ahk. |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Sun Dec 23, 2007 1:04 pm Post subject: |
|
|
Thank you very much for the example Lex. As always your advice is 2nd to none
Very cool. It seems a tiny bit slow to complete, but I think thats fine.
Here is the full code for anyone that wants to try it (I know people hate me taking functions out of the standard library etc... but I just cant help it. I hate to include all that code when its not needed )
I would like to wrap all this into 1 easy to use function and add some of my own options. As long as no-one has any objections Id like to neaten this and supercede my function with this
| Code: | ; Get COLOR_3DFACE (default GUI colour.)
SetFormat, Integer, H
bgc := DllCall("GetSysColor","int",15)
bgc := bgc >> 16 | bgc & 0xFF00 | (bgc & 0xFF) << 16
bgc := SubStr("000000" SubStr(bgc, 3), -5)
SetFormat, Integer, D
html =
(
<body bgcolor="#%bgc%" scroll="no" style="margin: 0">
<html>
<body>
<b>This text is bold</b>
<br>
<strong>
This text is strong
</strong>
<br>
<big>
This text is big
</big>
<br>
<em>
This text is emphasized
</em>
<br>
<i>
This text is italic
</i>
<br>
<small>
This text is small
</small>
<br>
This text contains
<sub>
subscript
</sub>
<br>
This text contains
<sup>
superscript
</sup>
</body>
</html><br>
</body>
)
GuiAddHtml(html, "W200")
Gui, Show
Return
GuiAddHtml(html, Options="") ; (only positioning options should be used)
{
IE_Init()
Gui, +LastFound
if ! RegExMatch(Options, "(?<!\S)W(\d+)", w)
w1 := 100
ie := IE_Add(WinExist(), 0, 0, w1, 100)
WinSet, ExStyle, -0x200, % "ahk_id " COM_AtlAxGetContainer(ie)
IE_LoadURL(ie, "about:blank")
doc := IE_Document(ie)
COM_Invoke(doc, "write", html)
COM_Invoke(doc, "close")
body := COM_Invoke(doc, "body")
if !(w && RegExMatch(Options, "(?<!\S)H\d+"))
{
; Wait up to one second for document to load, in case images were specified.
; Loop 10 {
; if COM_Invoke(doc, "readyState") = "complete"
; break
; Sleep, 100
; }
; body.offsetHeight seems to simply be the height of the control,
; so use the bottom of the lowest element.
h := 0
all := COM_Invoke(body, "all")
Loop % COM_Invoke(all, "length") {
item := COM_Invoke(all, "item", A_Index-1)
x := COM_Invoke(item, "clientLeft") + COM_Invoke(item, "offsetLeft")
+ COM_Invoke(item, "offsetWidth")
y := COM_Invoke(item, "clientTop") + COM_Invoke(item, "offsetTop")
+ COM_Invoke(item, "offsetHeight")
if (y > h)
h := y
if (x > w1)
w1 := x
COM_Release(item)
}
COM_Release(all)
}
COM_Release(body)
COM_Release(doc)
Gui, Add, Text, W%w1% H%h% %Options% hwndhtext Hidden, guihtml%ie%
GuiControlGet, t, Pos, guihtml%ie%
IE_Move(ie, tX, tY, tW, tH)
return ie
}
Esc::ExitApp
IE_Init()
{
COM_AtlAxWinInit()
}
COM_AtlAxWinInit(Version = "")
{
COM_CoInitialize()
If Not DllCall("GetModuleHandle", "str", "atl" . Version)
DllCall("LoadLibrary" , "str", "atl" . Version)
Return DllCall("atl" . Version . "\AtlAxWinInit")
}
COM_CoInitialize()
{
Return DllCall("ole32\CoInitialize", "Uint", 0)
}
IE_Add(hWnd, x, y, w, h)
{
Return COM_AtlAxGetControl(COM_AtlAxCreateContainer(hWnd, x, y, w, h, "Shell.Explorer"))
}
COM_AtlAxCreateContainer(hWnd, l, t, w, h, Name = "", Version = "")
{
Return DllCall("CreateWindowEx", "Uint",0x200, "str", "AtlAxWin" . Version, "Uint", Name ? &Name : 0, "Uint", 0x54000000, "int", l, "int", t, "int", w, "int", h, "Uint", hWnd, "Uint", 0, "Uint", 0, "Uint", 0)
}
COM_AtlAxGetControl(hWnd, Version = "")
{
If DllCall("atl" . Version . "\AtlAxGetControl", "Uint", hWnd, "UintP", punk)=0
pdsp:=COM_QueryInterface(punk), COM_Release(punk)
Return pdsp
}
COM_QueryInterface(ppv, IID = "")
{
If DllCall(NumGet(NumGet(1*ppv)+0), "Uint", ppv, "Uint", COM_GUID4String(IID,IID ? IID : IID=0 ? "{00000000-0000-0000-C000-000000000046}" : "{00020400-0000-0000-C000-000000000046}"), "UintP", ppv)=0
Return ppv
}
COM_GUID4String(ByRef CLSID, String)
{
VarSetCapacity(CLSID, 16)
DllCall("ole32\CLSIDFromString", "Uint", COM_Unicode4Ansi(String,String,38), "Uint", &CLSID)
Return &CLSID
}
COM_Unicode4Ansi(ByRef wString, sString, nSize = "")
{
If (nSize = "")
nSize:=DllCall("kernel32\MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sString, "int", -1, "Uint", 0, "int", 0)
VarSetCapacity(wString, nSize * 2 + 1)
DllCall("kernel32\MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sString, "int", -1, "Uint", &wString, "int", nSize + 1)
Return &wString
}
COM_AtlAxGetContainer(pdsp)
{
DllCall(NumGet(NumGet(1*pdsp)+ 0), "Uint", pdsp, "Uint", COM_GUID4String(IID_IOleWindow,"{00000114-0000-0000-C000-000000000046}"), "UintP", pwin)
DllCall(NumGet(NumGet(1*pwin)+12), "Uint", pwin, "UintP", hCtrl)
DllCall(NumGet(NumGet(1*pwin)+ 8), "Uint", pwin)
Return DllCall("GetParent", "Uint", hCtrl)
}
IE_LoadURL(pwb, u)
{
pUrl := COM_SysAllocString(u)
VarSetCapacity(var, 8 * 2, 0)
DllCall(NumGet(NumGet(1*pwb)+44), "Uint", pwb, "Uint", pUrl, "Uint", &var, "Uint", &var, "Uint", &var, "Uint", &var)
COM_SysFreeString(pUrl)
}
COM_SysFreeString(bstr)
{
Return DllCall("oleaut32\SysFreeString", "Uint", bstr)
}
COM_SysAllocString(sString)
{
Return DllCall("oleaut32\SysAllocString", "Uint", COM_Ansi2Unicode(sString,wString))
}
COM_Ansi2Unicode(ByRef sString, ByRef wString, nSize = "")
{
If (nSize = "")
nSize:=DllCall("kernel32\MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sString, "int", -1, "Uint", 0, "int", 0)
VarSetCapacity(wString, nSize * 2 + 1)
DllCall("kernel32\MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sString, "int", -1, "Uint", &wString, "int", nSize + 1)
Return &wString
}
IE_Document(pwb)
{
DllCall(NumGet(NumGet(1*pwb)+72), "Uint", pwb, "UintP", pdoc)
Return pdoc
}
COM_Invoke(pdisp, sName, arg0="vT_NoNe",arg1="vT_NoNe",arg2="vT_NoNe",arg3="vT_NoNe",arg4="vT_NoNe",arg5="vT_NoNe",arg6="vT_NoNe",arg7="vT_NoNe",arg8="vT_NoNe",arg9="vT_NoNe")
{
Global _hResult_
sParams := 0123456789
Loop, Parse, sParams
If (arg%A_LoopField% == "vT_NoNe")
{
nParams := A_Index - 1
Break
}
sParams := SubStr(sParams,1,nParams)
VarSetCapacity(DispParams,16,0), VarSetCapacity(varResult,16,0), VarSetCapacity(IID_NULL,16,0), VarSetCapacity(varg,nParams*16,0)
NumPut(&varg,DispParams,0), NumPut(nParams,DispParams,8)
If (nFlags := SubStr(sName,0) <> "=" ? 3 : 12) = 12
NumPut(&varResult,DispParams,4), NumPut(1,DispParams,12), NumPut(-3,varResult), sName:=SubStr(sName,1,-1)
Loop, Parse, sParams
If arg%A_LoopField% Is Not Integer
NumPut(8,varg,(nParams-A_Index)*16,"Ushort"), NumPut(COM_SysAllocString(arg%A_LoopField%),varg,(nParams-A_Index)*16+8)
Else NumPut(SubStr(arg%A_LoopField%,1,1)="+" ? 9 : 3,varg,(nParams-A_Index)*16,"Ushort"), NumPut(arg%A_LoopField%,varg,(nParams-A_Index)*16+8)
If (0 = _hResult_:=DllCall(NumGet(NumGet(1*pdisp)+20), "Uint", pdisp, "Uint", &IID_NULL, "UintP", COM_Unicode4Ansi(wName, sName), "Uint", 1, "Uint", LCID, "intP", dispID))
&& (0 = _hResult_:=DllCall(NumGet(NumGet(1*pdisp)+24), "Uint", pdisp, "int", dispID, "Uint", &IID_NULL, "Uint", LCID, "Ushort", nFlags, "Uint", &dispParams, "Uint", &varResult, "Uint", 0, "Uint", 0))
&& (3 = nFlags)
Result:=(vt:=NumGet(varResult,0,"Ushort"))=8||vt<0x1000&&DllCall("oleaut32\VariantChangeTypeEx","Uint",&varResult,"Uint",&varResult,"Uint",LCID,"Ushort",1,"Ushort",8)=0 ? COM_Ansi4Unicode(bstr:=NumGet(varResult,8)) . SubStr(COM_SysFreeString(bstr),1,0) : NumGet(varResult,8)
Loop, % nParams
NumGet(varg,(A_Index-1)*16,"Ushort")=8 ? COM_SysFreeString(NumGet(varg,(A_Index-1)*16+8)) : ""
Return Result
}
COM_Ansi4Unicode(pString, nSize = "")
{
If (nSize = "")
nSize:=DllCall("kernel32\WideCharToMultiByte", "Uint", 0, "Uint", 0, "Uint", pString, "int", -1, "Uint", 0, "int", 0, "Uint", 0, "Uint", 0)
VarSetCapacity(sString, nSize)
DllCall("kernel32\WideCharToMultiByte", "Uint", 0, "Uint", 0, "Uint", pString, "int", -1, "str", sString, "int", nSize + 1, "Uint", 0, "Uint", 0)
Return sString
}
COM_Release(ppv)
{
Return DllCall(NumGet(NumGet(1*ppv)+8), "Uint", ppv)
}
IE_Move(pwb, l, t, w, h)
{
WinMove, % "ahk_id " . COM_AtlAxGetContainer(pwb), , l, t, w, h
} |
I had actually nearly finished writing a way to wrap the old version without having to use a new gui. I would add all the text in a straight line, and after each new piece of text was added, then it would check the x position that it was added and its width and then determine whther to guicontrol it to the next line and continue from there, which i actually think was a quite neat way to do it. |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|