Checking if a variable is a bound func object

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
tester
Posts: 84
Joined: 10 Jun 2021, 23:03

Checking if a variable is a bound func object

Post by tester » 27 Sep 2022, 04:14

Hello,

I'm trying to check if a variable contains a bound func object. This is what I got so far but it's indirect. Is there a better way?

Code: Select all

oFoo      := new Foo()
oBar      := Func( "bar" )
oBound    := ObjBindMethod( oFoo, "test" )
oUnknown  := Func( "unknown" )
; msgbox % isobject( oUnknown )
oUnknown2 := ObjBindMethod( oFoo, "unknown" )

msgbox % "oFoo:`t`t" GetObjectType( oFoo ) "`n"
    . "oBar:`t`t" GetObjectType( oBar ) "`n"
    . "oBound:`t`t" GetObjectType( oBound ) "`n"
    . "oUnknown:`t`t" GetObjectType( oUnknown ) "`n"
    . "oUnknown2:`t" GetObjectType( oUnknown2 ) "`n"

bar() {
}
class Foo {
    test() {
    }
}

GetObjectType( o ) {
    RegexMatch( ScriptInfo( "ListVars" ), "O): \K(.+)object.+\Q" FHex( &o ) "\E", _oMatch )
    return _oMatch.Value( 1 )
}

; https://www.autohotkey.com/board/topic/85571-dec-hex-without-setformat-command/
FHex( int, pad=0 ) { ; Function by [VxE]. Formats an integer (decimals are truncated) as hex.
; "Pad" may be the minimum number of digits that should appear on the right of the "0x".
	Static hx := "0123456789ABCDEF"
	If !( 0 < int |= 0 )
		Return !int ? "0x0" : "-" FHex( -int, pad )
	s := 1 + Floor( Ln( int ) / Ln( 16 ) )
	h := SubStr( "0x0000000000000000", 1, pad := pad < s ? s + 2 : pad < 16 ? pad + 2 : 18 )
	u := A_IsUnicode = 1
	Loop % s
		NumPut( *( &hx + ( ( int & 15 ) << u ) ), h, pad - A_Index << u, "UChar" ), int >>= 4
	Return h
}
; https://www.autohotkey.com/boards/viewtopic.php?p=53542#p53542
ScriptInfo(Command)
{
    static hEdit := 0, pfn, bkp
    if !hEdit {
        hEdit := DllCall("GetWindow", "ptr", A_ScriptHwnd, "uint", 5, "ptr")
        user32 := DllCall("GetModuleHandle", "str", "user32.dll", "ptr")
        pfn := [], bkp := []
        for i, fn in ["SetForegroundWindow", "ShowWindow"] {
            pfn[i] := DllCall("GetProcAddress", "ptr", user32, "astr", fn, "ptr")
            DllCall("VirtualProtect", "ptr", pfn[i], "ptr", 8, "uint", 0x40, "uint*", 0)
            bkp[i] := NumGet(pfn[i], 0, "int64")
        }
    }

    if (A_PtrSize=8) {  ; Disable SetForegroundWindow and ShowWindow.
        NumPut(0x0000C300000001B8, pfn[1], 0, "int64")  ; return TRUE
        NumPut(0x0000C300000001B8, pfn[2], 0, "int64")  ; return TRUE
    } else {
        NumPut(0x0004C200000001B8, pfn[1], 0, "int64")  ; return TRUE
        NumPut(0x0008C200000001B8, pfn[2], 0, "int64")  ; return TRUE
    }

    static cmds := {ListLines:65406, ListVars:65407, ListHotkeys:65408, KeyHistory:65409}
    cmds[Command] ? DllCall("SendMessage", "ptr", A_ScriptHwnd, "uint", 0x111, "ptr", cmds[Command], "ptr", 0) : 0

    NumPut(bkp[1], pfn[1], 0, "int64")  ; Enable SetForegroundWindow.
    NumPut(bkp[2], pfn[2], 0, "int64")  ; Enable ShowWindow.

    ControlGetText, text,, ahk_id %hEdit%
    return text
}

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Checking if a variable is a bound func object

Post by swagfag » 27 Sep 2022, 04:34

this is direct(and may also cease to work anytime ahk is updated, so put ur big boy pants on if ure contemplating using it)

Code: Select all

IsBoundFunc(Obj) {
	#Requires AutoHotkey v1.1.34.04
	
	if !IsObject(Obj)
		return false

	return DllCall(NumGet(NumGet(&Obj+0, "Ptr") + (8 * A_PtrSize), "Ptr"), "Ptr", &Obj, "Str") = "BoundFunc"
}

tester
Posts: 84
Joined: 10 Jun 2021, 23:03

Re: Checking if a variable is a bound func object

Post by tester » 27 Sep 2022, 22:46

Pretty neat, thank you.


tester
Posts: 84
Joined: 10 Jun 2021, 23:03

Re: Checking if a variable is a bound func object

Post by tester » 28 Sep 2022, 23:51

@Chunjee Interesting. numGet(&(_ := something), "ptr") gives the same number with bound func objects and built-in and user defined functions. Thank you.

Post Reply

Return to “Ask for Help (v1)”