1

I'm currently using the Interception library on some projects, and it would highly useful if I was able to send coordinates and simulate mouse clicks within the existing code. I know there are things within the currently library that support doing such things, but with the lack of documentation (and contact with the developer), I fear I may never be able to accomplish my goals.

The only leads I have so far are the mouse coordinate function uses real mouse coordinates (meaning setting a certain variable to -1 would invert the mouse, and thing like that) but I would like to be able pass screen coordinates to it instead. Also, it has certain mouse flags (INTERCEPTION_MOUSE1_DOWN, INTERCEPTION_MOUSE1_UP, etc. etc.) but after trying to pass these with SendInput it seemed to fail.

If anyone can provide any help it would be a blessing, thank you all!

http://oblita.com/interception.html

P.S - I did see another question where someone asked something similiar to this, there was still some complication and a bit of lacking information. Thanks again.

Fiend
  • 11
  • 3
  • the library deals with raw device data solely, as presented by Windows. It doesn't deal with higher level interfaces where you would be able to do it (using screen coordinates) easily. You can try to built it from such raw data. What I generally recommend is that you play with the library using the most basic application, one that just logs the events and pass them through. – oblitum Dec 01 '14 at 01:10
  • @pepper_chico You've never attempted this before? Mouse click simulation (with the existing code) seems like something that possibly could done. Also, may you please still provide the information on the type of raw mouse data I'm working with (if it has a name?) and what method I should go on to build sorts, I really need this to be possible. Thanks again for your response. – Fiend Dec 01 '14 at 04:09
  • I've done it before, and I know of other people that have done it without any issues. I guess you should try it a bit harder. The headers and example are quite self-explanatory (I say this because other people were able to produce applications from it without much dificult). – oblitum Dec 01 '14 at 05:30
  • If I get the time, I'll post a sample as an answer. – oblitum Dec 01 '14 at 05:33
  • @pepper_chico Wow, that would be amazing! Thank you! – Fiend Dec 01 '14 at 07:27

1 Answers1

0
#include <cmath>
#include <iostream>

#include <utils.h>
#include <interception.h>

using namespace std;

namespace scancode {
    enum {
        esc   = 0x01,
        num_0 = 0x0B,
        num_1 = 0x02,
        num_2 = 0x03,
        num_3 = 0x04,
        num_4 = 0x05,
        num_5 = 0x06,
        num_6 = 0x07,
        num_7 = 0x08,
        num_8 = 0x09,
        num_9 = 0x0A,
    };
}

const double pi = 3.14159265358979323846264338327950288419716939937510582097494;
const double scale = 15;
const int screen_width = get_screen_width(), screen_height = get_screen_height();
const unsigned long milliseconds = calculate_busy_wait_millisecond();

struct point {
    double x;
    double y;
    point(double x, double y) : x(x), y(y) {}
};

typedef point (*curve)(double t);

point circle(double t) {
    double f = 10;

    return point(scale * f * cos(t), scale * f * sin(t));
}

point mirabilis(double t) {
    double f = 1. / 2., k = 1. / (2. * pi);

    return point(scale * f * (exp(k * t) * cos(t)),
                 scale * f * (exp(k * t) * sin(t)));
}

point epitrochoid(double t) {
    double f = 1, R = 6, r = 2, d = 1;
    double c = R + r;

    return point(scale * f * (c * cos(t) - d * cos((c * t) / r)),
                 scale * f * (c * sin(t) - d * sin((c * t) / r)));
}

point hypotrochoid(double t) {
    double f = 10. / 7., R = 5, r = 3, d = 5;
    double c = R - r;

    return point(scale * f * (c * cos(t) + d * cos((c * t) / r)),
                 scale * f * (c * sin(t) - d * sin((c * t) / r)));
}

point hypocycloid(double t) {
    double f = 10. / 3., R = 3, r = 1;
    double c = R - r;

    return point(scale * f * (c * cos(t) + r * cos((c * t) / r)),
                 scale * f * (c * sin(t) - r * sin((c * t) / r)));
}

point bean(double t) {
    double f = 10, c = cos(t), s = sin(t);

    return point(scale * f * ((pow(c, 3) + pow(s, 3)) * c),
                 scale * f * ((pow(c, 3) + pow(s, 3)) * s));
}

point Lissajous(double t) {
    double f = 10, a = 2, b = 3;

    return point(scale * f * (sin(a * t)), scale * f * (sin(b * t)));
}

point epicycloid(double t) {
    double f = 10. / 42., R = 21, r = 10;
    double c = R + r;

    return point(scale * f * (c * cos(t) - r * cos((c * t) / r)),
                 scale * f * (c * sin(t) - r * sin((c * t) / r)));
}

point rose(double t) {
    double f = 10, R = 1, k = 2. / 7.;

    return point(scale * f * (R * cos(k * t) * cos(t)),
                 scale * f * (R * cos(k * t) * sin(t)));
}

point butterfly(double t) {
    double f = 10. / 4., c = exp(cos(t)) - 2 * cos(4 * t) + pow(sin(t / 12), 5);

    return point(scale * f * (sin(t) * c), scale * f * (cos(t) * c));
}

void math_track(InterceptionContext context, InterceptionDevice mouse,
                curve curve, point center, double t1, double t2,
                unsigned int partitioning) {
    lower_process_priority();

    InterceptionMouseStroke mstroke;
    double delta = t2 - t1;
    point position = curve(t1);

    mstroke.flags = INTERCEPTION_MOUSE_MOVE_ABSOLUTE;

    mstroke.state = INTERCEPTION_MOUSE_LEFT_BUTTON_UP;
    mstroke.x = static_cast<int>((0xFFFF * center.x) / screen_width);
    mstroke.y = static_cast<int>((0xFFFF * center.y) / screen_height);
    interception_send(context, mouse, (InterceptionStroke *)&mstroke, 1);

    mstroke.state = 0;
    mstroke.x = static_cast<int>((0xFFFF * (center.x + position.x)) / screen_width);
    mstroke.y = static_cast<int>((0xFFFF * (center.y - position.y)) / screen_height);
    interception_send(context, mouse, (InterceptionStroke *)&mstroke, 1);

    for (unsigned int i = 0, j = 0; i <= partitioning + 2; ++i, ++j) {
        if (j % 250 == 0) {
            busy_wait(25 * milliseconds);
            mstroke.state = INTERCEPTION_MOUSE_LEFT_BUTTON_UP;
            interception_send(context, mouse, (InterceptionStroke *)&mstroke, 1);

            busy_wait(25 * milliseconds);
            mstroke.state = INTERCEPTION_MOUSE_LEFT_BUTTON_DOWN;
            interception_send(context, mouse, (InterceptionStroke *)&mstroke, 1);
            mstroke.state = 0;

            if (i > 0)
                i -= 2;
        }

        position = curve(t1 + (i * delta) / partitioning);
        mstroke.x = static_cast<int>((0xFFFF * (center.x + position.x)) / screen_width);
        mstroke.y = static_cast<int>((0xFFFF * (center.y - position.y)) / screen_height);
        interception_send(context, mouse, (InterceptionStroke *)&mstroke, 1);

        busy_wait(3 * milliseconds);
    }

    busy_wait(25 * milliseconds);
    mstroke.state = INTERCEPTION_MOUSE_LEFT_BUTTON_DOWN;
    interception_send(context, mouse, (InterceptionStroke *)&mstroke, 1);

    busy_wait(25 * milliseconds);
    mstroke.state = INTERCEPTION_MOUSE_LEFT_BUTTON_UP;
    interception_send(context, mouse, (InterceptionStroke *)&mstroke, 1);

    busy_wait(25 * milliseconds);
    mstroke.state = 0;
    mstroke.x = static_cast<int>((0xFFFF * center.x) / screen_width);
    mstroke.y = static_cast<int>((0xFFFF * center.y) / screen_height);
    interception_send(context, mouse, (InterceptionStroke *)&mstroke, 1);

    raise_process_priority();
}

int main() {
    InterceptionContext context;
    InterceptionDevice device, mouse = 0;
    InterceptionStroke stroke;
    point position(screen_width / 2, screen_height / 2);

    raise_process_priority();

    context = interception_create_context();

    interception_set_filter(context, interception_is_keyboard,
                            INTERCEPTION_FILTER_KEY_DOWN | INTERCEPTION_FILTER_KEY_UP);
    interception_set_filter(context, interception_is_mouse,
                            INTERCEPTION_FILTER_MOUSE_MOVE);

    cout << "NOTICE: This example works on real machines.\n"
         << "        Virtual machines generally work with absolute mouse\n"
         << "        positioning over the screen, which this samples isn't\n"
         << "        prepared to handle.\n\n";

    cout << "Now please, first move the mouse that's going to be impersonated." << endl;

    while (interception_receive(context, device = interception_wait(context), &stroke, 1) > 0) {
        if (interception_is_mouse(device)) {
            if (!mouse) {
                mouse = device;
                cout << "Impersonating mouse " << device - INTERCEPTION_MOUSE(0) << ".\n\n";

                cout << "Now:\n"
                     << "  - Go to Paint (or whatever place you want to draw)\n"
                     << "  - Select your pencil\n"
                     << "  - Position your mouse in the drawing board\n"
                     << "  - Press any digit (not numpad) on your keyboard to draw an equation\n"
                     << "  - Press ESC to exit." << endl;
            }

            InterceptionMouseStroke &mstroke = *(InterceptionMouseStroke *)&stroke;

            position.x += mstroke.x;
            position.y += mstroke.y;

            if (position.x < 0)
                position.x = 0;
            if (position.x > screen_width - 1)
                position.x = screen_width - 1;
            if (position.y < 0)
                position.y = 0;
            if (position.y > screen_height - 1)
                position.y = screen_height - 1;

            mstroke.flags = INTERCEPTION_MOUSE_MOVE_ABSOLUTE;
            mstroke.x = static_cast<int>((0xFFFF * position.x) / screen_width);
            mstroke.y = static_cast<int>((0xFFFF * position.y) / screen_height);

            interception_send(context, device, &stroke, 1);
        }

        if (mouse && interception_is_keyboard(device)) {
            InterceptionKeyStroke &kstroke = *(InterceptionKeyStroke *)&stroke;

            switch (kstroke.state) {
                case INTERCEPTION_KEY_DOWN:
                    switch (kstroke.code) {
                        case scancode::num_0:
                            math_track(context, mouse, circle, position, 0, 2 * pi, 200);
                            break;
                        case scancode::num_1:
                            math_track(context, mouse, mirabilis, position, -(6 * pi), 6 * pi, 200);
                            break;
                        case scancode::num_2:
                            math_track(context, mouse, epitrochoid, position, 0, 2 * pi, 200);
                            break;
                        case scancode::num_3:
                            math_track(context, mouse, hypotrochoid, position, 0, 6 * pi, 200);
                            break;
                        case scancode::num_4:
                            math_track(context, mouse, hypocycloid, position, 0, 2 * pi, 200);
                            break;
                        case scancode::num_5:
                            math_track(context, mouse, bean, position, 0, pi, 200);
                            break;
                        case scancode::num_6:
                            math_track(context, mouse, Lissajous, position, 0, 2 * pi, 200);
                            break;
                        case scancode::num_7:
                            math_track(context, mouse, epicycloid, position, 0, 20 * pi, 1000);
                            break;
                        case scancode::num_8:
                            math_track(context, mouse, rose, position, 0, 14 * pi, 500);
                            break;
                        case scancode::num_9:
                            math_track(context, mouse, butterfly, position, 0, 21 * pi, 2000);
                            break;
                        default:
                            interception_send(context, device, &stroke, 1);
                            break;
                    }
                    break;
                case INTERCEPTION_KEY_UP:
                    switch (kstroke.code) {
                        case scancode::num_0:
                        case scancode::num_1:
                        case scancode::num_2:
                        case scancode::num_3:
                        case scancode::num_4:
                        case scancode::num_5:
                        case scancode::num_6:
                        case scancode::num_7:
                        case scancode::num_8:
                        case scancode::num_9:
                            break;
                        default:
                            interception_send(context, device, &stroke, 1);
                            break;
                    }
                    break;
                default:
                    interception_send(context, device, &stroke, 1);
                    break;
            }

            if (kstroke.code == scancode::esc)
                break;
        }
    }

    interception_destroy_context(context);
}

Sources: https://github.com/oblitum/Interception/tree/master/samples/mathpointer

oblitum
  • 11,380
  • 6
  • 54
  • 120