1

Тема: AHK: Команда ControlClick

Возникла проблема с командой ControlClick. При отправке 2ух кликов в Интернет эксплорер командой, происходит только выделение ссылки(1). Как сделать так, что бы при посылке кликов открывалась ссылка, а не просто выделялась?(При ручном нажатии на ссылку-она открывается в новом окне)
Скриншот прилагается:
http://s49.radikal.ru/i125/1010/82/1fe5f307a2fe.jpg

2

Re: AHK: Команда ControlClick

Не совсем понял. Если нужен двойной щелчок (а не два отдельных), то ControlClick его не умеет делать. Вот тут это обсуждалось: ControlClick fails to perform a double click in the Pos mode. Там же был найден обходной путь, оформленный в виде функции ControlClick2, производящей двойной щелчок по координатам. Две функции под ней тоже нужны, она их использует.

ControlClick2(X, Y, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="") 
{ 
  hwnd:=ControlFromPoint(X, Y, WinTitle, WinText, cX, cY 
                             , ExcludeTitle, ExcludeText) 
  PostMessage, 0x201, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_LBUTTONDOWN 
  PostMessage, 0x202, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_LBUTTONUP 
  PostMessage, 0x203, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_LBUTTONDBLCLCK 
  PostMessage, 0x202, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_LBUTTONUP 
} 

; Retrieves the control at the specified point. 
; X         [in]    X-coordinate relative to the top-left of the window. 
; Y         [in]    Y-coordinate relative to the top-left of the window. 
; WinTitle  [in]    Title of the window whose controls will be searched. 
; WinText   [in] 
; cX        [out]   X-coordinate relative to the top-left of the control. 
; cY        [out]   Y-coordinate relative to the top-left of the control. 
; ExcludeTitle [in] 
; ExcludeText  [in] 
; Return Value:     The hwnd of the control if found, otherwise the hwnd of the window. 
ControlFromPoint(X, Y, WinTitle="", WinText="", ByRef cX="", ByRef cY="", ExcludeTitle="", ExcludeText="") 
{ 
    static EnumChildFindPointProc=0 
    if !EnumChildFindPointProc 
        EnumChildFindPointProc := RegisterCallback("EnumChildFindPoint","Fast") 
    
    if !(target_window := WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText)) 
        return false 
    
    VarSetCapacity(rect, 16) 
    DllCall("GetWindowRect","uint",target_window,"uint",&rect) 
    VarSetCapacity(pah, 36, 0) 
    NumPut(X + NumGet(rect,0,"int"), pah,0,"int") 
    NumPut(Y + NumGet(rect,4,"int"), pah,4,"int") 
    DllCall("EnumChildWindows","uint",target_window,"uint",EnumChildFindPointProc,"uint",&pah) 
    control_window := NumGet(pah,24) ? NumGet(pah,24) : target_window 
    DllCall("ScreenToClient","uint",control_window,"uint",&pah) 
    cX:=NumGet(pah,0,"int"), cY:=NumGet(pah,4,"int") 
    return control_window 
} 

; Ported from AutoHotkey::script2.cpp::EnumChildFindPoint() 
EnumChildFindPoint(aWnd, lParam) 
{ 
    if !DllCall("IsWindowVisible","uint",aWnd) 
        return true 
    VarSetCapacity(rect, 16) 
    if !DllCall("GetWindowRect","uint",aWnd,"uint",&rect) 
        return true 
    pt_x:=NumGet(lParam+0,0,"int"), pt_y:=NumGet(lParam+0,4,"int") 
    rect_left:=NumGet(rect,0,"int"), rect_right:=NumGet(rect,8,"int") 
    rect_top:=NumGet(rect,4,"int"), rect_bottom:=NumGet(rect,12,"int") 
    if (pt_x >= rect_left && pt_x <= rect_right && pt_y >= rect_top && pt_y <= rect_bottom) 
    { 
        center_x := rect_left + (rect_right - rect_left) / 2 
        center_y := rect_top + (rect_bottom - rect_top) / 2 
        distance := Sqrt((pt_x-center_x)**2 + (pt_y-center_y)**2) 
        update_it := !NumGet(lParam+24) 
        if (!update_it) 
        { 
            rect_found_left:=NumGet(lParam+8,0,"int"), rect_found_right:=NumGet(lParam+8,8,"int") 
            rect_found_top:=NumGet(lParam+8,4,"int"), rect_found_bottom:=NumGet(lParam+8,12,"int") 
            if (rect_left >= rect_found_left && rect_right <= rect_found_right 
                && rect_top >= rect_found_top && rect_bottom <= rect_found_bottom) 
                update_it := true 
            else if (distance < NumGet(lParam+28,0,"double") 
                && (rect_found_left < rect_left || rect_found_right > rect_right 
                 || rect_found_top < rect_top || rect_found_bottom > rect_bottom)) 
                 update_it := true 
        } 
        if (update_it) 
        { 
            NumPut(aWnd, lParam+24) 
            DllCall("RtlMoveMemory","uint",lParam+8,"uint",&rect,"uint",16) 
            NumPut(distance, lParam+28, 0, "double") 
        } 
    } 
    return true 
}

3

Re: AHK: Команда ControlClick

А после выделения ссылки если нажать Ентер, она не открывается?

4 (изменено: Skare, 2010-10-20 21:12:31)

Re: AHK: Команда ControlClick

Нужно просто открыть эту ссылку, при условии, что она открывается только двойным щелчком.
InFlames, не открывается.:|
To YMP, не совсем понял, как это применять?:)

5

Re: AHK: Команда ControlClick

Вызвать функцию ControlClick2, указав нужные Вам координаты и целевое окно. Координаты относительно этого окна.

ControlClick2(57, 115, "ahk_class Notepad")

6

Re: AHK: Команда ControlClick

Как я понимаю, для клика по координатам 100, 215 в браузере на определённой страничке надо делать так:

ControlClick2(57, 115, "Страничка - Windows Internet Explorer")

Вот только почему-то выдаёт ошибку:(.

7

Re: AHK: Команда ControlClick

Кто выдаёт и какую ошибку? Я же не телепат всё-таки.

8

Re: AHK: Команда ControlClick

Извините, AHK выдаёт.
http://s58.radikal.ru/i162/1010/62/e37d14fb286f.png

9

Re: AHK: Команда ControlClick

А сами функции в скрипт вставил? Те, что в посте #2.

10

Re: AHK: Команда ControlClick

Ах, нет.:(
Тогда получается код будет такой:

ControlClick2(57, 115, "Список GSM в ремонте - Windows Internet Explorer")
{ 
  hwnd:=ControlFromPoint(X, Y, WinTitle, WinText, cX, cY 
                             , ExcludeTitle, ExcludeText) 
  PostMessage, 0x201, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_LBUTTONDOWN 
  PostMessage, 0x202, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_LBUTTONUP 
  PostMessage, 0x203, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_LBUTTONDBLCLCK 
  PostMessage, 0x202, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_LBUTTONUP 
} 

; Retrieves the control at the specified point. 
; X         [in]    X-coordinate relative to the top-left of the window. 
; Y         [in]    Y-coordinate relative to the top-left of the window. 
; WinTitle  [in]    Title of the window whose controls will be searched. 
; WinText   [in] 
; cX        [out]   X-coordinate relative to the top-left of the control. 
; cY        [out]   Y-coordinate relative to the top-left of the control. 
; ExcludeTitle [in] 
; ExcludeText  [in] 
; Return Value:     The hwnd of the control if found, otherwise the hwnd of the window. 
ControlFromPoint(X, Y, WinTitle="", WinText="", ByRef cX="", ByRef cY="", ExcludeTitle="", ExcludeText="") 
{ 
    static EnumChildFindPointProc=0 
    if !EnumChildFindPointProc 
        EnumChildFindPointProc := RegisterCallback("EnumChildFindPoint","Fast") 
    
    if !(target_window := WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText)) 
        return false 
    
    VarSetCapacity(rect, 16) 
    DllCall("GetWindowRect","uint",target_window,"uint",&rect) 
    VarSetCapacity(pah, 36, 0) 
    NumPut(X + NumGet(rect,0,"int"), pah,0,"int") 
    NumPut(Y + NumGet(rect,4,"int"), pah,4,"int") 
    DllCall("EnumChildWindows","uint",target_window,"uint",EnumChildFindPointProc,"uint",&pah) 
    control_window := NumGet(pah,24) ? NumGet(pah,24) : target_window 
    DllCall("ScreenToClient","uint",control_window,"uint",&pah) 
    cX:=NumGet(pah,0,"int"), cY:=NumGet(pah,4,"int") 
    return control_window 
} 

; Ported from AutoHotkey::script2.cpp::EnumChildFindPoint() 
EnumChildFindPoint(aWnd, lParam) 
{ 
    if !DllCall("IsWindowVisible","uint",aWnd) 
        return true 
    VarSetCapacity(rect, 16) 
    if !DllCall("GetWindowRect","uint",aWnd,"uint",&rect) 
        return true 
    pt_x:=NumGet(lParam+0,0,"int"), pt_y:=NumGet(lParam+0,4,"int") 
    rect_left:=NumGet(rect,0,"int"), rect_right:=NumGet(rect,8,"int") 
    rect_top:=NumGet(rect,4,"int"), rect_bottom:=NumGet(rect,12,"int") 
    if (pt_x >= rect_left && pt_x <= rect_right && pt_y >= rect_top && pt_y <= rect_bottom) 
    { 
        center_x := rect_left + (rect_right - rect_left) / 2 
        center_y := rect_top + (rect_bottom - rect_top) / 2 
        distance := Sqrt((pt_x-center_x)**2 + (pt_y-center_y)**2) 
        update_it := !NumGet(lParam+24) 
        if (!update_it) 
        { 
            rect_found_left:=NumGet(lParam+8,0,"int"), rect_found_right:=NumGet(lParam+8,8,"int") 
            rect_found_top:=NumGet(lParam+8,4,"int"), rect_found_bottom:=NumGet(lParam+8,12,"int") 
            if (rect_left >= rect_found_left && rect_right <= rect_found_right 
                && rect_top >= rect_found_top && rect_bottom <= rect_found_bottom) 
                update_it := true 
            else if (distance < NumGet(lParam+28,0,"double") 
                && (rect_found_left < rect_left || rect_found_right > rect_right 
                 || rect_found_top < rect_top || rect_found_bottom > rect_bottom)) 
                 update_it := true 
        } 
        if (update_it) 
        { 
            NumPut(aWnd, lParam+24) 
            DllCall("RtlMoveMemory","uint",lParam+8,"uint",&rect,"uint",16) 
            NumPut(distance, lParam+28, 0, "double") 
        } 
    } 
    return true 
}

Но тогда ошибка уже такая:
http://i016.radikal.ru/1010/69/5ba007748960.jpg

11

Re: AHK: Команда ControlClick

Тот код из 2 поста остается неизменным, а ту строку, что дал YMP в посте #5 написать перед всем этим кодом из поста #2.
Я попробовал, но у меня почему-то не делает двойной клик, точнее не кликает вообще.

12

Re: AHK: Команда ControlClick

Так вот как надо... Попробовал, заработало, спасибо:). А можно ли заставить эту команду работать не по координатам, а как-то иначе?:) Как-нибудь заставить находить место ссылки по тексту на ней?

13 (изменено: Malcev, 2016-02-19 04:52:35)

Re: AHK: Команда ControlClick

Код из 2 поста у меня работает в блокноте и при закомментированных:

; PostMessage, 0x201, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_LBUTTONDOWN 
; PostMessage, 0x202, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_LBUTTONUP 

Если же их раскомментировать и использовать в Adobe Premiere, то посылается иногда 3 клика вместо 2.
Может быть двойной клик правильней посылать без WM_LBUTTONDOWN WM_LBUTTONUP?
Хотя майкрософт пишет:

Double-clicking the left mouse button actually generates a sequence of four messages: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, and WM_LBUTTONUP

14 (изменено: YMP, 2016-02-19 06:59:56)

Re: AHK: Команда ControlClick

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