英文:
New Window Detection
问题
以下是您要翻译的代码部分:
#SingleInstance Force
Persistent
SetTitleMatchMode "RegEx"
ids := []
Loop {
global ids
all := "ahk_exe ((msedge)|(chrome)|(Notepad)|(olk)|(explorer))\.exe"
beside := ""
for i, id in ids {
beside .= (i == 1 ? " ahk_id ^((?!\"" : "|\")) \"" id "\")+" : "")
}
MsgBox all beside
WinWait all beside
ids.push(WinGetID())
; 在这里处理窗口。
WinSetTransparent 217
for i, id in ids {
if(!WinExist("ahk_id " id)) {
ids.RemoveAt(i)
} else {
for n, nid in ids {
if(n > i && nid == id)
ids.RemoveAt(n)
}
}
}
}
请注意,我已将 HTML 实体字符(例如 "
和 >
)还原为原始的字符。如果您需要进一步的帮助或翻译其他部分,请随时提出。
英文:
The following script for AHK 2.0 is meant to do something to certain windows once, then ignore them while checking for new windows:
#SingleInstance Force
Persistent
SetTitleMatchMode "RegEx"
ids := []
Loop {
global ids
all := "ahk_exe ((msedge)|(chrome)|(Notepad)|(olk)|(explorer))\.exe"
beside := ""
for i, id in ids {
beside .= (i == 1 ? " ahk_id ^((?!" : "|") "(" id ")" (i == ids.Length ? ").)+$" : "")
}
MsgBox all beside
WinWait all beside
ids.push(WinGetID())
; Do something with the window here.
WinSetTransparent 217
for i, id in ids {
if(!WinExist("ahk_id " id)) {
ids.RemoveAt(i)
} else {
for n, nid in ids {
if(n > i && nid == id)
ids.RemoveAt(n)
}
}
}
}
Right now, it finds the foremost window (usually the Taskbar), then it finds no other window. The regular expression I'm using for the ahk_id
values matches anything not within the capture groups; the full statement would look something like this if it finds multiple windows: ahk_exe ((msedge)|(chrome)|(Notepad)|(olk)|(explorer))\.exe ahk_id ^((?!(66328)|(14420486)).)+$
.
Is there a better way to exclude a changing list of windows from WinWait
? I tried to use window groups and the ExcludeTitle
parameter, but I believe that parameter may really only be for titles rather than ahk_criteria
. Window groups also cannot be changed without reloading the script.
I just want to find new windows of certain executables, do something, then wait for new windows (not detecting the old windows). How might I accomplish that?
答案1
得分: 0
以下是翻译好的部分:
在这个问题中,我只需要影响新创建的窗口。我找到了一个关于旧示例的一些引用,它涉及到Shell Hook的使用。这允许创建一个触发器,用于检测窗口的创建、销毁和更改。
我已经为AutoHotkey 2.0调整了示例代码:
#SingleInstance Force
Persistent
detector := Gui()
DllCall("RegisterShellHookWindow", "UInt", detector.Hwnd)
messenger := DllCall("RegisterWindowMessage", "Str", "SHELLHOOK")
OnMessage(messenger, recipient)
recipient(message, id, *) {
if (message == 1) {
if (WinGetProcessName("ahk_id " id) == "YourExecutable.exe") {
; 在这里对窗口进行操作。
WinSetTransparent(229, "ahk_id " id)
}
}
}
关于嵌套的if语句:
if (message == 1) {
if (WinGetProcessName("ahk_id " id) == "YourExecutable.exe") {
- 当检测到窗口已创建时(当
message == 1
时),id
包含了已创建的窗口的ID。当message != 1
时,id
可能不包含有效的窗口ID,因此将检查放在同一个if语句中可能会引发错误。 message == 1
用于检查钩子是否检测到了窗口的创建。有关该钩子可以检测的消息列表,请参阅之前提到的Shell Hooks链接。WinGetProcessName("ahk_id " id) == "YourExecutable.exe"
,可以更改为您想要检查的与已创建窗口相关的任何内容。已创建窗口的标题是("ahk_id " id)
。请注意,在某些情况下,这可能会偶尔引发错误并无法找到窗口;我不确定为什么会出现这种情况,但在我的个人脚本中,为了解决这个问题,我将这个if语句放在了try块中。
对于此示例,我再次设置了窗口的透明度。正如我刚才提到的,我使用了钩子检测到的窗口标题:WinSetTransparent(229, "ahk_id " id)
。
希望这个答案对您和我一样有用!
英文:
In this question, I needed to affect newly created windows only. Instead of using WinWait, I found a few references to an old example of a Shell Hook. This allows for the creation of a trigger which detects creation, destruction of, and changes to windows.
I have adapted the example for AutoHotkey 2.0:
#SingleInstance Force
Persistent
detector := Gui()
DllCall("RegisterShellHookWindow", "UInt",detector.Hwnd)
messenger := DllCall("RegisterWindowMessage", "Str","SHELLHOOK")
OnMessage(messenger, recipient)
recipient(message, id, *) {
if(message == 1) {
if(WinGetProcessName("ahk_id " id) == "YourExecutable.exe") {
; Do something with the window here.
WinSetTransparent(229, "ahk_id " id)
}
}
}
Concerning the nested if statements:
if(message == 1) {
if(WinGetProcessName("ahk_id " id) == "YourExecutable.exe") {
- When detecting if a window has been created (when
message == 1
),id
will contain the id of the window that was created. Whenmessage != 1
,id
may not contain a valid window id, so putting the checks in the same if statement may throw an error. message == 1
checks to see if the hook detected the creation of a window. For a list of the messages the hook can detect, see the link mentioned previously for Shell Hooks.WinGetProcessName("ahk_id " id) == "YourExecutable.exe"
, can be changed to anything you want to check concerning the window that was created. The title of the window that was created is("ahk_id " id)
. Note that this may occasionally throw an error and not find a window in certain circumstances; I'm not sure why it does this, but, to solve this in my personal script, I put this if statement in a try block.
For this example, I once again set the transparency of the window. I did so using the title of the window detected by the hook, as I mentioned just above: WinSetTransparent(229, "ahk_id " id)
.
I hope that this answer is as useful to you as it was for me!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论