4
votes

I want to move the mouse cursor with a c++ script. I am using Visual C++ 2010 Express in a Windows 7 inside Parallels and I created a console application.

I know SetCursorPos method but it is just not working (it does nothing).

I managed to simulate clicks with SendInput but it does not actually move the mouse.

This is my code:

#include <Windows.h>
#include <Tlhelp32.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <time.h>

void mouseLeftClick(const int x, const int y);

// window
HWND hWindow;

int main()
{
    // find window
    hWindow = FindWindow(NULL, "Calculadora");

    if (NULL == hWindow) {
        OutputDebugStringA("Couldn't find application.");
    }else{

        if (!SetForegroundWindow(hWindow)) {
            OutputDebugStringA("Couldn't set application to foreground.");
        }else{
            // click on 1
            mouseLeftClick(20 265));
            Sleep(500);
            // click on 2
            mouseLeftClick(60, 265);
            Sleep(500);
        }
    }
    return 0;
}

void mouseLeftClick(const int x, const int y)
{ 
    // get the window position
    RECT rect;
    GetWindowRect(hWindow, &rect);

    // calculate scale factor
    const double XSCALEFACTOR = 65535 / (GetSystemMetrics(SM_CXSCREEN) - 1);
    const double YSCALEFACTOR = 65535 / (GetSystemMetrics(SM_CYSCREEN) - 1);

    // get current position
    POINT cursorPos;
    GetCursorPos(&cursorPos);
    double cx = cursorPos.x * XSCALEFACTOR;
    double cy = cursorPos.y * YSCALEFACTOR;

    // calculate target position relative to application
    double nx = (x + rect.left) * XSCALEFACTOR;
    double ny = (y + rect.top) * YSCALEFACTOR;

    INPUT Input={0};
    Input.type = INPUT_MOUSE;

    Input.mi.dx = (LONG)nx;
    Input.mi.dy = (LONG)ny;

    // set move cursor directly and left click
    Input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP;

    SendInput(1,&Input,sizeof(INPUT));
}
2
Are you sure it isn't moving it? Perhaps the virtual machine software immediately moves it back. (Cursor movement functions inside the virtual machine can't affect the host system, of course, so the host mouse pointer is still in the same place it was before, over the virtual machine window) - Ben Voigt
Show use your code. We can't help you unless we see what you've already tried. - selbie
How are you trying to use SetCursorPos? As for SendInput, you should probably have 3 events: Move, Button Down, Button Up. - chris
SetCursorPos didn't work for me. As for SendInput, all those 3 events are done in one command (as seen in examples all over the net) - jerkan
@BenVoigt "Cursor movement functions inside the virtual machine can't affect the host system, of course" - let's not confuse the words "shouldn't" and "can't"...! :-/ - HostileFork says dont trust SE

2 Answers

6
votes

This happens in Parallels because of SmartMouse is On or on Auto. In order for a program in Parallels VM to control the mouse with SetCursorPos you need to hide cursor first. You can do that with ShowCursor(0); before you do any mouse movement e.g. SetCursorPos. Now you will be able to control the mouse while SmartMouse is set to Auto or Off.

2
votes

I found the problem. It turns out Parallels has a feature called Smart Mouse that allows you move freely between OSX and Windows. Once I deactivated it, mouse moved as expected.