Can AppleScript read mouse position / action in one application and replicate it in another application? - macos

I've been searching for a mouse broadcaster for Mac for a while and it seems there are no solutions for doing this, so I must look for alternative solutions now. I'm wondering if AppleScript is capable of performing such a task. Basically, what I would like to do is read mouse position and action when performed in one application for as long as the script is active, and broadcast/replicate it in one or more other applications. Is AppleScript capable of this?
Just to clarify, I'd need to simulate mouse movement in the other applications... for example, if I opened up several instances of a drawing program, assuming that the program had the same resolution, anything I drew in the main program, would replicate on the other programs.

Really applescript cannot do what you need. It's not made for that. Applescript is made to run the commands in an application's applescript dictionary. I assume that the dictionary of the applications you want to control give you no way to read and control the mouse.
You do have an applescript alternative though. I have made a command line tool to read the mouse position and also to move the mouse. So theoretically you can do what you want with applescript and my tool. I do not believe you will get the results you expect though. Anyway you can try. Here's a link to the web page for my tool. I hope it helps.
Get it here.
Your basic approach could be 1) activate the application you want to read the mouse position, 2) run my tool in a repeat loop and record the mouse positions, 3) activate the second application that you want to duplicate the mouse movements, 4) use a repeat loop with my tool to make the mouse move according to how you recorded it.

Related

Create a program that alters the execution of a windows application

I have a windows application which has several sub-forms. i have to navigate through 5 or 6 forms to reach the form i need. this is time consuming since i have to open it several times through the day and i do it daily.
my need: i dont have the source project for this application, i got it as an executable program, but i need to create some application that does these steps for me automatically. In other words i need to find a way to automatically click the buttons that navigate through the forms and opens the form i need from step one.
is there any way i can do this ?
There is indeed, though generic solutions already exist to perform just this kind of function to arbitrary programs.
You can use Spy++ or a resource-editor, like ResHack or ResEdit to look at the program and get the control ids of the navigation buttons.
Once done, you can get a handle to the program itself and then send messages to it's WindowProcedure that would be generated if the user clicked the controls with a mouse,
Another alternative, is to get the position of the running target application, after you've got it's HWND, by using the GetWindowRect function. You could then use this position along with vert/horiz distances to generate mouse events.
The two have more-or-less the same result, though some applications won't work with approach #1.
In one instance, you need to use Spy++ to get the control IDs.
In the other instance, you need to use an image editor to get the pixel offsets of the controls.
In both instances, you'll need to use FindWindow, along with the window's title-text in order to get a HWND handle.
You could use a combination of the two - asking the program itself with GetDlgItem for the handle of the controls you need to click. You could then query the control for its position, before using mouse_event to position the mouse above it and again to click it.
Quite a few ways to skin this cat, actually.
Pre-existing solutions like AutoIt are said to be very easy to use and will be much easier than coding a new program for each target.

Detecting SetCursorPos()?

You can probably figure out why I am asking this question. Even if not, it's very simple.
My question is whether it is possible to detect the use of SetCursorPos() on one's own application, without scanning other running applications for any calls to this API.
For example, if I have my cursor in a window and I call SetCursorPos(), can this window in anyway know that the cursor placement is not directly from the mouse (raw input)?
I am not oblivious to the fact that you can 'know' whether a mouse input is raw simply by checking how the position alters; for example, if the position changes from 100(X) & 100(Y) to 500(X) and 500(Y), without moving through each individual location between these two, then with certainty, something has altered the mouse position.
If anyone of you know of a way to produce 'raw mouse input', without any application being able to tell the difference between the output from a function, and that from a mouse--if there is such a difference--then that'd suffice, too.
Of course, whenever I move my mouse, the operating system I am using detects this and then appropriately moves the cursor accordingly. In practice, I should be able to alter this low level functionality as to my will?
There is no way for a window to directly determine how the mouse was moved. External applications could be using SetCursorPos(), but they could also be using lower level functions like mouse_event() or SendInput() instead. By the time the notification reach the target window, the OS has already normalized the data and any source information is lost If you really needed to detect use of SetCursorPos() or other functions, you would have to directly hook into those functions in every running process. Alternatively, you might try registering for "Raw Input" via RegisterRawInputDevices() and see if you get a corresponding notification from the mouse hardware directy, assumine those simulating functions do not trigger Raw notifications as well.

How to write an OS X application that can effect changes (custom cursor, draw an image) even when it is not active?

I previously asked a question about changing the cursor system-wide on OSX. I used NSCursor to change the cursor, but the effects are only as long as the application is active. When another application becomes active, the custom cursor is lost.
Here is a related, more general question. How can you write an application to have system-wife effects? For example drawing an image on-screen even when your application is not active, and something else is?
I understand I probably need to go at a lower level than the Cocoa APIs. I just cannot figure out where to start looking? Any specific Carbon APIs that I need to be looking at? Or even lower?
Any pointers would be appreciated! If you specifically know how to change the cursor system-wide or how to draw an image and move it around (no matter what application is active), that would solve my current problem as well! Can I write an application that can achieve this when its installed on the system?
Thanks!
You can achieve the effect you want, but not the way you're thinking about doing it.
You say,
I am writing a presentation aid application that shows the equivalent of the "laser pointer" on screen, programmatically. My first idea was to use the mouse cursor itself as the pointer, and change its appearance as a red circle.
Then fake that. Create an application, perhaps of type LSUIElement, perhaps not, depending on the behavior you want. Create a borderless window (type NSBorderlessWindowMask) and fill it with a clear color. Set its window level high enough so that it floats over everything (using -[NSWindow setLevel:], though I can't think of what the best level would be off-hand), and draw into it.
It's true that you cannot set the cursor when you are not the foremost app. It's true that you cannot just scribble on the screen. But you can get the same effects if you're clever.
This behaviour is not provided by any APIs on Mac OS X. You would have to modify the resource files in the OS, and that's a very dangerous operation that could brick the target computer. You have to know what you're doing.
Are you trying to implement a theming app or something like that? What's your goal? If you tell us what you are trying to do, we may be able to suggest alternate approaches.

How Imitate a [Ctrl+Left mouse click] on the center of the form or open another program and type in a word?

Babylon dictionary and a couple of other dictionaries allow to click on any word in any windows program
and automatically recognize the word under the cursor, and at once open the dictionary window while searching for that word in installed dictionaries.
You can on the other hand open your dictionary, type in your word and press Enter, the result will be the same.
There's a Delphi form, containing a text label, for example with the word "Automaton".
My question is:
How to send a word from my Delphi application right into the dictionary window, as if you typed it manually and pressed Enter?
The best solution is to send some message through the Windows mechanism, but if it is too complicated, there's another solution, and so the second answer: as I described, we need to model a [Ctrl+left mouse] click on a form where this word is displayed on a form [ a visual label on the screen of my Delphi application], to be exact, on some central pixel of this label.
Could you kindly give an advice how to do one thing or another in Delphi ?
** edit:
The problem with AppActivate is this: Babylon dict has a daemon part that seats in the tray.
In the task manager a real window where the text should be input also is named 'Babylon'.
So AppActivate('Babylon') tries to bring to front the non-visual part of the application.
Do you have any suggestion how to determine the windows handle or something of a real visual part of the application? In the task manager, I repeat both visual and non-visual parts are named 'Babylon'.
I cannot offer an answer so much as some insight and advice...
There are certain applications which "intercept" keyboard and mouse instructions, and essentially "nullify" them if they are being immitated by software. Generally-speaking, you'd only see this in proper AntiVirus software such as Kaspersky by design... however:
The way some (not many, but some) programs hook keyboard and mouse inputs, as a side-effect, behave the same way. If you have attempted all of the advice given as comments above, and cannot get Babylon to trigger an action as a result, it is likely Babylon behaves as I have described.
If what I suspect is true, then the method you are attempting is simply not possible (at least, not using any simple Pascal code on its own... ASM might be able to do it but that's beyond my knowledge).
A better solution may be to do a little research to see if any of the following options are available to you:
1) Does Babylon have a Pipeline or API you can use to interface your application(s) with it?
2) Is the particular functionality you require of Babylon accessible through one (or more) DLL files distributed as part of Babylon?
3) Is there an alternative to using Babylon for your needs?
I know it's not an answer as such (certainly not one you'd want to hear), but it may point you in a better direction.

Is there anything like Winsplit Revolution for Mac OS X?

Is there anything like Winsplit Revolution for Mac OS X?
Try these:
Zooom/2 ($15) has been my favorite since I installed it. Fast, flexible, and minimizes the number of key combinations I need to remember
Divvy ($15) might soon replace Zoom/2 for me. It's closer to Winsplit. You can arrange windows on a grid, define your own grid arrangements, and define your own shortcuts. It also minimizes the number of keystroke combinations you need to remember. BONUS: There are Mac and Windows versions, which means if you use both platforms you can use the same window management method across all your machines.
Breeze ($8) makes it easy to make windows fullscreen, split left, or split right. It also lets you save screen states (generic) and for specific apps.
Moom ($5) is a more recent entry. It supports both keyboard shortcuts and mouse shortcuts. For the mouse shortcuts, moving the cursor over the greeen zoom button displays a popup list of different layout options: full screen, left/right half, top/bottom half, or any of the corners.
SizeUp ($10) mimics various aspects of WinSplit functionality, but it relies on many keystroke combinations that take time to learn. The advantage is quickly moving windows. The drawback is that it uses up a lot of global keyboard shortcuts, and there are so many I couldn't remember them all.
Cinch ($7) is a mouse-driven app by the makers of SizeUp. Drag your window to various hot zones on the screen edges and the window will "cinch" to that edge and resize to fill half the screen. Similar to the built-in resizing feature in Windows 7.
MercuryMover ($20) is quite powerful and offers fine-grained control. However, there are a lot of different key combinations and, overall, I didn't find it as easy to learn or as elegant as WinSplit. I uninstalled it almost immediately. It struck me as powerful, but inefficient and unwieldy.
The DIY approach (free) mentioned in another post is to combine some applescripts and bind them to quicksilver triggers. I haven't tried this. But it is a free solution.
I found the weak window management one of the hardest things to cope with when I started using a Mac.
Why go beyond spaces and expose?
Winsplit significantly adds to what spaces and expose can do. I didn't understand the appeal until I actually used it. Before that, I thought virtual desktops (ie, like spaces) was enough. Now I consider it must-have functionality, especially on large monitors and multi-mon setups.
On my Windows machine running 3 monitors, I would rank the importance of these different apps in the following order:
Winsplit-like window rearranging
Spaces-like virtual desktops
Expose-like application switching
On my MacBook, I've learned to approach it the other way.
Expose-like application switching
Winsplit-like window rearranging
Spaces-like virtual desktops
From the Winsplit website I understand more or less the functionality; in the past I actually used to have my window manager (Waimea) configured to do exactly that in linux.
You may try using Quicksilver to trigger one of a custom set of applescripts; each applescript would resize and move the currently focused window to a predefined location.
See this macosxhints post for inspiration...
ShiftIt is a free option. Assignable hotkeys to resize to different portions of the screen (Left, Right, Top, Bottom, Top Left, Top Right, Bottom Left, Bottom Right, Full Screen and Center with current size)
Link to ShiftIt on github
Just click on the big download button towards the right of the screen.
Spectacle is a good option, its free and open source. And easy to use with keyboard shortcut :
Windows can be moved to a number of predefined regions of the screen:
Move to the left half ⌥⌘←
Move to the right half ⌥⌘→
Move to the top half ⌥⌘↑
Move to the bottom half ⌥⌘↓
Move to the upper left ⌃⌘←
Move to the lower left ⌃⇧⌘←
Move to the upper right ⌃⌘→
Move to the lower right — ⌃⇧⌘→
Another question on StackOverflow adresses the same issue
https://stackoverflow.com/questions/276760/tiling-window-manager-for-os-x
One answer provided links to an app called TwoUP. It's free, and does the job on OSX!
Thanks to Dong Hoon's answer, I have developed a hybrid solution. Using the AppleScript Editor, you can create scripts to resize the current window, like this:
tell application "System Events"
set _everyProcess to every process
repeat with n from 1 to count of _everyProcess
set _frontMost to frontmost of item n of _everyProcess
if _frontMost is true then set _frontMostApp to process n
end repeat
set _windowOne to window 1 of _frontMostApp
set position of _windowOne to {5, 0}
set size of _windowOne to {1150, 735}
end tell
such a script will work on a 13" MacBook. Using subtle variations of this script saved to /Users/[YourUserNameHere]/Library/Scripts, you can have configure the AppleScript Editor to show itself in the menu bar, where it will allow you to select a script to run.
Using several different scripts, I'm able to resize and reposition any window with only two clicks.
Hope this helps.
It looks like TwoUp is dead, but here are some other options:
Cinch ($7) is like Aero Snap for Mac.
Breeze ($8) allows you to save window states and restore them like a template to another window.
Divvy ($14) shows a grid on the screen where you can select boxes to indicate how you want the window to fill your screen.
I haven't used Winsplit, so I don't know how it compares, but an app I developed, Optimal Layout, offers very flexible window tiling, as well as moving and resizing from the keyboard:
http://most-advantageous.com/optimal-layout/
You can also try Arrange application which features resize and reposition with keyboard shortcuts, on screen menu and by dragging window.
You should also try out secondbar. gives you an extra menubar at the second display + re-arrange options. See this link.
You can even try SplitScreenapp.com. It allows you to resize Mac Windows in many ways including full split, half split, drag and snap, etc.
I doubt it. Between Spaces and Expose, there's not much need for a third-party app to help manage multiple windows.

Resources