Go Back   Cockos Incorporated Forums > REAPER Forums > ReaScript, JSFX, REAPER Plug-in Extensions, Developer Forum

Reply
 
Thread Tools Display Modes
Old 09-25-2021, 05:39 AM   #1
wastee
Human being with feelings
 
Join Date: Mar 2015
Location: Mainland China
Posts: 157
Default [Solve]How can i send mouse click on third party vst window?

I know what cause this issue with @Edgemeal's help.

Because Linux can't get handles in parent HWND except stock plugin.

--------------------

My first tried:



JS_Window_FindChild + JS_WindowMessage_Send, ReaComp vst work.




Code:
...
-- Floating the fx window

reaper.trackfx_show(track, fx_idx, 3)



-- Get the fx window HWND        

fx_window_name = "ReaComp"

fx_window = reaper.JS_Window_Find(fx_window_name, 0)


-- Get the button HWND & mouse left click
local btn = reaper.JS_Window_FindChild(fx_window, "Auto make-up", false)

reaper.JS_WindowMessage_Send(btn, "WM_LBUTTONDOWN", 1, 0, 0, 0)
reaper.JS_WindowMessage_Send(btn, "WM_LBUTTONUP", 0, 0, 0, 0)

-----------------------------------------------



JS_Window_FindChild + JS_WindowMessage_Send, third party vst NOT work.

Button is None, can NOT find button HWND



Code:
...
-- Floating the fx window

reaper.trackfx_show(track, fx_idx, 3)



-- Get the fx window HWND        

fx_window_name = "Dragonfly Hall Reverb"

fx_window = reaper.JS_Window_Find(fx_window_name, 0)


-- Get the button HWND & mouse left click
local btn = reaper.JS_Window_FindChild(fx_window, "Large Halls", false)



-- btn is None, can not find button HWND


reaper.JS_WindowMessage_Send(btn, "WM_LBUTTONDOWN", 1, 0, 0, 0)
reaper.JS_WindowMessage_Send(btn, "WM_LBUTTONUP", 0, 0, 0, 0)

My second tried:

xdotool move mouse + xdotool click, ReaComp vst NOT work.
xdotool move mouse + xdotool click, third party vst NOT work.

Mouse will click on main window (click on background). Not the new floating window which call from script itself.


ps: xdotool is a X11 automation tool. It can use in Linux. Move mouse, click etc.


Code:

-- Floating the fx window

reaper.trackfx_show(track, fx_idx, 3)


fx_window_name = "Dragonfly Hall Reverb"

fx_window = reaper.JS_Window_Find(fx_window_name, 0)


-- Set window focus


reaper.JS_Window_SetFocus(fx_window)



-- move mouse and click

command = string.format("xdotool mousemove --sync %d %d", real_x, real_y)
os.execute(command)
os.execute("xdotool click 1")



-----------------------------------


I'm confuse how can i get BUTTON HWDN in thrid party plugin.

And why i can not use xdotool to click the new window in script itself.

Thank you!



Last edited by wastee; 09-27-2021 at 03:35 AM.
wastee is offline   Reply With Quote
Old 09-25-2021, 06:33 AM   #2
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,921
Default

REAPER has API to get and set params, for example TrackFX_GetParam().

But I don't see that setting in the param list, just each individual setting, so I think the easiest way is to just save them as Presets. For example, I selected medium halls and then saved it as a preset with the name "Medium Halls", then used this Lua code to select it...

BTW, tested on Windows 10 only, and only added the plugin temporarily to test this code, and don't know anything about that plugin.

Code:
local track = reaper.GetSelectedTrack(0,0) -- get selected track
local track_fx_count = reaper.TrackFX_GetCount(track)
for fx = 0, track_fx_count - 1 do -- loop thru fx
  local retval, fx_name = reaper.TrackFX_GetFXName(track, fx, "")  -- get fx name
  if fx_name:match('Dragonfly Hall Reverb') then -- find target fx
    reaper.TrackFX_SetPreset(track, fx, "Medium Halls") -- set preset 
    break -- exit loop
  end
end

Last edited by Edgemeal; 09-25-2021 at 06:50 AM.
Edgemeal is offline   Reply With Quote
Old 09-25-2021, 07:46 AM   #3
wastee
Human being with feelings
 
Join Date: Mar 2015
Location: Mainland China
Posts: 157
Default

Quote:
Originally Posted by Edgemeal View Post
REAPER has API to get and set params, for example TrackFX_GetParam().

But I don't see that setting in the param list, just each individual setting, so I think the easiest way is to just save them as Presets. For example, I selected medium halls and then saved it as a preset with the name "Medium Halls", then used this Lua code to select it...


These are some reasons i can not simply save/load a preset or fx chains.

Such as:

1. load vst Ozone match EQ in a track.
2. insert some audio in a track.
3. Click start capture in VST & play transport
4. Click stop capture in VST & stop transport


Maybe there's another way. The only way i know is do these step like "real human" doing (click the button).


Sorry i gave a not enough detail at first.

And thank you, i will try TrackFX_SetParam & TrackFX_GetParam, see if it can be achieved.

Last edited by wastee; 09-25-2021 at 06:12 PM.
wastee is offline   Reply With Quote
Old 09-26-2021, 05:03 AM   #4
wastee
Human being with feelings
 
Join Date: Mar 2015
Location: Mainland China
Posts: 157
Default

Quote:
Originally Posted by wastee View Post
i will try TrackFX_SetParam & TrackFX_GetParam, see if it can be achieved.

Some button NOT in fX param, such as the "Capture" button in Ozone 9 Match EQ plugin.





Maybe the only way is send click by other program. I'm wondering why i can't open a new window and send click to this new window in same script.

For example, i want to click "Preview filter Button". I use xdotool. And that is what will happend.


Last edited by wastee; 09-26-2021 at 05:10 AM.
wastee is offline   Reply With Quote
Old 09-26-2021, 06:51 AM   #5
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,921
Default

I don't know about that other plugin, but for ReaComp you can use REAPER API, try something like,...

Code:
-- Toggle 'Preview Filter' for VST: ReaComp (Cockos)

local track = reaper.GetSelectedTrack(0,0) -- get selected track
local track_fx_count = reaper.TrackFX_GetCount(track)
for fx = 0, track_fx_count - 1 do -- loop thru fx
  local retval, fx_name = reaper.TrackFX_GetFXName(track, fx, "")  -- get fx name
  if fx_name:match(' ReaComp ') then -- find target fx 
    local param_count = reaper.TrackFX_GetNumParams(track, fx) 
    for param = 0, param_count-1 do -- loop thru fx params
      local retval, param_name = reaper.TrackFX_GetParamName(track, fx, param, "")
      if param_name == 'PreviewF' then
        reaper.TrackFX_SetParam(track, fx, param, math.abs(reaper.TrackFX_GetParam(track, fx, param)-1))
        break
      end
    end
  end
end
Helper script, display all fx on tracks, their param name, min value, max value, current value..
Code:
-- Display Track FX Params

local tracks = reaper.CountTracks()
local t = {}

for i = 0, tracks - 1  do
  local track = reaper.GetTrack(0, i)
  local track_fx_count = reaper.TrackFX_GetCount(track)
  for fx = 0, track_fx_count - 1  do
    local retval, fx_name = reaper.TrackFX_GetFXName(track, fx, "") 
    t[#t+1] = ("Track "  .. tostring(i+1) .. ": " .. fx_name)
    local track_fxparam_count = reaper.TrackFX_GetNumParams(track, fx)
    for param = 0, track_fxparam_count - 1 do
      local retval, param_name = reaper.TrackFX_GetParamName(track, fx, param, "")
      local retval, minval, maxval = reaper.TrackFX_GetParam(track, fx, param)
      t[#t+1] = (param_name .. ": " .. minval .. ', ' .. maxval .. ', ' .. retval)
    end
    t[#t+1] = ''
  end 
end

reaper.ClearConsole()
reaper.ShowConsoleMsg(table.concat(t,"\n"))
Code:
Track 1: VST: ReaComp (Cockos)
Thresh: 0.0, 2.0, 0.12589253485203
Ratio: 0.0, 1.0, 0.030303031206131
Attack: 0.0, 1.0, 0.0060000000521541
Release: 0.0, 1.0, 0.0199025105685
Pre-comp: 0.0, 1.0, 0.0
resvd: 0.0, 1.0, 0.0
Lowpass: 0.0, 1.0, 1.0
Hipass: 0.0, 1.0, 0.0
SignIn: 0.0, 1.0, 0.0
AudIn: 0.0, 1.0, 0.0
Dry: 0.0, 2.0, 3.1622775509277e-008
Wet: 0.0, 2.0, 1.0
PreviewF: 0.0, 1.0, 1.0
RMS size: 0.0, 10.0, 0.0
Knee: 0.0, 1.0, 0.0
AutoMkUp: 0.0, 1.0, 0.0
AutoRel: 0.0, 1.0, 0.0
CompatOp: 0.0, 1.0, 0.25
DeprAnti: 0.0, 1.0, 0.0
Bypass: 0.0, 1.0, 0.0
Wet: 0.0, 1.0, 1.0

Last edited by Edgemeal; 09-26-2021 at 06:59 AM.
Edgemeal is offline   Reply With Quote
Old 09-26-2021, 07:29 AM   #6
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,921
Default

For windows with a painted UI (no actual control objects) one way is to get the location of where you want to click inside the window, then either Post or Send mouse down/up messages to the window handle at that location,...

Code:
function Post_LeftMouseClickAt(hwnd, x, y)
  reaper.JS_WindowMessage_Post(hwnd, "WM_LBUTTONDOWN", 1, 0, x, y)
  reaper.JS_WindowMessage_Post(hwnd, "WM_LBUTTONUP", 0, 0, x, y)
end
Only a Windows 10 user here, no clue if this works in the other OSs.
Edgemeal is offline   Reply With Quote
Old 09-26-2021, 07:21 PM   #7
wastee
Human being with feelings
 
Join Date: Mar 2015
Location: Mainland China
Posts: 157
Default

Quote:
Originally Posted by Edgemeal View Post
Code:
...
      if param_name == 'PreviewF' then
        reaper.TrackFX_SetParam(track, fx, param, math.abs(reaper.TrackFX_GetParam(track, fx, param)-1))
        break
      end
...
GetParam/SetParam seems to work in stock plugins.
Stock plugin button's HWND also can be found in JS_Window_FindChild, then click using JS_WindowMessage_Post like what you shared.

Either these two ways both not work in some third party plugins. Because can not get third party plugins's button Param or HWND.

Your Helper script is very helpful! Your experience share let me pretty much sure that third party plugins can not simply set param or click using stock api and JS_reascript api.

Hope these information will help someone who meet similar situation.
wastee is offline   Reply With Quote
Old 09-26-2021, 10:15 PM   #8
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,921
Default

Quote:
Originally Posted by wastee View Post
Either these two ways both not work in some third party plugins. Because can not get third party plugins's button Param or HWND.
Are you sure you were sending the click message to the actual plugin window? I used SPY++ to get classname of plugin and used that to identify the windows inside the fx chain window.

For example Amplitube 4 plugin is just one window handle, to click the 'info' button near bottom-left I get the client size and figured the offset for the info button, send click msg to that location and the info window for the plugin pops up!

Code:
function Main()
-- Testing, plugin shown in FX Chain window (1080p, 100% scaling, Win10)

 track = reaper.GetSelectedTrack(0,0) -- get selected track
  fxchain_hwnd = reaper.CF_GetTrackFXChain(track) -- SWS: get fx chain window
  if fxchain_hwnd then
    arr = reaper.new_array({}, 1024)
    reaper.JS_Window_ArrayAllChild(fxchain_hwnd, arr)
    childs = arr.table() 
    for j = 1, #childs do 
      hwnd = reaper.JS_Window_HandleFromAddress(childs[j])
      if reaper.JS_Window_GetClassName(hwnd):match("IKWindow") then
        -- msg('Amplitube 4 window found')
        -- reaper.JS_Window_SetFocus(hwnd) -- was not needed, some apps may ignore msgs is they don't have focus!
        Post_LeftMouseClickAt(hwnd,120,568)  -- Click where 'info' button graphic is (near bottom-left) in plugin client window
        break
      end
    end
  end
end
Edgemeal is offline   Reply With Quote
Old 09-27-2021, 03:33 AM   #9
wastee
Human being with feelings
 
Join Date: Mar 2015
Location: Mainland China
Posts: 157
Default

Quote:
Originally Posted by Edgemeal View Post
Are you sure you were sending the click message to the actual plugin window? I used SPY++ to get classname of plugin and used that to identify the windows inside the fx chain window.

For example Amplitube 4 plugin is just one window handle, to click the 'info' button near bottom-left I get the client size and figured the offset for the info button, send click msg to that location and the info window for the plugin pops up!

I finally know why i can't send click to fx windows with your help! My code run perfect in Windows 10 virtual machine but NOT in Linux!

I print all the "windows handle" of same fx window in Windows/Linux, and compare them. They are different!

Then i try to get HWND under my mouse point. With stock plugins like ReaComp, Windows/Linux almost the same. But third party plugin not, in Linux i can't get anything in fx window except the window title.

I CAN get window HWND in Linux, it seems an empty layer.(I got the parent HWND, and it has nothing in it) That makes me confuse.

Thanks for your help!
My code run perfect in Window 10 virtual machine!
wastee is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 08:43 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.