比如,右键是这种感觉的
我用sendMessage可以设置他的模式,但怎样判断当前的模式呢?
请问怎样获得某程序托盘右键菜单的状态?
Moderators: tmplinshi, arcticir
-
- Posts: 16
- Joined: 31 Jan 2015, 09:28
请问怎样获得某程序托盘右键菜单的状态?
Autohotkey2
Re: 请问怎样获得某程序托盘右键菜单的状态?
方法1: 使用 acc.ahk
获取菜单项及勾选状态:
方法2:
TrayIcon: https://autohotkey.com/boards/viewtopic.php?t=1229
Acc: https://autohotkey.com/boards/viewtopic.php?t=26201
Code: Select all
MsgBox % ss_isPacMode()
ss_isPacMode() {
TrayIcon_Button("Shadowsocks.exe", "R") ; 点击托盘图标右键
WinWait, ahk_class #32768 ahk_exe Shadowsocks.exe,, 2
if ErrorLevel
throw "没有找到菜单窗口"
oAcc := Acc_ObjectFromWindow( WinExist() )
WinClose
for i, child in Acc_Children(oAcc)
{
if ( child.accName(0) ~= "^(系统代理模式|系統代理模式|Mode)$" )
return !!(child.accChild(1).accState(1) & 0x10) ; 0x10=STATE_SYSTEM_CHECKED
}
}
Code: Select all
SetBatchLines -1
TrayIcon_Button("Shadowsocks.exe", "R") ; 点击托盘图标右键
WinWait, ahk_class #32768 ahk_exe Shadowsocks.exe,, 2
oAcc := Acc_ObjectFromWindow( WinExist() )
for i, child in Acc_Children(oAcc)
{
if ( child.accName(0) = "系统代理模式" ) {
Loop, % child.accChild(1).accChildCount
{
itemName := child.accChild(1).accName(A_Index)
itemState := child.accChild(1).accState(A_Index)
sChecked := (itemState & 0x10) ? " √" : "" ; 0x10=STATE_SYSTEM_CHECKED
MenuList .= itemName sChecked "`n"
}
WinClose ; 关闭菜单
MsgBox, % MenuList
ExitApp
}
}
方法2:
Code: Select all
SetBatchLines -1
TrayIcon_Button("Shadowsocks.exe", "R") ; 点击托盘图标右键
WinWait, ahk_class #32768 ahk_exe Shadowsocks.exe,, 2
SendMessage, 0x1E1, 0, 0 ; MN_GETHMENU
MenuGetAll_sub(ErrorLevel, "", sContents)
MsgBox, % sContents
ExitApp
; https://autohotkey.com/boards/viewtopic.php?f=6&t=8085
MenuGetAll_sub(menu, prefix, ByRef cmds)
{
Loop % DllCall("GetMenuItemCount", "ptr", menu)
{
VarSetCapacity(itemString, 2000)
if !DllCall("GetMenuString", "ptr", menu, "int", A_Index-1, "str", itemString, "int", 1000, "uint", 0x400)
continue
itemString := StrReplace(itemString, "&")
itemID := DllCall("GetMenuItemID", "ptr", menu, "int", A_Index-1)
if (itemID = -1)
if subMenu := DllCall("GetSubMenu", "ptr", menu, "int", A_Index-1, "ptr")
{
MenuGetAll_sub(subMenu, prefix itemString " > ", cmds)
continue
}
sChecked := MI_isChecked(menu, A_Index-1) ? " √" : ""
cmds .= itemID "`t" prefix RegExReplace(itemString, "`t.*") sChecked "`n"
}
}
MI_isChecked(hMenu, position){
nState := DllCall("GetMenuState", "ptr", hMenu, "uint", position, "uint", 0x00000400)
return !!(nState & 0x00000008) ; MF_CHECKED = 0x00000008
}
Acc: https://autohotkey.com/boards/viewtopic.php?t=26201
Last edited by tmplinshi on 12 Oct 2018, 09:17, edited 1 time in total.
Re: 请问怎样获得某程序托盘右键菜单的状态?
使用 SetWinEventHook 避免菜单显示出来。
Code: Select all
#NoEnv
SetBatchLines -1
MsgBox % ss_isPacMode()
ss_isPacMode() {
global g_ss_isPacMode := ""
; EVENT_SYSTEM_MENUPOPUPSTART := 0x0006
hook := New WinEventHook(0x0006, 0x0006, "HookProc")
TrayIcon_Button("Shadowsocks.exe", "R") ; 点击托盘图标右键
while (g_ss_isPacMode = "")
Sleep, 10
return g_ss_isPacMode
}
HookProc(hWinEventHook, event, hWnd, idObject, idChild, dwEventThread, dwmsEventTime) {
global g_ss_isPacMode
oAcc := Acc_ObjectFromWindow( hwnd )
for i, child in Acc_Children(oAcc)
{
if ( child.accName(0) ~= "^(系统代理模式|系統代理模式|Mode)$" )
{
DllCall("SendMessage", "ptr", hwnd, "uint", WM_CLOSE:=0x10, "ptr", 0, "ptr", 0)
return g_ss_isPacMode := !!(child.accChild(1).accState(1) & 0x10) ; 0x10=STATE_SYSTEM_CHECKED
}
}
}
class WinEventHook
{
__New(eventMin, eventMax, funcName) {
this.hWinEventHook := DllCall("SetWinEventHook"
, "UInt", eventMin
, "UInt", eventMax
, "Ptr", 0
, "Ptr", RegisterCallback(funcName, "F")
, "UInt", 0
, "UInt", 0
, "UInt", 0x0)
}
__Delete() {
DllCall("UnhookWinEvent", "Ptr", this.hWinEventHook)
}
}
Re: 请问怎样获得某程序托盘右键菜单的状态?
这个好,谢谢。。。
Who is online
Users browsing this forum: No registered users and 48 guests