PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Работа с мышью


Работа с мышью

Сообщений 1 страница 30 из 31

1

Я не привожу ни одной строчки кода.
Вопрос таков.
Как реализовать такой алгоритм:
В цикле получать координаты курсора мыши и показывать их пользователю.
В этом же цикле следить (не нажата ли левая кнопка мыши (ЛКМ))
Как только нажали ЛКМ - вызвать функцию (получить координаты курсора мыши из нажатия ЛКМ
и пока удерживается ЛКМ присваивать эти координаты курсору мыши).

0

2

Вот заготовка проги.

Код:
Procedure TimerMouse() ; Процедура вызывается по таймеру
  Temp.POINT
  GetCursorPos_(@Temp)  ; Текузая позиция курсора мышки относительно экрана
  SetGadgetText(1,"Y =  "+Str(Temp\y))
  SetGadgetText(2,"X =  "+Str(Temp\x))
  
  If GetAsyncKeyState_(#VK_LBUTTON) ; Нажата левая кнопка мышки
    SetGadgetText(3,"Нажата ЛКМ")
  Else
    SetGadgetText(3,"")
  EndIf
EndProcedure

If OpenWindow(0,4,4,90,70,"Pos", #PB_Window_MinimizeGadget)
  StickyWindow(0,1) 

  TextGadget(1,10,10,70,16, "Y")
  TextGadget(2,10,28,70,16,"X")
  TextGadget(3,10,48,80,16,"")
  
  SetTimer_(WindowID(0), 2, 40, @TimerMouse() ) ; Запуск таймера
  
  Repeat
    Event=WaitWindowEvent()   
  Until Event=#PB_Event_CloseWindow
  
  KillTimer_(WindowID(0), 2)
  
EndIf
End

0

3

Петр.
Спасибо Вам.
Признаюсь честно - я пишу в основном на AutoIt.
Вы знакомы с этим языком?
Но PureBasic для меня - это супер находка.
Но очень большая проблема у меня - не дружу с английским.
Потому мне тяжело и в AutoIt и в PureBasic.
Ну, а вообще, мир программирования начал постигать с Sign 0f Misery.

Вот тот код, мной написанный, что я спрашивал, но на AutoIt:

Код:
#Include <Misc.au3>
While 1
Sleep (50)	
$pos = MouseGetPos() ; получить текущие координыты указателя мыши
ToolTip("Mouse x,y: "& $pos[0] & "," & $pos[1], 0, 0) ; вывести визуально эти координаты
If _IsPressed(01) = 1 Then	; если вдруг нажмем ЛКМ, - вызвать функцию "MyCoordinate"
	Call("MyCoordinate")
EndIf
WEnd

Func MyCoordinate()
	While _IsPressed(01) = 1 ; пока зажата ЛКМ выполнять
	Sleep (20)	
	MouseMove($pos[0], $pos[1], 1) ; устанавливать указатель по этим координатам    
	WEnd
EndFunc

Но прошу не выгонять из форума и т.п.

0

4

Нет, с AutoIt я не знаком.

Мне не совсем понятно что значит "пока удерживается ЛКМ присваивать эти координаты курсору мыши".
Судя из программы на AutoIt, если нажата ЛКМ, то нужно запретить перемещение кусора мышки, я правильно понял?

Тогда нужно использовать API функцию SetCursorPos.
Да, это нужно производить в пределах окна прогаммы, или по всему экрану и в других программах тоже?

Код:
Procedure TimerMouse() ; Процедура вызывается по таймеру
Static x,y, State
  Temp.POINT
  GetCursorPos_(@Temp)  ; Текузая позиция курсора мышки относительно экрана
  SetGadgetText(1,"Y =  "+Str(Temp\y))
  SetGadgetText(2,"X =  "+Str(Temp\x))
  
  If GetAsyncKeyState_(#VK_LBUTTON) ; Нажата левая кнопка мышки
    If State=0
      x=Temp\x
      y=Temp\y
    EndIf
    State=1
    SetGadgetText(3,"Нажата ЛКМ")
    SetCursorPos_(x, y)
  Else
    State=0
    SetGadgetText(3,"")
  EndIf
EndProcedure

If OpenWindow(0,4,4,90,70,"Pos", #PB_Window_MinimizeGadget)
  StickyWindow(0,1) 

  TextGadget(1,10,10,70,16, "Y")
  TextGadget(2,10,28,70,16,"X")
  TextGadget(3,10,48,80,16,"")
  
  SetTimer_(WindowID(0), 2, 40, @TimerMouse() ) ; Запуск таймера
  
  Repeat
    Event=WaitWindowEvent()   
  Until Event=#PB_Event_CloseWindow
  
  KillTimer_(WindowID(0), 2)
  
EndIf
End

0

5

Петр.
Спасибо.
Вы спрашивали:
"Мне не совсем понятно что значит "пока удерживается ЛКМ присваивать эти координаты курсору мыши".
Судя из программы на AutoIt, если нажата ЛКМ, то нужно запретить перемещение кусора мышки, я правильно понял?"

Пока зажата ЛКМ - надо постоянно присваивать курсору мыши те координаты, которые были на момент события клика ЛКМ.

Цель - игра Counter Strike Source (просто так для интереса)
В процессе игры при стрельбе из автомата Калашникова добиться
максимальной кучности стрельбы (из-за отдачи идет рассеивание пуль от цели путем перемещения координат прицела вверх и чуть в сторону).
Прицел постоянно находится по центру карты игры.
Сама карта перемещается относительно прицела.
Попытки командования мышью в данном процессе в AutoIt и PureBasic - без результата.
Думал сначала, что защита.
Но в Sign 0f Misery проверил и удивился - это получается.
Просто уже почти забыл Sign 0f Misery да и синтаксис там тяжеловат и многих функций не хватает.
Возможно (я точно не знаю) тут нужен чистый API.

0

6

Юрий написал(а):

тут нужен чистый API

Так чистый API и используется!
Другое дело что игры используют DirectX для работы с мышкой и клавиатурой.
Тут нужен глобальный хук мышки и то не факт что сработает.

0

7

А можно сделать так, чтобы
курсор становился на определенные координаты,
затем выполнял действие(т.е. автоматически нажималась ЛКМ),
через несколько секунд переход на другие координаты, выполнял действие,
и т.д.???

0

8

imeli написал(а):

А можно сделать так, чтобыкурсор становился на определенные координаты,затем выполнял действие(т.е. автоматически нажималась ЛКМ),через несколько секунд переход на другие координаты, выполнял действие,и т.д.???

Мне кажется блокировать мышь или ограничивать её перемещение во время стрельбы не совсем корректно. Если противник прыгнет или присядет или начнет уходить в бок, но блокировка мыши сделает только хуже. У тебя по идее не мышь уходит вверх а координаты попадания пули смещаются относительно курсора мыши.
Тут по идее надо  просчитать зависимость смешения высоты пули от времени  непрерывной стрельбы (время зажатой ЛКМ). Т.е. определить зависимости  смешения вверх и вбок пули от количества Милисекунд непрерывной стрельбы (зажатой ЛКМ) а потом просто в координаты мышки вносить эту поправку, каждые допустим 100 Мсек.
Или можно  ввести намеренную паузу в стрельбе. Т.е. при зажатой ЛКМ после 3-х выстрелов делать паузу хоть в пол секунды или меньше, чтобы  кучность стрельбы не сильно портилась…  Вроде при 3-х, 5-ти выстрелах кучность практически не страдает..Или после 3-5 выстрелов делать автоматическую смену на пистолет, а потом обратно...Все это привязать к Мсек.,которые зажата ЛКМ…

Отредактировано Lucagin (21.12.2010 15:39:49)

0

9

мне не для этого. нужно, что бы на автомате курсор по монитору ездил и выполнял действия

0

10

imeli написал(а):

мне не для этого. нужно, что бы на автомате курсор по монитору ездил и выполнял действия

Последствия клика мышки можно описать c помощью процедуры(что более правильно), но если нужен именно клик, то его можно реализовать методом, описанным тут… Вопросы новичка (Пост 841)
Координаты мышки можно отслеживать и менять с помощью команд: 
MouseLocate(x, y)- Изменяет абсолютную позицию (в пикселях) мыши на текущем экране.
MouseX() - Возвращает горизонтальное положение мыши X (в пикселях) на текущем экране
MouseY() - Возвращает горизонтальное положение мыши Y (в пикселях) на текущем экране

0

11

вообще не въеду...

0

12

imeli написал(а):

А можно сделать так, чтобы
курсор становился на определенные координаты,
затем выполнял действие(т.е. автоматически нажималась ЛКМ)

Вот процедура, перемещающая курсор мышки в заданую позицию и эмулирующая клик левой кнопокй мышки

Код:
Procedure SimulateMouseLeftClick(MouseX, MouseY)
  Temp.POINT
  GetCursorPos_(@Temp)
  SetCursorPos_(MouseX, MouseY)
  mouse_event_(#MOUSEEVENTF_ABSOLUTE | #MOUSEEVENTF_LEFTDOWN, MouseX,MouseY,0,0)
  Delay(100)
  mouse_event_(#MOUSEEVENTF_ABSOLUTE | #MOUSEEVENTF_LEFTUP, MouseX,MouseY,0,0)
  SetCursorPos_(Temp\x, Temp\y)
EndProcedure

0

13

Не получается программу написать

курсор становился на определенные координаты,
затем выполнял действие(т.е. автоматически нажималась ЛКМ),
через несколько секунд переход на другие координаты, выполнял действие,
и т.д.???

0

14

imeli написал(а):

Не получается программу написать

Вот к примеру, при разрешении экрана 1024х768, этот код эмулируя мышку, откроет меню "Пуск"

Код:
Procedure SimulateMouseLeftClick(MouseX, MouseY)
  Temp.POINT
  GetCursorPos_(@Temp)
  SetCursorPos_(MouseX, MouseY)
  mouse_event_(#MOUSEEVENTF_ABSOLUTE | #MOUSEEVENTF_LEFTDOWN, MouseX,MouseY,0,0)
  Delay(100)
  mouse_event_(#MOUSEEVENTF_ABSOLUTE | #MOUSEEVENTF_LEFTUP, MouseX,MouseY,0,0)
  SetCursorPos_(Temp\x, Temp\y)
EndProcedure

SimulateMouseLeftClick(20, 1000)

Вызывая процедуру SimulateMouseLeftClick с нужными координатами, можно эмулировать клики мышкой в требуемых местах экрана.

0

15

Всем привет :)
ЗАбрел сюда по одному очень интересному вопросу...
Вот Вы, Пётр, пишете,

GetCursorPos_(@Temp)
SetCursorPos_(MouseX, MouseY)

Это PureBasic? (А то я еще не работал с указателями, адрес объекта есть '@' перед его именем?)
Если так, то как работать с API-функциями????

0

16

Код написан в формате PureBasic.
В данном случае, GetCursorPos и SetCursorPos это WinAPI функции, на что указывает нижний пробел между именем и открывающей скобкой.

0

17

дык, как их подключить то? в стд не нашел, можт надо либу какую юзать?

0

18

Павел написал(а):

дык, как их подключить то? в стд не нашел, можт надо либу какую юзать?

В полной версии Пурика ( не демо) подавляющее большинство API WIN 32 уже подключено в виде встроенных библиотек и их можно использовать не декларируя и не подключая специально. Если используется Демо версия, то использование API возможно при помощи подключения соотв. библиотек, что собственно можно делать и в полной версии Пурика, если вдруг найдется не встроенная API. Существенную помощь в подключении может оказать программа ApiViewer2004 , если её настроить на PureBasic:

Код:
OpenLibrary(0,"user32.dll")
CallFunction(0,"GetCursorPos",lpPoint.POINTAPI)

0

19

ох, неет...Лучше добуду Пурик нормальный, ибо сейчас юзаю Демо :)
Спасибо за разьяснение :)

0

20

мм. GetAsyncKeyState_(#VK_LBUTTON) - выдает нажата ли кнопка. А какая команда юзается для проверки отпуска?

0

21

Павел написал(а):

А какая команда юзается для проверки отпуска?

ну если кнопка не нажата, значит она отпущена - какая же тут нужна дополнительная проверка 8-)

А вообще события мышки нажатие и отжатие контролируются в Пурике по другому:

Код:
....
  Select WaitWindowEvent() 
    
       Case #WM_LBUTTONDOWN 
; Действия по нажатию
Case #WM_LBUTTONUP
; действия по отжатию

.....

Отредактировано ВиниПур (06.01.2011 19:34:36)

0

22

Дык, не в пуриковом окне, а в любом месте экрана

0

23

Павел
ну если кнопка не нажата, значит она отпущена - какая же тут нужна дополнительная проверка &
Приведи пример, где это необходимо.

0

24

Мне нужно проверить отпускание клавиши мыши на рабочем столе, чтобы засечь в каких координатах юзер щелкнул каждый раз. Вот :)
ЗЫ я явно недооченивал пурик :)

0

25

Павел написал(а):

нужно проверить отпускание клавиши мыши на рабочем столе, чтобы засечь в каких координатах юзер щелкнул каждый раз.

Код:
Temp.POINT
x=0
GetAsyncKeyState_(#VK_LBUTTON)
Repeat
  If GetAsyncKeyState_(#VK_LBUTTON)
    x=1
  Else
    If x=1
      GetCursorPos_(@Temp)
      Debug "Юзер отпустил ЛКМ; x="+Str(Temp\x)+";  y="+Str(Temp\y)
      x=0
    EndIf
  EndIf
  Delay(100)
ForEver

0

26

оно конечно хорошо, но я решил по-другому :)
UPD можно ли на пурике нарисовать прямоугольник поверх всего на экране? Желательно прозрачный (для интерактивности)

0

27

Павел написал(а):

можно ли на пурике нарисовать прямоугольник поверх всего на экране? Желательно прозрачный

Нужно что-то типа этого?

Код:
If OpenWindow(0, 0, 0, 200, 200, "2DDrawing Example", #PB_Window_BorderLess | #PB_Window_ScreenCentered)
    If CreateImage(0, 200, 200) And StartDrawing(ImageOutput(0))
      DrawingMode(#PB_2DDrawing_Gradient)      
      BackColor($0000FF)
      FrontColor($00FF00)
      LinearGradient(0,0, 200, 0)
      ;LinearGradient(0, 20, 255,20) 
      Box(0, 0, 200, 200)
      StopDrawing() 
      ImageGadget(0, 0, 0, 200, 200, ImageID(0))
    EndIf
    
    SetWindowLong_(WindowID(0), #GWL_EXSTYLE, $00080000 | #WS_EX_TOOLWINDOW) 
    SetLayeredWindowAttributes_(WindowID(0), 0, 120, 2)
    SetWindowPos_ (WindowID(0), #HWND_TOPMOST, 0, 0, 0, 0, #SWP_NOMOVE | #SWP_NOSIZE)
    SetWindowLong_ ( WindowID (0), #GWL_EXSTYLE , GetWindowLong_ ( WindowID (0), #GWL_EXSTYLE )|#WS_EX_LAYERED|#WS_EX_TRANSPARENT| #WS_DLGFRAME) 
    
    Repeat
      Event = WaitWindowEvent()
    Until Event = #PB_Event_CloseWindow
  EndIf

0

28

Ух ты, забавно, только у меня размер прямоугольника должен меняться постоянно, да и хотелось бы не через открытие доп.окна, а прямо так))
PS я в API не шарю, так что не знаю как устроено там все...

0

29

Павел написал(а):

размер прямоугольника должен меняться постоянно, да и хотелось бы не через открытие доп.окна, а прямо так))

Ну а что мешает менять размеры окна.
Можно прямо так, но результат будет хуже чем с окном.

Код:
hDC=GetDC_(0)
X=GetSystemMetrics_(#SM_CXSCREEN)
Y=GetSystemMetrics_(#SM_CYSCREEN)
brush = CreateSolidBrush_(RGB(176, 2, 40))
Pos.RECT
Pos\left=100
Pos\top=100
Pos\right=X-200
Pos\bottom=Y-200
If hDC And brush
  Repeat
    FillRect_(hDC,@Pos,brush)
    Delay(10)
  ForEver
  DeleteObject_(brush)
  ReleaseDC_(0,hDC)
EndIf

0

30

Павел написал(а):

можно ли на пурике нарисовать прямоугольник поверх всего на экране? Желательно прозрачный (для интерактивности)

Имеешь в виду что то типа этого?

Код:
deskDC.l = CreateDC_("DISPLAY", #Null, #Null,#Null)
   MoveToEx_(deskDC, 300, 200, 0)
   LineTo_(deskDC, 1000, 200)
   LineTo_(deskDC, 1000, 800)
   LineTo_(deskDC, 300, 800)
   LineTo_(deskDC, 300, 200)
   Delay( 5000)
   
   DeleteDC_(deskDC)

Нарисовать то не сложно, сложнее стереть. :confused:  Надо как то сделать обновление всего экрана, и всех окон, поверх которых рисуется прямоугольник. В общем сложность есть. Лично я делал так : рисовал прямоугольную область мышкой по полупрозрачному окну на весь экран.

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Работа с мышью