View Single Post
Old 09-09-2019, 09:28 AM   #21
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 3,714
Default

The FX stuff is working well, and Arthur and I have been PMing about the keystroke stuff, which also seems to be working out. As Mespotine noted, we are using out own defer loop and atexit function:
Code:
-- Just an example of a function that can be called when its key was pressed
function myExampleA()
    reaper.ShowConsoleMsg("A")
end

-- This table matches each intercepted key with its handler function
tKeyFuncs = {[0x57] = function() reaper.ShowConsoleMsg("W") end, 
             [0x41] = myExampleA,
            }

-- Intercept each of the keys listed in tKeyFuncs
for virtualKey in pairs(tKeyFuncs) do
    reaper.JS_VKeys_Intercept(virtualKey, 1)
end

local mainWindow = reaper.GetMainHwnd() -- Main window HWND will remain same, so no need to get new HWND each time when moving focus
local keyState   = reaper.JS_VKeys_GetState(0) -- Get starting key state, which will be updated in each cycle

-- When using Intercepts, it is safer to use pcall, so that the script doesn't immediately quit if an error is thrown, giving opportuniy for intercepts to be removed. 
function myProtectedFunction()
    -- Keep focus on target window, so that keyboard input goes to that window
    if reaper.JS_Window_GetFocus() == w then -- Perhaps GetForeground?  Not sure which works best.
        local keystrokeWindow = reaper.MIDIEditor_GetActive() -- or reaper.OpenMediaExplorer("", false) -- or mainWindow (no need to get new HWND for the main window, but Editor or Explorer HWND may change).
        if keystrokeWindow then
            reaper.JS_Window_SetFocus(keystrokeWindow)
        end
    end
    -- Get keystrokes and handle them by calling matching function.
    -- To get newly pressed keys, compare the keyState of previous cycle with keyState of current cycle.  WARNING: In slow scripts, the may disregard keys that were pressed and released very quickly in-between cycles.
    local keysPrev = keyState
    keyState = reaper.JS_VKeys_GetState(0) 
    if keyState ~= keysPrev then
        for key, func in pairs(tKeyFuncs) do
            if keyState:byte(key) > keysPrev:byte(key) then func() end
        end
    end
end

function myLoop()
    noError, errorMsg = pcall(myProtectedFunction)
    -- Only continue if no errors, and GUI still open
    if noError and gfx.getchar() >= 0 then reaper.defer(myLoop) else gfx.quit() end
end

-- On exit, remove intercepts.
-- If there was an error, make sure all intercepts are zero.  This may affect other scripts that also intercept these keys.
-- If no error, simply lower intercept by 1.
function restoreIntercepts()
    if noError then
        for key in pairs(tKeyFuncs) do
            reaper.JS_VKeys_Intercept(key, -1)
        end
    else
        for key in pairs(tKeyFuncs) do
            for i = 1, 255 do if reaper.JS_VKeys_Intercept(key, -1) == 0 then break end end
        end
        reaper.ShowConsoleMsg(errorMsg or "")
    end
end

reaper.atexit(restoreIntercepts)
reaper.defer(myLoop)
I'm pleased to see the ReaScriptAPI functions being applied in other people's scripts!

Last edited by juliansader; 09-10-2019 at 11:37 AM.
juliansader is offline   Reply With Quote