![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Управление курсором [D7, WinXP]
Viktop © (2005-10-07 15:23:00)Приведите пожалуйста небольшой кусок кода, в котором курсор мышки движется от текущих координат (ну, или просто от одной точки к другой), до указанных. Желательно, чтобы скорость движения была "стандартная"
Джо (2005-10-08 20:24:00) [1]Не, для вящего сходства лучше так:
procedure DDAProc (X,Y: Integer; CustomData: Pointer); stdcall;
var
DX,DY: Integer;
begin
if Odd(Random (10)) then
Exit;
DX := Random(40) - 80;
DY := Random(40) - 80;
SetCursorPos(X+DX,Y+DY);
Sleep(1);
end;
%-)
Viktop (2005-10-08 20:20:00) [2]Вау. Работает. Спасибо
Джо (2005-10-08 20:14:00) [3]Дело было вечером, делать было нечего...
Вот функция, имитирующая передвижение курсора мыши из точки в точку, произведенное рукой человека в тяжком похмелии :)
// callback-функция для LineDDA
procedure DDAProc (X,Y: Integer; CustomData: Pointer); stdcall;
var
DX,DY: Integer;
begin
DX := Random(10) - 5;
DY := Random(10) - 5;
SetCursorPos(X+DX,Y+DY);
Sleep(1);
end;
// сабжевая функция
procedure MoveCursorGently(FromPoint,ToPoint: TPoint);
begin
SetCursorPos (FromPoint.X,FromPoint.Y);
LineDDA(FromPoint.X,FromPoint.Y,ToPoint.X,ToPoint.Y,@DDAProc,0);
SetCursorPos (ToPoint.X,ToPoint.Y);
end;
Вызов прост:
procedure TForm1.Button1Click(Sender: TObject);
begin
MoveCursorGently(Point(0,0),Point(500,500));
end;
Джо (2005-10-08 15:42:00) [4]П.С.
1. Call-back функция НЕ вызывается для начальной и конечной точек отрезка.
2. Чтобы движение не выглядело слишком "механично", в колбэке неплохо бы немного искажать полученные координаты случайным образом +- пару пикселей. Тогда движение будет выглядеть более "ествественно".
Джо (2005-10-08 15:39:00) [5]
> [7] Джо © (08.10.05 15:27)
Вот тебе элементарный пример.
procedure DDAProc (X,Y: Integer; CustomData: Pointer); stdcall;
begin
// в CustomData передается указатель на Canvas
TCanvas(CustomData).TextOut(X,Y,'X');
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with Image1.Canvas do
begin
Brush.Style := bsClear;
Font.Name := 'Arial';
Font.Size := 9;
end;
LineDDA(0,0,100,100,@DDAProc,Integer(Image1.Canvas));
end;
И "руками" траекторию считать не нужно :)
Sysanin (2005-10-08 15:36:00) [6]
> Т.е. Поставить цикла на
> Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, Pt.
> x, Pt.y, 0, 0);.
> Тока как траекторию расчитать. Подумаю ещё.
Обычный цикл сдесь не подойдёт. Получится то же самое (т. е. курсор мнгновенно переместиться к оъекту). Нужно использовать именно таймер.
Траекторию можешь попробовать посчитать математической линейной функцией (y=ax+b) подставляешь треуемый х - находишь у. Только придётся подумать как расчитать коэфиценты a и b. Хотя это тоже можно: знаешь координаты двух точек принадлежащий этой прямой (курсора и объекта) и решаешь систему с двумя неизвестными. Надеюсь знаешь как?
Джо (2005-10-08 15:27:00) [7]
> [6] Viktop (08.10.05 14:19)
> Что такое LineDDA и как его можно использовать?
Позволяет задать callback-функцию, которая будет вызываться для каждого пиксела отрезка, соеденяющего две точки с указанными координатами.
Viktop (2005-10-08 14:19:00) [8]Что такое LineDDA и как его можно использовать?
Viktop (2005-10-07 20:15:00) [9]Т.е. Поставить цикла на
Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, Pt.x, Pt.y, 0, 0);.
Тока как траекторию расчитать. Подумаю ещё.
Sysanin (2005-10-07 18:39:00) [10]Попробуй перемещать курсор не сразу к объекту, а на несколько пикселей и на процедуру поставь таймер с интервалом 15-25 млс. Получится плавное движение мыши.
Piter (2005-10-07 17:53:00) [11]Viktop (07.10.05 17:21) [2]
блин, падумай, а?
Viktop (2005-10-07 17:21:00) [12]А как сделать-то, чтобы было видно, что курсор движется
Piter (2005-10-07 16:03:00) [13]Вопрос: как эмулировать нажатие клавиши или кнопки мыши
Ответ:
1) Для мыши:
procedure MouseClick(Pt: TPoint; BackCursor: boolean = True);
// Переводим экранные координаты к принятым в mouse_event
function ScreenToAbsolute(const Pt: TPoint): TPoint;
begin
Result.x := Round(Pt.x * 65535 / Screen.Width);
Result.y := Round(Pt.y * 65535 / Screen.Height);
end;
var
OldPt: TPoint;
begin
if BackCursor then
OldPt := ScreenToAbsolute(Mouse.CursorPos);
Pt := ScreenToAbsolute(Pt);
{Переместим курсор мыши}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, Pt.x, Pt.y, 0, 0);
{Нажамаем левую кнопку мыши}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, Pt.x, Pt.y, 0, 0);
{Отпускаем левую кнопки мыши}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, Pt.x, Pt.y, 0, 0);
if BackCursor then
{Перемещаем кнопку мыши обратно}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, OldPt.x, OldPt.y, 0, 0);
end;
Например поместим на форму две кнопки Button1 и Button2 и в их обработчиках напишем следующее:
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Test');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
MouseClick(Button1.ClientToScreen(Point(2, 2)), True); // Кликаем по первой кнопке..
end;