我尝试从这里运行此脚本https://autohotkey.com/board/topic/25619-detect-on-screen/,但如果窗口顶部边框未接触屏幕顶部,则该脚本不起作用:
^F2::
If ( ID := WinExist("Calculator") )
{
WinGetPos , X, Y, , , ahk_id %ID%
If ( DllCall("WindowFromPoint", Int,X+5, Int,Y+5 ) = ID )
MsgBox, Calculator is ON SCREEN
}
Return
使用
det_winIsVisible := WinGetStyle("ahk_id " . hwnd) & WS_VISIBLE
WS_VISIBLE := 0x10000000
; Is a Window Visible on Screen - AutoHotkey Community
; https://www.autohotkey.com/boards/viewtopic.php?t=107797
;
; WinGetStyle / WinGetExStyle - Syntax & Usage | AutoHotkey v2
; https://www.autohotkey.com/docs/v2/lib/WinGetStyle.htm
/**
*
* @param hwnd - The window handle.
* @returns {Boolean|""} - true if visible, false if hidden, null if non-existent.
*/
detm_winIsVisible(hwnd) {
DetectHiddenWindows_prev := DetectHiddenWindows(true)
try {
det_winIsVisible := WinGetStyle("ahk_id " . hwnd) & WS_VISIBLE
return det_winIsVisible
} catch TargetError as e {
return ""
} finally {
DetectHiddenWindows(DetectHiddenWindows_prev)
}
}
作为检查窗口是否可见的替代方法,您可以随时间比较窗口文本内容并确定它是否足够您使用。
在此示例中,我正在检查
Media Player Home Cinema
窗口播放时间,以确定是否应该按 Media Play/Stop
按钮,或者聚焦于 Media Player Home Cinema
窗口并按 Space
(直接播放/停止):
Pause::
window_identifier = ahk_class MediaPlayerClassicW
WinGetTitle, window_title, %window_identifier%
if( !window_title ) {
Send {Media_Play_Pause}
}
else {
WinWaitActive, %window_title%, , 0.1
is_window_focused := true
if( ErrorLevel ) {
; MsgBox, WinWait timed out.
is_window_focused := false
}
else {
PlayPauseVideo()
return
}
counter := 5
first_result := GetRunningWindowText(window_title)
while( counter > 0) {
sleep, 200
counter := counter - 1
second_result := GetRunningWindowText(window_title)
if( first_result != second_result ) {
PlayPauseVideo()
return
}
}
if( is_window_focused ) {
PlayPauseVideo()
}
else {
Send {Media_Play_Pause}
}
}
GetRunningWindowText(window_title) {
WinGetText, window_text, %window_title%
; FoundPos := RegExMatch(window_text, "O)(?:\d\d:)+(?<frames>\d\d)", first_result)
FoundPos := RegExMatch(window_text, "O)drawn: (?<frames>\d+)", first_result)
; Msgbox % first_result.Count() ": " first_result.Name(1) "=" first_result["frames"]
return first_result["frames"]
}
PlayPauseVideo() {
; Msgbox, It is running video...
WinActivate, ahk_class MediaPlayerClassicW
Send {Space}
}
return
参考资料:
重写函数中的主要代码以实现更好的泛化/重用:
Pause::CheckForPlayerWindow("ahk_class MediaPlayerClassicW",
"{Media_Play_Pause}", "{Space}", "false")
^!Left::CheckForPlayerWindow("ahk_class MediaPlayerClassicW", "{Media_Prev}", "^p")
^!Right::CheckForPlayerWindow("ahk_class MediaPlayerClassicW", "{Media_Next}", "^n")
; https://stackoverflow.com/questions/55670223/how-to-determine-whether-a-window
CheckForPlayerWindow(window_identifier, media_key, player_key, reactive=true) {
WinGetTitle, window_title, %window_identifier%
if( !window_title ) {
Send % media_key
}
else {
WinWaitActive, %window_title%, , 0.1
is_window_focused := true
if( ErrorLevel ) {
; MsgBox, WinWait timed out.
is_window_focused := false
}
else {
PlayPauseVideo(window_identifier, player_key, reactive)
return
}
counter := 5
first_result := GetRunningWindowText(window_title)
while( counter > 0) {
sleep, 200
counter := counter - 1
second_result := GetRunningWindowText(window_title)
if( first_result != second_result ) {
PlayPauseVideo(window_identifier, player_key, reactive)
return
}
}
if( is_window_focused ) {
PlayPauseVideo(window_identifier, player_key, reactive)
}
else {
Send % media_key
}
}
}
GetRunningWindowText(window_title) {
WinGetText, window_text, %window_title%
; FoundPos := RegExMatch(window_text, "O)(?:\d\d:)+(?<frames>\d\d)", first_result)
FoundPos := RegExMatch(window_text, "O)drawn: (?<frames>\d+)", first_result)
; Msgbox % first_result.Count() ": " first_result.Name(1) "=" first_result["frames"]
return first_result["frames"]
}
PlayPauseVideo(window_identifier, player_key, reactive=true) {
; Msgbox, It is running video...
if( reactive == true ) {
WinGetActiveTitle, active_window_title
}
WinActivate, %window_identifier%
SendInput % player_key
if( reactive == true ) {
WinActivate, %active_window_title%
}
}
return
新参考:
它不起作用,因为 Windows API
https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-windowfrompoint的函数
WindowFromPoint
被错误使用。
它只需要 1 个参数,而不是传递的 2 个参数。如果您需要,此函数可以正确地将 2 个参数转换为 1 个参数:
WindowFromPoint(x, y)
{
VarSetCapacity(POINT, 8)
Numput(x, POINT, 0, "int")
Numput(y, POINT, 4, "int")
return DllCall("WindowFromPoint", int64, NumGet(POINT, 0, "int64"))
}
完整示例:
Pause::
window_identifier = ahk_class MediaPlayerClassicW
WinGetTitle, window_title, %window_identifier%
is_visible := IsWindowVisible(window_identifier)
If( is_visible > 0 ) {
MsgBox, Window %window_title% is visible!
}
else {
If( is_visible < 0 ) {
MsgBox, Window %window_identifier% not found!
} else
{
MsgBox, Window %window_title% is NOT visible!
}
}
IsWindowVisible(window_name) {
ID := WinExist(window_name)
If( ErrorLevel != 0 ) {
; MsgBox, Window %window_name% not found!
return -1
}
If( ID > 0 ) {
WinGetPos, X, Y, , , ahk_id %ID%
active_window_id_hwnd := WindowFromPoint(X, Y)
; MsgBox, %X%, %Y%, %active_window_id_hwnd%
If( active_window_id_hwnd = ID ) {
; MsgBox, Window %window_name% is visible!
return 1
}
else {
; MsgBox, Window %window_name% is NOT visible!
return 0
}
}
; MsgBox, Window %window_name% not found!
return -1
}
WindowFromPoint(x, y)
{
VarSetCapacity(POINT, 8)
Numput(x, POINT, 0, "int")
Numput(y, POINT, 4, "int")
return DllCall("WindowFromPoint", int64, NumGet(POINT, 0, "int64"))
}
Return
参考资料: