新窗口检测

huangapple go评论48阅读模式
英文:

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. When message != 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!

huangapple
  • 本文由 发表于 2023年6月29日 06:55:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76577162.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定