1 (изменено: stealzy, 2014-03-20 20:18:27)

Тема: AHK: Проверка активности окна [#If WinActive] не хочет работать

Подскажите пожалуйста, как сделать, чтобы хоткеи действовали только при активном окне.
Аналогичные IfWinNotActive/IfWinActive внутри подпрограмм хоткеев работают, но хочется ведь чтобы клавиши вообще не обрабатывались.
Не работает:


#IfWinActive, ahk_class ytWindow ; -  не работает.
+vk25::
MsgBox, Ok.
return
#If

Работает, но клавиши обрабатываются даже когда окно неактивно:


+vk25::
IfWinNotActive, ahk_class ytWindow ; - работает
    return
MsgBox, Ok.
return

Работает в примере. Но у меня не Msgbox, а цикл(под спойлером)

+ открыть спойлер

+vk25::
GetKeyState, state, LButton
if state = U
SendPlay {Click down}; 640, 400}
Loop {
MouseMove, -20, 0, 0, R
GetKeyState, state, vk25
if state = U
{
SendPlay {Click Up}
Break
}
}


#IfWinActive, ahk_class ytWindow ; -  не работает.
+Left::
MsgBox, Ok.
return
#If

Зачем все это

+ открыть спойлер

Скрипт предназначен для перетаскивания изображения в граф.просмотрщике клавиатурой.
Алгоритм: шифт эмул. ЛКМ; стрелки - MouseMove, если зажат шифт.
Сам просмотрщик со скриптом прилагается, просто разархивируйте и запустите picas.ahk, откроется картинка; затем нажмите комбинацию Shift+Left/Right/Up.

2

Re: AHK: Проверка активности окна [#If WinActive] не хочет работать


+Left::

Возможно что такой замены будет достаточно.

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

3

Re: AHK: Проверка активности окна [#If WinActive] не хочет работать

Для начала, неплохо бы скачать вложение - почему-то и ТКоммандер, и WinRar ругаются на битый архив 7z.

4

Re: AHK: Проверка активности окна [#If WinActive] не хочет работать

Аналогичные IfWinNotActive/IfWinActive внутри подпрограмм хоткеев работают, но хочется ведь чтобы клавиши вообще не обрабатывались.
Работает:


+vk25::
IfWinNotActive, ahk_class ytWindow ; - работает
    return
MsgBox, Ok.
return

Не работает:


#IfWinActive, ahk_class ytWindow ; -  не работает.
+vk25::
MsgBox, Ok.
return
#If

5 (изменено: Irbis, 2014-03-21 01:06:06)

Re: AHK: Проверка активности окна [#If WinActive] не хочет работать

Так работает. Комбинации клавиш (вверх+влево и т.п.) также обрабатываются.

SetBatchLines -1
Run, %A_ScriptDir%\PicasaPhotoViewer.exe pic.jpg, %A_ScriptDir%
Return
~vk1b::ExitApp

#If WinActive("ahk_class ytWindow")
*Shift:: LButton
#If WinActive("ahk_class ytWindow") && GetKeyState("Shift","P")
*Left::
*Right::
*Up::
*Down::
   While K:=MoveKeys()
      MouseMove -20*(K&1)+20*(K>>1&1),-20*(K>>2&1)+20*(K>>3),0,R
Return
#IfWinActive

MoveKeys()
{
   Return GetKeyState("Left","P") | GetKeyState("Right","P")<<1
        | GetKeyState("Up","P")<<2 | GetKeyState("Down","P")<<3
}

Вариант с ускорением движения может быть интересней, плюс курсор передвигается стрелками при зажатой клавише Control:

SetBatchLines -1
Run, %A_ScriptDir%\PicasaPhotoViewer.exe pic.jpg, %A_ScriptDir%
Step := 0.5, dmax := 20
Return
~vk1b::ExitApp

#If WinActive("ahk_class ytWindow")
*Shift:: LButton
#If WinActive("ahk_class ytWindow") && (GetKeyState("Shift","P") || GetKeyState("Ctrl","P"))
*Left::
*Right::
*Up::
*Down::
   d := 0
   While K:=MoveKeys() {
      if (d<dmax)
         d+=Step
      MouseMove -d*(K&1)+d*(K>>1&1),-d*(K>>2&1)+d*(K>>3),0,R
   }
Return
#IfWinActive

MoveKeys()
{
   Return GetKeyState("Left","P") | GetKeyState("Right","P")<<1
        | GetKeyState("Up","P")<<2 | GetKeyState("Down","P")<<3
}

6

Re: AHK: Проверка активности окна [#If WinActive] не хочет работать

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

+ магия

http://img0.joyreactor.cc/pics/comment/David-Blaine-harrison-ford-Харрисон-Форд-девид-блейн-800456.jpeg

7 (изменено: stealzy, 2014-03-28 01:41:28)

Re: AHK: Проверка активности окна [#If WinActive] не хочет работать

Добавим еще уличной магии:
Перемещение без мышки, независимо от положения курсора
(невозможно промахнуться или сдвинуть изображение за край экрана),
получение полного пути к файлу в буфер обмена.



#MaxHotkeysPerInterval 200
SetBatchLines -1
CoordMode, Mouse, Screen
pointStart:=-4, step:=0.04, dmax:=40, Global key_lock:=0, shift_press:=0, XcenterFullScrPic:=A_ScreenWidth / 2, YcenterFullScrPic:=(A_ScreenHeight-32) / 2
PixPre(XcenterFullScrPic, YcenterFullScrPic, Rpre, Gpre, Bpre) ; Get prediction RGB in center pixel
OnExit, ExitSub
{ ; Передает последний параметр просмотрщику, без параметров - передает pic.jpg в своей дир.
param0 := %0%
Loop %0%
{
param1 := %A_Index%
}
If param0 = 0
    Run, %A_ScriptDir%\PicasaPhotoViewer.exe %A_ScriptDir%\pic.jpg, %A_ScriptDir%
Else
    Run, %A_ScriptDir%\PicasaPhotoViewer.exe %param1%, %A_ScriptDir%
}
{ ; Проверка сущ процесса
#Persistent
SetTimer, CheckWin, 1000
return
CheckWin:
If Not WinActive("ahk_class ytWindow")
    PixPre(XcenterFullScrPic, YcenterFullScrPic, Rpre, Gpre, Bpre)
if !WinExist("ahk_class ytWindow") 
    ExitApp
Return
}
Return

{ ;    Keys
#If WinActive("ahk_class ytWindow")
~vk1b::ExitApp                            ;Exit            
Enter::ExitApp                                

vkdc::                                    ;Получить полный путь в буфер
WinGetTitle, tit, ahk_class ytWindow
filename := RegExReplace(tit, "^(.+?\.(jpg|png|gif)) - .*", "\$1")
If param0 = 0
    fpath := A_ScriptDir
Else
    fpath := RegExReplace(param1, "^(.+)\\[^\\]+\.(jpg|png|gif)$", "$1")
ffilename := (fpath . filename)
clipboard := ffilename
Return

*Shift::                                ; имитация LKM
If shift_press=0
{
    LKM_press(XcenterFullScrPic, YcenterFullScrPic, Rpre, Gpre, Bpre)
    shift_press:=1
}
Return
*Shift Up::
    shift_press:=0
    SendPlay {LButton Up}
    RestoreCursors()
Return
                                        ; имитация mousemove
#If WinActive("ahk_class ytWindow") && (GetKeyState("Shift","P") || GetKeyState("Ctrl","P"))
*Left::
*Right::
*Up::
*Down::
   i := pointStart, d := 0
   While (K:=MoveKeys()) && Not key_lock {
      MovePicTroughScreenBorder(key_lock, XcenterFullScrPic, YcenterFullScrPic, Rpre, Gpre, Bpre)
      K:=K&~Borders()
      if (d<dmax)
      {
        i:=i+Step                        ; step
        a:=!a                             ; addiction
        d:=(dmax*(1/(1+(3**(-i)))))+a     ; s-образная (сигмоида)
      }
      MouseMove -d*(K&1)+d*(K>>1&1),-d*(K>>2&1)+d*(K>>3),0,R
   }
Return
#IfWinActive
}

;    куча условий, чтобы не промазать мимо картинки
LKM_press(XcenterFullScrPic, YcenterFullScrPic, Rpre, Gpre, Bpre) {
Global key_lock:=1
    CoordMode, Mouse, Screen
    MouseGetPos, xpos, ypos ;, id
    WinGetPos, X, Y, width, heigth, ahk_class ytWindow
    If (X||Y)=0 {
        CoordMode, Mouse, Screen
        if (ypos<(A_ScreenHeight-52))
        {
            if A_Cursor=SizeAll
                lbd:=1
            else {
                If PixIsImage(XcenterFullScrPic, YcenterFullScrPic, Rpre, Gpre, Bpre)
                {
                    MouseMove, %XcenterFullScrPic%, %YcenterFullScrPic%, 0
                    Sleep 100
                    if A_Cursor=SizeAll
                        lbd:=1
                } else {
                    MouseMove, XcenterFullScrPic-100, A_ScreenHeight, 0
                    Click 2
                    MouseMove, %XcenterFullScrPic%, %YcenterFullScrPic%, 0
                    Sleep 100
                    IfWinExist, Настройка Picasa Photo Viewer
                        WinClose
                    if A_Cursor=SizeAll
                        lbd:=1
                }
            }
        } else {
            MouseMove, 0, (A_ScreenHeight-58-ypos), 0, R
            if A_Cursor=SizeAll
                lbd:=1
            else {
                If PixIsImage(XcenterFullScrPic, YcenterFullScrPic, Rpre, Gpre, Bpre)
                {
                    MouseMove, %XcenterFullScrPic%, %YcenterFullScrPic%, 1
                    Sleep 100
                    if A_Cursor=SizeAll
                        lbd:=1
                } else {
                    MouseMove, XcenterFullScrPic-100, A_ScreenHeight, 0
                    Click 2
                    MouseMove, %XcenterFullScrPic%, %YcenterFullScrPic%, 1
                    Sleep 100
                    IfWinExist, Настройка Picasa Photo Viewer
                        WinClose
                    if A_Cursor=SizeAll
                        lbd:=1
                }
            }
        }
    }
    If lbd
        SetSystemCursor()
        SendPlay {LButton down}
    WinGetPos, X, Y, width, heigth, ahk_class ytWindow
    If (X||Y)!=0 {
        if lbd
            SendPlay {LButton Up}
        WinActivate, ahk_class ytWindow
            WinGetPos, X, Y, Width, Height
            Xcentr:=X+Width/2
            Ycentr:=Y+Height/2+15
            If (Xcentr-A_ScreenWidth)>-5 || (Ycentr-A_ScreenHeight)>-5 || Xcentr<5 || Ycentr<5
            {
                WinMove, (XcenterFullScrPic-Width/2), (YcenterFullScrPic-Height/2-15)
            }
        MoveMouseToClientAreaCenter()
        SendMode Input
        ControlSend,, {Enter}, ahk_class ytWindow
        Sleep 300
        if A_Cursor=SizeAll
        {
            SetSystemCursor()
            SendPlay {LButton down}
        }
    }
    lbd:=0, Global key_lock:=0
}

MoveKeys() {
   Return GetKeyState("Left","P") | GetKeyState("Right","P")<<1
        | GetKeyState("Up","P")<<2 | GetKeyState("Down","P")<<3
}
Borders() {       ; если курсор не у края - 0000, в правом нижнем углу - возвращает 0101, у верхней - 0010
MouseGetPos, x, y
Return ((x<=0) | (x>=A_ScreenWidth-1)<<1
   | (y<=0)<<2 | (y>=A_ScreenHeight-56)<<3)
}
;    Для того, чтобы не тыкать мимо картинки
PixGet(X, Y, ByRef R, ByRef G, ByRef B) {           ; получает цвета в переменные
PixelGetColor, color, %X%, %Y%, Slow
R := "0x" . SubStr(Color, 7, 2)
G := "0x" . SubStr(Color, 5, 2)
B := "0x" . SubStr(Color, 3, 2)
}
PixPre(X, Y, ByRef Rpre, ByRef Gpre, ByRef Bpre) {  ; по цвету оригинального пикселя предсказывает цвет затененного
PixGet(X, Y, R, G, B)
Rpre := Floor(Round((0.3198*R),0) + Round((0.1465*G),0) + Round((0.0255*B),0))
Gpre := Floor(Round((0.0726*R),0) + Round((0.3936*G),0) + Round((0.0255*B),0))
Bpre := Floor(Round((0.0726*R),0) + Round((0.1465*G),0) + Round((0.2728*B),0))
}
PixIsTrans(Rpre, R, Gpre, G, Bpre, B) {                ; сравнивает предсказанный цвет с введенным
If Abs(Rpre-R) >5 || Abs(Gpre-G) >5 || Abs(Bpre-B) >5
{
    if Rpre>R && Gpre>G && Bpre>B
    {
        CR:=Rpre/R-1, CG:=Gpre/G-1, CB:=Bpre/B-1
        if CR<0.6 && CG<0.6 && CB<0.6 && Abs(CR-CG)<0.1 && Abs(CR-CB)<0.1 && Abs(CB-CG)<0.1
            Return 1
        else
            Return 0
    }
    Else
        Return 0
}
Else
    Return 1
}
PixIsGrey(X, Y, R, G, B) {
    If (R=G and G=B)
        If (R=127)
            Return 1
        Else
            If (R<127 and R>=84)
            {
                G:=Borders(), sx:=X, sy:=Y
                PixGet((X+sx*(G&1)-sx*(G>>1&1)), (Y+sy*(G>>2&1)-sy*(G>>3)), Rb, Gb, Bb)
                Return (Rb=Gb and Gb=Bb and Rb=127)
            }
            Else
                Return 0
    Else
        Return 0
}
PixIsImage(X, Y, Rpre, Gpre, Bpre) {                ; возвращает 1 если это пиксель картинки
PixGet(X, Y, R, G, B)
Return Not ( PixIsTrans(Rpre, R, Gpre, G, Bpre, B ) ||  PixIsGrey(X, Y, R, G, B) )
}
MovePicTroughScreenBorder(key_lock, XcenterFullScrPic, YcenterFullScrPic, Rpre, Gpre, Bpre) {
    If (G:=Borders()&MoveKeys()) And (key_lock=0) ;And  ; если центр.пиксель принадлежит картинке, курсор на границе
    {
        if PixIsImage(XcenterFullScrPic, YcenterFullScrPic, Rpre, Gpre, Bpre)
        {    
            MsgBox % Rpre " " Gpre " " Bpre
            SendPlay {LButton Up}
            s:=10 ; поправка
            MouseMove, ((XcenterFullScrPic-s)*((G&1)-(G>>1&1))), ((YcenterFullScrPic-s)*((G>>2&1)-(G>>3))), 0, R    ; перемещаем курсор в центр, s - смещение
            ;If A_Cursor=SizeAll
                SendPlay {LButton Down}
            ;Else
                ;LKM_press(XcenterFullScrPic, YcenterFullScrPic, Rpre, Gpre, Bpre)
        } else {
            Global i:=-2, d:=1
        }
    }
}
;    Прячем/показываем курсор
SetSystemCursor() {
    Cursor = %A_ScriptDir%\no.ani
    CursorHandle := DllCall( "LoadCursorFromFile", Str,Cursor )
    DllCall( "SetSystemCursor", Uint,CursorHandle, Int,32649 )
    CursorHandle := DllCall( "LoadCursorFromFile", Str,Cursor )
    DllCall( "SetSystemCursor", Uint,CursorHandle, Int,32646 )
    CursorHandle := DllCall( "LoadCursorFromFile", Str,Cursor )
    DllCall( "SetSystemCursor", Uint,CursorHandle, Int,32512 )
}
RestoreCursors() {
    SPI_SETCURSORS := 0x57
    DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 )
}
;    Mousemove в центр окна в случае, если промазали
GetClientRect(hwnd, ByRef rX, ByRef rY, ByRef rWidth, ByRef rHeight) {
    WinGetPos, , , , Window_Height, ahk_id %hwnd%
    VarSetCapacity(rcClient, 16, 0) 
    DllCall("user32\GetClientRect","uint", hwnd ,"uint",&rcClient)   
    rcClient_b := NumGet(rcClient, 12) 
    VarSetCapacity(pwi, 68, 0)
    DllCall("GetWindowInfo", "UInt", hwnd, "UInt", &pwi) 
    rX := NumGet(pwi, 48) , by := NumGet(pwi, 52) 
    rY := Window_Height - by - rcClient_b  
    rWidth := NumGet(rcClient, 8)
    rHeight := NumGet(rcClient, 12)
}
MoveMouseToClientAreaCenter() {
    Sleep 50
    GetClientRect(WinExist("ahk_class ytWindow"), rX, rY, rWidth, rHeight)
    XcenterPi:=(rWidth // 2)
    YcenterPi:=(rHeight // 2)
    Send {LButton Up}
    CoordMode, Mouse, Client
    MouseMove, %XcenterPi%, %YcenterPi%, 0
    CoordMode, Mouse, Screen
    Sleep 50
}

ExitSub:
{
    RestoreCursors() 
    If GetKeyState("Left")
        Send {Shift up}
    If GetKeyState("LButton")
        Send {LButton up}
    Sleep 500
    IfWinExist, AHK_class ytWindow
        WinClose
    Sleep 500
    Process, Close, PicasaPhotoViewer.exe
    ExitApp
}

/*
Логика функции LKM_press
окно макс -мышь не ниже -курсор (-pix центр  (-даблклик по галерее))

                    -ниже -поднимаем  -курсор (-pix -центр  (-даблклик по галерее))
                    
окно мин  - окно в границах -да мышь над окном - да - энтер - курсор
                                          - нет - тащим мышь к окну - энтер - курсор
                            -нет - тащим окно в центр -и мышь - энтер*/

8

Re: AHK: Проверка активности окна [#If WinActive] не хочет работать

stealzy, у нас прянято пользоваться знаками препинания. Отредактируйте свои посты.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder