Code:
;
; Active Window Info
;
#NoEnv
#NoTrayIcon
#SingleInstance Ignore
SetWorkingDir, %A_ScriptDir%
SetBatchLines, -1
CoordMode, Pixel, Screen
; http://www.autohotkey.com/board/topic/26033-scrollable-gui-proof-of-concept/#entry168174
OnMessage(0x115, "OnScroll") ; WM_VSCROLL
OnMessage(0x114, "OnScroll") ; WM_HSCROLL
IfExist, ..\toolicon.icl ; Seems useful enough to support standalone operation.
Menu, Tray, Icon, ..\toolicon.icl, 9
VarSetCapacity(rect, 16)
isUpd := true
txtNotFrozen := "(Win+A to freeze display)"
txtFrozen := "(Win+A to unfreeze display)"
Gui, New, hwndhGui AlwaysOnTop
Gui, +Resize +0x300000 ; WS_VSCROLL | WS_HSCROLL
Gui, Add, Text,, Window Title, Class and process:
Gui, Add, Edit, w320 r3 ReadOnly vCtrl_Title
Gui, Add, Text,, Mouse Position:
Gui, Add, Edit, w320 r3 ReadOnly vCtrl_MousePos
Gui, Add, Text,, Control Under Mouse Position:
Gui, Add, Edit, w320 r3 ReadOnly vCtrl_MouseCur
Gui, Add, Text,, Active Window Position:
Gui, Add, Edit, w320 r2 ReadOnly vCtrl_Pos
Gui, Add, Text,, Status Bar Text:
Gui, Add, Edit, w320 r2 ReadOnly vCtrl_SBText
Gui, Add, Checkbox, vCtrl_IsSlow, Slow TitleMatchMode
Gui, Add, Text,, Visible Text:
Gui, Add, Edit, w320 r3 ReadOnly vCtrl_VisText
Gui, Add, Text,, All Text:
Gui, Add, Edit, w320 r3 ReadOnly vCtrl_AllText
Gui, Add, Text, w320 r1 vCtrl_Freeze, % txtNotFrozen
Gui, Show, AutoSize, Active Window Info
SetTimer, Update, 250
return
Update:
Gui %hGui%:Default
curWin := WinExist("A")
if (curWin = hGui)
return
WinGetTitle, t1
WinGetClass, t2
WinGet, t3, ProcessName, A
GuiControl,, Ctrl_Title, % t1 "`nahk_class " t2 "`nahk_exe " t3
CoordMode, Mouse, Screen
MouseGetPos, msX, msY, msWin, msCtrlHwnd, 2
CoordMode, Mouse, Relative
MouseGetPos, mrX, mrY,, msCtrl
CoordMode, Mouse, Client
MouseGetPos, mcX, mcY
GuiControl,, Ctrl_MousePos, % "Absolute:`t" msX ", " msY " (less often used)`nRelative:`t" mrX ", " mrY " (default)`nClient:`t" mcX ", " mcY " (recommended)"
PixelGetColor, mClr, %msX%, %msY%, RGB
mClr := SubStr(mClr, 3)
mText := "`nColor:`t" mClr " (Red=" SubStr(mClr, 1, 2) " Green=" SubStr(mClr, 3, 2) " Blue=" SubStr(mClr, 5) ")"
if (curWin = msWin)
{
ControlGetText, ctrlTxt, %msCtrl%
mText := "ClassNN:`t" msCtrl "`nText:`t" textMangle(ctrlTxt) mText
} else mText := "`n" mText
GuiControl,, Ctrl_MouseCur, % mText
WinGetPos, wX, wY, wW, wH
DllCall("GetClientRect", "ptr", curWin, "ptr", &rect)
wcW := NumGet(rect, 8, "int")
wcH := NumGet(rect, 12, "int")
GuiControl,, Ctrl_Pos, % "x: " wX "`ty: " wY "`tw: " wW "`th: " wH "`nClient:`t`tw: " wcW "`th: " wcH
sbTxt := ""
Loop
{
StatusBarGetText, ovi, %A_Index%
if ovi =
break
sbTxt .= "(" A_Index "):`t" textMangle(ovi) "`n"
}
StringTrimRight, sbTxt, sbTxt, 1
GuiControl,, Ctrl_SBText, % sbTxt
GuiControlGet, bSlow,, Ctrl_IsSlow
SetTitleMatchMode, % bSlow ? "Slow" : "Fast"
DetectHiddenText, Off
WinGetText, ovVisText
DetectHiddenText, On
WinGetText, ovAllText
GuiControl,, Ctrl_VisText, % ovVisText
GuiControl,, Ctrl_AllText, % ovAllText
return
GuiClose:
ExitApp
GuiSize:
UpdateScrollBars(A_Gui, A_GuiWidth, A_GuiHeight)
; Allow Resizing via Anchor:
Anchor("Ctrl_Title", "w")
Anchor("Ctrl_MousePos", "w")
Anchor("Ctrl_MouseCur", "w")
Anchor("Ctrl_Pos", "w")
Anchor("Ctrl_SBText", "w")
Anchor("Ctrl_VisText", "w")
Anchor("Ctrl_AllText", "w")
Anchor("Ctrl_Freeze", "w")
return
textMangle(x)
{
if pos := InStr(x, "`n")
x := SubStr(x, 1, pos-1), elli := true
if StrLen(x) > 40
{
StringLeft, x, x, 40
elli := true
}
if elli
x .= " (...)"
return x
}
#a::
Gui %hGui%:Default
isUpd := !isUpd
SetTimer, Update, % isUpd ? "On" : "Off"
GuiControl,, Ctrl_Freeze, % isUpd ? txtNotFrozen : txtFrozen
return
#IfWinActive ahk_group MyGui
WheelUp::
WheelDown::
+WheelUp::
+WheelDown::
; SB_LINEDOWN=1, SB_LINEUP=0, WM_HSCROLL=0x114, WM_VSCROLL=0x115
OnScroll(InStr(A_ThisHotkey,"Down") ? 1 : 0, 0, GetKeyState("Shift") ? 0x114 : 0x115, WinExist())
return
#IfWinActive
UpdateScrollBars(GuiNum, GuiWidth, GuiHeight)
{
static SIF_RANGE=0x1, SIF_PAGE=0x2, SIF_DISABLENOSCROLL=0x8, SB_HORZ=0, SB_VERT=1
Gui, %GuiNum%:Default
Gui, +LastFound
; Calculate scrolling area.
Left := Top := 9999
Right := Bottom := 0
WinGet, ControlList, ControlList
Loop, Parse, ControlList, `n
{
GuiControlGet, c, Pos, %A_LoopField%
if (cX < Left)
Left := cX
if (cY < Top)
Top := cY
if (cX + cW > Right)
Right := cX + cW
if (cY + cH > Bottom)
Bottom := cY + cH
}
Left -= 8
Top -= 8
Right += 8
Bottom += 8
ScrollWidth := Right-Left
ScrollHeight := Bottom-Top
; Initialize SCROLLINFO.
VarSetCapacity(si, 28, 0)
NumPut(28, si) ; cbSize
NumPut(SIF_RANGE | SIF_PAGE, si, 4) ; fMask
; Update horizontal scroll bar.
NumPut(ScrollWidth, si, 12) ; nMax
NumPut(GuiWidth, si, 16) ; nPage
DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_HORZ, "uint", &si, "int", 1)
; Update vertical scroll bar.
; NumPut(SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL, si, 4) ; fMask
NumPut(ScrollHeight, si, 12) ; nMax
NumPut(GuiHeight, si, 16) ; nPage
DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_VERT, "uint", &si, "int", 1)
if (Left < 0 && Right < GuiWidth)
x := Abs(Left) > GuiWidth-Right ? GuiWidth-Right : Abs(Left)
if (Top < 0 && Bottom < GuiHeight)
y := Abs(Top) > GuiHeight-Bottom ? GuiHeight-Bottom : Abs(Top)
if (x || y)
DllCall("ScrollWindow", "uint", WinExist(), "int", x, "int", y, "uint", 0, "uint", 0)
}
OnScroll(wParam, lParam, msg, hwnd)
{
static SIF_ALL=0x17, SCROLL_STEP=10
bar := msg=0x115 ; SB_HORZ=0, SB_VERT=1
VarSetCapacity(si, 28, 0)
NumPut(28, si) ; cbSize
NumPut(SIF_ALL, si, 4) ; fMask
if !DllCall("GetScrollInfo", "uint", hwnd, "int", bar, "uint", &si)
return
VarSetCapacity(rect, 16)
DllCall("GetClientRect", "uint", hwnd, "uint", &rect)
new_pos := NumGet(si, 20) ; nPos
action := wParam & 0xFFFF
if action = 0 ; SB_LINEUP
new_pos -= SCROLL_STEP
else if action = 1 ; SB_LINEDOWN
new_pos += SCROLL_STEP
else if action = 2 ; SB_PAGEUP
new_pos -= NumGet(rect, 12, "int") - SCROLL_STEP
else if action = 3 ; SB_PAGEDOWN
new_pos += NumGet(rect, 12, "int") - SCROLL_STEP
else if (action = 5 || action = 4) ; SB_THUMBTRACK || SB_THUMBPOSITION
new_pos := wParam>>16
else if action = 6 ; SB_TOP
new_pos := NumGet(si, 8, "int") ; nMin
else if action = 7 ; SB_BOTTOM
new_pos := NumGet(si, 12, "int") ; nMax
else
return
min := NumGet(si, 8, "int") ; nMin
max := NumGet(si, 12, "int") - NumGet(si, 16) ; nMax-nPage
new_pos := new_pos > max ? max : new_pos
new_pos := new_pos < min ? min : new_pos
old_pos := NumGet(si, 20, "int") ; nPos
x := y := 0
if bar = 0 ; SB_HORZ
x := old_pos-new_pos
else
y := old_pos-new_pos
; Scroll contents of window and invalidate uncovered area.
DllCall("ScrollWindow", "uint", hwnd, "int", x, "int", y, "uint", 0, "uint", 0)
; Update scroll bar.
NumPut(new_pos, si, 20, "int") ; nPos
DllCall("SetScrollInfo", "uint", hwnd, "int", bar, "uint", &si, "int", 1)
}
/*
Function: Anchor
Defines how controls should be automatically positioned relative to the new dimensions of a window 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:
To assume the current window size for the new bounds of a control (i.e. resetting) simply omit the second and third parameters.
However if the control had been created with DllCall() and has its own parent window,
the container AutoHotkey created GUI must be made default with the +LastFound option prior to the call.
For a complete example see anchor-example.ahk.
License:
- Version 4.60a <http://www.autohotkey.net/~polyethene/#anchor>
- Dedicated to the public domain (CC0 1.0) <http://creativecommons.org/publicdomain/zero/1.0/>
*/
; Revised version for 64-bit/unicode - author unknown
; http://www.autohotkey.com/board/topic/91997-gui-anchor-for-current-version-of-ahk/?p=580170
Anchor(i, a := "", r := false) {
static c, cs := 12, cx := 255, cl := 0, g, gs := 8, gl := 0, gpi, gw, gh, z := 0, k := 0xffff, ptr
if z = 0
VarSetCapacity(g, gs * 99, 0), VarSetCapacity(c, cs * cx, 0), ptr := A_PtrSize ? "Ptr" : "UInt", z := true
if !WinExist("ahk_id" . i) {
GuiControlGet t, Hwnd, %i%
if ErrorLevel = 0
i := t
else ControlGet i, Hwnd,, %i%
}
VarSetCapacity(gi, 68, 0), DllCall("GetWindowInfo", "UInt", gp := DllCall("GetParent", "UInt", i), ptr, &gi)
, giw := NumGet(gi, 28, "Int") - NumGet(gi, 20, "Int"), gih := NumGet(gi, 32, "Int") - NumGet(gi, 24, "Int")
if (gp != gpi) {
gpi := gp
loop %gl%
if NumGet(g, cb := gs * (A_Index - 1), "UInt") == gp {
gw := NumGet(g, cb + 4, "Short"), gh := NumGet(g, cb + 6, "Short"), gf := 1
break
}
if !gf
NumPut(gp, g, gl, "UInt"), NumPut(gw := giw, g, gl + 4, "Short"), NumPut(gh := gih, g, gl + 6, "Short"), gl += gs
}
ControlGetPos dx, dy, dw, dh,, ahk_id %i%
loop %cl%
if NumGet(c, cb := cs * (A_Index - 1), "UInt") == i {
if (a = "") {
cf := 1
break
}
giw -= gw, gih -= gh, as := 1, dx := NumGet(c, cb + 4, "Short"), dy := NumGet(c, cb + 6, "Short")
, cw := dw, dw := NumGet(c, cb + 8, "Short"), ch := dh, dh := NumGet(c, cb + 10, "Short")
loop Parse, a, xywh
if A_Index > 1
av := SubStr(a, as, 1), as += 1 + StrLen(A_LoopField)
, d%av% += (InStr("yh", av) ? gih : giw) * (A_LoopField + 0 ? A_LoopField : 1)
DllCall("SetWindowPos", "UInt", i, "UInt", 0, "Int", dx, "Int", dy
, "Int", InStr(a, "w") ? dw : cw, "Int", InStr(a, "h") ? dh : ch, "Int", 4)
if r != 0
DllCall("RedrawWindow", "UInt", i, "UInt", 0, "UInt", 0, "UInt", 0x0101) ; RDW_UPDATENOW | RDW_INVALIDATE
return
}
if cf != 1
cb := cl, cl += cs
bx := NumGet(gi, 48, "UInt"), by := NumGet(gi, 16, "Int") - NumGet(gi, 8, "Int") - gih - NumGet(gi, 52, "UInt")
if cf = 1
dw -= giw - gw, dh -= gih - gh
NumPut(i, c, cb, "UInt"), NumPut(dx - bx, c, cb + 4, "Short"), NumPut(dy - by, c, cb + 6, "Short")
, NumPut(dw, c, cb + 8, "Short"), NumPut(dh, c, cb + 10, "Short")
return true
}