Тема: AHK: IfWinNotActive для всех полноэкранных приложений
Здравствуйте, нужна команда, которая будет исключать возможность срабатывания скрипта в любом полноэкранном приложении. Что-то типо IfWinNotActive.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Здравствуйте, нужна команда, которая будет исключать возможность срабатывания скрипта в любом полноэкранном приложении. Что-то типо 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)
}
belyankin12
Может, всё таки речь о развёрнутом окне, а не том, что в полноэкранном режиме?
F1::
WinGet, style, style, A
if style & 0x01000000
MsgBox, Окно развёрнуто.
else
MsgBox, Окно восстановлено.
Flasher, нет, активное окно, например окно Notepad не должно блокировать скрипт. Меня просто бесит что в играх срабатывают комбинации, вот и нужен блок на полный экран.
YMP, а как мне этим воспользоваться? var := ActiveAppNotFullScreen() if (var = "True")?
Попытался так как выше предположил. Ничего не вышло.
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
}
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
Можно без таймера попробовать:
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
belyankin12, не проще ли вам создать группу окон (GroupAdd), и включить в нее игры и т.д.?
Return ((style & 0x20800000) or winH < A_ScreenHeight or winW < A_ScreenWidth) ? false : true }
A_ScreenWidth и A_ScreenHeight в данном случае ненадёжны. Кто догадается почему, тому плюс в карму.
При нескольких мониторах?
Доп. пиксели с краёв, поди.
Ну не знаю.
Перед опубликованием кода я проверил его на нескольких приложениях - Chrome, IE, WMP.
Нигде не соврал.
Пока никто не угадал. Я, кстати, сам вчера не сразу вспомнил, почему использовал не их, а вызовы SysGet.
А в чем разница?
В справке написано, что они идентичны:
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.
Идентичны не всегда, в этом и ненадёжность. А вот когда они неидентичны, пока никто не догадался.
Анаморфирование при смене разрешения в играх? Не?
Или это как-то с печатной областью связано?
P.S. Сам, наверное, на золотой плюс за раскрытие секрета фирмы тянет.
YMP, если идентичны не всегда, а в справке указано, что они идентичны - значит это баг.
А баг не поддается угадыванию.
Приз уходит Flasher'у! Игра может работать с другим разрешением экрана.
Ну и что из этого?
Если мануально сменить разрешение экрана, то A_ScreenWidth тоже изменится.
Или если я запущу какую-нибудь программу в режиме 640 на 480, то также A_ScreenWidth покажет верное разрешение.
Ну как что? Не определяется игра в этом случае, как полноэкранное приложение, т.е. код не выполняет свою функцию.
Почему?
Только что запустил vlc в режиме 640x480, поставил его на полный экран - код определил, что приложение у меня fullscreen.
Или если я запущу какую-нибудь программу в режиме 640 на 480, то также A_ScreenWidth покажет верное разрешение.
Про какую-нибудь программу ничего не скажу, а на играх я проверял, там при пониженном разрешении работает только вариант с SysGet.
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, я не знаю как это сделать, если вы мне поможете, то пожалуйста.
Ну, если только это, то таймер не нужен. Просто добавить проверку.
Lwin & Я::
If ActiveAppNotFullScreen() {
Menu, MyMenu, Show ; Показывать меню по нажатию Win-Z или Ctrl+Правый клик. ,
}
return
Все работает, спасибо.
Про какую-нибудь программу ничего не скажу, а на играх я проверял, там при пониженном разрешении работает только вариант с 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
АНК последний, Windows 10 x64, игра DeadHunt. Но при ближайшем рассмотрении эта игра ведёт себя странно, в ней оба варианта ActiveAppFullScreen (с переменными и с SysGet) то работают, то нет. Но isWindowFullScreen("A") стабильно не работает. Видимо, просто совпало. Сначала isWindowFullScreen и ActiveAppFullScreen обе не работали, потом я заменил у себя переменные на SysGet и моя функция заработала. Значит, просто чудила игра. Надо разбираться, что с ней не так. В Fallout 4 работают все три варианта, в Crysis тоже.
В общем, эта тема сложнее, чем казалась изначально.
В общем, при загрузке DeadHunt её клиентская область равна разрешению экрана, в меню она становится меньше и остаётся таковой в самой игре, что визуально никак не проявляется. Если в настройках сменить разрешение, то в дальнейшем клиентская область остаётся равной экрану до выхода из игры. Лучше здесь использовать размер окна, с ним таких изменений не происходит.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться