#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. #Warn ; Enable warnings to assist with detecting common errors. SendMode Input ; Recommended for new scripts due to its superior speed and reliability. SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. #SingleInstance force ; Replaces script (Reloads). #Persistent ; to make it run indefinitely #IfWinActive ahk_exe S:\MuseScore 3.6.2 portable\MuseScorePortable\App\MuseScore\bin\MuseScore3.exe ; Enables Hotkeys when MuseScore3 Window is Active ; replace the path S:\etc. with your location of MuseScore3.exe ; for users of Windows ; AutoHotkey: download the Unicode version https://www.autohotkey.com/docs/Tutorial.htm#s11 ; rename Select_Measure.txt in Select_Measure.ahk and put the file in your working directory ; put all images in your working directory ; all coordinates work on the testscreen, resolution 1920x1080 at 96 Dots Per Inch ; replace the given coordinates by those found by you using the AHK inbuilt tool WindowSpy ; the screen has to be in a Defined State especially if you consider using AutoHotkey for more tasks ; this means: the macro must be executed in the same screen layout as that in which the coordinates have been measured ; e.g. always full screen with only taskbar Note Input visible - of the side panels at least the Inspector must be visible ; in each Defined State the image IM_01_Inspector_Inspector.png occupies always the same area ; the Inspectorcheck verifies this and warns if this is not the case ; a complete implementation of the Defined State takes also the width of the side panels into account ; in this context the width of the Inspector is especially relevant because it influences the position of the image IM_01_Inspector_Inspector.png ; this file includes also the semi automatic reset of these widths to the defined widths ; a fully automatic reset is possible as well but takes more work in creating DIY items ; if you work always in the same screen lay-out (e.g. full or maximized screen) and your macros don't use the side panels ; -> you can of course leave out the hotkeys of the Defined State ; if you always take care to select a note or rest you don't need Statusbar_Note_Pitch.png and Statusbar_Rest.png ; if you prefer variant 2 - you want to select the measure with any element selected - you need the image Statusbar_Voice1.png ; but in this variant the macro will operate a bit slower ; IM_01_Inspector_Inspector.png Search area: IM_01_X1 := 1639 ; Upper-Left Corner of Search rectangle X IM_01_Y1 := 23 ; idem Y IM_01_X2 := 1697 ; Lower-Right Corner of Search rectangle IM_01_Y2 := 43 ; idem Y ; determine the X-coordinate of the Defined Inspector width by a separator shift to the left ; starting at the right of the separator ; tips about how to determine the width of the Inspector on page 14 of AutoHotkey_for_MuseScore.pdf ; in the attachment to post 1 on https://musescore.org/en/node/316166 Min_Insp_Width := 1853 ; my found minimal (docked) Inspector width Def_Insp_Width := 1640 ; my defined (docked) Inspector width ; Determine the X-coordinate of the Defined Palette width by a separator shift to the right ; starting at the left of the separator ; fixing this width is relevant if you want to use the automation of the Selection Filter ; not so for the Palettes. See post 6 on https://musescore.org/en/node/316166 Min_Pal_Width := 67 ; my found minimal (docked) Palettes width Def_Pal_Width := 111 ; my defined (docked) Palettes width ; Statusbar (here in Full Screen) SB_X1 := 0 ; extreme left border SB_Y1 := 1038 ; set the height so that the surface can accomodate 2 stacked statusbars (in some situations the statusbar can get an extra line) SB_Wide_X2 := 710 ; to recognize Notes, Rests, 'beat 1' - to include the 'duration percentages' of the Piano Roll Editor SB_Y2 := 1079 ; in full screen this coordinate is of course the height (Y- resolution) of your screen minus 1 (pixel zero is the first pixel) ; Canvas Search Area CSA_X1 := 120 ; Canvas Search Area upper-left corner CSA_Y1 := 55 CSA_X2 := 1633 ; Canvas Search Area lower-right corner CSA_Y2 := 1052 ColorV1 := 0x0065bf ; color selected voice 1 element (default) - ui/score/voice1/color in MuseScore Preferences -> Advanced ; ColorSearch used in MuseScore is a powerful feature with many (also new) applications ; AutoHotkey uses 0x where MuseScore writes # ; ♣===================================== SELECT MEASURE =========================================== ; NB: with Control + Alt + R you can reload the macro for easy editing ; creation macro stimulated by https://musescore.org/en/node/322101 ; hotkey combination Z + Left Mouse Button ; the prefix key Z is used because of its accessibility ; using Z as prefix key presupposes a redefinition of the MuseScore shortcut 'Show symbol palette' ; e.g. as Shift + Z ; or replace Z by an 'innocen' key, e.g. CapsLock ; the hotkey comes in 2 variants ; variant 1: condition: initially note or rest in voice 1 selected ; the mouse can be anywhere and clicks the selected note or rest ; variant 2: initially any element in any voice can be selected ; the cursor loops to voice 1 and selects the measure - mouse doesn't move ; variant 2 is here outcommented by /* and */ ; limitation: if an initially selected rest has duration measure (part of) the next measure will be selected as well ; idem if the selected note has the duration of a measure ; in both cases an additional Shift + Left selects only the measure again ~z & LButton:: ; select measure CoordMode, Mouse, Screen CoordMode, Pixel, Screen Gosub, InspectorCheck ; subroutine at end of script - to outcomment this line put a semicolon and a space before it ImageSearch, , , SB_X1, SB_Y1, SB_Wide_X2, SB_Y2, *40 Statusbar_Note_Pitch.png If (ErrorLevel = 1) { ImageSearch, , , SB_X1, SB_Y1, SB_Wide_X2, SB_Y2, *40 Statusbar_Rest.png If (Errorlevel = 1) { MsgBox, 4144, Set Range Color, No note or rest selected!`nSelect a note or rest and try again. Return } } PixelSearch, X, Y, % CSA_X1, % CSA_Y1, % CSA_X2, % CSA_Y2, ColorV1, , Fast RGB Click, %X%, %Y% Sleep, 200 ImageSearch, , , SB_X1, SB_Y1, SB_Wide_X2, SB_Y2, *40 StatusBar_Beat_1.png If (ErrorLevel = 0) Send ^+{right} If (ErrorLevel = 1) { Send ^{left} Sleep, 50 Send ^+{right} } Return /* ~z & LButton:: ; select measure CoordMode, Mouse, Screen CoordMode, Pixel, Screen Gosub, InspectorCheck Send {Volume_Mute} ; mute/unmute the master volume Loop ; voice 1 everywhere present { Sleep, 100 ; increase sleep time if MuseScore reacts slow ImageSearch, , , SB_X1, SB_Y1, SB_Wide_X2, SB_Y2, *40 Statusbar_Voice1.png If (ErrorLevel = 1) { Send !{left} Continue } If (ErrorLevel = 0) Break } Sleep, 100 ; cursor in voice 1 ImageSearch, , , SB_X1, SB_Y1, SB_Wide_X2, SB_Y2, *40 StatusBar_Beat_1.png If (ErrorLevel = 1) { Send ^{left} Sleep, 50 Send ^+{right} } If (ErrorLevel = 0) Send ^+{right} Send {Volume_Mute} ; mute/unmute the master volume Return */ ^!r::reload ; ♣====================================== DEFINED STATE =========================================== ; ♣============================ RESET WIDTH PALETTES/SELECTION FILTER ============================ ; Found minimal Palettes width is 'Min_Pal_Width' ; Defined Palettes width is 'Def_Pal_Width' ; PM: The y coordinate of the dragpoint is half the screenheight ~z & -:: ; semi-automatic reset CoordMode, Mouse, Screen MsgBox, 4161, Reset Palettes to my defined width, ( Make sure that the Palettes are as narrow as possible. If not, do it now. Reset also the screen to your preferred size, maximized or full. If everything is ready: press OK and click an empty spot on the screen. ) IfMsgBox, Cancel Return Keywait, LButton, D Click, up MouseGetPos, StartX, StartY ; original position MouseMove, % Min_Pal_Width, % A_ScreenHeight / 2 ; to my found minimal Palettes width at half screen height Sleep, 100 Click, Down ; drag enable Sleep, 50 MouseMove, % Def_Pal_Width, % A_ScreenHeight / 2 ; to my defined Palettes width at half screen height Click, U ; drag disable Sleep, 50 Send {Escape} MouseMove, StartX, StartY Send {Home} Return ; ♣================================ RESET WIDTH INSPECTOR ========================================= ; Found minimal Inspector width is 'Min_Insp_Width' ; Defined Inspector width is 'Def_Insp_Width' ; PM: The y-coordinate of the dragpoint is at half screenheight ~z & =:: ; semi-automatic reset CoordMode, Mouse, Screen MsgBox, 4161, Reset Inspector to my defined width, ( Make sure that the Inspector is as narrow as possible. If not, do it now. Reset also the screen to your preferred size, maximized or full. If everything is ready: press OK and click an empty spot on the screen. ) IfMsgBox, Cancel Return Keywait, LButton, D Click, up MouseGetPos, StartX, StartY ; original position MouseMove, % Min_Insp_Width, % A_ScreenHeight / 2 ; to my found minimal (docked) Inspector width at half screen height Sleep, 100 Click, Down ; drag enable Sleep, 50 MouseMove, % Def_Insp_Width, % A_ScreenHeight / 2 ; to my defined Inspector width at half screen height Click, U ; drag disable Send {Escape} MouseMove, StartX, StartY Send {Home} Return ; ♣===================================== SUBROUTINE =============================================== InspectorCheck: ImageSearch, , , IM_01_X1, IM_01_Y1, IM_01_X2, IM_01_Y2, *40 IM_01_Inspector_Inspector.png If ErrorLevel { Send {Click} Sleep, 100 Send {Escape} ; to suppress the contextual menu Sleep, 50 MsgBox, 4112, Inspector Check, The screen is not in the defined state.`nThe macro will exit., 1 Exit } Return