请教各位,AHK 弹出菜单后,如何实现点击菜单外的位置菜单消失

按 Alt 弹出菜单后,必须选择其中某一项,菜单才会消失,我想实现点击菜单外的位置时,菜单自动消失

然而 MyMenu.Show() 后脚本执行好像被挂起了,即使添加了鼠标左键的 hotkey,检测点击,也不会被执行。

请教大家有什么好的方法吗?
实在不行添加一项菜单,什么都不做也可以,就是不太好。

Proc(ItemName, ItemPos, MyMenu) {
}

~LAlt:: {
    ; 弹出菜单
    MyMenu := Menu()
    MyMenu.Add("第一项", Proc)
    MyMenu.Add("第二项", Proc)
    MyMenu.Show()
}

我猜可能跟我之前遇到的情况相似,我之前弄ahk的菜单遇到问题也是折腾了一会,大致情况是右键调出Menu后会重复bug叠加,然后卡住,后来研究了一番,有两个方法解决:

1、调用的菜单前面加一个DeleteAll,作用是在调用前把全部的菜单项删除,这样执行Add就不会造成重复叠加了。

~LAlt:: {
    Menu, MyMenu, DeleteAll
      MyMenu := Menu()
      MyMenu.Add("第一项", Proc)
      MyMenu.Add("第二项", Proc)
    MyMenu.Show()
}

2、第二种方法就是分两个标签写Menu键值和它的Show命令,这样也不会重复执行Add叠加。

; 需要在脚本头先执行一遍
gosub, MyMenuLabel


~LAlt:: {
    Menu, MyMenu, Show
}

MyMenuLabel:
    MyMenu := Menu()
    MyMenu.Add("第一项", Proc)
    MyMenu.Add("第二项", Proc)
    return


发现只是偶尔会有这种情况,点击别处后,菜单不会自动消失,但多数情况是可以的

这种情况可能是因为切换到其它窗口了?

出现这种情况时,我用右键点菜单项,激活这个菜单,然后按 ESC 可以消失

这样写也不行,测试几次,还是偶尔有菜单不消失的情况

; 弹出菜单
MyMenu := Menu()
MyMenu.Add("第一项", Proc)
MyMenu.Add("第二项", Proc)

Proc(ItemName, ItemPos, MyMenu) {
}

~LAlt:: {
    MyMenu.Show()
}

AutoHotkey 的菜单只能轻量/少量地用用,各种问题,最好还是用 GUI 写个模拟菜单。

我也在怀疑是这个菜单本身的问题了

确实有问题,我写的“曹操快切”用的就是这个菜单,
也会偶然出现这种菜单不消失的现象。

蹲一下解决方案。

找到类似情况,但我按帖子的改法加了 DllCall("SwitchToThisWindow", "UInt", A_ScriptHwnd, "UInt", 1) 后也没解决,还会第一次弹出一个窗口

https://www.autohotkey.com/boards/viewtopic.php?t=15006

gpt-4 建议我写个透明的全屏窗口,来捕获点击,但给出的代码没法用,感觉是个勉强的思路

研究明白了,太麻烦了,测试几次还可以,没出现不消失的情况,我再多试试

MyGui := ""

Proc(ItemName, ItemPos, MyMenu) {
	MyGui.Destroy()
	MsgBox(ItemName)
}

~LAlt:: {
	; 创建一个全屏透明窗口
	global MyGui
	if (MyGui !== "")
		MyGui.Destroy()
	MyGui := Gui("+LastFound +AlwaysOnTop -Caption +ToolWindow +E0x20")
	MyGui.BackColor := "EEAA99"
	WinSetTransColor("EEAA99", MyGui)
	MyGui.Show("x0 y0 w" A_ScreenWidth " h" A_ScreenHeight)
	OnMessage(0x201, WM_LBUTTONDOWN)
	; 在全屏窗口上显示菜单
	MyMenu := Menu()
	MyMenu.Add("第一项", Proc)
	MyMenu.Add("第二项", Proc)
	MyMenu.Show()
}

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) {
	MyGui.Destroy()
}
1 个赞