Okay, so I spent a while trying to get this to work.
With the icon in the tray it became more difficult to activate it correctly. You can bring the window back with just WinShow, but it breaks XY since the icon remains and it is still waiting for you to bring it out of the tray even though the window is shown.
As a result the script is a lot longer and more complicated, but it seems to work reliably.
I'm using some code (with permission) that was posted in the AHK forums, this allows interaction with icons in the tray menu to simulate a left click. I'm not sure how well everything will work on something other than XP SP2 so try at your own risk on other systems.
You'll need to update XY_PATH to point to your XYplorer executable
You can just save this whole thing to a file and import/include/run that or add it to your own scripts.
Feel free to modify and distribute as you like, but please continue to credit Sean at AHK for that section of code.
Code: Select all
#E::
;Path to XYplorer - Change this for you system.
XY_PATH := "..\..\XYplorer\XYplorer.exe"
;Main window's window class.
MainWindowClass := "ThunderRT6FormDC"
;Store to restore
dhwm := A_DetectHiddenWindows
;Check for an existing XYplorer process.
SplitPath XY_PATH, filename, dir
Process Exist, %filename%
pid := ErrorLevel
if (ErrorLevel) {
;Is running
;Determine if the main window is visible.
DetectHiddenWindows OFF
WinGet id, ID, ahk_class %MainWindowClass% ahk_pid %pid%
if (! id) {
;Is not visible
;************************************************************
; The following is taken and modified from Sean's post
; found at http://www.autohotkey.com/forum/topic17314.html
;************************************************************
DetectHiddenWindows ON
;Get and count the ToolbarWindow32x controls from shell.
WinGet ControlList, ControlList, ahk_class Shell_TrayWnd
RegExMatch(ControlList, "(?<=ToolbarWindow32)\d+(?!.*ToolbarWindow32)", toolbarCnt)
;Locate the ToolbarWindow32x control that is actually the tray.
toolbarIDX := -1
Loop %toolbarCnt% {
idx := A_Index
ControlGet thisHWND, HWND,, ToolbarWindow32%idx%, ahk_class Shell_TrayWnd
thisParent := DllCall("GetParent", "Uint", thisHWND)
WinGetClass parentClass, ahk_id %thisParent%
if (parentClass = "SysPager") {
toolbarIDX := idx
break
}
}
if (toolbarIDX < 0) {
;Tray toolbar was not found.
MsgBox Error: Notification area could not be identified.
return
}
;Open a handle for the shell's explorer process.
WinGet pidTaskbar, PID, ahk_class Shell_TrayWnd
hProc := DllCall("OpenProcess", "Uint", 0x38, "int", 0, "Uint", pidTaskbar)
;Reserve memory for variables.
pRB := DllCall("VirtualAllocEx", "Uint", hProc, "Uint", 0, "Uint", 20, "Uint", 0x1000, "Uint", 0x4)
VarSetCapacity(btn, 20)
VarSetCapacity(nfo, 24)
VarSetCapacity(sTooltip, 128)
VarSetCapacity(wTooltip, 128 * 2)
;Number of icons to check
SendMessage 0x418, 0, 0, ToolbarWindow32%toolbarIDX%, ahk_class Shell_TrayWnd ; TB_BUTTONCOUNT
el := ErrorLevel
Loop, %el% {
;Current button
SendMessage 0x417, A_Index - 1, pRB, ToolbarWindow32%toolbarIDX%, ahk_class Shell_TrayWnd ; TB_GETBUTTON
;Read information about the button from memory.
DllCall("ReadProcessMemory", "Uint", hProc, "Uint", pRB, "Uint", &btn, "Uint", 20, "Uint", 0)
iBitmap := NumGet(btn, 0)
idn := NumGet(btn, 4)
Statyle := NumGet(btn, 8)
dwData := NumGet(btn,12)
iString := NumGet(btn,16)
;Read program specific info about the button from memory.
DllCall("ReadProcessMemory", "Uint", hProc, "Uint", dwData, "Uint", &nfo, "Uint", 24, "Uint", 0)
hWnd := NumGet(nfo, 0)
uID := NumGet(nfo, 4)
nMsg := NumGet(nfo, 8)
hIcon := NumGet(nfo,20)
;Get window information.
WinGet pid, PID, ahk_id %hWnd%
WinGet sProcess, ProcessName, ahk_id %hWnd%
WinGetClass sClass, ahk_id %hWnd%
if (filename = sProcess) {
;Found the icon we're looking for.
break
}
}
;Clean up and close the handle.
DllCall("VirtualFreeEx", "Uint", hProc, "Uint", pRB, "Uint", 0, "Uint", 0x8000)
DllCall("CloseHandle", "Uint", hProc)
;MsgBox % "idn: " . idn . " | Pid: " . pid . " | uID: " . uID . " | MessageID: " . nMsg . " | hWnd: " . hWnd . " | Class: " . sClass . " | Process: " . sProcess . "`n"
;************************************************************
; End of Sean's code.
;************************************************************
;Simulate a left click on the tray icon.
PostMessage %nMsg%, %uID%, 0x201,, ahk_id %hWnd%
PostMessage %nMsg%, %uID%, 0x202,, ahk_id %hWnd%
}
} else {
;Not running attempt to run.
run %XY_PATH%,%dir%,,pid
}
;Activate the window after it is shown.
WinWait ahk_class %MainWindowClass% ahk_pid %pid%,,10
if (! ErrorLevel) {
WinActivate ahk_class %MainWindowClass% ahk_pid %pid%
}
;Restore setting(s)
DetectHiddenWindows %dhwm%
return
EDIT: Updated to check the process and class, should prevent other VB apps from interfering.