http://www.autohotkey.com/de/forum/ptopic3910.html.
Recently at work i needed the possibility to suspend hotkeys and/or pause my scripts.
I thought it would be a good idea to add this functionality to Scriptcontrol from DerRaphael. His original program can restart and close (also compiled) AHK-Scripte. It also starts the standard editor and open the properties of the script. It shows PID, Programname and remote Commandline Parameters in a Listview.
I added Suspend and Pause Support. A special point: You can pause/suspend/end/restart all your scripts with one buttonclick. I added a new function to get the Commandline Parameters so this works also.
Code: Select all
; ScriptControl 1.2.ahk
; Einfache Kontrolle Über alle laufenden AHK Scripte
; Funktionen für Suspend und Pause eingebaut von haichen 2014
; control your running scripts
; added functions for suspend and pause: haichen 2014
; changed function for getting remote parameters
; original version http://www.autohotkey.com/de/forum/ptopic3910.html
; ScriptControl-v1-1.ahk / zLib License Style Relased / (c) & (w) 2008 by derRaphael(at)oleco.net
; most parts of the script are from Lexikos,Titan,Shimanov,Wicked,DerRaphael
#SingleInstance force
#Persistent
#NoEnv
Sendmode, Input
DetectHiddenWindows, ON
SetTitleMatchmode, 2
toggle1 := true
toggle2 := true
WM_COMMAND := 0x111
ID_FILE_SUSPEND := 65404
ID_FILE_PAUSE := 65403
scripttitle:="Script Control 1.2"
rememberxywh:=1
guiheight:= 180 ; initial height
guiwidth:= 400 ; initial width
guix:=(A_ScreenWidth-guiwidth)/2
guiy:=(A_ScreenHeight-guiheight)/2 -2
Menu, cMenu, Add, Editieren / edit, AHKEDIT
Menu, cMenu, Add
Menu, cMenu, Add, Pausieren / pause, AHKPAUSE
Menu, cMenu, Add, Hotkeys Suspendieren / suspend hotkeys, AHKSUSPEND
Menu, cMenu, Add
Menu, cMenu, Add, Neu Starten / restart, AHKRESTART
Menu, cMenu, Add, Beenden / exit, AHKCLOSE
Menu, cMenu, Add
Menu, cMenu, Add, Eigenschaften / properties, AHKPROPS
Menu, Tray, Icon, Shell32.dll, 81
Menu, Tray, NoStandard
Menu, Tray, Add, Skript Liste Anzeigen, AHKSkripts
Menu, Tray, Add, Beenden, AppExit
Menu, Tray, Default, Skript Liste Anzeigen
return
AHKSkripts:
Gui, Submit , NoHide
if WinExist(scripttitle)
{
WinActivate, %scripttitle%
return
}
Gui, Add, ListView, r6 w400 vListView gAHKListe hwndhLV AltSubmit, PID|Name|Parameter|Pause on|Hotkeys off
Gui, Add, Button, x10 y+5 w30 h25 vb1 HWNDb1 gAHKCLOSE, X
Gui, Add, Button, x+5 y+-25 w30 h25 HWNDb2 vb2 gAHKRESTART, R
Gui, Add, Button, x+60 y+-25 w30 h25 HWNDb3 vb3 gAHKPAUSE, P
Gui, Add, Button, x+5 y+-25 w30 h25 HWNDb4 vb4 gAHKSUSPEND,S
Gui, Add, Button, x+5 y+-25 w30 h25 HWNDb5 vb5 gAHKPAUSEALL, P all
Gui, Add, Button, x+5 y+-25 w30 h25 HWNDb6 vb6 gAHKSUSPENDALL, S all
Gui, Add, Button, x+60 y+-25 w30 h25 HWNDb7 vb7 gAHKRESTARTALL, R all
Gui, Add, Button, x+5 y+-25 w30 h25 HWNDb8 vb8 gAHKCLOSEALL, X all
AddToolTip(B1,"Close the script")
AddToolTip(B2," Restart the script")
AddToolTip(B3,"Pause")
AddToolTip(B4,"Disable/Enable Hotkeys")
AddToolTip(B5,"Pause All SCRIPTS")
AddToolTip(B6,"All SCRIPTS Disable/Enable Hotkeys")
AddToolTip(B7,"Restart All SCRIPTS")
AddToolTip(B8,"Close All SCRIPTS")
Gui, +Resize +MinSize
Gui, +ToolWindow +AlwaysOnTop +Resize
Gui, Show,Hide, %scripttitle%
WinWait, %scripttitle%
WinMove,%scripttitle% ,,guix+2, guiy+2, guiwidth+2, guiheight+2
Gui, Show,, %scripttitle%
SetTimer, Update, 500
Gui +LastFound
return
Update:
oListe := Liste
oP := pauseds
oS := suspendeds
Liste := PIDs := PARAMS := suspendeds := pauseds := ShortNames := ""
WinGet, hwnd, List, ahk_class AutoHotkey
; to exclude scriptcontrol.ahk from pause/suspend we need the PID
WinGet, ThisPID, PID, %A_ScriptFullPath% ahk_class AutoHotkey
Loop, %hwnd%
{
ID := hwnd%A_Index%
suspendeds .= ScriptState(ID,"S")
pauseds .= ScriptPaused(ID,"P")
WinGetTitle, Titel, ahk_id %ID%
SkriptPath := RegExReplace(titel, " - AutoHotkey v(.*)", "")
SplitPath,SkriptPath,KurzName
WinGet, PID, PID, %SkriptPath% ahk_class AutoHotkey
Liste .= SkriptPath "`n"
PIDs .= PID "`n"
;QP := QueryParameter(PID)
QP := getParameter(PID)
QP := RegExReplace(QP,"\Q""" A_AhkPath """\E\s+")
QP := RegExReplace(QP,"\Q""" SkriptPath """\E\s+")
PARAMS .= QP "`n"
ShortNames .= KurzName "`n"
}
if (oListe!=Liste) or (oP!=pauseds) or (oS!=suspendeds) {
LV_Delete()
StringSplit,PID,PIDs,`n
StringSplit,PARAM,PARAMS,`n
StringSplit,FullPath,Liste,`n
ShortNames := SubStr(ShortNames,1,-1)
StringSplit,susps,suspendeds
StringSplit,paus,pauseds
StringSplit,ScriptNames,ShortNames,`n
Loop, Parse, ShortNames,`n
{
LV_Add("",PID%A_Index%,A_LoopField, PARAM%A_Index%, paus%A_Index%,susps%A_Index% )
if (lastfokus != "") and (lastfokus = A_LoopField) ;remember last clicked row
LV_Modify(A_Index, "Focus select")
}
LV_ModifyCol(1,"AutoHdr")
LV_ModifyCol(2,"AutoHdr")
}
return
AHKPAUSEALL:
Loop % FullPath0-1
{
Skript := FullPath%A_Index%
if (ThisPID != PID%A_Index%) and (!toggle1 != !paus%A_Index%)
PostMessage, WM_COMMAND, ID_FILE_PAUSE,,, %Skript% ahk_class AutoHotkey
}
toggle1:=!toggle1
lastfokus:=
return
AHKSUSPENDALL:
Loop % FullPath0-1
{
Skript := FullPath%A_Index%
if (ThisPID != PID%A_Index%) and (!toggle2 != !susps%A_Index%)
PostMessage, WM_COMMAND, ID_FILE_SUSPEND,,, %Skript% ahk_class AutoHotkey
}
toggle2:=!toggle2
lastfokus:=
return
AHKCLOSEALL:
Loop % FullPath0-1
{
Skript := FullPath%A_Index%
WinClose, %Skript% ahk_class AutoHotkey
}
return
AHKRESTARTALL:
Loop % FullPath0-1
{
Interpreter := A_AhkPath
Kommando := """" Interpreter """ /restart """ Skript """ " Param
Run, %Kommando%
}
lastfokus:=
return
AHKPAUSE:
GoSub, GetSkript
WM_COMMAND := 0x111
ID_FILE_PAUSE := 65403
PostMessage, WM_COMMAND, ID_FILE_PAUSE,,, %Skript% ahk_class AutoHotkey
return
AHKSUSPEND:
GoSub, GetSkript
WM_COMMAND := 0x111
ID_FILE_SUSPEND := 65404
PostMessage, WM_COMMAND, ID_FILE_SUSPEND,,, %Skript% ahk_class AutoHotkey
return
AHKCLOSE:
GoSub, GetSkript
WinClose, %Skript% ahk_class AutoHotkey
return
AHKRESTART:
GoSub, GetSkript
Interpreter := A_AhkPath
Kommando := """" Interpreter """ /restart """ Skript """ " Param
Run, %Kommando%
return
AHKPROPS:
GoSub, GetSkript
Interpreter := A_AhkPath
Kommando := """" Skript """"
Run, properties %Kommando%
return
AHKEDIT:
GoSub, GetSkript
Interpreter := A_AhkPath
Kommando := """" Skript """"
IfInString, ScriptNames%Zeile%, .ahk
Run, edit %Kommando%
return
GetSkript:
Zeile := LV_GetNext(0, "F")
Skript := FullPath%Zeile%
lastfokus:=ScriptNames%Zeile% ;remember last clicked row
Param := PARAM%Zeile%
return
AHKListe:
If (A_GuiEvent="Normal") {
Zeile := LV_GetNext(0, "F")
ToolTip, % FullPath%Zeile%
SetTimer, TT, 1500
}
return
TT:
SetTimer, TT, OFF
ToolTip
return
GuiContextMenu:
If (A_GuiControl="ListView") {
Menu, cMenu, Show, %A_GuiX%, %A_GuiY%
}
return
GuiSize:
Anchor("ListView", "wh")
Anchor("b1", "y")
Anchor("b2", "y")
Anchor("b3", "y")
Anchor("b4", "y")
Anchor("b5", "y")
Anchor("b6", "y")
Anchor("b7", "y")
Anchor("b8", "y")
Return
GuiClose:
GuiEscape:
WinGetPos, guix, guiy, guiwidth, guiheight, A
Liste := ""
Gui, Destroy
SetTimer, Update, OFF
return
AppExit:
ExitApp
ScriptSuspend(scriptHWND, SuspendOn:="")
{
SetTitleMatchMode, 2
; Get the HWND of the script's main window (which is usually hidden).
dhw := A_DetectHiddenWindows
DetectHiddenWindows On
if scriptHWND
{
; This constant is defined in the AutoHotkey source code (resource.h):
static ID_FILE_SUSPEND := 65404
; Get the menu bar.
mainMenu := DllCall("GetMenu", "ptr", scriptHWND)
; Get the File menu.
fileMenu := DllCall("GetSubMenu", "ptr", mainMenu, "int", 0)
; Get the state of the menu item.
state := DllCall("GetMenuState", "ptr", fileMenu, "uint", ID_FILE_SUSPEND, "uint", 0)
; Get the checkmark flag.
isSuspended := state >> 3 & 1
; Clean up.
DllCall("CloseHandle", "ptr", fileMenu)
DllCall("CloseHandle", "ptr", mainMenu)
; if (!SuspendOn != !isSuspended)
; SendMessage 0x111, ID_FILE_SUSPEND,,, ahk_id %scriptHWND%
; Otherwise, it's already in the right state.
}
DetectHiddenWindows %dhw%
return isSuspended
}
ScriptPaused(scriptHWND, SuspendOn:="")
{
;Lexikosv
SetTitleMatchMode, 2
; Get the HWND of the script's main window (which is usually hidden).
dhw := A_DetectHiddenWindows
DetectHiddenWindows On
if scriptHWND
{
; This constant is defined in the AutoHotkey source code (resource.h):
static ID_FILE_SUSPEND := 65404
static ID_FILE_PAUSE := 65403
static WM_ENTERMENULOOP := 0x211
static WM_EXITMENULOOP := 0x212
SendMessage WM_ENTERMENULOOP, ,,, ahk_id %scriptHWND%
SendMessage WM_EXITMENULOOP, ,,, ahk_id %scriptHWND%
; Get the menu bar.
mainMenu := DllCall("GetMenu", "ptr", scriptHWND)
; Get the File menu.
fileMenu := DllCall("GetSubMenu", "ptr", mainMenu, "int", 0)
; Get the state of the menu item.
state := DllCall("GetMenuState", "ptr", fileMenu, "uint", ID_FILE_PAUSE, "uint", 0)
; Get the checkmark flag.
isPaused := state >> 3 & 1
; Clean up.
DllCall("CloseHandle", "ptr", fileMenu)
DllCall("CloseHandle", "ptr", mainMenu)
; if (!SuspendOn != !isSuspended)
; SendMessage 0x111, ID_FILE_SUSPEND,,, ahk_id %scriptHWND%
; Otherwise, it's already in the right state.
}
DetectHiddenWindows %dhw%
return isPaused
}
ScriptState(scriptHWND, SorP)
{
;Lexikos
;SorP= S Suspend or P Pause
;SetTitleMatchMode, 2
; Get the HWND of the script's main window (which is usually hidden).
dhw := A_DetectHiddenWindows
DetectHiddenWindows On
if scriptHWND
{
; This constant is defined in the AutoHotkey source code (resource.h):
static ID_FILE_SUSPEND := 65404
static ID_FILE_PAUSE := 65403
static WM_ENTERMENULOOP := 0x211
static WM_EXITMENULOOP := 0x212
if (SorP = "P"){
ID_FILE_SorP := ID_FILE_PAUSE
SendMessage WM_ENTERMENULOOP, ,,, ahk_id %scriptHWND%
SendMessage WM_EXITMENULOOP, ,,, ahk_id %scriptHWND%
}
else if (SorP = "S")
ID_FILE_SorP := ID_FILE_SUSPEND
; Get the menu bar.
mainMenu := DllCall("GetMenu", "ptr", scriptHWND)
; Get the File menu.
fileMenu := DllCall("GetSubMenu", "ptr", mainMenu, "int", 0)
; Get the state of the menu item.
state := DllCall("GetMenuState", "ptr", fileMenu, "uint", ID_FILE_SorP, "uint", 0)
; Get the checkmark flag.
currentstate := state >> 3 & 1
; Clean up.
DllCall("CloseHandle", "ptr", fileMenu)
DllCall("CloseHandle", "ptr", mainMenu)
; if (!SuspendOn != !isSuspended)
; SendMessage 0x111, ID_FILE_SUSPEND,,, ahk_id %scriptHWND%
; Otherwise, it's already in the right state.
}
DetectHiddenWindows %dhw%
return currentstate
}
/*
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/>
*/
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
If z = 0
VarSetCapacity(g, gs * 99, 0), VarSetCapacity(c, cs * cx, 0), 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), "UInt", &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)) == gp) {
gw := NumGet(g, cb + 4, "Short"), gh := NumGet(g, cb + 6, "Short"), gf := 1
Break
}
If (!gf)
NumPut(gp, g, gl), 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)) == 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, "Int", 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), by := NumGet(gi, 16, "Int") - NumGet(gi, 8, "Int") - gih - NumGet(gi, 52)
If cf = 1
dw -= giw - gw, dh -= gih - gh
NumPut(i, c, cb), 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
}
AddToolTip(CtrlHwnd,text,Modify=0) { ; ***** Add Multiline ToolTips to any Gui Control ***** [ AHK, AHK_L compatible ]
;Author Art http://www.autohotkey.com/board/topic/27670-add-tooltips-to-controls/page-2#entry431059
Static TThwnd, GuiHwnd, Ptr ; - 'Text' and 'Picture' Controls requires a g-label to be defined.
If (!TThwnd){ ; - 'ComboBox' = Drop-Down button + Edit (Get hWnd of the 'Edit' control using "ControlGet" command).
Gui,+LastFound ; - 'ListView' = ListView + Header (Get hWnd of the 'Header' control using "ControlGet" command).
GuiHwnd:=WinExist()
TThwnd:=DllCall("CreateWindowEx","Uint",0,"Str","TOOLTIPS_CLASS32","Uint",0,"Uint",2147483648 | 3,"Uint",-2147483648
,"Uint",-2147483648,"Uint",-2147483648,"Uint",-2147483648,"Uint",GuiHwnd,"Uint",0,"Uint",0,"Uint",0)
Ptr:=(A_PtrSize ? "Ptr" : "UInt"), DllCall("uxtheme\SetWindowTheme","Uint",TThwnd,Ptr,0,"UintP",0) ; TTM_SETWINDOWTHEME
}
Varsetcapacity(TInfo,44,0), Numput(44,TInfo), Numput(1|16,TInfo,4), Numput(GuiHwnd,TInfo,8), Numput(CtrlHwnd,TInfo,12), Numput(&text,TInfo,36)
!Modify ? (DllCall("SendMessage",Ptr,TThwnd,"Uint",1028,Ptr,0,Ptr,&TInfo,Ptr)) ; TTM_ADDTOOL = 1028 (used to add a tool, and assign it to a control)
. (DllCall("SendMessage",Ptr,TThwnd,"Uint",1048,Ptr,0,Ptr,A_ScreenWidth)) ; TTM_SETMAXTIPWIDTH = 1048 (This one allows the use of multiline tooltips)
DllCall("SendMessage",Ptr,TThwnd,"UInt",(A_IsUnicode ? 0x439 : 0x40c),Ptr,0,Ptr,&TInfo,Ptr) ; TTM_UPDATETIPTEXT (OLD_MSG=1036) (used to adjust the text of a tip)
}
getParameter(pid)
{
; http://www.autohotkey.com/board/topic/95550-how-to-get-a-list-of-autohotkey-scripts-running/
; http://www.xp-waste.com/post23929.html#p23929
; _Process:=Object()
; _Processes:=0
; _Process.Remove(0,_Process.MaxIndex()) ;don't know if this is necessary
For Process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
if (pid = Process.ProcessId)
return Process.CommandLine
return
}