1 (изменено: becauseim, 2015-09-27 21:31:33)

Тема: AHK: Событие при клике в заданных координатах окна

Хотелось бы реализовать следующее:
При нажатии ЛКМ в диапазоне координат положения курсора (Mouse relative control:  от x180 y0 до x1950 y40) в заданном окне, отправляется нажатие клавиши A, а при поднятии (отпускании) ЛКМ, отправляется нажатие клавиши B, но при условии, что в промежутке между нажатием и отпусканием ЛКМ совершается движение мышью (курсора) в левую или правую сторону, а в том случае, когда кнопка нажимается и отпускается без смещения курсора в горизонтальной плоскости (при простом клике мышью), отправляется нажатие клавиши С.

Поиски по форуму не привели к результату, думаю, тема окажется полезной не мне одному, поэтому, буду очень признателен помощи.

2

Re: AHK: Событие при клике в заданных координатах окна

Похожая тема.
Блокировка ЛКМ в заданных координатах.

3

Re: AHK: Событие при клике в заданных координатах окна

На основе одного из вариантов из предложенной темы получился такой сценарий, который выполняет первые две задачи:


#IfWinActive, ahk_id 0x37a10da
MouseGetPos, x, y
    IF ((x<180) OR (x>1950)) OR ((y<0) OR (y>40))
        ~LButton:: Send, {a}
         return
        ~LButton Up:: Send, {b}

Как реализовать отправление клавиши c по простому клику, без смещения курсора, не представляется очевидным.
Так же упустил один момент: необходимо, что при опускании ЛКМ отправлялась клавиша a, а при поднятии - b только в том случае, когда движение курсора с зажатой ЛКМ происходит в правую сторону, если в левую, то необходим обратный порядок отправления клавиш, т.е. сначала b, потом a.

4

Re: AHK: Событие при клике в заданных координатах окна

Global xm
CoordMode, Mouse, Screen
IfPos(x1,y1,x2,y2){
MouseGetPos xm,ym
return ((xm >= x1) and (xm <= x2)) and ((ym >= y1) and (ym <= y2))
}

#IF IfPos(0,0,200,200) ; тут указывыть координаты x1,y1,x2,y2
LButton::
ToolTip Действие 1 и ожидание отжатия %A_ThisHotkey%
KeyWait %A_ThisHotkey%
MouseGetPos xd
if (xd < xm)
    ToolTip Действие 2.1. Курсор ушел в лево от начальной позиции.
if (xd = xm)
    ToolTip Действие 2.2. Курсор остался на начальной позиции.
if (xd > xm)
    ToolTip Действие 2.3. Курсор ушел в право от начальной позиции.
#if

5

Re: AHK: Событие при клике в заданных координатах окна

yalanne, а куда добавить отправление клавиш и условие для срабатывания в конкретном окне? Попробовал самостоятельно, не получилось.

6 (изменено: yalanne, 2015-09-29 10:50:05)

Re: AHK: Событие при клике в заданных координатах окна

becauseim пишет:

yalanne, а куда добавить отправление клавиш

В место тултупа.

А для окна надо вроде
CoordMode, Mouse, window

7

Re: AHK: Событие при клике в заданных координатах окна

Вместо проверки (xd=xm) лучше использовать abs(xd-xm)<N, где N подбирается экспериментально (2..5).
Так меньше вероятность ложных срабатываний при сдвиге курсора на 1-2 пикселя.

8

Re: AHK: Событие при клике в заданных координатах окна


Global xm
CoordMode, Mouse, Window
IfPos(x1,y1,x2,y2){
MouseGetPos xm,ym
return ((xm >= x1) and (xm <= x2)) and ((ym >= y1) and (ym <= y2))
}
IfWinActive, ahk_id 0x37a10da
#IF IfPos(180,0,1950,40)
LButton::
Send, {a}
KeyWait %A_ThisHotkey%
MouseGetPos xd
if (xd < xm)
    Send, {b}
if (xd = xm)
    Send, {c}
if (xd > xm)
    Send, {b}
#if

В таком виде клавиши отправляются сразу после запуска скрипта (прямо в редактор). При кликах в целевом окне не отправляются. Также не понял значения действий 1, 2.1, 2.3, которые по задумке должны варьироваться в зависимости от смещения курсора в одну из сторон. Или я неправильно понял этой формы.

9

Re: AHK: Событие при клике в заданных координатах окна

Скрипт в соответствии с пунктами из поста #3.

CoordMode, Mouse, Window
Arr:= ["{c}","{a}{b}","{b}{a}"]

IfPos(x1,y1,x2,y2){
   MouseGetPos xm,ym
   return ((xm >= x1)&&(xm <= x2))&&((ym >= y1)&&(ym <= y2))
}

#IF IfPos(180,0,1950,40) && WinActive("ahk_exe notepad++.exe") ; Название своего exe-файла.
LButton::
   MouseGetPos x0
   KeyWait %A_ThisHotkey%
   MouseGetPos xd
   SendInput % Arr[1+((Abs(xd-x0))>4)*(1+(xd < x0))]
Return
#IF

10 (изменено: yalanne, 2015-09-29 20:25:36)

Re: AHK: Событие при клике в заданных координатах окна

Надо бы еще проверять ширину окна, иначе вот так получается:
http://i.imgur.com/xiDTrCA.gif

Вот тут проверка ширины:

CoordMode, Mouse, Window
Arr:= ["{c}","{a}{b}","{b}{a}"]

IfPos(x1,y1,x2,y2){
   MouseGetPos xm,ym
   return ((xm >= x1)&&(xm <= x2))&&((ym >= y1)&&(ym <= y2))
}

GetWWin(Title)
{
WinGetPos,,,w,,%Title%
    return w
}
Title := "ahk_exe notepad++.exe"
#IF IfPos(180,0,GetWWin(Title),40) && WinActive(Title) ; Название своего exe-файла.
LButton::
   MouseGetPos x0
   KeyWait %A_ThisHotkey%
   MouseGetPos xd
   tooltip % Arr[1+((Abs(xd-x0))>4)*(1+(xd < x0))]
Return
#IF

11

Re: AHK: Событие при клике в заданных координатах окна

Можно. В общем случае, все ситуации трудно предусмотреть, пользователь может в одном окне нажать ЛКМ, переключиться на другое и там отпустить. )
Подождем фидбек топикстартера.

12 (изменено: Alectric, 2015-09-29 21:39:06)

Re: AHK: Событие при клике в заданных координатах окна

IfPos(x1,y1,x2,y2){
MouseGetPos xm,ym,win
WinGet,id,id,ahk_exe notepad++.exe
if (id!=win)
  return 0
return ((xm >= x1) and (xm <= x2)) and ((ym >= y1) and (ym <= y2))
}
+ открыть спойлер
Global xm
CoordMode, Mouse, Window
IfPos(x1,y1,x2,y2){
MouseGetPos xm,ym,win
WinGet,id,id,ahk_exe notepad++.exe
if (id!=win)
  return 0
return ((xm >= x1) and (xm <= x2)) and ((ym >= y1) and (ym <= y2))
}

#IF IfPos(0,0,200,200) ; тут указывыть координаты x1,y1,x2,y2
LButton::
KeyWait %A_ThisHotkey%
MouseGetPos xd
if (abs(xd-xm)<5)
    ToolTip остался.
else if (xd < xm)
    ToolTip лево.
else if (xd > xm)
    ToolTip право.
#if

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

13

Re: AHK: Событие при клике в заданных координатах окна

Скрипт из девятого комментария, к сожалению, никак себя не проявил. Не знаю, почему.
На данный момент использую следующий скрипт, но, опять же, работает только отправление "с", а также действие, при котором последовательно отправляются клавиши "а" и "b", вне зависимости от того, в какую сторону было совершено движение курсором.

IfWinActive, ahk_pid 4916
        MouseGetPos, x, y
        IF ((x<180) OR (x>1950)) OR ((y<0) OR (y>40))
            ~LButton:: 
                Send {c}
                Send {a}
                ~LButton Up:: Send, {b}

Наверное, решить этот вопрос можно тем, чтобы не отправлять клавиш при нажатии ЛКМ, а запоминать координаты совершенного клика, и в зависимости от того, с какой из сторон от места отпускания ЛКМ окажутся эти координаты, возвращаться в эти координаты и отправлять соответствующую клавишу. Суть в том, чтобы буква "a" всегда оказывалась левее буквы "b", вне зависимости от того, при каких условиях они были отправлены (при нажатии или при отпускании). На всякий случай, если останусь непонятым, опишу предполагаемое в виде порядка действий:

В пределах координат x180-1950/y0-40 относительно целевого окна совершается нажатие на ЛКМ в координатах x200/y20, которые AHK должен запомнить. По клику ничего не отправляется. Далее, не отпуская ЛКМ, курсор перемещается и ЛКМ отпускается, например, в координатах x180/20, следовательно, при отпускании ЛКМ, отправляется клавиша "a", т.к. конечные координаты расположены левее начальных. Далее курсор возвращается на начальные координаты (которые были записаны в памяти) и отправляет нажатие клавиши "b".

14 (изменено: yalanne, 2015-10-02 10:26:40)

Re: AHK: Событие при клике в заданных координатах окна

А вот так подходит?

CoordMode, Mouse, Window
arr := ["A","B"]
ifposM(Title,x1,y1,x2,y2)
{
    MouseGetPos x,y,id
    return (WinActive(Title) = id) and ((x >= x1 and x <= x2) and (y >= y1 and y <= y2))
}

#if ifposM("ahk_exe notepad++.exe",180,0,1950,40)
LButton::
MouseGetPos xA,Y
KeyWait %A_ThisHotkey%
MouseGetPos xB
Send % arr[    z := (Abs(xB-xA)>4)*(1+(xB > xA))    ]
MouseMove xA,Y,
if z = 1
    Send % arr[ 2 ]
return
#if

15

Re: AHK: Событие при клике в заданных координатах окна

yalanne, на этот раз проверил в текстовом редакторе и в целевом окне. В текстовом редакторе печатаются буквы "А" и "B", причем при перемещении курсора с зажатой ЛКМ в левую сторону, отправляются обе клавиши в необходимом порядке, а при перемещении вправо - только клавиша "B". Момент с отправлением клавиши "С", полагаю, здесь упущен. А вот в окне целевой программы вижу только то, как курсор запоминает момент положения при нажатии, и возвращается в это положение после отпускания, а вот клавиши не отправляются. На всякий случай, замечу, что в окне целевой программы клавиши "А", "B", "C" имеют характер горячих клавиш, но не отправляемых текстовых символов.

Есть подозрение, что помимо отправления клавиш в момент клика, требуется также и сам клик (или также клавиша "С", или то и другое).  Т.к. в момент работы скрипта в текстовом редакторе, нет возможности его же, например, свернуть, а представленный мною выше куда более примитивный сценарий срабатывает необходимым образом, но только в правую сторону, к сожалению.

Был бы признателен, если бы Вы также добавили комментарии к последнему варианту кода. Очень интересно понять, как это работает. Например, хотел заменить клавишу "А" на комбинацию из других клавиш, но не сработало.

16

Re: AHK: Событие при клике в заданных координатах окна

+  коменты к последнему посту.
CoordMode, Mouse, Window ; координаты будут относительно окна.
arr := ["A","B"] ; создаем массив с клавишами. У каждой клавиши есть свой порядковый номер,у A-1;B-2 и тд.(если есть).
ifposM(Title,x1,y1,x2,y2) ; функция-условия для #if. В первое поле Title окна; позиция x и y первой точки; позиция x2 и y2 второй точки.
{
    ; все переменные в нутри функции временные.
    MouseGetPos x,y,id ; получаем позицию курсора и его id.
    return (WinActive(Title) = id) and ((x >= x1 and x <= x2) and (y >= y1 and y <= y2))
    ;(WinActive(Title) = id) - проверяет активно ли окно и клик по нему.
    ; ((x >= x1 and x <= x2) - Если x больше либо равно первой точке и при этом меньше либо равно второй ,то по икску клик был в нужном диапозоне.
    ; с y то же самая проверка.
}

#if ifposM("ahk_exe notepad++.exe",180,0,1950,40)
LButton::
; Если скрипт перешел сюда значит нужное окно активно и клик был в нужном диапозоне.
MouseGetPos xA,Y ; Получаем первую позицию x + y.
KeyWait %A_ThisHotkey% ; ждем отжатия кнопки которая создала поток(LButton)
MouseGetPos xB ; получаем вторую позицию x.
Send % arr[    z := (Abs(xB-xA)>4)*(1+(xB > xA))    ]
    ; z := - просто запись в переменную полученного результата, что бы не повторять действия вычисления повторно.
    ; Abs(xB-xA)>4) - Получение абсолютного числа(число будет хоть как положительное) между разностью xB и xA. Если это число больше 4 значит ответом этой группы будет 1 иначе 0.
    ; (1+(xB > xA)) - Если курсор ушел в лево то будет, а если в право срабатывает условие и + 1=2. 
    ; дальше идет умножение первой и второй группы. в первой может быть только 1 или 0; во второй только 1 или 2.
    ; в итоге может получится 3 ответа 0 - так как в масиве нету не чего под 0 то и ответа не будет. 1-Буква A. 2-Буква Б,
MouseMove xA,Y, ; перемещаем обратно курсор.
if z = 1 ; если мышь двигалась в лево то еще
    Send % arr[ 2 ] ; нажимаем букву Б.
return
#if
becauseim пишет:

В текстовом редакторе печатаются буквы "А" и "B", причем при перемещении курсора с зажатой ЛКМ в левую сторону, отправляются обе клавиши в необходимом порядке, а при перемещении вправо - только клавиша "B". Момент с отправлением клавиши "С", полагаю, здесь упущен. А вот в окне целевой программы вижу только то, как курсор запоминает момент положения при нажатии, и возвращается в это положение после отпускания, а вот клавиши не отправляются.

Если идет в право то надо BC так же писать как и с лево(AB)?

+ открыть спойлер
CoordMode, Mouse, Window
arr := ["A","B","C"]
ifposM(Title,x1,y1,x2,y2)
{
    MouseGetPos x,y,id
    return (WinActive(Title) = id) and ((x >= x1 and x <= x2) and (y >= y1 and y <= y2))
}

#if ifposM("ahk_exe notepad++.exe",180,0,1950,40)
LButton::
MouseGetPos xA,Y
KeyWait %A_ThisHotkey%
MouseGetPos xB
Send % arr[    z := (Abs(xB-xA)>4)*(1+(xB > xA))    ]
MouseMove xA,Y,
if z = 1
    SendInput % arr[ 2 ]
if z = 2
    SendInput % arr[ 3 ]
return
#if

17

Re: AHK: Событие при клике в заданных координатах окна

Думаю нужно отправлять виртуальные коды.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

18

Re: AHK: Событие при клике в заданных координатах окна

yalanne, большое спасибо за комментарии к коду! Хотел с помощью них понять, как мне объединить упрощенный действующий скрипт с Вашим, но пока еще не пытался. Последний вариант работает также только в текстовом редакторе. Почему, не знаю, но предположения прежние. Попробовал бы заменить отправление клавиш на виртуальные коды, как советует Alectric, но по-прежнему, не знаю, как заменить указанные единичные символы на сочетания клавиш. В данной строке все понятно:

arr := ["A","B"] 

а вот дальше - нет.
Также хотел попробовать убрать условие работы скрипта в определенном окне, чтобы понять, требуются ли виртуальные коды, но, опять же, не получилось. Хотелось бы услышать подсказки по этим пунктам.

Если идет в право то надо BC так же писать как и с лево(AB)?

Нет, вправо также требуется получить отправление первых двух клавиш, только если при перемещении влево, клавишу В мы получаем после возвращения курсора в начальное положение, то при перемещении вправо, клавишу B необходимо отправить в момент отпускания ЛКМ, а после возвращения курсора в начальное положение, отправить клавишу A.
Клавишу С же необходимо получить при отсутствии движения курсора при зажатой ЛКМ, а также вместе с клавишами A и B.

19

Re: AHK: Событие при клике в заданных координатах окна

Появилась возможность упростить желаемый сценарий, а именно исключить срабатывание лишь в определенных координатах заданного окна, а также исключить момент возвращения курсора в положение нажатия на ЛКМ, если того не потребует сценарий.
Желаемый результат:


; если не отпуская ЛКМ, курсор будет направлен вправо от места нажатия:
LButton:: Send {^!+p}{a}
LButton Up:: Send {b}

; если.. влево:
LButton:: Send {^!+p}{b}
LButton Up:: Send {a}

; если курсор остается на месте (c погрешностью в 2-3 пикселя либо без погрешнсоти):
LButton Up:: Send {^!+p}

Понимаю, что можно было модифицировать уже предложенные сценарии, но у меня не получилось сделать это верным образом.

20 (изменено: serzh82saratov, 2015-10-21 18:11:05)

Re: AHK: Событие при клике в заданных координатах окна


fault := 3 ; погрешность
 
#IfWinActive ahk_class Notepad++
~LButton::
    MouseGetPos sX
    While GetKeyState("LButton", "P")
    {
        MouseGetPos eX 
        If abs(odds := eX-sX) > fault
        {
            Send % odds < 0 ? "^!+{vk50}{vk42}" : "^!+{vk50}{vk41}"
            Break
        }
    }
    KeyWait, LButton 
    Send % odds < -fault ? "{vk41}" : odds > fault ? "{vk42}" : "^!+{vk50}"
    Return
#IfWinActive
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

21

Re: AHK: Событие при клике в заданных координатах окна

Спасибо! Пока не выяснил для себя, все ли работает так, как задумывалось. На досуге посмотрю внимательнее.

22

Re: AHK: Событие при клике в заданных координатах окна

serzh82saratov, Хотелось бы иметь усовершенствованный вариант. Помогите, пожалуйста, его реализовать:

После совершения зажатия ЛКМ на 150 мсек, запоминаются координаты положения курсора и начинается ожидание траектории движения курсора, но при движении ничего не отправляется, как в последней редакции, а при отпускании ЛКМ справа от места зажатия отправляется клавиша {b}, далее отправляется MouseClick в полученные вначале координаты и отправляется клавиша {а}. Если отпускается слева - то наоборот, сначала {а}, потом MouseClick {b}. Если остается на месте - отправляется {^!+p} без MouseClick . Если ЛКМ была отпущена ранее 150 мсек после нажатия, т.е. без зажатия, то работает как обычно, т.е. отправлется LButton.

23

Re: AHK: Событие при клике в заданных координатах окна


SetDefaultMouseSpeed, 0
CoordMode, Mouse

fault := 3 ; погрешность
 
#IfWinActive ahk_class Notepad++
LButton::
	MouseGetPos sX, sY
	Start := A_TickCount
	While GetKeyState("LButton", "P")
		Continue
	If (A_TickCount - Start < 150)
	{
		Click
		Return
	}
	MouseGetPos eX 
    SendInput % eX - sX < -fault ? "{vk41}{Click " sX " " sY "}{vk42}" : eX - sX > fault ? "{vk42}{Click " sX " " sY "}{vk41}" : "^!+{vk50}"
    Return
#IfWinActive
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

24

Re: AHK: Событие при клике в заданных координатах окна

serzh82saratov, спасибо, работает! Однако я забыл подробнее описать тот момент, что ожидание должно включаться не просто после удержания, а удержания в одной позиции (координатах), можно с погрешностью в 2-3 пикселя. Также мне сложно дается редактирование регулярных выражений, и у меня не получилось добавить дополнительное отправление клавиш перед {a} и {b}, а именно заменить {a} на ^!+{p}{a} и аналогично {b} на ^!+{p}{b}, вне зависимости от порядка их отправления (движения курсора).

25

Re: AHK: Событие при клике в заданных координатах окна

SetDefaultMouseSpeed, 0
CoordMode, Mouse, Window

fault := 3 ; погрешность
 
#If NeedArea(0, 0, 30, 30, sX, sY)
LButton::
	Start := A_TickCount
	While GetKeyState("LButton", "P")
		Continue
	If (A_TickCount - Start < 150)
	{
		Click
		Return
	}
	MouseGetPos eX 
    SendInput % eX - sX < -fault ? "^!+{vk50}{vk41}{Click " sX " " sY "}^!+{vk50}{vk42}" 
				: eX - sX > fault ? "^!+{vk50}{vk42}{Click " sX " " sY "}^!+{vk50}{vk41}" 
				: "^!+{vk50}"
    Return
#IfWinActive 

NeedArea(x1, y1, x2, y2, ByRef x, ByRef y) {
    MouseGetPos, x, y
	If (x >= x1 && x <= x2 && y >= y1 && y <= y2)
        Return 1 
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

26 (изменено: becauseim, 2016-05-10 15:40:11)

Re: AHK: Событие при клике в заданных координатах окна

serzh82saratov, задерживаю ЛКМ на одной позиции, после чего перемещаю в одну из сторон, но ничего не отправляется. В предыдущей редакции клавиши отправлялись должным образом.

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


LButton::
MouseGetPos sX, sY
PixelGetColor, Color, sX, sY
if (Color = "0x222222") or (Color = "0x191919"){
...

27

Re: AHK: Событие при клике в заданных координатах окна

becauseim пишет:

задерживаю ЛКМ на одной позиции

На какой позиции?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

28

Re: AHK: Событие при клике в заданных координатах окна

serzh82saratov, на позиции, где совершается клик. Т.е. если я задерживаю ЛКМ на одном месте, то начинается ожидание отпускания ЛКМ с дальнейшим ходом сценария.

Но, учитывая последнюю поправку, условие на удержание можно упразднить (или оставить с возможностью закомментирования на случай, если в нем нет необходимости) и заменить на условие, описаное в 26-ом посте.

29

Re: AHK: Событие при клике в заданных координатах окна

becauseim пишет:

на позиции, где совершается клик.

Вы уже совсем запутались в своих хотелках, и сами не помните чего хотели:

becauseim пишет:

Однако я забыл подробнее описать тот момент, что ожидание должно включаться не просто после удержания, а удержания в одной позиции (координатах), можно с погрешностью в 2-3 пикселя.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

30

Re: AHK: Событие при клике в заданных координатах окна

serzh82saratov, в данном случае, не запутался. Происходит зажатие ЛКМ на 150 мсек без сдвига - начинается ожидание. На текущий момент ожидание начинается тогда, когда ЛКМ зажимается как со сдвигом, так и без него.

На всякий случай, перефразирую. Если курсор не сдвигается при зажатой ЛКМ в течение 150 мсек, нечинается ожидание отжатия ЛКМ с дальнейшим ходом сценария.