StandAlone version of GetParent() [
with a few Tweaks]:
Usage:Quote:
Passing Parameters to GetParent() ::- Param#2 and #3: byRef variables, used to pass back additional info (should be blank).
- (Param#1): aWinID, Must be blank or a pure HWND only. (i.e. 0x01f324 or 1145823 )
- If aWinID is blank:: GetParent() checks †1, else 2 (else 3).
- Returns the Parent of any existing DropDown|Context menu's (class #32768). ELSE
- Returns the Parent(HWND) of the Active (topMost) Window or Dialog. ELSE
- Returns the HWND of the Active Window or Dialog.
† :: Class #32768 can't be detected with WinActive().
In all the cases I can think of: a DropDown/Context Menu wont exist unless it's been activated by an active window. In the rare case this might be possible, it's likely beneficial to detect this type of menu that isn't owned by the active window.
Development Notes | Observations:
Parent is generally more useful than Ancestor, e.g. the Parent of a Find Dialog, or the Parent of a ContextMenu or DropDown Menu.
Whereas when there is no valid Parent for a given "window" the Ancestor is (as far as I can tell) always the DeskTop.
Thus the GetParent function returns the Windows HWND when there is no parent. Whereas in all my tests GetParentOrAncestor is returning 65546 (when there is no valid parent), which is equivalent to DllCall("GetDesktopWindow").
Code:
HotKey, #p, GetParent, ON
HotKey, #a, GetParentOrAncestor, ON
return
GetParent( byRef aWinID, byRef aClass, byRef aMenu )
{
aWinID:=(!aWinID ? ( (aMenu:=aWinID:=WinExist("ahk_class #32768")) ? aWinID : WinExist("A")) : aWinID )
aParent:=( (aParent:=DllCall( "GetParent", "UInt", aWinID ) + 0) ? aParent : WinExist("A") + 0 )
WinGetClass, aClass, ahk_id %aParent%
return aParent
}
GetParentOrAncestor( byRef aWinID, byRef aClass, byRef aMenu )
{
aWinID:=(!aWinID ? ( (aMenu:=aWinID:=WinExist("ahk_class #32768")) ? aWinID : WinExist("A")) : aWinID )
aParent:=( (aParent:=DllCall( "GetParent", "UInt", aWinID ) + 0) ? aParent : ( (aParent:=DllCall( "GetAncestor", "UInt", aWinID, "UInt", 1 ) + 0) ? aParent : WinExist("A") + 0 ) )
WinGetClass, aClass, ahk_id %aParent%
return aParent
}
DisplayParent(FName)
{
if( FName == "GetParentOrAncestor" )
compareID:=GetParent(aWinID2, aClass2, aMenu2)
parentID:=%FName%(aWinID, aClass, aMenu)
if( (parentStr:="`nParent's") && compareID && ( compareID <> parentID ) )
parentStr:="`nAncestor's"
if((aTitle:="Menu") && !aMenu )
{
if( parentStr=="`nAncestor's" && parentID==DllCall("GetDesktopWindow") )
aTitle:=" |DeskTop| "
else
WinGetTitle, aTitle, ahk_id %aWinID%
}
ToolTip, % parentStr " HWND of (" aTitle "): " parentID "`n`nParent's AHKClass: " aClass "`n"
KeyWait, LWin
KeyWait, RWin
ToolTip
return
}
GetParent:
DisplayParent("GetParent")
return
GetParentOrAncestor:
DisplayParent("GetParentOrAncestor")
return
[Edit: Clarified Usage. The only important function is GetParent(), the rest is just a functional wrapper.]