Someone sparked an interesting thread in the Macro Scheduler forums recently when they asked if it was possible to activate a macro by detecting a click on a specific area of the screen. They wanted to know if you could define a portion of the screen so that if a click is detected in that portion of screen a macro could be fired.
Macro Scheduler can do most things and I very rarely respond negatively by saying it can’t be done. Even when I can’t see a solution immediately, I usually have a good think about it, try a few ideas and come back with a solution. In this case I missed a nice solution and replied saying it isn’t yet possible. I don’t know what I was thinking! This sparked a few forum regulars to suggest some solutions ranging from maximised custom dialogs with image maps, to active desktop configurations. Then Dick suggested using the OnEvent function and VK1 – the virtual key code for a left mouse click. Of course! I kicked myself. Why didn’t I think of that?
So I set about writing an example to test the theory. The script actually turns out to be quite simple and elegant. Here it is:
// Set Bounds Here Let>X1=440 Let>X2=630 Let>Y1=40 Let>Y2=200 // Only detect clicks on Desktop, or Anywhere? Let>OnlyDesktop=1 OnEvent>KEY_DOWN,VK1,0,MouseClick Label>MainLoop Wait>0.2 Goto>MainLoop SRT>MouseClick GetActiveWindow>title,xact,yact // OnlyDesktop/all window check Let>OkToContinue=FALSE If>OnlyDesktop=1 If>title=Program Manager Let>OkToContinue=TRUE Endif Else Let>OkToContinue=TRUE Endif If>OkToContinue=TRUE // Check Cursor is Within Bounds GetCursorPos>X,Y If>{((%X% >= %X1%) AND (%X% <= %X2%)) AND ((%Y% >= %Y1%) AND (%Y% <= %Y2%))} // Replace next line with call to macro using Macro> command or call to a subroutine MessageModal>Hello // Macro>your_macro // Pass LClick on? // LClick Endif Endif END>MouseClick
This script sets up a continuous loop and an OnEvent function which responds to the key down event of virtual keycode 1, which happens to be a mouse left click. Yes, perhaps because this is considered a keydown event and uses a virtual key code it is not immediately obvious that you can detect a mouse click. The subroutine that is called when the event occurs checks which window is active and gets the mouse position. If the active window is one in which we should check for mouse clicks (in this case the script works either only on the desktop or on any window) and if the mouse cursor position is within the defined bounds, our routine is called. In this case the event is just a message box, but that can be replaced with a call to another macro or an external application, a subroutine call, or any code you like. If necessary the left click can then be passed on to the underlying window as it was intended – but this should only be necessary if your routine steals focus or does something to prevent the underlying window getting the click. The code could be modified to make it work only against a specific window.
This macro needs to run all the while you want the screen clicks to be detected. If that is all the time then you could set the macro to run on startup, or compile it to an executable and have that run on startup. Or maybe you only need to start the script for a short while when the screen click detection is required.
I’ve also posted the code and an explanation to the forum here. I’ve also added this to Scripts & Tips.