1 (изменено: belyankin12, 2017-02-24 17:55:49)

Тема: AHK: IfWinNotActive для всех полноэкранных приложений

Здравствуйте, нужна команда, которая будет исключать возможность срабатывания скрипта в любом полноэкранном приложении. Что-то типо IfWinNotActive.

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

2

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Когда-то для подобного я использовал вот такие функции:


ActiveAppFullScreen()
{
    static SM_CXSCREEN := 0, SM_CYSCREEN := 1, Rect
    hwndActive := WinExist("A")
    WinGetClass, classActive, ahk_id %hwndActive%
    If (classActive = "WorkerW" || classActive = "Shell_TrayWnd")
        Return False
    VarSetCapacity(Rect, 16)
    DllCall("GetClientRect", "Ptr", hwndActive, "Ptr", &Rect)
    width := NumGet(Rect, 8, "UInt")
    height := NumGet(Rect, 12, "UInt")
    SysGet, fs_width, %SM_CXSCREEN%
    SysGet, fs_height, %SM_CYSCREEN%
    Return (width = fs_width) &&  (height = fs_height)
}

ActiveAppNotFullScreen()
{
    static SM_CXSCREEN := 0, SM_CYSCREEN := 1, Rect
    hwndActive := WinExist("A")
    WinGetClass, classActive, ahk_id %hwndActive%
    If (classActive = "WorkerW" || classActive = "Shell_TrayWnd")
        Return True
    VarSetCapacity(Rect, 16)
    DllCall("GetClientRect", "Ptr", hwndActive, "Ptr", &Rect)
    width := NumGet(Rect, 8, "UInt")
    height := NumGet(Rect, 12, "UInt")
    SysGet, fs_width, %SM_CXSCREEN%
    SysGet, fs_height, %SM_CYSCREEN%
    Return (width < fs_width) &&  (height < fs_height)
}

3

Re: AHK: IfWinNotActive для всех полноэкранных приложений

belyankin12
Может, всё таки речь о развёрнутом окне, а не том, что в полноэкранном режиме?

F1::

WinGet, style, style, A
if style & 0x01000000
  MsgBox, Окно развёрнуто.
else
  MsgBox, Окно восстановлено.

4

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Flasher, нет, активное окно, например окно Notepad не должно блокировать скрипт. Меня просто бесит что в играх срабатывают комбинации, вот и нужен блок на полный экран.

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

5

Re: AHK: IfWinNotActive для всех полноэкранных приложений

YMP, а как мне этим воспользоваться? var := ActiveAppNotFullScreen() if (var = "True")?

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

6

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Попытался так как выше предположил. Ничего не вышло.

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

7

Re: AHK: IfWinNotActive для всех полноэкранных приложений

isFullScreen := isWindowFullScreen( "A" )
MsgBox % isFullScreen ? "Full Screen" : "Windowed"
Return

isWindowFullScreen( winTitle ) {
	;checks if the specified window is full screen
	
	winID := WinExist( winTitle )

	If ( !winID )
		Return false

	WinGet style, Style, ahk_id %WinID%
	WinGetPos ,,,winW,winH, %winTitle%
	; 0x800000 is WS_BORDER.
	; 0x20000000 is WS_MINIMIZE.
	; no border and not minimized
	Return ((style & 0x20800000) or winH < A_ScreenHeight or winW < A_ScreenWidth) ? false : true
}

8

Re: AHK: IfWinNotActive для всех полноэкранных приложений

belyankin12 пишет:

YMP, а как мне этим воспользоваться? var := ActiveAppNotFullScreen() if (var = "True")?

Все комбинации отключать? Тогда, наверно, запускать таймер, чтобы проверял на полноэкранность, и если она есть, то Suspend.


SetTimer, FullScreen, 2000
Return

FullScreen:
    If ActiveAppFullScreen() {
        If (!A_IsSuspended) {
            Suspend, On
        }
    } Else {
        If (A_IsSuspended) {
            Suspend, Off
        }
    }
    Return

9

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Можно без таймера попробовать:

Gui +LastFound
hAB := WinExist(), L := 0
ABM := DllCall( "RegisterWindowMessage", Str,"AppBarMsg" )
WinGetPos, GX,GY,GW,GH, ahk_id %hAB%
VarSetCapacity( APPBARDATA,36,0 ) ; http://msdn2.microsoft.com/en-us/library/ms538008.aspx
Off := NumPut(36,APPBARDATA), Off :=  NumPut( hAB, Off+0 ), Off :=  NumPut( ABM, Off+0 )
Off := NumPut(   1, Off+0 ) , Off :=  NumPut(  GX, Off+0 ), Off :=  NumPut(  GY, Off+0 )
Off := NumPut(  GW, Off+0 ) , Off :=  NumPut(  GH, Off+0 ), Off :=  NumPut(   1, Off+0 )
DllCall( "Shell32.dll\SHAppBarMessage", UInt,(ABM_NEW:=0x0), UInt,&APPBARDATA ) 
OnMessage( ABM, "ABM_Callback" )  
OnExit, QuitScript
Return


ABM_Callback( wParam, LParam, Msg, HWnd ) {
  If (LParam != L) {
    L := LParam
  }
  if (L=1) {
        If (!A_IsSuspended) {
            Suspend, On
        }
    } Else {
        If (A_IsSuspended) {
            Suspend, Off
        }
    }
    Return
}

QuitScript:
  DllCall("Shell32.dll\SHAppBarMessage", UInt,(ABM_REMOVE := 0x1), UInt,&APPBARDATA )
  ExitApp
Return

10

Re: AHK: IfWinNotActive для всех полноэкранных приложений

belyankin12, не проще ли вам создать группу окон (GroupAdd), и включить в нее игры и т.д.?

11

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Malcev пишет:

	Return ((style & 0x20800000) or winH < A_ScreenHeight or winW < A_ScreenWidth) ? false : true
}

A_ScreenWidth и A_ScreenHeight в данном случае ненадёжны. Кто догадается почему, тому плюс в карму.

12

Re: AHK: IfWinNotActive для всех полноэкранных приложений

При нескольких мониторах?

13

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Доп. пиксели с краёв, поди.

14

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Ну не знаю.
Перед опубликованием кода я проверил его на нескольких приложениях - Chrome, IE, WMP.
Нигде не соврал.

15

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Пока никто не угадал. Я, кстати, сам вчера не сразу вспомнил, почему использовал не их, а вызовы SysGet.

16

Re: AHK: IfWinNotActive для всех полноэкранных приложений

А в чем разница?
В справке написано, что они идентичны:

SM_CXSCREEN, SM_CYSCREEN: Width and height of the screen of the primary display monitor, in pixels. These are the same as the built-in variables A_ScreenWidth and A_ScreenHeight.

17

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Идентичны не всегда,  в этом и ненадёжность. А вот когда они неидентичны, пока никто не догадался.

18

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Анаморфирование при смене разрешения в играх? Не?
Или это как-то с печатной областью связано?

P.S. Сам, наверное, на золотой плюс за раскрытие секрета фирмы тянет.

+ YMP

19

Re: AHK: IfWinNotActive для всех полноэкранных приложений

YMP, если идентичны не всегда, а в справке указано, что они идентичны - значит это баг.
А баг не поддается угадыванию.

20

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Приз уходит Flasher'у! Игра может работать с другим разрешением экрана.

21 (изменено: Malcev, 2017-02-24 11:25:13)

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Ну и что из этого?
Если мануально сменить разрешение экрана, то A_ScreenWidth тоже изменится.
Или если я запущу какую-нибудь программу в режиме 640 на 480, то также A_ScreenWidth покажет верное разрешение.

22

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Ну как что? Не определяется игра в этом случае, как полноэкранное приложение, т.е. код не выполняет свою функцию.

23

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Почему?
Только что запустил vlc в режиме 640x480, поставил его на полный экран - код определил, что приложение у меня fullscreen.

24

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Malcev пишет:

Или если я запущу какую-нибудь программу в режиме 640 на 480, то также A_ScreenWidth покажет верное разрешение.

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

25

Re: AHK: IfWinNotActive для всех полноэкранных приложений

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


#include D:\Обитель Белки\Cache\VA.ahk

Menu, MyMenu, Add, Создать скрипт с скопированным кодом, Create
Menu, MyMenu, Add, Запустить скрипт путь которого скопирован, RunClipboard
Menu, MyMenu, Add, Запустить биндер, RunBinder
Menu, MyMenu, Add, Открыть Cache, OpenCache
Menu, MyMenu, Add, Открыть GTA SA User Files\SAMP, OpenGTASAUF
Menu, MyMenu, Add, Очистить Uninvite.ini, DelUn
return	

Create:
path := A_Desktop "\AutoHotkeyScript.ahk"
IfExist, %path%
goto z
else
goto zz
z:
FileDelete, %path%
goto zz
zz:
lll := "" . ClipGetText([CodePage]) . ""
FileAppend, %lll%, %path%
return

RunClipboard: ; Если скрипт существует - запускает скрипт
path:= "" . ClipGetText([CodePage]) . ""
Run, %path%, UseErrorLevel
return

RunBinder:
Run, D:\Обитель Белки\AHK\Биндер\Samp binds - мои.ahk
return

OpenCache:
Run, D:\Обитель Белки\AHK\Биндер\Cache
return

OpenGTASAUF:
Run, %A_MyDocuments%\GTA San Andreas User Files\SAMP
return

DelUn:
FileDelete, D:\Обитель Белки\AHK\Биндер\Cache\uninvite.txt
FileAppend,, D:\Обитель Белки\AHK\Биндер\Cache\uninvite.txt
return

Lwin & Я::
Menu, MyMenu, Show  ; Показывать меню по нажатию Win-Z или Ctrl+Правый клик. ,
return


Pause:: return

^Pause:: return

!Pause:: return

Мне нужно, чтобы при нажатии Win + Z не выскакивало окно в играх.
Steazy, я не знаю как это сделать, если вы мне поможете, то пожалуйста.

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

26

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Ну, если только это, то таймер не нужен. Просто добавить проверку.


Lwin & Я::
If ActiveAppNotFullScreen() {
    Menu, MyMenu, Show  ; Показывать меню по нажатию Win-Z или Ctrl+Правый клик. ,
}
return

27

Re: AHK: IfWinNotActive для всех полноэкранных приложений

Все работает, спасибо.

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

28 (изменено: Malcev, 2017-02-25 00:47:36)

Re: AHK: IfWinNotActive для всех полноэкранных приложений

YMP пишет:

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

Проверяли сейчас на актуальной версии автохотки?
На какой системе и на какой игре?
Специально установил на Win7 Heroes of Might and Magic 3, которая запускается под разрешением 800 на 600.
A_ScreenWidth показал 800.
Также посмотрел исходник автохотки:
https://github.com/Lexikos/AutoHotkey_L … cript2.cpp
Там есть такая функция для A_ScreenWidth, A_ScreenHeight:

VarSizeType BIV_ScreenWidth_Height(LPTSTR aBuf, LPTSTR aVarName)
{
	return aBuf
		? (VarSizeType)_tcslen(ITOA(GetSystemMetrics(aVarName[13] ? SM_CYSCREEN : SM_CXSCREEN), aBuf))
		: MAX_INTEGER_LENGTH;
}

И такая для sysget:

	case SYSGET_CMD_METRICS: // In this case, aCmd is the value itself.
return output_var.Assign(GetSystemMetrics(ATOI(aCmd))); // Input and output are both signed integers.

Из чего можно сделать вывод, что и в первом и во втором случае идет обращение к GetSystemMetrics function.
https://msdn.microsoft.com/en-us/librar … s.85).aspx

29

Re: AHK: IfWinNotActive для всех полноэкранных приложений

АНК последний, Windows 10 x64, игра DeadHunt. Но при ближайшем рассмотрении эта игра ведёт себя странно, в ней оба варианта ActiveAppFullScreen (с переменными и с SysGet) то работают, то нет. Но isWindowFullScreen("A") стабильно не работает. Видимо, просто совпало. Сначала isWindowFullScreen и ActiveAppFullScreen обе не работали, потом я заменил у себя переменные на SysGet и моя функция заработала. Значит, просто чудила игра. Надо разбираться, что с ней не так. В Fallout 4 работают все три варианта, в Crysis тоже.

В общем, эта тема сложнее, чем казалась изначально.

30

Re: AHK: IfWinNotActive для всех полноэкранных приложений

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