OK, I,ve finally found some time to do a demo script, with what I've learned.
The script demonstrate how to get the ID of the window that was active before the user clicked on the tray menu to call a function via the tray menu. (The solution of the subject of this thread.)
It demonstrates also how to refresh the tray menu dynamically to take the current active ID properties into account.
In passing, it shows also how to process the middle mouse button and X buttons 1 and 2 clicks over the tray icon.
Here it is:
Code:
; *** initialization
#Persistent
#SingleInstance force
#NoEnv
SendMode Input
Menu, Tray, Add
last_prop_menu_label = Info: -
Menu, Tray, Add, %last_prop_menu_label%, LabWinInfo
Menu, Tray, Default, %last_prop_menu_label%
Menu, Tray, Disable, %last_prop_menu_label%
Menu, Tray, Click, 1
LastActiveID := ActiveId()
Gui +LastFound
DllCall( "RegisterShellHookWindow", UInt,WinExist() )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
OnMessage(0x404, "TrayMessage")
OnExit, CleanExit
Return
; exit app
CleanExit:
OnExit,
DllCall("DeregisterShellHookWindow", UInt,hWnd)
ExitApp
; Shell hook
ShellMessage(wParam,lParam)
{
Global LastActiveID
If (wParam=4 And checkNormalWin(lParam)) {
LastActiveID := lParam
}
}
; called whenever the mouse pointer is over the tray icon
TrayMessage(wParam, lParam)
{
global xbutton, LastActiveID
if lParam = 0x204 ; WM_RBUTTONDOWN
{
; refresh the tray menu before it is displayed
RefreshMenu(LastActiveID)
}
if lParam = 0x208 ; WM_MBUTTONUP
{
; executed when the tray icon is clicked with the middel mouse button
MsgBox Middle mouse button
}
if (lParam=524) ; lParam = 524: Up message for XButton1 AND 2!
{
if xbutton = 1
{
; executed when the tray icon is clicked with the Xbutton1
MsgBox X Button 1
}
else
{
; executed when the tray icon is clicked with the Xbutton2
MsgBox X Button 2
}
}
}
; we need to retrieve the XButton number using those hotkeys
XButton1::
xbutton=1
Send {XButton1 Down}
return
XButton1 Up::
xbutton=1
Send {XButton1 Up}
return
XButton2::
xbutton=2
Send {XButton2 Down}
return
XButton2 Up::
xbutton=2
Send {XButton2 Up}
return
; return the windowID passed in argument if the window is not a system window,
; otherwise, return 0
checkNormalWin(wid)
{
ifWinNotExist ahk_id %wid%
return 0
WinGetClass, class, ahk_id %wid%
if class in Shell_TrayWnd,Progman,Static,tooltips_class32,SysShadow
return 0
return %wid%
}
;; return the windowID passed in argument if the window appears
;; in the Alt-Tab menu and exists, otherwise, return 0
;checkNormalWin(wid)
;{
; ifWinNotExist ahk_id %wid%
; return 0
; WinGet, es, ExStyle, ahk_id %wid%
; if ((!DllCall("GetWindow","uint",wid, "uint",4) and !(es & WS_EX_TOOLWINDOW)) \
; or (es & WS_EX_APPWINDOW))
; return %wid%
; return 0
;}
; return the window ID of the currently active window,
; or 0 if the active window is not a "normal" window.
ActiveId()
{
WinGet, wid, ID, A
return checkNormalWin(wid)
}
; refresh the menu when the user clicks on the tray icon
RefreshMenu(wid)
{
global last_prop_menu_label
wid := checkNormalWin(wid)
if (wid > 0)
{
WinGetTitle, title, ahk_id %wid%
if title =
title = Untitled
if (strlen(title) > 22)
title := SubStr(title, 1, 20)"..."
if last_prop_menu_label != Info: %title%
{
Menu, Tray, Rename, %last_prop_menu_label%, Info: %title%
last_prop_menu_label = Info: %title%
Menu, Tray, Default, %last_prop_menu_label%
Menu, Tray, Enable, %last_prop_menu_label%
}
}
else
{
if last_prop_menu_label != Info: -
{
Menu, Tray, Rename, %last_prop_menu_label%, Info: -
last_prop_menu_label = Info: -
Menu, Tray, Default, %last_prop_menu_label%
Menu, Tray, Disable, %last_prop_menu_label%
}
}
}
; demo function
LabWinInfo:
WinInfo(LastActiveID)
return
WinInfo(wid)
{
WinGetTitle, title, ahk_id %wid%
WinGetClass, class, ahk_id %wid%
WinGetPos, xpos, ypos, width, height, ahk_id %wid%
WinGet, processname, ProcessName, ahk_id %wid%
WinGet, pid, PID, ahk_id %wid%
WinGet, style, Style, ahk_id %wid%
WinGet, exstyle, ExStyle, ahk_id %wid%
MsgBox, 262208, TrayDesktop: Active window info, Window title : %title%`nWindow class : %class%`nWindow ID : %wid%`nWindow position : %xpos%`,%ypos%`, Size : %width% x %height%`nWindow style : %style%`, ExStyle : %exstyle%`nProcess : %processname% (PID = %pid%)
}
Note that there are 2 versions of checkNormalWin(). Currently, I prefer the first one, that filters the windows based on a list of window classes. If you prefer to process only the root windows, you should replace the current function by the one that is commented out in the code.
Sorry, there are very few comments, but I haven't enough time to do it better.
A huge thanks to the contributors!