英文:
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),idwill contain the id of the window that was created. Whenmessage != 1,idmay not contain a valid window id, so putting the checks in the same if statement may throw an error. message == 1checks 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!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论