Autohotkey控制窗口

至少在 Windows 上,任何窗口都可能在屏幕上的任何位置弹出,这不是很烦人吗? 每天的随机性是否让您感到紧张,并且您更愿意更好地控制窗口在屏幕上的位置? 好吧,现在你可以了,感谢 AutoHotKey。

在本教程中,我们将了解如何使用 AutoHotKey 脚本解决此问题。 我们将构建它,以便在按键时将任何窗口移动到屏幕中心。 听起来很甜? 让我们看看它是如何完成的!

创建脚本时的一半战斗是在输入单个字符之前就想好它的工作方式。 所以,让我们用简单的英语制定这样一个行动计划,然后我们将“变异”成一个脚本。

“问题”窗口有

Windows(如“我们屏幕上的矩形物体”,而不是操作系统)倾向于在屏幕上的任何位置弹出。 它会让人分心,而且当它反复发生时也会很烦人。 尤其是在处理出现在不同位置的多个请求者时,期待用户输入。

问题的解决方案

除了将击键和鼠标点击发送到任何窗口之外,AutoHotKey 还可以操作它们。 过去我们看到了如何使用 AutoHotKey 使用键盘快捷键将窗口“始终置于顶部”。 不过,这一次,我们将利用 AutoHotKey 的窗口操作能力来:

  1. “读取”活动窗口的 ID。
  2. 还“读取”它的尺寸(宽度和高度)。
  3. “读取”显示器的尺寸。
  4. 结合显示器和窗口的尺寸来计算在屏幕中心呈现所述窗口的最佳坐标。
  5. 将窗口移动到这些坐标。

最后,我们将上面的内容映射到一个快捷方式。 这样,您可以将其称为“按需”,而不是在所有窗口上应用它——这可能会干扰全屏应用程序和游戏。

请注意,在本教程中,我们将直接研究 AutoHotKey。 如果您不熟悉它并想提前了解更多信息,请查看我们为初学者准备的快速 AutoHotKey 指南。

一、设置热键

我们提到了如何将我们将创建的函数映射到快捷方式。 但是,如果我们从那部分开始将其排除在外,可能会更好。

首先从下载安装程序 AutoHotKey 的官方网站. 选择“当前”版本,而不是 v2 beta 或已弃用的 1.0 版本。 然后,将其安装在您的 PC 上。

启动文件资源管理器(最快的方法是使用 Windows 键 + E 组合键)并移动到要创建脚本的路径。 安装 AutoHotKey 后,您将在右键菜单中出现一些新选项。 因此,右键单击文件资源管理器窗口的空白区域并选择 新建 > AutoHotKey 脚本.

为脚本文件命名,然后右键单击它并 编辑 它。 如果您没有使用代码友好的文本编辑应用程序,例如 Visual Studio Code 或 Notepad++,请使用 Windows 记事本。 避免使用像写字板这样的编辑器,它们可能会在您的“代码”中添加无用的(出于目的)语法。

在您选择的编辑器中,您会看到 AutoHotKey 脚本顶部已经预先填充了一些行。 出于稳定性和兼容性的原因,它们在那里。 它们是可调整的,但在本教程中保持原样。

在它们下方“移动”两三行,然后输入将启动您的功能的快捷方式。 您可以通过使用“+”代表 Shift、“^”代表 CTRL、“!”来制作组合键。 用于 Alt,“#”用于 Windows 键,以及键盘上的任何“普通”键(字母和数字)。

例如,要让 CTRL + Y 组合启动您的脚本,请使用:

^y::

双“:”就像在说,“嘿,AutoHotKey,请将左侧的字符串或组合键映射到右侧的所有内容”。

按 Enter 键“移动”两到三行,然后键入“return”,这将标记特定函数的结束。 完整的结果应如下所示:

^y::
; This is a comment.
return

“;这是一条评论”。 行就是这样,AutoHotKey 不会执行的脚本“代码”中的注释。 它用于文档目的,以标记我们将在以下步骤中输入脚本“代码”的位置。

如果您过去曾按照我们的指南使用 AutoHotKey 创建特定于应用程序的热键,在这种情况下……不要。 您希望您的窗口居中热键是“全局的”,以使任何应用程序的任何窗口居中。 如果你将它“绑定”到一个特定的应用程序,它只会在这个应用程序的窗口上起作用。

获取活动窗口的详细信息

我们希望我们的快捷方式作用于活动窗口,并且我们还需要它的尺寸来进行计算。 我们可以通过以下方式找到这些详细信息:

WinGetTitle, ActiveWindowTitle, A
WinGetPos,,, Width, Height, %ActiveWindowTitle%

将我们在上一节中添加到脚本中的注释行替换为上面的两行。 结果?

  • 第一行获取活动窗口的标题。
  • 第二行读取它的宽度和高度,并将它们映射到单词/变量“宽度”和“高度”,我们将在接下来的计算中使用它们。

我们得到了活动窗口的详细信息,但我们还需要监视器的可见区域的尺寸来实现我们的目标。 值得庆幸的是,找到这些更容易。

主监控区域呢?

我们不需要额外的命令来找到我们的主显示器的宽度和高度。 AutoHotKey 带有两个已经为我们包含该信息的预设变量:“A_ScreenWidth”和“A_ScreenHeight”。

因此,当您在下一节中看到它们时,它们已经“包含”了主监视器的宽度和高度。 无需为它们分配正确的值。 因此,我们可以直接在计算中使用它们。

计算目标位置的时间

我们可以将计算直接包含在我们需要它们的脚本点中。 尽管如此,如果我们将它们映射到两个变量,然后在我们的脚本中使用这些变量,它会更容易且更好地提高可读性。

因此,让我们选择“TargetX”作为将保存水平坐标的变量,将“TargetY”作为具有垂直坐标的变量,我们应该在其中移动窗口以使其出现在屏幕的中心。

TargetX := (A_ScreenWidth/2)-(Width/2) ; Here we calculate the horizontal window target...
TargetY := (A_ScreenHeight/2)-(Height/2) ; ...and here the vertical one.

让我们用简单的英语解读这些行:

  • “TargetX”和“TargetY”是两个变量。
  • “:=” 通知 AutoHotKey 变量应该等于右边的计算结果,并且这些结果应该被视为数字。
  • “(A_ScreenWidth/2)” 将整个显示器的宽度除以 2。
  • “(Width/2)” 对活动窗口的宽度做同样的事情。

有了上面,我们从屏幕宽度的一半中减去活动窗口宽度的一半。 剩下的是窗口左侧的空间 – 从屏幕左侧到窗口应该出现的位置。 第二行做同样的事情,但高度。

现在重新定位窗口

配备从我们上面看到的神秘命令中获得的全能知识,我们现在可以制作完成窗口传送仪式的魔法咒语。 或者,简单地说,使用 AutoHotKey 的“WinMove”命令在屏幕上移动窗口。

WinMove 期望我们为它“提供”至少三个信息来完成它的工作:目标窗口的标题和移动它的坐标。 由于我们已经将这些信息映射到变量,因此命令很简单:

WinMove, %ActiveWindowTitle%,, %TargetX%, %TargetY%

在上面:

  • “WinMove”是移动窗口的 AutoHotKey 命令。
  • “%ActiveWindowTitle%”是活动窗口标题映射的变量。
  • “%TargetX%”和“%TargetY%”是移动窗口的水平和垂直坐标。

您还可以使用 WinMove 调整窗口大小,跳过标题或内容中带有特定文本字符串的窗口等。由于这些功能超出了本文的范围,请检查 AutoHotKey 关于 WinMove 命令的官方文档 了解更多信息。

最终剧本

最后,我们到达了旅程中最具挑战性的部分。 为下一步做好准备,希望您保存脚本,然后……运行它。

是的,就是这样 – 脚本已经完成,除了试一试之外别无他法。 使用您定义的快捷方式,任何活动窗口都会移动到屏幕的中心。

在文本编辑器中打开的最终脚本文件应如下所示:

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
^y::
WinGetTitle, ActiveWindowTitle, A ; Get the active window's title for "targetting" it/acting on it.
WinGetPos,,, Width, Height, %ActiveWindowTitle% ; Get the active window's position, used for our calculations.
TargetX := (A_ScreenWidth/2)-(Width/2) ; Calculate the horizontal target where we'll move the window.
TargetY := (A_ScreenHeight/2)-(Height/2) ; Calculate the vertical placement of the window.

WinMove, %ActiveWindowTitle%,, %TargetX%, %TargetY% ; Move the window to the calculated coordinates.

return

请注意,您可以复制上面的脚本,将其粘贴到记事本或类似的文本编辑器中,然后使用 AHK 扩展名保存。 然后,在安装 AutoHotKey 的情况下“运行”它,以在您按下 CTRL + Y 时将任何窗口居中。如果您不喜欢该快捷方式,请将“^y::”行调整为不同的组合键。 例如, !+c:: 会将函数映射到 Shift + Alt + C 组合键。

奖金轨道

为方便起见,我们决定创建一个辅助脚本,该脚本将对具有双显示器设置的用户有用。

为了简化本文,我们以注释的形式包含了有关脚本如何在其中工作的信息。 您可以从迭代中删除它们。

它与上面脚本的不同之处在于我们还添加了一个 PositionToggle 变量和一些“IF 逻辑”。 然后我们使用它们在监视器之间“轻弹”窗口。 我们应该注意到,这是一个不雅且“hack-y”的问题解决方案。 然而,我们更喜欢它而不是更简化的代码,因为这种方法对于不熟悉 AutoHotKey 的每个人来说更容易理解和调整。

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
PositionToggle = 1 ; Use a number as a toggle for marking on which monitor the window should appear.
^y::
WinGetTitle, ActiveWindowTitle, A
WinGetPos,,, Width, Height, %ActiveWindowTitle%

If PositionToggle = 1 ; Check the toggle's state and "do what's between the curly brackets" if it's set to 1 for our primary monitor.
{
TargetX := (A_ScreenWidth/2)-(Width/2)
TargetY := (A_ScreenHeight/2)-(Height/2)
PositionToggle = 2 ; "Flick" the toggle so that if we reuse the hotkey, our active window will move to the second monitor.
}
Else If PositionToggle = 2 ; Have we used the hotkey before, "flicking" the toggle number to the second monitor? Then the script should instead do what's between the following curly brackets instead of the ones above.
{
SysGet, Mon2, Monitor, 2 ; Get the second monitor's details
Mon2Width := Mon2Right - Mon2Left ; Calculate the second monitor's actual width.
Mon2Height := Mon2Bottom - Mon2Top ; Calculate the second monitor's actual height.

TargetX := (Mon2Width/2)-(Width/2)+A_ScreenWidth ; Calculate where to move the window. Notice that we also add the primary monitor's width since AutoHotKey can't move windows on individual monitors but across their combined "surface".
TargetY := (Mon2Height/2)-(Height/2)+Mon2Top ; Calculate the optimal vertical target for moving the window on the second monitor. Like above, the second monitor's vertical details are detected in relation to the primary monitor. Thus, we have to get creative to get an optimal target by acknowledging how the second monitor's top isn't equal to 0 (like the primary one's).

PositionToggle = 1 ; Flick the toggle back so that if we reuse the hotkey, the window will move back to the primary monitor.
}

WinMove, %ActiveWindowTitle%,, %TargetX%, %TargetY% ; The actual action, moving the active window to our calculated coordinates.

return

用钥匙将窗口居中,简单的方法

现在你完成了! 如果一切正常,您现在可以随时使用新设置的热键将窗口居中。