|
|
|
01-20-2024, 10:23 AM
|
#1961
|
Human being with feelings
Join Date: Apr 2009
Location: Nashville
Posts: 240
|
Could I use this to get and set these options in the MIDI editor?
|
|
|
01-20-2024, 03:20 PM
|
#1962
|
Human being with feelings
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 4,035
|
Quote:
Originally Posted by Rockum
Could I use this to get and set these options in the MIDI editor?
|
Hope you can follow this (see code comments ).
To set the scale menu item I had to revert to sending keys to the menu
Good luck!
Code:
function msg(str) reaper.ShowConsoleMsg(tostring(str) .. '\n')end
function SetComboBoxIndex(hwnd, index)
local id = reaper.JS_Window_AddressFromHandle(reaper.JS_Window_GetLongPtr(hwnd, "ID"))
reaper.JS_WindowMessage_Send(hwnd, "CB_SETCURSEL", index,0,0,0)
reaper.JS_WindowMessage_Send(reaper.JS_Window_GetParent(hwnd), "WM_COMMAND", id, 1, reaper.JS_Window_AddressFromHandle(hwnd), 0) -- 1 = CBN_SELCHANGE
end
local VK_RIGHT = 0x27 -- RIGHT ARROW key
local VK_DOWN = 0x28 -- DOWN ARROW key
local VK_RETURN = 0x0D -- ENTER key
function PostKey(hwnd, vk_code)
reaper.JS_WindowMessage_Post(hwnd, "WM_KEYDOWN", vk_code, 0,0,0)
reaper.JS_WindowMessage_Post(hwnd, "WM_KEYUP", vk_code, 0,0,0)
end
local is_windows = reaper.GetOS():match('Win')
local class_name = is_windows and '#32768' or '__SWELL_MENU' -- Thanks to FTC
function SelectMenuItem()
local ret, list = reaper.JS_Window_ListAllTop()
for address in string.gmatch(list .. ',', '[^,]+') do
local hwnd = reaper.JS_Window_HandleFromAddress(address)
if reaper.JS_Window_GetClassName(hwnd) == class_name then
-- Send keys to select menu item!
-- EXAMPLE #1: Select menu item "Blues", (7th item in menu)
-- for i = 1, 7 do PostKey(hwnd, VK_DOWN) end
-- PostKey(hwnd, VK_RETURN)
--
-- EXAMPLE #2 Select menu item "Chords > Major 7th"
PostKey(hwnd, VK_DOWN)
PostKey(hwnd, VK_RIGHT)
PostKey(hwnd, VK_DOWN)
PostKey(hwnd, VK_DOWN)
PostKey(hwnd, VK_RETURN)
return -- All done!
end
end
if reaper.time_precise() - init_time > 2 then msg('TimeOut: Menu not found!') return end
reaper.defer(SelectMenuItem)
end
-- NOTE: Testing with "One ME pre-project"
hwnd = reaper.MIDIEditor_GetActive() -- get active MIDI Editor
chk = reaper.JS_Window_FindChildByID(hwnd, 0x4EC) -- get handle to KeySnap checkbox
state = reaper.JS_WindowMessage_Send(chk, "BM_GETCHECK", 0,0,0,0)-- get KeySnap checkbox checked state
--
msg(state) -- 1 = checked, 0 = not checked
-- EXAMPLE to toggle key snap checkbox
--reaper.JS_WindowMessage_Send(chk, "BM_SETCHECK", 1-state, 0,0,0) -- set checkbox checked state
--reaper.JS_WindowMessage_Send(hwnd, "WM_COMMAND", 0x4EC, 0,0,0) -- apply the setting
if state == 1 then
-- get current key & scale settings
cbo_key = reaper.JS_Window_FindChildByID(hwnd, 0x4ED)
cbo_scale = reaper.JS_Window_FindChildByID(hwnd, 0x4EE)
key_txt = reaper.JS_Window_GetTitle(cbo_key)
scale_txt = reaper.JS_Window_GetTitle(cbo_scale)
--
msg(key_txt) msg(scale_txt)
-- Set Key to "A" (index 4)
SetComboBoxIndex(cbo_key, 4)
-- Set Scale: Open scale menu,
reaper.JS_WindowMessage_Post(hwnd, "WM_COMMAND", 0x4EE, 0,0,0)
-- Send keys to menu to make selection
init_time = reaper.time_precise()
SelectMenuItem()
end
|
|
|
01-20-2024, 05:39 PM
|
#1963
|
Human being with feelings
Join Date: Apr 2009
Location: Nashville
Posts: 240
|
Wow that was a lot of work. Thank you for taking the time.
|
|
|
01-21-2024, 02:11 PM
|
#1964
|
Human being with feelings
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 4,035
|
Quote:
Originally Posted by Rockum
Wow that was a lot of work. Thank you for taking the time.
|
Most of it was copied/pasted from previous scripts/screwing around.
For setting the Key combobox, don't really need function SetComboBoxIndex() since we already have the combo parent and ID, you could simply do it this way..
Code:
-- Set Key to "A" (index 4)
reaper.JS_WindowMessage_Send(cbo_key, "CB_SETCURSEL", 4 ,0,0,0) -- select index 4 in combobox
reaper.JS_WindowMessage_Send(hwnd, "WM_COMMAND", 0x4ED, 1, reaper.JS_Window_AddressFromHandle(cbo_key), 0) -- notify parent of combo index change
Last edited by Edgemeal; 01-22-2024 at 10:10 AM.
|
|
|
03-18-2024, 10:29 AM
|
#1965
|
Human being with feelings
Join Date: Sep 2018
Location: China
Posts: 572
|
Is there a way to "reset" the value obtained by reaper.JS_VKeys_GetState? For example, if a key is detected to have a state value of 1, can I forcibly reset it back to 0?
Typically, when a key is pressed, reaper.JS_VKeys_GetState will detect its value as 1, and when released, the value will return to 0.
However, I've noticed a special case. Suppose I set the function of a key to import an audio file (reaper.InsertMedia), when it starts running, an import file popup window will appear. This window impacts the judgment of the key's state by reaper.JS_VKeys_GetState, it erroneously considers the key as still being pressed, even though it has actually been released. It won't be correctly identified until I press it again.
If there's no way to forcibly reset it, is there any way to avoid the impact on the judgment of the key state by the pop-up window when importing an audio file?
|
|
|
03-18-2024, 01:37 PM
|
#1966
|
Human being with feelings
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 4,035
|
Quote:
Originally Posted by dsyrock
However, I've noticed a special case. Suppose I set the function of a key to import an audio file (reaper.InsertMedia), when it starts running, an import file popup window will appear. This window impacts the judgment of the key's state by reaper.JS_VKeys_GetState, it erroneously considers the key as still being pressed, even though it has actually been released. It won't be correctly identified until I press it again.
|
Confirmed. Not sure you can reset the key states, Maybe workaround would be to detect the key's released/Up state?, quick test seems to work OK here,..
Code:
-- If "A" key Up...
if reaper.JS_VKeys_GetUp(reaper.time_precise()-0.1):byte(65) == 1 then
reaper.InsertMedia(file, 1)
end
|
|
|
03-18-2024, 07:52 PM
|
#1967
|
Human being with feelings
Join Date: Sep 2018
Location: China
Posts: 572
|
Quote:
Originally Posted by Edgemeal
Confirmed. Not sure you can reset the key states, Maybe workaround would be to detect the key's released/Up state?, quick test seems to work OK here,..
Code:
-- If "A" key Up...
if reaper.JS_VKeys_GetUp(reaper.time_precise()-0.1):byte(65) == 1 then
reaper.InsertMedia(file, 1)
end
|
Thanks for your advise, I will try it later.
|
|
|
03-19-2024, 06:31 AM
|
#1968
|
Human being with feelings
Join Date: Jun 2009
Location: Croatia
Posts: 4,793
|
There is a config variable that drastically influences VKeys Getstate.
Code:
r.SNM_SetIntConfigVar("alwaysallowkb", 1)
It can be only changed via SWS. Setting this var to 1 solves a lot of issues:
Blocked by popups, other windows etc. (where state hangs while some popup is blocking it)
Example:
1. Setting turned off (0)
Here I open the script (via key press) and immediately right click and release the key. Result is script is always open since the state of key is interrupted by right click context (VKeyGetState reports 1 always here since it hangs)
2. Setting turned on (1)
Same as above but script is not running anymore since key is not held down (VKeyGetState reports proper state, no hangs anymore)
Last edited by Sexan; 03-19-2024 at 06:40 AM.
|
|
|
03-19-2024, 08:37 AM
|
#1969
|
Human being with feelings
Join Date: Sep 2018
Location: China
Posts: 572
|
Quote:
Originally Posted by Sexan
There is a config variable that drastically influences VKeys Getstate.
Code:
r.SNM_SetIntConfigVar("alwaysallowkb", 1)
|
Oh you mean the option in the "Advanced UI/system tweaks"? Thanks, didn't know that before
|
|
|
03-19-2024, 08:52 AM
|
#1970
|
Human being with feelings
Join Date: Jun 2009
Location: Croatia
Posts: 4,793
|
yeah
|
|
|
04-07-2024, 09:32 AM
|
#1971
|
Human being with feelings
Join Date: Aug 2023
Posts: 3
|
Any plans for compiling a build for Linux aarch64 (ARM64)?
|
|
|
06-07-2024, 04:02 PM
|
#1972
|
Human being with feelings
Join Date: Aug 2016
Posts: 100
|
I'm trying to set the rate knob in the media explorer to that of the selected item. For the most part it works, but sometimes the 'ctrl + a' key pattern doesn't work (see 2nd last block of code). Sometimes it will delete the text and sometimes it will add two A characters. Anyone know why?
Code:
function Msg(var)
reaper.ShowConsoleMsg(tostring(var))
end
-----------------------------------------------------------------------------------------------------------------------
function Get_Sel_Item_Rate()
local sel_item = reaper.GetSelectedMediaItem(0, 0)
local take = reaper.GetActiveTake(sel_item)
local rate = reaper.GetMediaItemTakeInfo_Value(take, "D_PLAYRATE")
return rate
end
-----------------------------------------------------------------------------------------------------------------------
function post_text(hwnd, str) -- https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-char
for char in string.gmatch(str, ".") do
local ret = reaper.JS_WindowMessage_Post(hwnd, "WM_CHAR", string.byte(char),0,0,0)
if not ret then break end
end
end
-----------------------------------------------------------------------------------------------------------------------
function Post_Key(hwnd, vk_code)
-- highlight text
reaper.JS_WindowMessage_Post(hwnd, "WM_KEYDOWN", vk_code, 0, 0, 0)
reaper.JS_WindowMessage_Post(hwnd, "WM_KEYDOWN", 0x41, 0, 0, 0)
reaper.JS_WindowMessage_Post(hwnd, "WM_KEYUP", vk_code, 0, 0, 0)
reaper.JS_WindowMessage_Post(hwnd, "WM_KEYUP", 0x41, 0, 0, 0)
-- delete text
reaper.JS_WindowMessage_Post(hwnd, "WM_KEYDOWN", 0x2E, 0, 0, 0)
reaper.JS_WindowMessage_Post(hwnd, "WM_KEYUP", 0x2E, 0, 0, 0)
end
-----------------------------------------------------------------------------------------------------------------------
function Main()
local take_rate = Get_Sel_Item_Rate()
local hWnd = reaper.JS_Window_Find("Media Explorer", true)
if hWnd == nil then return end
local rate = reaper.JS_Window_FindChildByID(hWnd, 1454)
if rate == nil then return end
local delete = 0x2E
local backspace = 0x08
local tab = 0x09
local ctrl = 0x11
local a_key = 0x41
Post_Key(rate, ctrl)
post_text(rate, tostring(take_rate))
end
-----------------------------------------------------------------------------------------------------------------------
Main()
|
|
|
06-07-2024, 04:53 PM
|
#1973
|
Human being with feelings
Join Date: Aug 2016
Posts: 100
|
Seems like using different keyboard commands will have different results. One will work and the other will post two "A" characters in addition to the rate value.
|
|
|
06-07-2024, 08:58 PM
|
#1974
|
Human being with feelings
Join Date: Aug 2016
Posts: 100
|
Okay, I found the 'reaper.JS_Window_SetTitle(hwnd, "")' function which is solid
|
|
|
07-27-2024, 07:39 AM
|
#1975
|
Human being with feelings
Join Date: May 2016
Posts: 16
|
Hi,
Does the "JS API" works with Reaper 7?
|
|
|
07-27-2024, 02:39 PM
|
#1976
|
Human being with feelings
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 4,035
|
Quote:
Originally Posted by g.lolo3
Hi,
Does the "JS API" works with Reaper 7?
|
Seems fine here, though I only use a small handful of the functions.
|
|
|
08-19-2024, 07:34 AM
|
#1977
|
Human being with feelings
Join Date: Oct 2019
Location: Moscow / Tbilisi
Posts: 999
|
It seems I found a bug in the function JS_Mouse_LoadCursor
If a user uses a custom cursor it can't load any matching one.
Look:
I'm trying to find an ID for the current cursor.
First I'm getting handle of it, and then use the function to get handle from an integer. When handles match I use the integer as ID.
It would be useful for contextual scripts, but it doesn't work for users with custom cursors, which is strange, because ID should be static when the picture and handle can be vary.
Here my small test script for it:
https://stash.reaper.fm/v/46789/Get%...%20tool_AZ.lua
|
|
|
08-19-2024, 08:52 PM
|
#1978
|
Human being with feelings
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 4,035
|
Quote:
Originally Posted by AZpercussion
It seems I found a bug in the function JS_Mouse_LoadCursor
If a user uses a custom cursor it can't load any matching one.
|
IOW if its because you are trying to load soo many cursors (200,000 loops every defer?) into memory. Looking at the GDI count column in Windows Task Manager for reaper.exe it jumped from ~32 to ~9,900 when I tried your script, and 10,000 is the max, if an app tries to use more then that it would crash, but I guess the devs here are smart enough to detect it and release cursors (or whatever) from memory so REAPER doesn't crash! Amazing!
For detecting cursors probably best to start by only loading the known cursors. FWIW, I added a custom cursor (arrange_ibeam.cur) to REAPER/Cursor folder, ran script below, it detected it as user and always shows the same number for it, so not sure JS_API has a bug.
Good Luck!
Code:
-- Get cursor ID
-- Edgemeal - Aug 19, 2024
-- 16 Windows cursors, https://learn.microsoft.com/en-us/windows/win32/menurc/about-cursors
-- 68 REAPER cursors, via v7.20_x64
local cursor_id = {105, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 202, 203, 204, 205, 207, 208, 211,
216, 217, 220, 225, 417, 418, 419, 420, 421, 429, 430, 431, 433, 434, 450, 453, 460, 461, 462, 463, 464, 465, 472,
473, 488, 502, 503, 515, 517, 525, 526, 528, 529, 530, 531, 532, 533, 534, 535, 599, 600, 601, 612, 613, 614, 615, 1009, 1010, 1011,
32512, 32513, 32514, 32515, 32516, 32642, 32643, 32644, 32645, 32646, 32648, 32649, 32650, 32651, 32671, 32672 } --< Last row is Windows cursors
local cursor_h = {}
local found = false
local prev_cursor = nil
-- Store cursor handles for comparison
for i = 1, #cursor_id do
cursor_h[i] = reaper.JS_Mouse_LoadCursor(cursor_id[i])
end
function Loop()
local cur_cursor = reaper.JS_Mouse_GetCursor()
if prev_cursor ~= cur_cursor then
prev_cursor = cur_cursor
found = false
for i = 1, #cursor_h do
if cur_cursor == cursor_h[i] then
reaper.ShowConsoleMsg(cursor_id[i] .. "\n")
found = true
break
end
end
if not found then -- User custom cursor ?
cursor_h[#cursor_h+1] = cur_cursor
cursor_id[#cursor_id+1] = "User: " .. tostring(reaper.JS_Window_AddressFromHandle(cur_cursor))
--
reaper.ShowConsoleMsg("Added: " .. cursor_id[#cursor_id] .. "\n")
reaper.ShowConsoleMsg("# Cursors: " .. #cursor_id .. "\n")
end
end
reaper.defer(Loop)
end
reaper.defer(Loop)
|
|
|
08-19-2024, 10:17 PM
|
#1979
|
Human being with feelings
Join Date: Oct 2019
Location: Moscow / Tbilisi
Posts: 999
|
Thanks, Edgemeal!
I didn't know about JS_Window_AddressFromHandle function.
That's the point: you use it instead of JS_Mouse_LoadCursor.
I'll check it later, hope the ID will be the same as native cursor has.
By the way my script works fine (win 8.1), I can see the numbers of all Reaper native cursors and windows cursors 9k+
Previously I had 10k limit, but expanded it below zero for testing purposes.
|
|
|
08-20-2024, 08:00 AM
|
#1980
|
Human being with feelings
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 4,035
|
Quote:
Originally Posted by AZpercussion
Thanks, Edgemeal!
I didn't know about JS_Window_AddressFromHandle function.
That's the point: you use it instead of JS_Mouse_LoadCursor.
|
No, I use loadcursor, I get the cursor handles for the known cursors by their ID# and store them in a table.
I only used JS_Window_AddressFromHandle() for display purpose (easier to read) and keep the two tables in sync.
Quote:
I'll check it later, hope the ID will be the same as native cursor has.
|
At first I thought my custom arrange cursor would be identified as # 220, but its not, since REAPER is loading the cursor from file it has no resource ID, so my script simply adds the custom cursor handle(s) to the cursor_h table for later detection.
Quote:
By the way my script works fine (win 8.1), I can see the numbers of all Reaper native cursors and windows cursors 9k+
Previously I had 10k limit, but expanded it below zero for testing purposes.
|
Ya I figured
Not sure if any of this actually helps in your quest, but Good luck!
|
|
|
08-24-2024, 08:19 AM
|
#1981
|
Human being with feelings
Join Date: Oct 2019
Location: Moscow / Tbilisi
Posts: 999
|
Thank you for the tips!
I see that it's really a Reaper's missing.
I updated my script so that it can show the ID of current cursor as red if it doesn't match with any of 10k cursors and can't be loaded via JS_Mouse_LoadCursor.
So I see 3 points:
1. JS_Mouse_LoadCursor can't load cursors with large ID number.
2. Custom cursors have ID values measuring in millions.
3. After Reaper restart the ID will be changed - it's not a constant.
Here my new utlity script: https://stash.reaper.fm/v/49167/Get%...tool_AZ_v2.lua
|
|
|
08-26-2024, 06:53 AM
|
#1982
|
Human being with feelings
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 4,035
|
Quote:
Originally Posted by AZpercussion
Thank you for the tips!
|
Sounds like you're confusing the handle (fairly large values) with the resource ID (normally very low values).
A resource ID is set by the developer at design time for objects embedded into a dll/exe, like Cursors, Icons, etc, the ID makes it easy for developer/users to access these embedded objects, like change the icon used for the apps main exe/shortcut. I don't think its possible do what you want.
|
|
|
08-26-2024, 10:28 AM
|
#1983
|
Human being with feelings
Join Date: Oct 2019
Location: Moscow / Tbilisi
Posts: 999
|
So we can say, that custom cursors just have no resource ID at all, right?
|
|
|
08-28-2024, 06:45 AM
|
#1984
|
Human being with feelings
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 4,035
|
Quote:
Originally Posted by AZpercussion
So we can say, that custom cursors just have no resource ID at all, right?
|
Correct, if cursor is loaded from a file then there is no resource ID. Using Resource Hacker you can open reaper.exe with it and view its resources, cursors are in "Cursor Group", notice first item has an ID of 105 (same as table in my script).
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 07:38 PM.
|