Home Forums Software Development Accessing gaze data stream with AutoHotkey

Tagged: 

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #5124
    Cliff
    Participant

    I’d like to access a gaze data stream in my AutoHotkey script. As a first step, I’ve been trying to replicate the MinimalGazeDataStream sample that’s included with the C SDK, but in AHK. I’ve managed to get my AHK version of HandleEvent() called, but the problem is it only gets called a limited number of times, then never gets called again. And the number of times it gets called differs for each run.

    #NoEnv
    #SingleInstance force
    #EscapeChar ~ ; avoid default of backtick to prevent clash with tobii.com developer forums
    
    ; ----------------------------------------------------------------------------------------------------------------------
    ; AHK version of MinimalGazeDataStream
    ; ----------------------------------------------------------------------------------------------------------------------
    
    ; values of enum TX_RESULT from EyeXFrameworkTypes.h
    TX_RESULT_UNKNOWN := 1
    TX_RESULT_OK := 2
    TX_RESULT_CANCELLED := 28
    
    ; values of enum TX_BEHAVIORTYPE from EyeXFrameworkTypes.h
    TX_BEHAVIORTYPE_GAZEPOINTDATA := 1
    TX_BEHAVIORTYPE_EYEPOSITIONDATA := 2
    TX_BEHAVIORTYPE_FIXATIONDATA := 6
    
    ; values of enum TX_GAZEPOINTDATAMODE from EyeXFrameworkTypes.h
    TX_GAZEPOINTDATAMODE_UNFILTERED := 1
    TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED := 2
    
    ; values of enum TX_EYEXCOMPONENTOVERRIDEFLAGS from EyeXClientTypes.h
    TX_EYEXCOMPONENTOVERRIDEFLAG_NONE := 0
    
    ; values of enum TX_CONNECTIONSTATE from EyeXClientTypes.h
    TX_CONNECTIONSTATE_CONNECTED := 1
    TX_CONNECTIONSTATE_DISCONNECTED := 2
    TX_CONNECTIONSTATE_TRYINGTOCONNECT := 3
    TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW := 4
    TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH := 5
    
    ; values from EyeXClientTypes.h
    TX_EMPTY_HANDLE := 0
    TX_INVALID_TICKET := 0
    TX_TRUE := 1
    TX_FALSE := 0
    TX_CLEANUPTIMEOUT_DEFAULT := 500
    
    dllFile := A_ScriptDir . "\Tobii.EyeX.Client.dll"
    
    InteractorId := "Twilight Sparkle"
    g_hGlobalInteractorSnapshot := TX_EMPTY_HANDLE
    
    ; AutoExecute
        main()
    Return
    
    InitializeGlobalInteractorSnapshot(hContext) {
    
        Global dllFile, InteractorId, g_hGlobalInteractorSnapshot, TX_EMPTY_HANDLE, TX_RESULT_OK, TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED
    
        hInteractor := TX_EMPTY_HANDLE
        VarSetCapacity(gazeParamStruct, 4, 0)
        NumPut(TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED, gazeParamStruct, 0, "UInt")
        
        success := DllCall(dllFile . "\txCreateGlobalInteractorSnapshot"
            , "Int", hContext
            , "Str", InteractorId
            , "Int*", g_hGlobalInteractorSnapshot
            , "Int*", hInteractor
            , "Cdecl Int") == TX_RESULT_OK
        success &= DllCall(dllFile . "\txCreateGazePointDataBehavior"
            , "Int", hInteractor
            , "Ptr", &gazeParamStruct
            , "Cdecl Int") == TX_RESULT_OK
        DllCall(dllFile . "\txReleaseObject"
            , "Int*", hInteractor
            , "Cdecl")
    
        return success
        
    }
    
    OnSnapshotCommitted(hAsyncData, param) {
    
        Global dllFile, TX_RESULT_OK, TX_RESULT_UNKNOWN
        
        result := TX_RESULT_UNKNOWN
        success := DllCall(dllFile . "\txGetAsyncDataResultCode"
            , "Int", hAsyncData
            , "Int*", result
            , "Cdecl Int") == TX_RESULT_OK
        DebugMessage("OnSnapshotCommitted: success=" . success . ", result=" . result)
        
    }
    
    OnEngineConnectionStateChanged(connectionState, userParam) {
    
        Global dllFile, g_hGlobalInteractorSnapshot, TX_RESULT_OK, TX_CONNECTIONSTATE_CONNECTED, TX_CONNECTIONSTATE_DISCONNECTED, TX_CONNECTIONSTATE_TRYINGTOCONNECT, TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW, TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH
        
        if (connectionState == TX_CONNECTIONSTATE_CONNECTED) {
            success := DllCall(dllFile . "\txCommitSnapshotAsync"
                , "Int", g_hGlobalInteractorSnapshot
                , "Ptr", RegisterCallback("OnSnapshotCommitted", "Cdecl")
                , "Int", 0
                , "Cdecl Int") == TX_RESULT_OK
            if (!success) {
                DebugMessage("Failed to initialize the data stream.")
            } else {
                DebugMessage("Waiting for gaze data to start streaming...")
            }
        } else if (connectionState == TX_CONNECTIONSTATE_DISCONNECTED) {
            DebugMessage("The connection state is now DISCONNECTED (We are disconnected from the EyeX Engine)")
        } else if (connectionState == TX_CONNECTIONSTATE_TRYINGTOCONNECT) {
            DebugMessage("The connection state is now TRYINGTOCONNECT (We are trying to connect to the EyeX Engine)")
        } else if (connectionState == TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW) {
            DebugMessage("The connection state is now SERVER_VERSION_TOO_LOW: this application requires a more recent version of the EyeX Engine to run.")
        } else if (connectionState == TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH) {
            DebugMessage("The connection state is now SERVER_VERSION_TOO_HIGH: this application requires an older version of the EyeX Engine to run.")
        }
        
    }
    
    HandleEvent(hAsyncData, userParam) {
    
        Global dllFile, TX_EMPTY_HANDLE, TX_RESULT_OK, TX_BEHAVIORTYPE_GAZEPOINTDATA
        
    	hEvent := TX_EMPTY_HANDLE
    	hBehavior := TX_EMPTY_HANDLE
        
        Static count := 0
        DebugMessage(count++ . ": hAsyncData=" . hAsyncData . ", userParam=" . userParam)
        
    }
    
    main() {
    
        Global dllFile, TX_EMPTY_HANDLE, TX_INVALID_TICKET, TX_EYEXCOMPONENTOVERRIDEFLAG_NONE, TX_RESULT_OK, TX_FALSE, TX_CLEANUPTIMEOUT_DEFAULT
        
        hContext := TX_EMPTY_HANDLE
        hConnectionStateChangedTicket := TX_INVALID_TICKET
        hEventHandlerTicket := TX_INVALID_TICKET
        
        hModule := DllCall("LoadLibrary", "Str", dllFile)
        
        success := DllCall(dllFile . "\txInitializeEyeX"
            , "Int", TX_EYEXCOMPONENTOVERRIDEFLAG_NONE
            , "Int", 0
            , "Int", 0
            , "Int", 0
            , "Int", 0
            , "Cdecl Int") == TX_RESULT_OK
        success &= DllCall(dllFile . "\txCreateContext"
            , "Int*", hContext
            , "Int", TX_FALSE
            , "Cdecl Int") == TX_RESULT_OK
        success &= InitializeGlobalInteractorSnapshot(hContext)
    	success &= DllCall(dllFile . "\txRegisterConnectionStateChangedHandler"
            , "Int", hContext
            , "Int*", hConnectionStateChangedTicket
            , "Ptr", RegisterCallback("OnEngineConnectionStateChanged", "Cdecl", 2)
            , "Int", 0
            , "Cdecl Int") == TX_RESULT_OK
        success &= DllCall(dllFile . "\txRegisterEventHandler"
            , "Int", hContext
            , "Int*", hEventHandlerTicket
            , "Ptr", RegisterCallback("HandleEvent", "Cdecl", 2)
            , "Int", 0
            , "Cdecl Int") == TX_RESULT_OK
        success &= DllCall(dllFile . "\txEnableConnection"
            , "Int", hContext
            , "Cdecl Int") == TX_RESULT_OK
        
        DebugMessage("success=" . success . ", hConnectionStateChangedTicket=" . hConnectionStateChangedTicket . ", hEventHandlerTicket=" . hEventHandlerTicket)
        
        if (success) {
            DebugMessage("Initialization was successful.")
        } else {
            DebugMessage("Initialization failed.")
        }
        DebugMessage("Press any key to exit...")
    
        Input, SingleKey, L1, {LControl}{RControl}{LAlt}{RAlt}{LShift}{RShift}{LWin}{RWin}{AppsKey}{F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}{Left}{Right}{Up}{Down}{Home}{End}{PgUp}{PgDn}{Del}{Ins}{BS}{Capslock}{Numlock}{PrintScreen}{Pause}
        
        DebugMessage("Exiting.")
        
        DllCall(dllFile . "\txDisableConnection"
            , "Int", hContext
            , "Cdecl Int")
        DllCall(dllFile . "\txReleaseObject"
            , "Int*", g_hGlobalInteractorSnapshot
            , "Cdecl Int")
        success &= DllCall(dllFile . "\txShutdownContext"
            , "Int", hContext
            , "Int", TX_CLEANUPTIMEOUT_DEFAULT
            , "Int", TX_FALSE
            , "Cdecl Int") == TX_RESULT_OK
        success &= DllCall(dllFile . "\txReleaseContext"
            , "Int*", hContext
            , "Cdecl Int") == TX_RESULT_OK
        success &= DllCall(dllFile . "\txUninitializeEyeX"
            , "Cdecl Int") == TX_RESULT_OK
    
        DllCall("FreeLibrary", "Ptr", hModule)
        
    }
    
    ; From https://autohotkey.com/board/topic/59612-simple-debug-console-output/
    DebugMessage(str)
    {
        global h_stdout
        DebugConsoleInitialize()  ; start console window if not yet started
        str .= "~n" ; add line feed
        ;DllCall("WriteFile", "uint", h_Stdout, "uint", &str, "uint", StrLen(str), "uint*", BytesWritten, "uint", NULL) ; write into the console
        FileAppend %str%, CONOUT$
        WinSet, Bottom,, ahk_id %h_stout%  ; keep console on bottom
    }
    
    DebugConsoleInitialize()
    {
        global h_Stdout     ; Handle for console
        static is_open = 0  ; toogle whether opened before
        if (is_open = 1)     ; yes, so don't open again
            return
         
        is_open := 1	
        ; two calls to open, no error check (it's debug, so you know what you are doing)
        DllCall("AttachConsole", int, -1, int)
        DllCall("AllocConsole", int)
    
        dllcall("SetConsoleTitle", "str","Paddy Debug Console")    ; Set the name. Example. Probably could use a_scriptname here 
        h_Stdout := DllCall("GetStdHandle", "int", -11) ; get the handle
        WinSet, Bottom,, ahk_id %h_stout%      ; make sure it's on the bottom
        ;WinActivate,Lightroom   ; Application specific; I need to make sure this application is running in the foreground. YMMV
        return
    }
    

    I’m running on Windows 8.1 Pro, 64-bit; AHK 1.1.23.05 32-bit Unicode; using EyeX SDK for C/C++ 1.7.480. FWIW, MinimalGazeDataStream.c from the same SDK on the same system compiles and runs fine.

    Anyone have any suggestions? Thanks.

    #5126
    Cliff
    Participant

    If anyone else is interested, I added “Critical” as the first line of HandleEvent() which seems to have helped.

    On an unrelated note, I also added “ExitApp” to the end of main() to make sure the script exits.

    #5140
    Cliff
    Participant

    Here’s the complete MinimalGazeDataStream.ahk that works for me, with either 32-bit or 64-bit Unicode AHK. Just make sure you use the corresponding 32-bit or 64-bit Tobii.EyeX.Client.dll.

    #NoEnv
    #SingleInstance force
    #EscapeChar ~ ; avoid default of backtick to prevent clash with tobii.com developer forums
    
    ; ----------------------------------------------------------------------------------------------------------------------
    ; AHK version of MinimalGazeDataStream from EyeX SDK sample
    ; ----------------------------------------------------------------------------------------------------------------------
    
    ; values of enum TX_RESULT from EyeXFrameworkTypes.h
    TX_RESULT_UNKNOWN := 1
    TX_RESULT_OK := 2
    TX_RESULT_CANCELLED := 28
    
    ; values of enum TX_BEHAVIORTYPE from EyeXFrameworkTypes.h
    TX_BEHAVIORTYPE_GAZEPOINTDATA := 1
    TX_BEHAVIORTYPE_EYEPOSITIONDATA := 2
    TX_BEHAVIORTYPE_FIXATIONDATA := 6
    
    ; values of enum TX_GAZEPOINTDATAMODE from EyeXFrameworkTypes.h
    TX_GAZEPOINTDATAMODE_UNFILTERED := 1
    TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED := 2
    
    ; values of enum TX_EYEXCOMPONENTOVERRIDEFLAGS from EyeXClientTypes.h
    TX_EYEXCOMPONENTOVERRIDEFLAG_NONE := 0
    
    ; values of enum TX_CONNECTIONSTATE from EyeXClientTypes.h
    TX_CONNECTIONSTATE_CONNECTED := 1
    TX_CONNECTIONSTATE_DISCONNECTED := 2
    TX_CONNECTIONSTATE_TRYINGTOCONNECT := 3
    TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW := 4
    TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH := 5
    
    ; values from EyeXClientTypes.h
    TX_EMPTY_HANDLE := 0
    TX_INVALID_TICKET := 0
    TX_TRUE := 1
    TX_FALSE := 0
    TX_CLEANUPTIMEOUT_DEFAULT := 500
    
    dllFile := A_ScriptDir . "\Tobii.EyeX.Client.dll"
    InteractorId := "Twilight Sparkle"
    g_hGlobalInteractorSnapshot := TX_EMPTY_HANDLE
    
    ; AutoExecute
        main()
    Return
    
    InitializeGlobalInteractorSnapshot(hContext) {
    
        Global dllFile, InteractorId, g_hGlobalInteractorSnapshot, TX_EMPTY_HANDLE, TX_RESULT_OK, TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED
    
        hInteractor := TX_EMPTY_HANDLE
        VarSetCapacity(gazeParamStruct, 4, 0)
        NumPut(TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED, gazeParamStruct, 0, "UInt")
        
        success := DllCall(dllFile . "\txCreateGlobalInteractorSnapshot"
            , "Int", hContext
            , "Str", InteractorId
            , "Int*", g_hGlobalInteractorSnapshot
            , "Int*", hInteractor
            , "Cdecl Int") == TX_RESULT_OK
        success &= DllCall(dllFile . "\txCreateGazePointDataBehavior"
            , "Int", hInteractor
            , "Ptr", &gazeParamStruct
            , "Cdecl Int") == TX_RESULT_OK
        DllCall(dllFile . "\txReleaseObject"
            , "Int*", hInteractor
            , "Cdecl")
    
        return success
        
    }
    
    OnSnapshotCommitted(hAsyncData, param) {
    
        Global dllFile, TX_RESULT_OK, TX_RESULT_UNKNOWN
        
        result := TX_RESULT_UNKNOWN
        success := DllCall(dllFile . "\txGetAsyncDataResultCode"
            , "Int", hAsyncData
            , "Int*", result
            , "Cdecl Int") == TX_RESULT_OK
        DebugMessage("OnSnapshotCommitted: success=" . success . ", result=" . result)
        
    }
    
    OnEngineConnectionStateChanged(connectionState, userParam) {
    
        Global dllFile, g_hGlobalInteractorSnapshot, TX_RESULT_OK, TX_CONNECTIONSTATE_CONNECTED, TX_CONNECTIONSTATE_DISCONNECTED, TX_CONNECTIONSTATE_TRYINGTOCONNECT, TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW, TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH
        
        if (connectionState == TX_CONNECTIONSTATE_CONNECTED) {
            success := DllCall(dllFile . "\txCommitSnapshotAsync"
                , "Int", g_hGlobalInteractorSnapshot
                , "Ptr", RegisterCallback("OnSnapshotCommitted", "Cdecl")
                , "Int", 0
                , "Cdecl Int") == TX_RESULT_OK
            if (!success) {
                DebugMessage("Failed to initialize the data stream.")
            } else {
                DebugMessage("Waiting for gaze data to start streaming...")
            }
        } else if (connectionState == TX_CONNECTIONSTATE_DISCONNECTED) {
            DebugMessage("The connection state is now DISCONNECTED (We are disconnected from the EyeX Engine)")
        } else if (connectionState == TX_CONNECTIONSTATE_TRYINGTOCONNECT) {
            DebugMessage("The connection state is now TRYINGTOCONNECT (We are trying to connect to the EyeX Engine)")
        } else if (connectionState == TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW) {
            DebugMessage("The connection state is now SERVER_VERSION_TOO_LOW: this application requires a more recent version of the EyeX Engine to run.")
        } else if (connectionState == TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH) {
            DebugMessage("The connection state is now SERVER_VERSION_TOO_HIGH: this application requires an older version of the EyeX Engine to run.")
        }
        
    }
    
    OnGazeDataEvent(hGazeDataBehavior) {
    
        Global dllFile, TX_RESULT_OK
        
        VarSetCapacity(eventParamsStruct, 32, 0) ; 4 (Int) + 8 (Double) + 8 (Double) + 8 (Double) = 28, but compiler has padded Int to 8 as member of struct
        success := DllCall(dllFile . "\txGetGazePointDataEventParams"
            , "Int", hGazeDataBehavior
            , "Ptr", &eventParamsStruct
            , "Cdecl Int") == TX_RESULT_OK
        if (success) {
            ;gazePointDataMode := NumGet(eventParamsStruct, 0, "Int")
            timestamp := NumGet(eventParamsStruct, 8, "Double")
            x := NumGet(eventParamsStruct, 16, "Double")
            y := NumGet(eventParamsStruct, 24, "Double")
            DebugMessage("Gaze Data: (" . x . ", " . y . ") " . timestamp . " ms")
        } else {
            DebugMessage("Failed to interpret gaze data event packet.")
        }
        
    }
    
    HandleEvent(hAsyncData, userParam) {
    
        Critical
    
        Global dllFile, TX_EMPTY_HANDLE, TX_RESULT_OK, TX_BEHAVIORTYPE_GAZEPOINTDATA
        
    	hEvent := TX_EMPTY_HANDLE
    	hBehavior := TX_EMPTY_HANDLE
        
        ;Static count := 0
        ;DebugMessage(count++ . ": hAsyncData=" . hAsyncData . ", userParam=" . userParam)
        
        success := DllCall(dllFile . "\txGetAsyncDataContent"
            , "Int", hAsyncData
            , "Int*", hEvent
            , "Cdecl Int") == TX_RESULT_OK
    
        isGazePointData := DllCall(dllFile . "\txGetEventBehavior"
            , "Int", hEvent
            , "Int*", hBehavior
            , "Int", TX_BEHAVIORTYPE_GAZEPOINTDATA
            , "Cdecl Int") == TX_RESULT_OK
        if (isGazePointData) {
            OnGazeDataEvent(hBehavior)
            DllCall(dllFile . "\txReleaseObject"
                , "Int*", hBehavior
                , "Cdecl Int")
        }
        
        DllCall(dllFile . "\txReleaseObject"
            , "Int*", hEvent
            , "Cdecl Int")
        
    }
    
    main() {
    
        Global dllFile, TX_EMPTY_HANDLE, TX_INVALID_TICKET, TX_EYEXCOMPONENTOVERRIDEFLAG_NONE, TX_RESULT_OK, TX_FALSE, TX_CLEANUPTIMEOUT_DEFAULT
        
        hContext := TX_EMPTY_HANDLE
        hConnectionStateChangedTicket := TX_INVALID_TICKET
        hEventHandlerTicket := TX_INVALID_TICKET
        
        hModule := DllCall("LoadLibrary", "Str", dllFile)
        
        success := DllCall(dllFile . "\txInitializeEyeX"
            , "Int", TX_EYEXCOMPONENTOVERRIDEFLAG_NONE
            , "Int", 0
            , "Int", 0
            , "Int", 0
            , "Int", 0
            , "Cdecl Int") == TX_RESULT_OK
        success &= DllCall(dllFile . "\txCreateContext"
            , "Int*", hContext
            , "Int", TX_FALSE
            , "Cdecl Int") == TX_RESULT_OK
        success &= InitializeGlobalInteractorSnapshot(hContext)
    	success &= DllCall(dllFile . "\txRegisterConnectionStateChangedHandler"
            , "Int", hContext
            , "Int*", hConnectionStateChangedTicket
            , "Ptr", RegisterCallback("OnEngineConnectionStateChanged", "Cdecl", 2)
            , "Int", 0
            , "Cdecl Int") == TX_RESULT_OK
        success &= DllCall(dllFile . "\txRegisterEventHandler"
            , "Int", hContext
            , "Int*", hEventHandlerTicket
            , "Ptr", RegisterCallback("HandleEvent", "Cdecl", 2)
            , "Int", 0
            , "Cdecl Int") == TX_RESULT_OK
        success &= DllCall(dllFile . "\txEnableConnection"
            , "Int", hContext
            , "Cdecl Int") == TX_RESULT_OK
        
        DebugMessage("success=" . success . ", hConnectionStateChangedTicket=" . hConnectionStateChangedTicket . ", hEventHandlerTicket=" . hEventHandlerTicket)
        
        if (success) {
            DebugMessage("Initialization was successful.")
        } else {
            DebugMessage("Initialization failed.")
        }
        DebugMessage("Press any key to exit...")
    
        Input, SingleKey, L1, {LControl}{RControl}{LAlt}{RAlt}{LShift}{RShift}{LWin}{RWin}{AppsKey}{F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}{Left}{Right}{Up}{Down}{Home}{End}{PgUp}{PgDn}{Del}{Ins}{BS}{Capslock}{Numlock}{PrintScreen}{Pause}
        
        DebugMessage("Exiting.")
        
        DllCall(dllFile . "\txDisableConnection"
            , "Int", hContext
            , "Cdecl Int")
        DllCall(dllFile . "\txReleaseObject"
            , "Int*", g_hGlobalInteractorSnapshot
            , "Cdecl Int")
        success &= DllCall(dllFile . "\txShutdownContext"
            , "Int", hContext
            , "Int", TX_CLEANUPTIMEOUT_DEFAULT
            , "Int", TX_FALSE
            , "Cdecl Int") == TX_RESULT_OK
        success &= DllCall(dllFile . "\txReleaseContext"
            , "Int*", hContext
            , "Cdecl Int") == TX_RESULT_OK
        success &= DllCall(dllFile . "\txUninitializeEyeX"
            , "Cdecl Int") == TX_RESULT_OK
    
        DllCall("FreeLibrary", "Ptr", hModule)
        
        ExitApp
        
    }
    
    ; From https://autohotkey.com/board/topic/59612-simple-debug-console-output/
    DebugMessage(str)
    {
        global h_stdout
        DebugConsoleInitialize()  ; start console window if not yet started
        str .= "~n" ; add line feed
        ;DllCall("WriteFile", "uint", h_Stdout, "uint", &str, "uint", StrLen(str), "uint*", BytesWritten, "uint", NULL) ; write into the console
        FileAppend %str%, CONOUT$
        WinSet, Bottom,, ahk_id %h_stout%  ; keep console on bottom
    }
    
    DebugConsoleInitialize()
    {
        global h_Stdout     ; Handle for console
        static is_open = 0  ; toogle whether opened before
        if (is_open = 1)     ; yes, so don't open again
            return
         
        is_open := 1	
        ; two calls to open, no error check (it's debug, so you know what you are doing)
        DllCall("AttachConsole", int, -1, int)
        DllCall("AllocConsole", int)
    
        dllcall("SetConsoleTitle", "str","Paddy Debug Console")    ; Set the name. Example. Probably could use a_scriptname here 
        h_Stdout := DllCall("GetStdHandle", "int", -11) ; get the handle
        WinSet, Bottom,, ahk_id %h_stout%      ; make sure it's on the bottom
        ;WinActivate,Lightroom   ; Application specific; I need to make sure this application is running in the foreground. YMMV
        return
    }
    
    #5162
    Grant [Tobii]
    Keymaster

    Hi @clifforama,

    Thank you for sharing your code and using the EyeX in this interesting way!

Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.