Я пишу программу для реализации хиральной прокрутки на сенсорной панели. У меня есть код для чтения необработанных данных сенсорной панели, и у меня есть приблизительное представление о том, как я хочу реализовать этот жест. Мой вопрос заключается в том, как реализовать поведение прокрутки. Это мои требования:
Какие у меня здесь варианты? Есть ли библиотеки, которые могут помочь? Нужно ли это реализовать как какой-то драйвер?
Я подумал и рассмотрел несколько возможных решений, но ни одно из них не кажется полным:
Здесь есть только один реальный вопрос: как создать прокрутку с поведением, которое я описал. Другие вопросы просто представляют некоторые вещи, о которых я подумал для контекста. Спрашивать кого-либо из них конкретно было бы проблемой XY. И я спрашиваю, как это сделать на C++, так что да, это вопрос программирования.
Я думаю, что хук и SendInput могут удовлетворить ваши потребности.
Вот быстрая демонстрация gif.
Запустите код,
После того, как крючок установлен, мышь нельзя двигать. Нажмите левую кнопку мыши, и мышь будет автоматически прокручиваться. Нажмите правую кнопку мыши, чтобы остановить прокрутку. После нажатия клавиши P, чтобы удалить крючок, все вернется на круги своя.
Когда мышь автоматически прокручивается, я все еще могу вручную прокручивать колесико мыши.
Пример кода: (код приблизительный, только для справки)
#include <Windows.h>
#include <iostream>
#include <thread>
using namespace std;
UINT ScrollMouse(int scroll);
void SetHook();
LRESULT __stdcall MouseHookCallback(int, WPARAM, LPARAM);
HHOOK MouseHook;
BOOL flag = 0;
void fun1()
{
while (1)
{
if (GetAsyncKeyState(0x50) & 0x0001)
{
UnhookWindowsHookEx(MouseHook);
}
}
}
void fun2()
{
while (1)
{
if (flag)
{
ScrollMouse(50);
Sleep(100);
}
}
}
int fun3()
{
while (1)
{
if (GetAsyncKeyState(0x4C) & 0x0001)
{
SetHook();
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
}
}
UINT ScrollMouse(int scroll)
{
INPUT input;
POINT pos;
GetCursorPos(&pos);
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_WHEEL;
input.mi.time = NULL; //Windows will do the timestamp
input.mi.mouseData = (DWORD)scroll; //A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, toward the user. One wheel click is defined as WHEEL_DELTA, which is 120.
input.mi.dx = pos.x;
input.mi.dy = pos.y;
input.mi.dwExtraInfo = GetMessageExtraInfo();
return SendInput(1, &input, sizeof(INPUT));
}
LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode >= 0)
{
switch (wParam)
{
case WM_MOUSEMOVE:
{
return 1;
}
case WM_LBUTTONDOWN:
{
flag = 1;
}
break;
case WM_RBUTTONDOWN:
{
flag = 0;
}
break;
}
}
return CallNextHookEx(MouseHook, nCode, wParam, lParam);
}
void SetHook()
{
if (!(MouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookCallback, NULL, 0)))
{
cout << "Failed to install MouseHook hook!" << endl;
}
}
int main()
{
thread t1(fun1);
thread t2(fun2);
thread t3(fun3);
t3.join();
return 0;
}
Отличный! Это делает именно то, что мне нужно! Гораздо проще, чем то, что я боялся, что мне тоже может понадобиться сделать.
Этот вопрос требует большего внимания. В настоящее время он включает несколько вопросов в один. Он должен сосредоточиться только на одной проблеме. (И поскольку это Stack Overflow, речь должна идти о программировании.)