EDIT: Working code at the bottom of post
Code: Select all
MsgBox % getActiveProcess()
getActiveProcess() {
handle := DllCall("GetForegroundWindow", "Ptr")
DllCall("GetWindowThreadProcessId", "Int", handle, "int*", pid)
WinGet, name, ProcessName, ahk_pid %pid%
return name
}
EDIT: Actually, this returns ApplicationFrameHost.exe for calculator, sorry, guess I should read the post you linked more carefully...
EDIT:I've done a little more work on it, but I'm still having a problem. Here's what I have right now:
Code: Select all
#s::MsgBox % getActiveProcess()
getActiveProcess() {
handle := DllCall("GetForegroundWindow", "Ptr")
DllCall("GetWindowThreadProcessId", "Int", handle, "int*", pid)
global true_pid := pid
callback := RegisterCallback("enumChildCallback")
DllCall("EnumChildWindows", "Int", handle, "ptr", callback, "int", pid)
WinGet, name, ProcessName, ahk_pid %true_pid%
return name
}
enumChildCallback(hwnd, pid) {
DllCall("GetWindowThreadProcessId", "Int", hwnd, "int*", child_pid)
msgbox % child_pid " " pid
if (child_pid != pid)
global true_pid := child_pid
return 1
}
This code seems to work for the most part, except that enumChildCallback only seems to be called for the
first child window, where I believe it should be called for
each child window. I believe this is the main issue with this script right now.
EDIT: Fixed that issue, just had to return 1 from the callback function. Now the only issue is that WinGet doesn't seem to get a process name from the "true" PID, guess WinApi functions are necessary for that too!
EDIT: And it's sorted!! Got it fully working:
Code: Select all
DetectHiddenWindows, on
;#s::MsgBox % getActiveProcess() ; one example of use
;"full" example use
#s::
IfWinExist, ahk_exe calculator.exe
if (getActiveProcess() = "calculator.exe")
MsgBox Calc active
else
MsgBox Calc open, not active
else
MsgBox Calc not open
return
getActiveProcess() {
handle := DllCall("GetForegroundWindow", "Ptr")
DllCall("GetWindowThreadProcessId", "Int", handle, "int*", pid)
global true_pid := pid
callback := RegisterCallback("enumChildCallback", "Fast")
DllCall("EnumChildWindows", "Int", handle, "ptr", callback, "int", pid)
handle := DllCall("OpenProcess", "Int", 0x0400, "Int", 0, "Int", true_pid)
length := 259 ;max path length in windows
VarSetCapacity(name, length)
DllCall("QueryFullProcessImageName", "Int", handle, "Int", 0, "Ptr", &name, "int*", length)
SplitPath, name, pname
return pname
}
enumChildCallback(hwnd, pid) {
DllCall("GetWindowThreadProcessId", "Int", hwnd, "int*", child_pid)
if (child_pid != pid)
global true_pid := child_pid
return 1
}
Returns
Calculator.exe for me on Windows 10, when calculator is active! (If you want the full path rather than just the process name, you can take out the SplitPath command at the end of the function and change the return to return name instead of pname). Should work with any program, whether the new Windows store style apps or traditional programs.
EDIT: Created a thread for this function:
https://autohotkey.com/boards/viewtopic.php?f=6&t=14300