Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Управление курсором [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;


Наверх

Титульная страница Поиск, карта сайта Написать письмо