在 Git Gui 中使用 AutoHotKey 检测焦点

发布于 2024-11-07 09:29:07 字数 2287 浏览 0 评论 0原文

我正在尝试编写一个 AutoHotKey 脚本来激活我的 AutoHotKey 脚本。 kernel.org/pub/software/scm/git/docs/git-gui.html" rel="nofollow">Git Gui 窗口,刷新它,并将焦点放在提交注释文本框中。激活和刷新没问题,但我没有成功改变焦点。 AutoHotKey 似乎无法正确检测 Git Gui 窗口中的子控件。

如果我运行 AutoHotKey 的 Window Spy 实用程序,切换到 Git Gui 窗口,并将鼠标放在提交注释文本框上,Window Spy 将显示以下输出(缩写):

>>>>>>>>>>( Window Title & Class )<<<<<<<<<<<
Git Gui (Tyler08) C:/svn/Tyler08
ahk_class TkTopLevel

>>>>>>>>>>>>( Mouse Position )<<<<<<<<<<<<<
On Screen:  808, 727  (less often used)
In Active Window:   816, 735

>>>>>>>>>( Now Under Mouse Cursor )<<<<<<<<
ClassNN:    TkChild18
Text:   
Color:  0xF0F0F0  (Blue=F0 Green=F0 Red=F0)

所以看起来该编辑框的类名称是 TkChild18 ,并且我希望能够在我的 AutoHotKey 脚本中编写以下内容:

NumpadAdd::
ControlFocus, TkChild18, Git Gui (Tyler08) C:/svn/Tyler08
return

但是当我启动此脚本然后按 Numpad + 时,什么也没有发生。我预计焦点会移至提交注释文本框,但焦点根本没有改变。

为了解决这个问题,我根据 ControlGetFocus 的 AutoHotKey 文档构建了以下脚本:

NumpadAdd::
ControlGetFocus, OutputVar, Git Gui (Tyler08) C:/svn/Tyler08
if ErrorLevel
    MsgBox, The target window doesn't exist or none of its controls has input focus.
else
    MsgBox, Control with focus = %OutputVar%

现在,如果我激活 Git Gui 窗口并按 Numpad +,AutoHotKey 会弹出一个消息框,显示:“Control with focus = TkChild1”。无论焦点在哪里——无论焦点是在提交注释文本框中,还是在差异窗格中,或者在“新提交”或“修改上次提交”单选按钮中,或者在任何按钮中—— AutoHotKey 始终报告焦点是 TkChild1。这与 Window Spy 不同,Window Spy 能够查看所有子窗口(TkChild18 等)。

上述脚本至少适用于某些其他应用程序(只要我更改第二行中的窗口标题)。如果 WPF 元素具有焦点(例如 Visual Studio 2010 中的输出窗口),它会显示“目标窗口不存在...”失败消息,但如果 WinForms 控件具有焦点(例如 VS2010 的属性网格),则会成功。所以我知道我已经掌握了 ControlGetFocus 命令的正确语法。我怀疑 Git Gui 正在对其子窗口执行一些奇怪的操作(它是使用 Tk 框架构建的,这可能会执行 AutoHotKey 无法处理的奇怪操作)。

有人对如何让 AutoHotKey 在 Git Gui 窗口中成功更改焦点有任何想法吗?

使用 AutoHotKey Basic v1.0.48.00 和 mSysGit 版本 1.7.3.1-preview20101002(64 位 Vista 上)。

I'm trying to write an AutoHotKey script that will activate my Git Gui window, refresh it, and put the focus in the commit-comment text box. Activating and refreshing are no problem, but I'm not having any success changing focus. AutoHotKey doesn't seem to be correctly detecting the child controls in the Git Gui window.

If I run AutoHotKey's Window Spy utility, switch to the Git Gui window, and put the mouse over the commit-comment text box, Window Spy shows the following output (abbreviated):

>>>>>>>>>>( Window Title & Class )<<<<<<<<<<<
Git Gui (Tyler08) C:/svn/Tyler08
ahk_class TkTopLevel

>>>>>>>>>>>>( Mouse Position )<<<<<<<<<<<<<
On Screen:  808, 727  (less often used)
In Active Window:   816, 735

>>>>>>>>>( Now Under Mouse Cursor )<<<<<<<<
ClassNN:    TkChild18
Text:   
Color:  0xF0F0F0  (Blue=F0 Green=F0 Red=F0)

So it looks like the class name of that edit box is TkChild18, and I would expect to be able to write the following in my AutoHotKey script:

NumpadAdd::
ControlFocus, TkChild18, Git Gui (Tyler08) C:/svn/Tyler08
return

But when I start this script and then press Numpad +, nothing happens. I expected the focus to move to the commit-comment text box, but the focus doesn't change at all.

In trying to troubleshoot this, I built the following script based on the AutoHotKey docs for ControlGetFocus:

NumpadAdd::
ControlGetFocus, OutputVar, Git Gui (Tyler08) C:/svn/Tyler08
if ErrorLevel
    MsgBox, The target window doesn't exist or none of its controls has input focus.
else
    MsgBox, Control with focus = %OutputVar%

Now if I activate the Git Gui window and press Numpad +, AutoHotKey pops up a message box that says: "Control with focus = TkChild1". No matter where the focus is -- whether the focus is in the commit-comment text box, or in the diff pane, or in the "New Commit" or "Amend Last Commit" radio buttons, or in any of the buttons -- AutoHotKey always reports that the focus is TkChild1. This disagrees with Window Spy, which is able to see all the child windows (TkChild18, etc.)

The above script does work with at least some other apps (as long as I change the window title in the second line). It shows its "target window doesn't exist..." failure message if a WPF element has focus (e.g. the Output window in Visual Studio 2010) but it succeeds if a WinForms control has focus (e.g. VS2010's Properties grid). So I know I've got the right syntax for the ControlGetFocus command. I suspect that Git Gui is doing something strange with its child windows (it's built with the Tk framework, which may do something weird that AutoHotKey can't handle).

Anyone have any ideas on how I can get AutoHotKey to successfully change focus within the Git Gui window?

Using AutoHotKey Basic v1.0.48.00 and mSysGit version 1.7.3.1-preview20101002 on 64-bit Vista.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小嗲 2024-11-14 09:29:07

我怀疑 Git Gui 正在对其子窗口执行一些奇怪的操作(它是使用 Tk 框架构建的,这可能会执行 AutoHotKey 无法处理的奇怪操作)。

我怀疑你是对的。大多数 Autohotkey 的命令只是 MSFT Win32 api 调用的包装。在这种情况下,ControlFocus 可能只是包装 SetFocus()。如果 TK 框架不响应正常的 Windows 消息,例如 WM_SETFOCUS 那么这些将不起作用。

你的代码在我的电脑上也失败了。我已经尝试了半个小时来找到解决方法,除了黑客之外没有运气。显然,您可以只发送 TAB 按键,直到您的提交消息编辑框获得焦点,但这是不可靠的,因为我们无法准确检查哪个控件确实具有焦点。

因此,我能想到的最好办法就是向该框发送基本的Click。我尝试了 ControlClick 这会阻止鼠标移动,但可惜的是,它像所有其他控制命令一样失败了。具有讽刺意味的是,ControlGetPos 的工作原理允许此解决方案(否则,如果调整 Git Gui 窗口的大小,硬编码坐标将会失败)。

SetTitleMatchMode, 2             ;// allow partial window title matches

NumpadAdd::
   WinActivate, Git Gui
   ControlGetPos, control_x, control_y, , , TkChild18, Git Gui

   CoordMode, Mouse, Screen
   MouseGetPos, mouse_x, mouse_y    ;// grab current mouse screen position

   click_x := control_x + 5      ;// we'll click 5 pixels inside the control
   click_y := control_y + 5
   CoordMode, Mouse, Relative
   Click %click_x%, %click_y%   ;// click relative to active window (moves mouse)

   CoordMode, Mouse, Screen
   MouseMove, %mouse_x%, %mouse_y%, 0   ;// restore old mouse position
return

I suspect that Git Gui is doing something strange with its child windows (it's built with the Tk framework, which may do something weird that AutoHotKey can't handle).

I suspect you're right. Most of Autohotkey's commands are merely wrappers for MSFT Win32 api calls. In this case, ControlFocus probably just wraps SetFocus(). If the TK framework doesn't respond to normal windows messages such as WM_SETFOCUS then these won't work.

Your code fails on my computer too. I've tried for a half hour to find a workaround, with no luck other than hacks. Obviously you can just send TAB keypresses until your commit message editbox has focus, but this is unreliable since we cannot accurately check which control does have focus.

So, the best I could come up with is to just resort to sending a basic Click to the box. I tried ControlClick which would prevent mouse movement, but alas, it failed just like all the other Control commands. Ironically ControlGetPos works which allows this solution (otherwise if the Git Gui window is resized, a hardcoded coordinate would fail).

SetTitleMatchMode, 2             ;// allow partial window title matches

NumpadAdd::
   WinActivate, Git Gui
   ControlGetPos, control_x, control_y, , , TkChild18, Git Gui

   CoordMode, Mouse, Screen
   MouseGetPos, mouse_x, mouse_y    ;// grab current mouse screen position

   click_x := control_x + 5      ;// we'll click 5 pixels inside the control
   click_y := control_y + 5
   CoordMode, Mouse, Relative
   Click %click_x%, %click_y%   ;// click relative to active window (moves mouse)

   CoordMode, Mouse, Screen
   MouseMove, %mouse_x%, %mouse_y%, 0   ;// restore old mouse position
return
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文