AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Control Anchoring v4 for resizing windows
Goto page Previous  1, 2, 3 ... , 9, 10, 11  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
<
View previous topic :: View next topic  
Author Message
TheIrishThug



Joined: 19 Mar 2006
Posts: 370

PostPosted: Sat Nov 17, 2007 9:05 pm    Post subject: Reply with quote

I have a gui with 3 tabs that each have at least one list view on them. The resize works fine if the gui opens with the default size. I use a ini file to save the previous gui size. Reopening the gui, after closing it at a larger size, opens the gui at the larger size and the listview on the first tab is resized. However the list views on the other tabs are not resized. And since I increase the size of each column based on the gui size, this causes problems with the look of the list views. This was also happening when I was using version 3.3.

Here is a stripped down version of my script just to show the effect I am talking about.
Code:
#SingleInstance, Force
; ------ Collect Variable Preferences
IniRead, LastGuiX, AbsoulteSolution.ini, Gui, guiX, Center
IniRead, LastGuiY, AbsoulteSolution.ini, Gui, guiY, Center
IniRead, LastGuiH, AbsoulteSolution.ini, Gui, guiH, 400
IniRead, LastGuiW, AbsoulteSolution.ini, Gui, guiW, 500
SysGet, VirtualW, 78
SysGet, VirtualH, 79
If (LastGuiX <= 0) Or (LastGuiX >= VirtualW )
  LastGuiX = Center
If (LastGuiY <= 0) Or (LastGuiY >= VirtualH )
  LastGuiY = Center

; ------ Gui
Gui, +Resize -Maximize +MinSize500x400
TabH := LastGuiH - 15
TabW := LastGuiW - 13
ListViewH := LastGuiH - 130
ListViewW := LastGuiW - 30
Gui, Add, Tab, x7 y7 vTabName w%TabW% h%TabH%, Mine|Watch|Table Groups

;Mine Tab
Gui, Tab, Mine
Gui, Add, Text, xp+8 yp+30 w250 vHandsSavedDisplay, Hands Saved: 0
Gui, Add, ListView, xp yp+15 w%ListViewW% h%ListViewH% Sort vTheListView, Hand Number|Winner|Pot ($)|Table
LV_ModifyCol(3, "Float Left")
;LV_ModifyCol(4, 0)
GapAfterListView := ListViewH + 10
CenterX := ListViewW/2 - 62
Gui, Add, CheckBox, xp+%CenterX% yp+%GapAfterListView% vOnlyObservedHands, Only Observed Hands
Gui, Add, Button, xp-35 yp+30 w70 Hidden, Stop
Gui, Add, Button, xp yp w70 , Start
Gui, Add, Button, xp+80 yp , Force Scan
Gui, Add, Button, xp+85 yp w70 gExit, Close

;Watch Tab
Gui, Tab, Watch
Gui, Add, Text, x15 y37 w35 vtxt_tables, Tables:
Gui, Add, ListView, xp yp+19 w323 h306 Sort +LV0x1 vlv_TableList , Priority|Table|Game|Limit|Players|Client|LastHand
LV_ModifyCol(7,0)
Gui, Add, Text, xp+338 yp-19 w34 vtxt_clients, Clients:
Gui, Add, ListView, xp yp+19 w131 h229 Sort +LV0x1 vlv_ClientList, Client|User Name|Machine|Tables
Gui, Add, Button, xp+3 yp+240 w30 vgui_gobutton w30 ,Go
Gui, Add, Button, xp+37 yp-1 w30 vgui_stopbutton w30 , Stop
Gui, Add, Text, xp-37 yp+30 w100 vTableScanTime, Last Scan at:

;Table Groups Tab
Gui, Tab, Table Groups
Gui, Add, Text, x15 y37 w31  vtext_game, Game:
Gui, Add, DropDownList, xp yp+19 Vwhich_game ,
( Join
Limit Hold'em|No-Limit Hold'em|Pot-Limit Hold'em|Omaha|Omaha Hi-Lo|No-Limit Omaha Hi-Lo|Pot-Limit Omaha|Pot-Limit Omaha Hi-Lo|7 Card Stud|7 Stud Hi-Lo|Razz
|SNG (NL Hold'em)|SNG (Limit Hold'em)|SNG (Omaha)|SNG (Omaha H/L)|SNG (PL Omaha)|SNG (PL Omaha H/L)|SNG (7 Stud)|SNG (7 Stud H/L)|SNG (Razz)
)
Gui, Add, Text, xp+130 yp-19 w24 , Limit:
Gui, Add, DropDownList, xp yp+19 vwhich_limit ,
Gui, Add, Text, xp+130 yp-19 w57 vmin_players_txt, Min Players:
Gui, Add, DropDownList, xp yp+19 vplayers_min w40 , 2|3|4|5|6|7|8|9
Gui, Add, Text, xp+67 yp-19 w54 vtables_tops_txt, Max tables:
Gui, Add, DropDownList, xp yp+19 vtables_tops w40 , ---|1|2|3|4|5|6|7|8|9|10
Gui, Add, Text, xp+68 yp-19 w65 vmin_pot_txt, Min. avg. pot:
Gui, Add, Edit, xp yp+19 w30 vmin_pot w30 r1 Number
Gui, Add, Radio, xp-395 yp+31 w36 vgui_typebox Checked , Full
Gui, Add, Radio, xp+51 yp w45 h13 vgui_typebox2 , 6max
Gui, Add, ListView, xp-50 yp+31 w460 h38 vListViewEdit LV0x8000 NoSortHdr Grid , Priority|Game|6max/Full|Limit|Players|Tables|Pot
Gui, Add, ListView, xp yp+48 w460 h200 vListViewPrefs -Hdr -LV0x4 Sort Grid , Priority|Game|6max/Full|Limit|Players|Tables|Pot
LV_ModifyCol(1, "Integer")
;Disable the stop button at startup.
GuiControl, Disable, gui_stopbutton
Gui, Show, x%LastGuiX% y%LastGuiY% w%LastGuiW% h%LastGuiH%, The Absolute Solution (Client %this_client%)
Critical, Off
Return

; ------ Menu & Tray Subroutines
l_reload:
Reload
return
l_listvars:
ListVars
Pause
return
Exit:
GuiClose:
Critical, On
WinGetPos, LastGuiX, LastGuiY, , , The Absolute Solution ahk_class AutoHotkeyGUI
IniWrite, %LastGuiX%, AbsoulteSolution.ini, Gui, guiX
IniWrite, %LastGuiY%, AbsoulteSolution.ini, Gui, guiY
IniWrite, %LastGuiH%, AbsoulteSolution.ini, Gui, guiH
IniWrite, %LastGuiW%, AbsoulteSolution.ini, Gui, guiW
ExitApp
Return
; ------ Other Gui Subroutines
GuiSize:

Anchor("TheListView", "wh")
Anchor("OnlyObservedHands", "y")
Anchor("Stop", "y")
Anchor("Start", "y")
Anchor("Force Scan", "y")
Anchor("Close", "y")
Anchor("TabName", "wh")
Anchor("lv_TableList", "wh")
Anchor("lv_ClientList", "xh")
Anchor("gui_gobutton", "xy")
Anchor("gui_stopbutton", "xy")
Anchor("TableScanTime", "xy")
Anchor("txt_clients", "x")
Anchor("ListViewEdit", "w")
Anchor("ListViewPrefs", "wh")
GuiControlGet, txt_tables, Pos

Gui, ListView, lv_TableList  ; Adjust Listview Col Width
LV_ModifyCol(1, ((A_GuiWidth - txt_tablesX)/1.5)/12)
LV_ModifyCol(2, ((A_GuiWidth - txt_tablesX)/1.5)/4)
LV_ModifyCol(3, ((A_GuiWidth - txt_tablesX)/1.5)/3.5)
LV_ModifyCol(4, ((A_GuiWidth - txt_tablesX)/1.5)/6)
LV_ModifyCol(5, ((A_GuiWidth - txt_tablesX)/1.5)/12)
LV_ModifyCol(6, ((A_GuiWidth - txt_tablesX)/1.5)/12)

Gui, ListView, lv_ClientList
LV_ModifyCol(1, ((A_GuiWidth - txt_tablesX)/3 - 1.25*8*2)/6)
LV_ModifyCol(2, ((A_GuiWidth - txt_tablesX)/3 - 1.25*8*2)/6*3)
LV_ModifyCol(3, 0)
LV_ModifyCol(4, ((A_GuiWidth - txt_tablesX)/3 - 1.25*8*2)/6)

Gui, ListView, ListViewEdit
LV_ModifyCol(1, (A_GuiWidth - 40)/20)
LV_ModifyCol(2, (A_GuiWidth - 40)/3)
LV_ModifyCol(3, (A_GuiWidth - 40)/7)
LV_ModifyCol(4, (A_GuiWidth - 40)/6)
LV_ModifyCol(5, (A_GuiWidth - 40)/10)
LV_ModifyCol(6, (A_GuiWidth - 40)/12)
LV_ModifyCol(7, (A_GuiWidth - 40)/10)

Gui, ListView, ListViewPrefs
LV_ModifyCol(1, (A_GuiWidth - 40)/20)
LV_ModifyCol(2, (A_GuiWidth - 40)/3)
LV_ModifyCol(3, (A_GuiWidth - 40)/7)
LV_ModifyCol(4, (A_GuiWidth - 40)/6)
LV_ModifyCol(5, (A_GuiWidth - 40)/10)
LV_ModifyCol(6, (A_GuiWidth - 40)/12)
LV_ModifyCol(7, (A_GuiWidth - 40)/10)

Gui, ListView, TheListview
LV_ModifyCol(1, (A_GuiWidth - 38)/6)
LV_ModifyCol(2, (A_GuiWidth - 38)/3)
LV_ModifyCol(3, (A_GuiWidth - 38)/6)
LV_ModifyCol(4, (A_GuiWidth - 38)/3)

LastGuiH = %A_GuiHeight%
LastGuiW = %A_GuiWidth%
Return

Anchor(cl, a = "", r = false) {
   static d, g, sd = 12, sg := 13, sc = 0, k = 0xffff, iz = 0, bx, by
   If !iz
      iz := 1, VarSetCapacity(g, sg * 99, 0), VarSetCapacity(d, sd * 200, 0)
   Gui, %A_Gui%:+LastFound
   If cl is xdigit
      c = %cl%
   Else {
      GuiControlGet, c, Hwnd, %cl%
      If ErrorLevel
         ControlGet, c, Hwnd, , %cl%
   }
   If !(A_Gui or c) and a
      Return
   cg := (A_Gui - 1) * sg
   Loop, %sc%
      If NumGet(d, z := (A_Index - 1) * sd) = c {
         p := NumGet(d, z + 4, "UInt64"), l := 1
            , x := p >> 48, y := p >> 32 & k, w := p >> 16 & k, h := p & k
            , gw := (gh := NumGet(g, cg + 1)) >> 16, gh &= k
         If a =
            Break
         Loop, Parse, a, xywh
            If A_Index > 1
            {
               v := SubStr(a, l, 1)
               If v in y,h
                  n := A_GuiHeight - gh
               Else n := A_GuiWidth - gw
               b = %A_LoopField%
               %v% += n * (b + 0 ? b : 1), l += StrLen(A_LoopField) + 1
            }
            DllCall("SetWindowPos", "UInt", c, "Int", 0
               , "Int", x, "Int", y, "Int", w, "Int", h, "Int", 4)
            If r
               VarSetCapacity(rc, 16, 0), NumPut(x, rc, 0, "Int"), NumPut(y, rc, 4, "Int")
                  , NumPut(w + x, rc, 8, "Int"), NumPut(h + y, rc, 12, "Int")
                  , DllCall("InvalidateRect", "UInt", WinExist(), "UInt", &rc, "UInt", true)
            Return
      }
   ControlGetPos, x, y, w, h, , ahk_id %c%
   If !p {
      If NumGet(g, cg, "UChar") != A_Gui {
         WinGetPos, , , , gh
         gh -= A_GuiHeight
         VarSetCapacity(bdr, 63, 0)
            , DllCall("GetWindowInfo", "UInt", WinExist(), "UInt", &bdr)
            , NumPut(A_Gui, g, cg, "UChar")
            , NumPut(A_GuiWidth << 16 | A_GuiHeight, g, cg + 1, "UInt")
            ,  NumPut((bx := NumGet(bdr, 48)) << 32
            | (by := gh - NumGet(bdr, 52)), g, cg + 5, "UInt64")
      }
      Else b := NumGet(g, cg + 5, "UInt64"), bx := b >> 32, by := b & 0xffffffff
   }
   s := x - bx << 48 | y - by << 32 | w << 16 | h
   If p
      NumPut(s, d, z + 4, "UInt64")
   Else NumPut(c, d, sc * 12), NumPut(s, d, sc * 12 + 4, "UInt64"), sc++
}
Back to top
View user's profile Send private message Visit poster's website AIM Address
haichen



Joined: 05 Feb 2007
Posts: 110
Location: Osnabrück, Germany

PostPosted: Sun Nov 18, 2007 1:39 am    Post subject: Reply with quote

You have static values for height and width of your non-resizing listviews.
So they start with that height-and widthvalues.

At the first Listview you calculate the height and width from the saved values.
You have to do this also for the other listviews.

Anchor changes existing controls not the starting height and width.
Back to top
View user's profile Send private message
jballi



Joined: 01 Oct 2005
Posts: 349
Location: Texas, USA

PostPosted: Sun Nov 18, 2007 2:08 am    Post subject: Reply with quote

haichen wrote:
You have static values for height and width of your non-resizing listviews.
So they start with that height-and widthvalues.

At the first Listview you calculate the height and width from the saved values.
You have to do this also for the other listviews.

Anchor changes existing controls not the starting height and width.

Some additional thoughts...

Consider this approach: 1) Create the GUI with (mostly) static W/H values. 2) Show the GUI using the saved X/Y positions and then 3) Move the GUI using the saved W/H values. The "Move" command gets Anchor to do what it does best -- adjust GUI objects to the desired position/size. Steps 2 and 3 would look something like this:
Code:
Gui, Show, x%LastGuiX% y%LastGuiY%, The Absolute Solution (Client %this_client%)
WinMove The Absolute Solution (Client %this_client%),,,,%LastGuiW%,%LastGuiH%

Of course this would require a lot of code changes (Step 1 mostly) but it might make the code easier to manage.

Good luck.
Back to top
View user's profile Send private message
TheIrishThug



Joined: 19 Mar 2006
Posts: 370

PostPosted: Sun Nov 18, 2007 4:53 am    Post subject: Reply with quote

Ok, thanks guys. I needed a fresh set of eyes to see that I was doing things differently for the list views.
Back to top
View user's profile Send private message Visit poster's website AIM Address
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Sat Jan 05, 2008 4:25 pm    Post subject: Reply with quote

How can I reset anchor if I programaticaly move controls around ?

I added in my local copy reset flag that reinitialises your sttic vars and that partialy worked. The new window setup was corerctly resized except when window was maximized/restored.

Check out latest RSS Reader. Play with the separator to see. First move separator, then maximize window. If I just resize the window, everything works normaly.
_________________
Back to top
View user's profile Send private message MSN Messenger
Titan



Joined: 11 Aug 2004
Posts: 5068
Location: imaginationland

PostPosted: Sat Jan 05, 2008 10:46 pm    Post subject: Reply with quote

Version 4.52 uploaded. This is a complete rewrite of version 4 which includes many performance enhancements and the ability to externally reposition controls whilst maintaining their relative anchors.

majkinetor wrote:
How can I reset anchor if I programaticaly move controls around ?
Download the latest version and see lines 22-26 in the demo script.
_________________

RegExReplace("irc.freenode.net/ahk", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2")
Back to top
View user's profile Send private message Visit poster's website
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Sat Jan 05, 2008 11:38 pm    Post subject: Reply with quote

It doesn't work in my script. Check it out. When you move separator and resize window, controls are not reset.

Code:
;Rss Reader v0.21
;by majkinetor
;SetBatchLines, -1
#Singleinstance, force
SetControlDelay, -1
#NoEnv
   if !FileExist("icons\loading.gif"){
      FileCreateDir, icons
      UrlDownloadToFile, http://www.autohotkey.net/~majkinetor/RSS`%20Read/loading.gif, icons\loading.gif
   }
   gosub SetStyle
   
   IE_Init()
   Gui, +LastFound +Resize
   hGui := WinExist()
   height := 800,    width := 1100
   cnt := 0



   tvm := 2.5
   _ := width // tvm - 25
   Gui, Add, ComboBox, x0 y0 w%_%, http://news.google.com/news?ned=us&topic=h&output=atom||http://www.autohotkey.com/forum/rss.php|http://www.mininova.org/rss.php|http://www.ghisler.ch/board/rss.php
   Gui, Add, Button, gOnGo w24 0x8000 x+0,Go

   _ += 25
   hIL := IL_Create(10,10)
   Gui, Add, TreeView, gOnClick ImageList%hIL% y25 x0 w%_% h%height%
   Separator_Create(_)   
   RSS_IE := IE_Add( hGui, _+5, 0, _*(tvm-1), height)
   psink := COM_ConnectObject(RSS_IE, "Web_")

   SetCursor("SIZEWE", "Static1")
   Gui, Show, w%width% h%height%
   
   Gosub, ongo
   
return

Separator_Create(x="+0",y=0,width=5,height=2000){
   local hSep
   WM_LBUTTONDOWN=0x201, WM_LBUTTONUP=0x202, WM_LBUTTONDBLCLK = 0x203
   Gui, Add, Text, HWNDhSep y%y% x%x% w%width% 0x1000  h%heigh%,`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n`n
   
   Separators .= hSep "|"
   Separator_%hSep%_width := width
   OnMessage(WM_LBUTTONDOWN,   "Separator_Handler")
}

Separator_Handler(wparam, lparam, msg, hwnd){
    local ctrl, WM_LBUTTONDOWN=0x201
   
   if (msg=WM_LBUTTONDOWN)   {
       MouseGetPos, ,,, ctrl, 2

      if InStr(Separators, ctrl "|"){
         Separator_hSep := ctrl
         SetTimer, Separator, 20
      }
      return
   }
}

GuiSize:
   Anchor("SysTreeView321", "h")
   Anchor("AtlAxWin1", "wh")
return

Separator:
   Separator_Move()
return

Separator_Move() {
   global Separator_hSep
   static px
   
   if !GetKeyState("LButton")
      SetTimer,  Separator, off
   
   MouseGetPos, x,y,A
   if (px = x)
      return
   else px := x

   if x < 0
      x := px := 5
   ControlMove, , x,,,,ahk_id %Separator_hSep%      

   w := Separator_%Separator_hSep%_width
   ControlMove,   SysTreeView321, ,, x-5,,A
   ControlMove,   ComboBox1, ,, x-30,,A
   ControlMove,   Button1, x-25,,,,A
   ControlGetPos,  x1,,w1,,AtlAxWin1,A
   ControlMove,   AtlAxWin1, x+w,,w1+x1-x-w,,A

   Anchor("SysTreeView321"), Anchor("AtlAxWin1")      ;reset anchor
}

GuiClose:
   FileDelete,  out.html
   ExitApp
return

OnClick:
   if A_GuiEvent!=S
      return
   
   parent := TV_GetParent(A_EventInfo)
   if !parent{
      RSS_ParseFeed()
      return
   }
   c := TV_GetChild(parent)

   loop,
   {
      if (c = A_EventInfo) {
         _ := A_Index
         break
      }
      c := TV_GetNext(c)
   }      
   RSS_ParseItem(_)
return

OnGo:
   ControlGetText,_, Edit1
   RSS_LoadFeed(_)
return

Web_BeforeNavigate2(prms, this) {
   global pwin
   return      
   url := COM_DispGetParam(prms, 1)
   if InStr(url, A_ScriptDir)
      return


   Run, %url%
    NumPut(-1, NumGet(NumGet(prms+0)+8), 0, "short")   ; cancel the navigation
}

RSS_ParseItem( idx ) {
   local xItem, html
     xItem := XML_Node(RSS_Items, idx)

   html = <html><head><style>%RSS_style%</style><body>
   xItem := XML_Node(RSS_Items, idx)
   html .= RSS_GetHtml(xItem) "</body></html>"
   FixHtml(html)
   FileDelete, out.html
   FileAppend, %html%, out.html
   IE_LoadURL(RSS_IE, A_ScriptDir "\out.html")

   pDoc := IE_Document(pwb)
   pWin := COM_Invoke(pDoc, "parentWindow")
}

RSS_LoadFeed(url){
   local xml, tvp, icon, icoNum

   TV_Delete(), IL_Destroy(hIL), hIL := IL_Create(10,10)
   RSS_Status("Loading " url)

   xml := XML_Open(url), icon := RSS_GetIcon(url) 
   RSS_type := XML_selectSingleNode(xml, "/feed") ? "atom" : "rss"
   icoNum := icon ? IL_ADD(hIL, icon) : IL_ADD(hIL, "shell32.dll", 141)
   tvp := TV_Add(XML_NodeText(xml, "//title"), 0, "Expand Icon" iconNum)

   
   RSS_Items := RSS_GetItems(xml)
   RSS_ParseFeed(tvp, icoNum)
}

RSS_GetItems(xml){
   global
   return   XML_selectNodes(xml, RSS_type="rss" ? "//item" : "//entry")
}


RSS_ParseFeed(parent=0, icoNum=0){
   local html, xItem
   
   html = <html><head><style>%RSS_style%</style><body>
   loop % XML_length(RSS_Items)
   {      
      xItem := XML_Node(RSS_Items, A_Index)
      if parent
         TV_Add( XML_NodeText(xItem, "title"), parent, "Icon" icoNum)
      html .= RSS_GetHtml(xItem)
   }
   html .= "</body></html>"
   FixHtml(html)

   FileDelete, out.html
   FileAppend, %html%, out.html
   IE_LoadURL(RSS_IE, A_ScriptDir "\out.html")
   pDoc := IE_Document(pwb)
   pWin := COM_Invoke(pDoc, "parentWindow")

   ;click on IE or scroll bar is bugged
   sleep, 100
   controlclick, Internet Explorer_Server1, ahk_id %hGui%,,,,x-1000 y-1000
}

RSS_GetChannelInfo(xml){
   local c, txt
   c := XML_selectSingleNode(xml,  RSS_type="rss" ? "rss/channel" : "/feed")
   txt := XML_NodeText(c, "title") "<BR>" XML_NodeText(c, RSS_type="rss" ? "description" : "tagline")
   return txt
}


RSS_GetHtml(xItem){
   local html

   html = <div id="post">
   if RSS_type = rss
      html  .= "<a href=""" XML_NodeText(xItem, "link") """>"
           . XML_NodeText(xItem, "title") "</a><br/>"
           . "<p>" XML_NodeText(xItem, "description") "</p></div>"

   else html .= "<h2>" XML_NodeText(xItem, "title")  "</h2></a><br/>"   
           .  "<p>" XML_NodeText(xItem, "content") "</p></div>"            

   return html
}


FixHtml(ByRef html){
    StringReplace, html, html,&lt;,<,A
   StringReplace, html, html,&gt;,>,A
   StringReplace, html, html,&nbsp;,%A_Space%,A
   StringReplace, html, html,&quot;,",A
   StringReplace, html, html,&amp;,&,A
}

RSS_Status(txt, img="icons\loading.gif") {
   global RSS_IE
   FileDelete, out.html
   FileAppend <div align=center style="padding:100px;"><div style="padding:30px;"><img src="%img%"></div><div>%txt%</div></div>, out.html
   IE_LoadURL(RSS_IE, A_ScriptDir "\out.html")
}

RSS_GetIcon(txt){
   global RSS_Type
   if RSS_Type = feed
      return
   RegExMatch(txt, "www\.(.+?)\..+?\/", icon)
   icoUrl = http://%icon%favicon.ico
   icoFn  = icons\%icon1%.ico
   if FileExist( icoFN )
      return icoFn

   UrlDownloadToFile, %icoUrl%, %icoFN%
   if ErrorLevel   
      return
   return icoFn
}




RSS_GetChannel(ByRef hFeed, channel=1, prefix="rssc_"){
   global
   static nodes := "title|link|description|language|copyright|managingEditor|webMaster|pubDate|lastBuildDate|category|generator|docs|cloud|ttl|image|rating|textInput|skipHours|skipDays"
;   loop, parse, nodes, |
;      %prefix%%A_loopField% := xpath(hFeed, "/rss/channel[" channel "]/" A_LoopField "/text()")
}


SetStyle:
      RSS_style =
      (
         .code{
            font-family: "Courier New", Courier, monospace;
            font-size: .8em;
            background:#EAEAEA;   
            border: solid 1px;
            }

         .quote{
            background:white;
         }
         
         #post {
            width:100`%;
            padding:20px;
            background:#E5E5E5;
            margin:10px;
         }
      )
return

;==================== START: #include MSDOM.ahk :B1AD529B-BF4E-477F-8B9F-3080CAC55AE3
;XML test
;   by majkinetor
;   docs: http://msdn2.microsoft.com/en-us/library/aa468547.aspx

xDoc := XML_Open("http://cyber.law.harvard.edu/rss/examples/rss2sample.xml")
if !xDoc
   return

xpath := "//item"
msgbox % DisplayNode( xDoc, 1 )

nodes :=  XML_selectNodes(xDoc, xpath )

msgbox % "XPath: " xpath "`n`n" DisplayNode(nodes)

return

DisplayNode(xcn, single=0, ident="") {
   if single
   xcn := XML_childNodes(xcn)

   loop, % XML_length(xcn)
   {
      xNode := XML_Node(xcn, A_Index)
      if txt := XML_IsTextNode(xNode)
         res .=   ident XML_nodeName(xNode) ": " txt "`n"
      else if XML_hasChildNodes(xNode)
      {
         res .= ident XML_nodeName(xNode) "`n"
         res .= DisplayNode(  XML_childNodes(xNode), 0, ident "   ")
      }
   }

   return res
}





;------------------------------------------------------------------------------

XML_Open( pDoc, pAsync=false, pShowErr=true ){
   COM_CoInitialize()
   xDoc := COM_ActiveXObject("Msxml2.DOMDocument.3.0")
   COM_Invoke(xDoc, "async=", pAsync)
   if COM_Invoke(xDoc, "Load", pDoc)
      return xDoc

   ;error
   if pShowErr
   {
      xPE := COM_Invoke(xDoc, "parseError")
      COM_Invoke(xPE, "errorCode")
      err := "XML Document failed to load`n"
          . "`nError:  "         COM_Invoke(xPE,"errorCode") 
         . "`n"               COM_Invoke(xPE,"reason")
           . "`nLine: "         COM_Invoke(xPe,"Line")
           . "`nLine Position: "   COM_Invoke(xPe,"linepos")
           . "`nFile Position: "   COM_Invoke(xPe,"filepos")
           . "`nSource Text: "      COM_Invoke(xPe,"srcText")
           . "`nDocument URL: "   COM_Invoke(xPe,"url")
   }
   
   return 0
}

XML_NodeText(pNode, xpath="") {
   return COM_Invoke(COM_Invoke(pNode, "selectSingleNode", xpath ? xpath "/text()" : "text()"), "nodeValue")
}

XML_IsTextNode(pNode){
   fc := COM_Invoke(pNode, "firstChild")
   if COM_Invoke(fc, "nodeType" ) = 3 ;NODE_TEXT
      return COM_Invoke(fc, "nodeValue")
}

XML_selectNodes( pNode, xPath ) {
  return COM_Invoke(pNode, "selectNodes", xPath)
}

XML_selectSingleNode( pNode, xPath ) {
  return COM_Invoke(pNode, "selectSingleNode", xPath)
}

XML_nodeType(pNode) {
   static TYPE_1="ELEMENT", TYPE_2="ATTRIBUTE", TYPE_3="TEXT", TYPE_4="CDATA_SECTION", TYPE_5="ENTITY_REFERENCE", TYPE_6="ENTITY", TYPE_7="PROCESSING_INSTRUCTION", TYPE_8="COMMENT", TYPE_9="DOCUMENT", TYPE_10="DOCUMENT_TYPE", TYPE_11="DOCUMENT_FRAGMENT", TYPE_12="NOTATION"
   res := COM_Invoke(pNode,"nodeType")
   return TYPE_%res%
}

XML_nodeName(pNode) {
   return COM_Invoke(pNode, "nodeName")   
}

XML_parentNode(pNode) {
   return COM_Invoke(pNode, "parentNode")
}

XML_firstChild(pNode) {
   return COM_Invoke(pNode, "firstChild")
}

XML_lastChild(pNode) {
   return COM_Invoke(pNode, "lastChild")
}

XML_previousSibling(pNode){
   return COM_Invoke(pNode, "previousSibling")
}

XML_nextSibling(pNode){
   return COM_Invoke(pNode, "nextSibling")
}


XML_hasChildNodes(pNode) {
   return COM_Invoke(pNode, "hasChildNodes")
}

XML_childNodes(pNode) {
   return COM_Invoke(pNode, "childNodes")
}

XML_length(pNodes){
   return COM_Invoke(pNodes, "length")
}

XML_Node(pNodes, idx) {
   return COM_Invoke(pNodes, "Item", idx-1)
}

;==================== END: #include MSDOM.ahk :B1AD529B-BF4E-477F-8B9F-3080CAC55AE3

;==================== START: #include SetCursor.ahk :B1AD529B-BF4E-477F-8B9F-3080CAC55AE3
;Title: SetCursor
;----------------------------------------------------------------------------------------------------------------------------------
; Function:      SetCursor
;            Set cursor shape for control or window
;
; Parameters:
;            pShape   - Name of the system cursor to set, or cursor handle
;            pCtrl   - Class of the control. If omited, cursor will be set for the window
;
; System Cursors:
;      APPSTARTING - Standard arrow and small hourglass
;      ARROW      - Standard arrow
;      CROSS      - Crosshair
;      HAND      - Windows 98/Me, Windows 2000/XP: Hand
;      HELP      - Arrow and question mark
;      IBEAM      - I-beam
;      ICON      - Obsolete for applications marked version 4.0 or later.
;      NO         - Slashed circle
;      SIZE      - Obsolete for applications marked version 4.0 or later. Use IDC_SIZEALL.
;      SIZEALL      - Four-pointed arrow pointing north, south, east, and west
;      SIZENESW   - Double-pointed arrow pointing northeast and southwest
;      SIZENS      - Double-pointed arrow pointing north and south
;      SIZENWSE   - Double-pointed arrow pointing northwest and southeast
;      SIZEWE      - Double-pointed arrow pointing west and east
;      UPARROW      - Vertical arrow
;      WAIT      - Hourglass
;
SetCursor(pShape, pCtrl="") {
   return SetCursor_(pShape, pCtrl, 0, 0)
}

SetCursor_(wparam, lparam, msg, hwnd) {
    static WM_SETCURSOR := 0x20, WM_MOUSEMOVE := 0x200
   static APPSTARTING := 32650,HAND := 32649 ,ARROW := 32512,CROSS := 32515 ,IBEAM := 32513 ,NO := 32648 ,SIZE := 32640 ,SIZEALL := 32646 ,SIZENESW := 32643 ,SIZENS := 32645 ,SIZENWSE := 32642 ,SIZEWE := 32644 ,UPARROW := 32516 ,WAIT := 32514
   static hover, curOld=32512, cursor, ctrls="`n", init

   if !init {
      OnMessage(WM_SETCURSOR, "SetCursor_")
      OnMessage(WM_MOUSEMOVE, "SetCursor_")
   }

   if A_Gui =
   {
      if wparam is not Integer
         cursor := DllCall("LoadCursor", "Uint", 0, "Int", %WPARAM%, "Uint")
      if lparam =
           curOld := cursor
      else  ctrls .= lparam "=" cursor "`n"
   }

   If (msg = WM_SETCURSOR)
      ifEqual, hover, 1,   return 1

   if (msg = WM_MOUSEMOVE)
   {
      MouseGetPos, ,,,c,ahk_id %hwnd%
      If j := InStr(ctrls, "`n" c "=")
      {
         hover := true,
         j += 2+StrLen(c)
         j := SubStr(ctrls, j, InStr(ctrls, "`n", 0, j)-j+1)
         DllCall("SetCursor", "uint",j)
      }
      else DllCall("SetCursor", "uint", curOld), hover := ""
   }
   
}
;---------------------------------------------------------------------------------------------------------------------
; Group: Example
;>   Gui,  SHow, w100 h100
;>   Gui,  Add, Text, , I am <->
;>   Gui,  Add, Text, , I am hand
;>   Gui,  Add, Text, , I am cross
;>   Gui,  Add, Text, , I am size
;>   Gui,  Add, Text, , I am no-no
;>   Gui,  Add, Text, , I am size all
;>   Gui,  Add, Text, , I am a waiting
;>
;>   SetCursor("APPSTARTING")      
;>   SetCursor("SIZEWE", "Static1")
;>   SetCursor("HAND",   "Static2")
;>   SetCursor("CROSS",   "Static3")
;>   SetCursor("SIZENWSE","Static4")
;>   SetCursor("NO",      "Static5")
;>   SetCursor("SIZEALL","Static6")
;>   SetCursor("WAIT",   "Static7")
;>
;>   gui, show, h200 w300
;>return

;---------------------------------------------------------------------------------------------------------------------
; Group: About
;      o Ver 1.0 by majkinetor. See http://www.autohotkey.com/forum/topic19400.html
;      o Licenced under Creative Commons Attribution-Noncommercial <http://creativecommons.org/licenses/by-nc/3.0/>.
;==================== END: #include SetCursor.ahk :B1AD529B-BF4E-477F-8B9F-3080CAC55AE3

;==================== START: #include COM.ahk :B1AD529B-BF4E-477F-8B9F-3080CAC55AE3
COM_Init(bOLE = False)
{
   Return   bOLE ? COM_OleInitialize() : COM_CoInitialize()
}

COM_Term(bOLE = False)
{
   Return   bOLE ? COM_OleUninitialize() : COM_CoUninitialize()
}

COM_VTable(ppv, idx)
{
   Return   NumGet(NumGet(1*ppv)+4*idx)
}

COM_QueryInterface(ppv, IID)
{
   DllCall(NumGet(NumGet(1*ppv)), "Uint", ppv, "Uint", COM_GUID4String(IID,IID), "UintP", ppv)
   Return   ppv
}

COM_AddRef(ppv)
{
   Return   DllCall(NumGet(NumGet(1*ppv)+4), "Uint", ppv)
}

COM_Release(ppv)
{
   Return   DllCall(NumGet(NumGet(1*ppv)+8), "Uint", ppv)
}

COM_QueryService(ppv, SID, IID = "")
{
   DllCall(NumGet(NumGet(1*ppv)+4*0), "Uint", ppv, "Uint", COM_GUID4String(IID_IServiceProvider,"{6D5140C1-7436-11CE-8034-00AA006009FA}"), "UintP", psp)
   DllCall(NumGet(NumGet(1*psp)+4*3), "Uint", psp, "Uint", COM_GUID4String(SID,SID), "Uint", IID ? COM_GUID4String(IID,IID) : &SID, "UintP", ppv)
   DllCall(NumGet(NumGet(1*psp)+4*2), "Uint", psp)
   Return   ppv
}

COM_FindConnectionPoint(pdp, DIID)
{
   DllCall(NumGet(NumGet(1*pdp)+ 0), "Uint", pdp, "Uint", COM_GUID4String(IID_IConnectionPointContainer, "{B196B284-BAB4-101A-B69C-00AA00341D07}"), "UintP", pcc)
   DllCall(NumGet(NumGet(1*pcc)+16), "Uint", pcc, "Uint", COM_GUID4String(DIID,DIID), "UintP", pcp)
   DllCall(NumGet(NumGet(1*pcc)+ 8), "Uint", pcc)
   Return   pcp
}

COM_GetConnectionInterface(pcp)
{
   VarSetCapacity(DIID, 16, 0)
   DllCall(NumGet(NumGet(1*pcp)+12), "Uint", pcp, "Uint", &DIID)
   Return   COM_String4GUID(&DIID)
}

COM_Advise(pcp, psink)
{
   DllCall(NumGet(NumGet(1*pcp)+20), "Uint", pcp, "Uint", psink, "UintP", nCookie)
   Return   nCookie
}

COM_Unadvise(pcp, nCookie)
{
   Return   DllCall(NumGet(NumGet(1*pcp)+24), "Uint", pcp, "Uint", nCookie)
}

COM_Enumerate(penum, ByRef Result)
{
   VarSetCapacity(varResult,16,0)
   If (0 =   _hResult_:=DllCall(NumGet(NumGet(1*penum)+12), "Uint", penum, "Uint", 1, "Uint", &varResult, "UintP", 0))
      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)
   Return   _hResult_
}

COM_Invoke(pdisp, sName, 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_
   nParams:=0
   Loop,   9
      If   (arg%A_Index% == "vT_NoNe")
         Break
      Else   ++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, %   nParams
      If   arg%A_Index% Is Not Integer
               NumPut(8,varg,(nParams-A_Index)*16,"Ushort"), NumPut(COM_SysAllocString(arg%A_Index%),varg,(nParams-A_Index)*16+8)
      Else   NumPut(SubStr(arg%A_Index%,1,1)="+" ? 9 : 3,varg,(nParams-A_Index)*16,"Ushort"), NumPut(arg%A_Index%,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_Invoke_(pdisp, sName, type1="",arg1="",type2="",arg2="",type3="",arg3="",type4="",arg4="",type5="",arg5="",type6="",arg6="",type7="",arg7="",type8="",arg8="",type9="",arg9="")
{
   Global   _hResult_
   nParams:=0
   Loop,   9
      If   (type%A_Index% = "")
         Break
      Else   ++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) <> "=" ? 1|2 : 4|8) & 12
      NumPut(&varResult,dispParams,4), NumPut(1,dispParams,12), NumPut(-3,varResult), sName:=SubStr(sName,1,-1)
   Loop, %   nParams
      NumPut(type%A_Index%,varg,(nParams-A_Index)*16,"Ushort"), type%A_Index%&0x4000=0 ? NumPut(type%A_Index%=8 ? COM_SysAllocString(arg%A_Index%) : arg%A_Index%,varg,(nParams-A_Index)*16+8,type%A_Index%=5||type%A_Index%=7 ? "double" : type%A_Index%=4 ? "float" : "int64") : type%A_Index%=0x400C||type%A_Index%=0x400E ? NumPut(arg%A_Index%,varg,(nParams-A_Index)*16+8) : VarSetCapacity(ref%A_Index%,8,0) . NumPut(&ref%A_Index%,varg,(nParams-A_Index)*16+8) . NumPut(type%A_Index%=0x4008 ? COM_SysAllocString(arg%A_Index%) : arg%A_Index%,ref%A_Index%,0,type%A_Index%=0x4005||type%A_Index%=0x4007 ? "double" : type%A_Index%=0x4004 ? "float" : "int64")
   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
      type%A_Index%&0x4000=0 ? (type%A_Index%=8 ? COM_SysFreeString(NumGet(varg,(nParams-A_Index)*16+8)) : "") : type%A_Index%=0x400C||type%A_Index%=0x400E ? "" : type%A_Index%=0x4008 ? (_TEMP_VT_BYREF_%A_Index%:=COM_Ansi4Unicode(NumGet(ref%A_Index%))) . COM_SysFreeString(NumGet(ref%A_Index%)) : (_TEMP_VT_BYREF_%A_Index%:=NumGet(ref%A_Index%,0,type%A_Index%=0x4005||type%A_Index%=0x4007 ? "double" : type%A_Index%=0x4004 ? "float" : "int64"))
   Return   Result
}

COM_DispInterface(this, prm1="", prm2="", prm3="", prm4="", prm5="", prm6="", prm7="", prm8="")
{
   Critical
   If   A_EventInfo = 6
      DllCall(NumGet(NumGet(NumGet(this+8))+28),"Uint",NumGet(this+8),"Uint",prm1,"UintP",pname,"Uint",1,"UintP",0), VarSetCapacity(sfn,63), DllCall("user32\wsprintfA","str",sfn,"str","%s%S","Uint",this+40,"Uint",pname,"Cdecl"), COM_SysFreeString(pname), (pfn:=RegisterCallback(sfn,"C F")) ? (hResult:=DllCall(pfn, "Uint", prm5, "Uint", this, "Cdecl")) . DllCall("kernel32\GlobalFree", "Uint", pfn) : (hResult:=0x80020003)
   Else If   A_EventInfo = 5
      hResult:=DllCall(NumGet(NumGet(NumGet(this+8))+40),"Uint",NumGet(this+8),"Uint",prm2,"Uint",prm3,"Uint",prm5)
   Else If   A_EventInfo = 4
      NumPut(0,prm3+0), hResult:=0x80004001
   Else If   A_EventInfo = 3
      NumPut(0,prm1+0), hResult:=0
   Else If   A_EventInfo = 2
      NumPut(hResult:=NumGet(this+4)-1,this+4), hResult ? "" : COM_Unadvise(NumGet(this+16),NumGet(this+20)) . COM_Release(NumGet(this+16)) . COM_Release(NumGet(this+8)) . COM_CoTaskMemFree(this)
   Else If   A_EventInfo = 1
      NumPut(hResult:=NumGet(this+4)+1,this+4)
   Else If   A_EventInfo = 0
      COM_IsEqualGUID(this+24,prm1)||InStr("{00020400-0000-0000-C000-000000000046}{00000000-0000-0000-C000-000000000046}",COM_String4GUID(prm1)) ? NumPut(this,prm2+0) . NumPut(NumGet(this+4)+1,this+4) . (hResult:=0) : NumPut(0,prm2+0) . (hResult:=0x80004002)
   Return   hResult
}

COM_DispGetParam(pDispParams, Position = 0, vtType = 8)
{
   VarSetCapacity(varResult,16,0)
   DllCall("oleaut32\DispGetParam", "Uint", pDispParams, "Uint", Position, "Ushort", vtType, "Uint", &varResult, "UintP", nArgErr)
   Return   NumGet(varResult,0,"Ushort")=8 ? COM_Ansi4Unicode(NumGet(varResult,8)) . SubStr(COM_SysFreeString(NumGet(varResult,8)),1,0) : NumGet(varResult,8)
}

COM_CreateIDispatch()
{
   Static   IDispatch
   If Not   VarSetCapacity(IDispatch)
   {
      VarSetCapacity(IDispatch,28,0),   nParams=3112469
      Loop,   Parse,   nParams
      NumPut(RegisterCallback("COM_DispInterface","",A_LoopField,A_Index-1),IDispatch,4*(A_Index-1))
   }
   Return &IDispatch
}

COM_GetDefaultInterface(pdisp, LCID = 0)
{
   DllCall(NumGet(NumGet(1*pdisp) +12), "Uint", pdisp , "UintP", ctinf)
   If   ctinf
   {
   DllCall(NumGet(NumGet(1*pdisp)+16), "Uint", pdisp, "Uint" , 0, "Uint", LCID, "UintP", ptinf)
   DllCall(NumGet(NumGet(1*ptinf)+12), "Uint", ptinf, "UintP", pattr)
   DllCall(NumGet(NumGet(1*pdisp)+ 0), "Uint", pdisp, "Uint" , pattr, "UintP", ppv)
   DllCall(NumGet(NumGet(1*ptinf)+76), "Uint", ptinf, "Uint" , pattr)
   DllCall(NumGet(NumGet(1*ptinf)+ 8), "Uint", ptinf)
   If   ppv
   DllCall(NumGet(NumGet(1*pdisp)+ 8), "Uint", pdisp),   pdisp := ppv
   }
   Return   pdisp
}

COM_GetDefaultEvents(pdisp, LCID = 0)
{
   DllCall(NumGet(NumGet(1*pdisp)+16), "Uint", pdisp, "Uint" , 0, "Uint", LCID, "UintP", ptinf)
   DllCall(NumGet(NumGet(1*ptinf)+12), "Uint", ptinf, "UintP", pattr)
   VarSetCapacity(IID,16), DllCall("RtlMoveMemory", "Uint", &IID, "Uint", pattr, "Uint", 16)
   DllCall(NumGet(NumGet(1*ptinf)+76), "Uint", ptinf, "Uint" , pattr)
   DllCall(NumGet(NumGet(1*ptinf)+72), "Uint", ptinf, "UintP", ptlib, "UintP", idx)
   DllCall(NumGet(NumGet(1*ptinf)+ 8), "Uint", ptinf)
   Loop, %   DllCall(NumGet(NumGet(1*ptlib)+12), "Uint", ptlib)
   {
      DllCall(NumGet(NumGet(1*ptlib)+20), "Uint", ptlib, "Uint", A_Index-1, "UintP", TKind)
      If   TKind <> 5
         Continue
      DllCall(NumGet(NumGet(1*ptlib)+16), "Uint", ptlib, "Uint", A_Index-1, "UintP", ptinf)
      DllCall(NumGet(NumGet(1*ptinf)+12), "Uint", ptinf, "UintP", pattr)
      nCount:=NumGet(pattr+48,0,"Ushort")
      DllCall(NumGet(NumGet(1*ptinf)+76), "Uint", ptinf, "Uint" , pattr)
      Loop, %   nCount
      {
         DllCall(NumGet(NumGet(1*ptinf)+36), "Uint", ptinf, "Uint", A_Index-1, "UintP", nFlags)
         If   !(nFlags & 1)
            Continue
         DllCall(NumGet(NumGet(1*ptinf)+32), "Uint", ptinf, "Uint", A_Index-1, "UintP", hRefType)
         DllCall(NumGet(NumGet(1*ptinf)+56), "Uint", ptinf, "Uint", hRefType , "UintP", prinf)
         DllCall(NumGet(NumGet(1*prinf)+12), "Uint", prinf, "UintP", pattr)
         nFlags & 2 ? DIID:=COM_String4GUID(pattr) : bFind:=COM_IsEqualGUID(pattr,&IID)
         DllCall(NumGet(NumGet(1*prinf)+76), "Uint", prinf, "Uint" , pattr)
         DllCall(NumGet(NumGet(1*prinf)+ 8), "Uint", prinf)
      }
      DllCall(NumGet(NumGet(1*ptinf)+ 8), "Uint", ptinf)
      If   bFind
         Break
   }
   DllCall(NumGet(NumGet(1*ptlib)+ 8), "Uint", ptlib)
   Return   bFind ? DIID : "{00000000-0000-0000-0000-000000000000}"
}

COM_GetGuidOfName(pdisp, Name, LCID = 0)
{
   DllCall(NumGet(NumGet(1*pdisp)+16), "Uint", pdisp, "Uint", 0, "Uint", LCID, "UintP", ptinf)
   DllCall(NumGet(NumGet(1*ptinf)+72), "Uint", ptinf, "UintP", ptlib, "UintP", idx)
   DllCall(NumGet(NumGet(1*ptinf)+ 8), "Uint", ptinf), ptinf:=0
   DllCall(NumGet(NumGet(1*ptlib)+44), "Uint", ptlib, "Uint", COM_Unicode4Ansi(Name,Name), "Uint", 0, "UintP", ptinf, "UintP", memID, "UshortP", 1)
   DllCall(NumGet(NumGet(1*ptlib)+ 8), "Uint", ptlib)
   DllCall(NumGet(NumGet(1*ptinf)+12), "Uint", ptinf, "UintP", pattr)
   GUID := COM_String4GUID(pattr)
   DllCall(NumGet(NumGet(1*ptinf)+76), "Uint", ptinf, "Uint" , pattr)
   DllCall(NumGet(NumGet(1*ptinf)+ 8), "Uint", ptinf)
   Return   GUID
}

COM_GetTypeInfoOfGuid(pdisp, GUID, LCID = 0)
{
   DllCall(NumGet(NumGet(1*pdisp)+16), "Uint", pdisp, "Uint", 0, "Uint", LCID, "UintP", ptinf)
   DllCall(NumGet(NumGet(1*ptinf)+72), "Uint", ptinf, "UintP", ptlib, "UintP", idx)
   DllCall(NumGet(NumGet(1*ptinf)+ 8), "Uint", ptinf), ptinf := 0
   DllCall(NumGet(NumGet(1*ptlib)+24), "Uint", ptlib, "Uint", COM_GUID4String(GUID,GUID), "UintP", ptinf)
   DllCall(NumGet(NumGet(1*ptlib)+ 8), "Uint", ptlib)
   Return   ptinf
}

; A Function Name including Prefix is limited to 63 bytes!
COM_ConnectObject(psource, prefix = "", DIID = "{00020400-0000-0000-C000-000000000046}")
{
   If   (DIID = "{00020400-0000-0000-C000-000000000046}")
      0+(pconn:=COM_FindConnectionPoint(psource,DIID)) ? (DIID:=COM_GetConnectionInterface(pconn))="{00020400-0000-0000-C000-000000000046}" ? DIID:=COM_GetDefaultEvents(psource) : "" : pconn:=COM_FindConnectionPoint(psource,DIID:=COM_GetDefaultEvents(psource))
   Else   pconn:=COM_FindConnectionPoint(psource,SubStr(DIID,1,1)="{" ? DIID : DIID:=COM_GetGuidOfName(psource,DIID))
   If   !pconn || !(ptinf:=COM_GetTypeInfoOfGuid(psource,DIID))
   {
      MsgBox, No Event Interface Exists! Now exit the application.
      ExitApp
   }
   psink:=COM_CoTaskMemAlloc(40+StrLen(prefix)+1), NumPut(1,NumPut(COM_CreateIDispatch(),psink+0)), NumPut(psource,NumPut(ptinf,psink+8))
   DllCall("RtlMoveMemory", "Uint", psink+24, "Uint", COM_GUID4String(DIID,DIID), "Uint", 16)
   DllCall("RtlMoveMemory", "Uint", psink+40, "Uint", &prefix, "Uint", StrLen(prefix)+1)
   NumPut(COM_Advise(pconn,psink),NumPut(pconn,psink+16))
   Return   psink
}

COM_CreateObject(CLSID, IID = "{00020400-0000-0000-C000-000000000046}", CLSCTX = 5)
{
   DllCall("ole32\CoCreateInstance", "Uint", SubStr(CLSID,1,1)="{" ? COM_GUID4String(CLSID,CLSID) : COM_CLSID4ProgID(CLSID,CLSID), "Uint", 0, "Uint", CLSCTX, "Uint", COM_GUID4String(IID,IID), "UintP", ppv)
   Return   ppv
}

COM_ActiveXObject(ProgID)
{
   DllCall("ole32\CoCreateInstance", "Uint", SubStr(ProgID,1,1)="{" ? COM_GUID4String(ProgID,ProgID) : COM_CLSID4ProgID(ProgID,ProgID), "Uint", 0, "Uint", 5, "Uint", COM_GUID4String(IID_IDispatch,"{00020400-0000-0000-C000-000000000046}"), "UintP", pdisp)
   Return   COM_GetDefaultInterface(pdisp)
}

COM_GetObject(Moniker)
{
   DllCall("ole32\CoGetObject", "Uint", COM_Unicode4Ansi(Moniker,Moniker), "Uint", 0, "Uint", COM_GUID4String(IID_IDispatch,"{00020400-0000-0000-C000-000000000046}"), "UintP", pdisp)
   Return   COM_GetDefaultInterface(pdisp)
}

COM_GetActiveObject(ProgID)
{
   DllCall("oleaut32\GetActiveObject", "Uint", SubStr(ProgID,1,1)="{" ? COM_GUID4String(ProgID,ProgID) : COM_CLSID4ProgID(ProgID,ProgID), "Uint", 0, "UintP", punk)
   DllCall(NumGet(NumGet(1*punk)+0), "Uint", punk, "Uint", COM_GUID4String(IID_IDispatch,"{00020400-0000-0000-C000-000000000046}"), "UintP", pdisp)
   DllCall(NumGet(NumGet(1*punk)+8), "Uint", punk)
   Return   COM_GetDefaultInterface(pdisp)
}

COM_CLSID4ProgID(ByRef CLSID, ProgID)
{
   VarSetCapacity(CLSID, 16)
   DllCall("ole32\CLSIDFromProgID", "Uint", COM_Unicode4Ansi(ProgID,ProgID), "Uint", &CLSID)
   Return   &CLSID
}

COM_GUID4String(ByRef CLSID, String)
{
   VarSetCapacity(CLSID, 16)
   DllCall("ole32\CLSIDFromString", "Uint", COM_Unicode4Ansi(String,String,38), "Uint", &CLSID)
   Return   &CLSID
}

COM_ProgID4CLSID(pCLSID)
{
   DllCall("ole32\ProgIDFromCLSID", "Uint", pCLSID, "UintP", pProgID)
   Return   COM_Ansi4Unicode(pProgID) . SubStr(COM_CoTaskMemFree(pProgID),1,0)
}

COM_String4GUID(pGUID)
{
   VarSetCapacity(String, 38 * 2 + 1)
   DllCall("ole32\StringFromGUID2", "Uint", pGUID, "Uint", &String, "int", 39)
   Return   COM_Ansi4Unicode(&String, 38)
}

COM_IsEqualGUID(pGUID1, pGUID2)
{
   Return   DllCall("ole32\IsEqualGUID", "Uint", pGUID1, "Uint", pGUID2)
}

COM_CoCreateGuid()
{
   VarSetCapacity(GUID, 16, 0)
   DllCall("ole32\CoCreateGuid", "Uint", &GUID)
   Return   COM_String4GUID(&GUID)
}

COM_CoTaskMemAlloc(cb)
{
   Return   DllCall("ole32\CoTaskMemAlloc", "Uint", cb)
}

COM_CoTaskMemFree(pv)
{
   Return   DllCall("ole32\CoTaskMemFree", "Uint", pv)
}

COM_CoInitialize()
{
   Return   DllCall("ole32\CoInitialize", "Uint", 0)
}

COM_CoUninitialize()
{
   Return   DllCall("ole32\CoUninitialize")
}

COM_OleInitialize()
{
   Return   DllCall("ole32\OleInitialize", "Uint", 0)
}

COM_OleUninitialize()
{
   Return   DllCall("ole32\OleUninitialize")
}

COM_SysAllocString(sString)
{
   Return   DllCall("oleaut32\SysAllocString", "Uint", COM_Ansi2Unicode(sString,wString))
}

COM_SysFreeString(bstr)
{
   Return   DllCall("oleaut32\SysFreeString", "Uint", bstr)
}

COM_SysStringLen(bstr)
{
   Return   DllCall("oleaut32\SysStringLen", "Uint", bstr)
}

COM_SafeArrayDestroy(psa)
{
   Return   DllCall("oleaut32\SafeArrayDestroy", "Uint", psa)
}

COM_VariantClear(pvarg)
{
   Return   DllCall("oleaut32\VariantClear", "Uint", pvarg)
}

COM_AtlAxWinInit(Version = "")
{
   COM_CoInitialize()
   If !DllCall("GetModuleHandle", "str", "atl" . Version)
       DllCall("LoadLibrary"    , "str", "atl" . Version)
   Return   DllCall("atl" . Version . "\AtlAxWinInit")
}

COM_AtlAxWinTerm(Version = "")
{
   COM_CoUninitialize()
   If hModule:=DllCall("GetModuleHandle", "str", "atl" . Version)
   Return   DllCall("FreeLibrary"    , "Uint", hModule)
}

COM_AtlAxGetControl(hWnd, Version = "")
{
   DllCall("atl" . Version . "\AtlAxGetControl", "Uint", hWnd, "UintP", punk)
   pdsp:=COM_QueryInterface(punk,IID_IDispatch:="{00020400-0000-0000-C000-000000000046}")
   COM_Release(punk)
   Return   pdsp
}

COM_AtlAxAttachControl(pdsp, hWnd, Version = "")
{
   punk:=COM_QueryInterface(pdsp,IID_IUnknown:="{00000000-0000-0000-C000-000000000046}")
   DllCall("atl" . Version . "\AtlAxAttachControl", "Uint", punk, "Uint", hWnd, "Uint", 0)
   COM_Release(punk)
}

COM_AtlAxCreateControl(hWnd, Name, Version = "")
{
   VarSetCapacity(IID_NULL, 16, 0)
   DllCall("atl" . Version . "\AtlAxCreateControlEx", "Uint", COM_Unicode4Ansi(Name,Name), "Uint", hWnd, "Uint", 0, "Uint", 0, "UintP", punk, "Uint", &IID_NULL, "Uint", 0)
   pdsp:=COM_QueryInterface(punk,IID_IDispatch:="{00020400-0000-0000-C000-000000000046}")
   COM_Release(punk)
   Return   pdsp
}

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_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)
}

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_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_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
}

COM_Unicode2Ansi(ByRef wString, ByRef sString, nSize = "")
{
   pString := wString + 0 > 65535 ? wString : &wString
   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_ScriptControl(sCode, sLanguage = "", bEval = False)
{
   COM_CoInitialize()
   psc :=   COM_CreateObject("MSScriptControl.ScriptControl")
   If   sLanguage
      COM_Invoke(psc, "Language=", sLanguage)
   Ret :=   COM_Invoke(psc, bEval ? "Eval" : "ExecuteStatement", sCode)
   COM_Release(psc)
   COM_CoUninitialize()
   Return   Ret
}

;==================== END: #include COM.ahk :B1AD529B-BF4E-477F-8B9F-3080CAC55AE3

;==================== START: #include IE.ahk :B1AD529B-BF4E-477F-8B9F-3080CAC55AE3
IE_Init()
{
   COM_AtlAxWinInit()
}

IE_Term()
{
   COM_AtlAxWinTerm()
}

IE_Add(hWnd, x, y, w, h)
{
   Return   COM_AtlAxGetControl(COM_AtlAxCreateContainer(hWnd, x, y, w, h, "Shell.Explorer"))
}

IE_Move(pwb, l, t, w, h)
{
   WinMove, % "ahk_id " . COM_AtlAxGetContainer(pwb), , l, t, w, h
}

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)
}

IE_LoadHTML(pwb, h)
{
   pUrl := COM_SysAllocString("about:" . h)
   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)
}

IE_GoBack(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+28), "Uint", pwb)
}

IE_GoForward(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+32), "Uint", pwb)
}

IE_GoHome(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+36), "Uint", pwb)
}

IE_GoSearch(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+40), "Uint", pwb)
}

IE_Refresh(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+48), "Uint", pwb)
}

IE_Stop(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+56), "Uint", pwb)
}

IE_Document(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+72), "Uint", pwb, "UintP", pdoc)
   Return   pdoc
}

IE_GetTitle(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+116), "Uint", pwb, "UintP", pTitle)
   COM_Unicode2Ansi(pTitle, sTitle)
   COM_SysFreeString(pTitle)
   Return   sTitle
}

IE_GetUrl(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+120), "Uint", pwb, "UintP", pUrl)
   COM_Unicode2Ansi(pUrl, sUrl)
   COM_SysFreeString(pUrl)
   Return   sUrl
}

IE_Busy(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+124), "Uint", pwb, "shortP", bBusy)
   Return   -bBusy
}

IE_Quit(pwb)            ; iexplore.exe only
{
   DllCall(NumGet(NumGet(1*pwb)+128), "Uint", pwb)
}

IE_hWnd(pwb)            ; iexplore.exe only
{
   DllCall(NumGet(NumGet(1*pwb)+148), "Uint", pwb, "UintP", hIE)
   Return   hIE
}

IE_FullName(pwb)         ; iexplore.exe only
{
   DllCall(NumGet(NumGet(1*pwb)+152), "Uint", pwb, "UintP", pFile)
   COM_Unicode2Ansi(pFile, sFile)
   COM_SysFreeString(pFile)
   Return   sFile
}

IE_GetStatusText(pwb)         ; iexplore.exe only
{
   DllCall(NumGet(NumGet(1*pwb)+176), "Uint", pwb, "UintP", pText)
   COM_Unicode2Ansi(pText, sText)
   COM_SysFreeString(pText)
   Return   sText
}

IE_SetStatusText(pwb, sText = "")   ; iexplore.exe only
{
   pText := COM_SysAllocString(sText)
   DllCall(NumGet(NumGet(1*pwb)+180), "Uint", pwb, "Uint", pText)
   COM_SysFreeString(pText)
}

IE_ReadyState(pwb)
{
/*
   READYSTATE_UNINITIALIZED = 0      ; Default initialization state.
   READYSTATE_LOADING       = 1      ; Object is currently loading its properties.
   READYSTATE_LOADED        = 2      ; Object has been initialized.
   READYSTATE_INTERACTIVE   = 3      ; Object is interactive, but not all of its data is available.
   READYSTATE_COMPLETE      = 4      ; Object has received all of its data.
*/
   DllCall(NumGet(NumGet(1*pwb)+224), "Uint", pwb, "intP", nReady)
   Return   nReady
}

IE_Open(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 1, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_New(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 2, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_Save(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 3, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_SaveAs(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 4, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_Print(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 6, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_PrintPreview(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 7, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_PageSetup(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 8, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_Properties(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 10, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_Cut(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 11, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_Copy(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 12, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_Paste(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 13, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_SelectAll(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 17, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_Find(pwb)
{
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 32, "Uint", 0, "Uint", 0, "Uint", 0)
}

IE_DoFontSize(pwb, s)
{
/*
   s = 4   ; Largest
   s = 3   ; Larger
   s = 2   ; Medium
   s = 1   ; Smaller
   s = 0   ; Smallest
*/
   VarSetCapacity(var, 8 * 2, 0)
   NumPut(3, var, 0)
   NumPut(s, var, 8)
   DllCall(NumGet(NumGet(1*pwb)+216), "Uint", pwb, "Uint", 19, "Uint", 2, "Uint", &var, "Uint", &var)
}

IE_InternetOptions(pwb)
{
   CGID_MSHTML(pwb, 2135)
}

IE_ViewSource(pwb)
{
   CGID_MSHTML(pwb, 2139)
}

IE_AddToFavorites(pwb)
{
   CGID_MSHTML(pwb, 2261)
}

IE_MakeDesktopShortcut(pwb)
{
   CGID_MSHTML(pwb, 2266)
}

IE_SendEMail(pwb)
{
   CGID_MSHTML(pwb, 2288)
}

CGID_MSHTML(pwb, nCmd, nOpt = 0)
{
   pct := COM_QueryInterface(pwb, IID_IOleCommandTarget:="{B722BCCB-4E68-101B-A2BC-00AA00404770}")
   DllCall(NumGet(NumGet(1*pct)+16), "Uint", pct, "Uint", COM_GUID4String(CGID_MSHTML,"{DE4BA900-59CA-11CF-9592-444553540000}"), "Uint", nCmd, "Uint", nOpt, "Uint", 0, "Uint", 0)
   COM_Release(pct)
}

;==================== END: #include IE.ahk :B1AD529B-BF4E-477F-8B9F-3080CAC55AE3

;==================== START: #include Anchor.ahk :B1AD529B-BF4E-477F-8B9F-3080CAC55AE3
/*

   Function: Anchor
      Defines how controls should be automatically positioned relative to the new dimensions of a GUI when resized.
   
   Parameters:
      cl - a control HWND, associated variable name or ClassNN to operate on
      a - (optional) one or more of the anchors: 'x', 'y', 'w' (width) and 'h' (height),
            optionally followed by a relative factor, e.g. "x h0.5"
      r - (optional) true to redraw controls, recommended for GroupBox and Button types
   
   Examples:
> "xy" ; bounds a control to the bottom-left edge of the window
> "w0.5" ; any change in the width of the window will resize the width of the control on a 2:1 ratio
> "h" ; similar to above but directrly proportional to height
   
   Remarks:
      Anchor must always be called within a GuiSize label where AutoHotkey assigns a real value to A_Gui.
      The only exception is when the second and third parameters are omitted to reset the stored positions for a control.
      For a complete example see anchor-example.ahk.
   
   License:
      - Version 4.52 by Titan <http://www.autohotkey.net/~Titan/#anchor>
      - GNU General Public License 3.0 or higher <http://www.gnu.org/licenses/gpl-3.0.txt>

*/

Anchor(i, a = "", r = false) {
   static c, cs = 12, cx = 255, cl = 0, g, gs = 8, z = 0, k = 0xffff, gx = 1
   If z = 0
      VarSetCapacity(g, gs * 99, 0), VarSetCapacity(c, cs * cx, 0), z := true
   If a =
   {
      StringLeft, gn, i, 2
      If gn contains :
      {
         StringTrimRight, gn, gn, 1
         t = 2
      }
      StringTrimLeft, i, i, t ? t : 3
      If gn is not digit
         gn := gx
   }
   Else gn := A_Gui
   If i is not xdigit
   {
      GuiControlGet, t, Hwnd, %i%
      If ErrorLevel = 0
         i := t
      Else ControlGet, i, Hwnd, , %i%
   }
   gb := (gn - 1) * gs
   Loop, %cx%
      If (NumGet(c, cb := cs * (A_Index - 1)) == i) {
         If a =
         {
            cf = 1
            Break
         }
         Else gx := A_Gui
         d := NumGet(g, gb), gw := A_GuiWidth - (d >> 16 & k), gh := A_GuiHeight - (d & k)
            , d := NumGet(c, cb + 4, "UInt64"), as := 1
            , dx := d >> 48, dy := d >> 32 & k, dw := d >> 16 & k, dh := d & k
         Loop, Parse, a, xywh
            If A_Index > 1
               av := SubStr(a, as, 1), as += 1 + StrLen(A_LoopField)
                  , d%av% += (InStr("yh", av) ? gh : gw) * (A_LoopField + 0 ? A_LoopField : 1)
         DllCall("SetWindowPos", "UInt", i, "Int", 0, "Int", dx, "Int", dy, "Int", dw, "Int", dh, "Int", 4)
         If r != 0
            DllCall("RedrawWindow", "UInt", i, "UInt", 0, "UInt", 0, "UInt", 0x0101) ; RDW_UPDATENOW | RDW_INVALIDATE
         NumPut(A_GuiWidth << 16 | A_GuiHeight, gl, gb)
         Return
      }
   ControlGetPos, dx, dy, dw, dh, , ahk_id %i%
   If cf != 1
      cb := cl, cl += cs
   If (!NumGet(g, gb)) {
      Gui, %gn%:+LastFound
      WinGetPos, , , , gh
      VarSetCapacity(pwi, 68, 0)
      DllCall("GetWindowInfo", "UInt", WinExist(), "UInt", &pwi)
      NumPut(((bx := NumGet(pwi, 48)) << 16 | by := gh - A_GuiHeight - NumGet(pwi, 52)), g, gb + 4)
         , NumPut(A_GuiWidth << 16 | A_GuiHeight, g, gb)
   }
   Else d := NumGet(g, gb + 4), bx := d >> 16, by := d & k
   If cf = 1
   {
      Gui, %gn%:+LastFound
      WinGetPos, , , gw, gh
      d := NumGet(g, gb), dw -= gw - (d >> 16) - bx * 2, dh -= gh - (d & k) - by - bx
   }
   NumPut(i, c, cb), NumPut(dx - bx << 48 | dy - by << 32 | dw << 16 | dh, c, cb + 4, "UInt64")
   Return, true
}
;==================== END: #include Anchor.ahk :B1AD529B-BF4E-477F-8B9F-3080CAC55AE3



The relevant code is from line 50 - 100

In your own example, press F10 , resizes right size, press F10, resize right size.
_________________
Back to top
View user's profile Send private message MSN Messenger