我试图在WinAPI中使用mouse_event
函数移动用户鼠标。这是我的代码:
while (LeftMouseDown)
{
POINT cursorPos;
GetCursorPos(&cursorPos);
//X Axis And Y Axis is DWORD Array
mouse_event(MOUSEEVENTF_MOVE, xaxis[iCount], yaxis[iCount], 0, 0);
iCount++;
Sleep(200);
}
它运作良好,但问题是我希望代码平滑移动,因为该功能瞬间传送光标而我不想要它,我希望它是平滑过渡或类似的东西
答案 0 :(得分:0)
我知道这已经很晚了,但我不妨回答一下。 在做 golang 时,我使用了这个名为 robots.go 的库,在那里他们有一个可以平滑输入的函数。因此,如果您愿意,可以将其用作参考。 https://github.com/go-vgo/robotgo/blob/master/mouse/mouse_c.h
答案 1 :(得分:-1)
从它看起来,你试图以平滑的方式穿过一条点。
如果是这样,那么你将不得不通过时间插入该路径。
基本上,这个想法是你首先获得路径的总长度。然后,当您更新时间时,您将通过总持续时间和经过的时间获得总距离。最后,您会找到获得距离在中间某处的两个点。然后,您只需沿这两个点进行插值即可获得相对准确的点。
使用此类,您可以传递路径的点和持续时间,以指定您希望沿路径移动的时间。然后你只需要通过时间间隔更新它。
<强> Mover.h 强>
#include <chrono>
#include <vector>
#ifndef MOVER_H
#define MOVER_H
struct Point {
int x, y;
Point(int x_, int y_)
: x(x_), y(y_) {
}
Point() : Point(0, 0) {
}
};
class Mover {
public:
struct PointData {
float total;
float distance;
Point p1;
Point p2;
PointData()
: total(0.f),
distance(0.f) {
}
PointData(float total, float distance, Point p1, Point p2)
: total(total),
distance(distance),
p1(p1),
p2(p2) {
}
};
using TimePoint = std::chrono::microseconds;
private:
std::vector<Point> m_points;
std::vector<PointData> m_distances;
TimePoint m_duration;
TimePoint m_elapsed;
float m_length;
public:
Mover(std::initializer_list<Point> points, TimePoint duration = std::chrono::microseconds(2000000));
template<typename iter_t>
Mover(iter_t begin, iter_t end, TimePoint duration = std::chrono::microseconds(2000000))
: m_points(begin, end),
m_duration(duration),
m_elapsed(std::chrono::milliseconds(0)) {
updateLength();
}
Mover(const Mover&) = default;
Mover& operator=(const Mover&) = default;
Point update(TimePoint delta);
bool isComplete() const;
void setDuration(TimePoint duration);
TimePoint getDuration() const;
TimePoint getElapsed() const;
private:
void updateLength();
};
#endif // MOVER_H
<强> Mover.cpp 强>
#include "Mover.h"
#include <algorithm>
#include <cmath>
Mover::Mover(std::initializer_list<Point> points, TimePoint duration)
: Mover(points.begin(), points.end(), duration)
{
}
Point Mover::update(TimePoint delta)
{
const auto comparison = [](float left, const PointData& right) {
return left < right.total;
};
m_elapsed = std::min(m_elapsed + delta, m_duration);
const float length = (static_cast<float>(m_elapsed.count()) / static_cast<float>(m_duration.count())) * m_length;
auto& data = *std::prev(std::upper_bound(m_distances.begin(), m_distances.end(), length, comparison));
const float percent = (length - data.total) / data.distance;
Point point(data.p1.x + percent * (data.p2.x - data.p1.x), data.p1.y + percent * (data.p2.y - data.p1.y));
return point;
}
bool Mover::isComplete() const
{
return m_duration == m_elapsed;
}
void Mover::setDuration(TimePoint duration)
{
m_duration = duration;
}
Mover::TimePoint Mover::getDuration() const
{
return m_duration;
}
Mover::TimePoint Mover::getElapsed() const
{
return m_elapsed;
}
void Mover::updateLength()
{
auto distance = [](float x1, float y1, float x2, float y2) -> float{
return std::sqrt(((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
};
float length = 0.f;
for (std::size_t index = 0; (index + 1) < m_points.size(); ++index) {
const float dist = distance(m_points[index].x, m_points[index].y, m_points[index + 1].x, m_points[index + 1].y);
m_distances.emplace_back(length, dist, m_points[index], m_points[index + 1]);
length += dist;
}
m_length = length;
}
示例强>
#include <iostream>
#include "Mover.h"
int main() {
std::vector<Point> points{ { 0, 0 }, { 100, 100 } };
Mover move(points.begin(), points.end());
auto t1 = std::chrono::steady_clock::now();
while (!move.isComplete()) {
auto t2 = std::chrono::steady_clock::now();
auto point = move.update(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1));
std::cout << point.x << ' ' << point.y;
t1 = t2;
}
}
值得一提的是,为了使用它,您将不得不跟踪时间以更新移动器。因此,可能值得实现一个Clock类或其他东西来跟踪你的时间。
此外,如果要沿相对于当前光标位置的路径移动,则只需将光标位置添加到活动路径点即可。
答案 2 :(得分:-2)
查看您的代码,您的鼠标将每200毫秒跳过一次像素。
while (LeftMouseDown)
{
POINT cursorPos;
GetCursorPos(&cursorPos);
//X Axis And Y Axis is DWORD Array
int i;
for (i = 0; i < 20; i++)
{
mouse_event(MOUSEEVENTF_MOVE, (xaxis[icount]-cursorPos.x)/20, (yaxis[icount]-cursorPos.y)/20, 0, 0);
iCount++;
Sleep(10);
}
}