Here's the source to RunInTrayMod condensed to a single file. I used Obfuscator to eliminate the include files:
RunInTrayMod.au3
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Res_Fileversion=1.2.0.0
#AutoIt3Wrapper_Res_Language=1033
#AutoIt3Wrapper_Res_Field=Productname|RunInTrayMod
#AutoIt3Wrapper_Res_Field=Productversion|1.2
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
; RunInTrayMod - modified version of RunInTray utility found here:
; http://www.cellsworth.com/news/computer-related/35-uncategorizied/96-runintray.html
;
; The main modification to RunInTray is on detection of the window.
; A handle is obtained and used in Hide Show and Close operations.
; This way the client may change window caption and still respond
; to Hide, Show, and Close commands.
;
; Also Close is used instead of Kill to close the client app.
;
Global Const $__WINVER = __Ver()
Global Const $TRAY_EVENT_PRIMARYUP = -8
Global Const $tagPOINT = "long X;long Y"
Global Const $tagGUID = "dword Data1;word Data2;word Data3;byte Data4[8]"
Global Const $HGDI_ERROR = Ptr(-1)
Global Const $INVALID_HANDLE_VALUE = Ptr(-1)
Global Const $KF_EXTENDED = 0x0100
Global Const $KF_ALTDOWN = 0x2000
Global Const $KF_UP = 0x8000
Global Const $LLKHF_EXTENDED = BitShift($KF_EXTENDED, 8)
Global Const $LLKHF_ALTDOWN = BitShift($KF_ALTDOWN, 8)
Global Const $LLKHF_UP = BitShift($KF_UP, 8)
Global Const $tagNOTIFYICONDATA = 'dword Size;hwnd hWnd;uint ID;uint Flags;uint CallbackMessage;ptr hIcon;wchar Tip[128];dword State;dword StateMask;wchar Info[256];uint Version;wchar InfoTitle[64];dword InfoFlags;'
Global Const $tagPRINTDLG = 'align 2;dword_ptr Size;hwnd hOwner;ptr hDevMode;ptr hDevNames;hwnd hDC;dword Flags;ushort FromPage;ushort ToPage;ushort MinPage;ushort MaxPage;' & __Iif(@AutoItX64, 'uint', 'ushort') & ' Copies;ptr hInstance;lparam lParam;ptr PrintHook;ptr SetupHook;ptr PrintTemplateName;ptr SetupTemplateName;ptr hPrintTemplate;ptr hSetupTemplate;'
AutoItSetOption("WinTitleMatchMode", -3)
AutoItSetOption("TrayOnEventMode", 1) ; Use event trapping for tray menu
AutoItSetOption("TrayMenuMode", 3) ; Default tray menu items will not be shown.
Const $delayMin = 1, $delayMax = 60
; call EmptyWorkingSet once a minute
Const $MemCountMax = 60
Global $Dir = "", $App = "", $handle = 0, $title = "", $memCount = 0, $delay = 0, $hasDelay = False
$iMsg = "Usage: " & @CRLF & @CRLF & "RunInTrayMod [ -d=n ] ProgramPath WorkingDir [ WindowTitle ]" & @CRLF
$iMsg &= " ( -d=n is seconds delay : Valid range for n is " & $delayMin & " to " & $delayMax & " )" & @CRLF & @CRLF
$iMsg &= "If any params contain space(s) wrap them in double quotes" & @CRLF & @CRLF
$iMsg &= "If App will not go to Tray specify exact Window Title as last param" & @CRLF & @CRLF
$iMsg &= "( If App leaves Icon in Taskbar when Trayed, it is not compatible )"
Switch $CmdLine[0]
Case 4
If Not StringInStr($CmdLine[1], "-d=") Then _ShowUsage($iMsg)
$delay = Number(StringMid($CmdLine[1], 4))
If $delay < $delayMin Or $delay > $delayMax Then $delay = 0
$App = $CmdLine[2]
$Dir = $CmdLine[3]
$title = $CmdLine[4]
Case 3
If StringInStr($CmdLine[1], "-d=") Then
$delay = Number(StringMid($CmdLine[1], 4))
If $delay < $delayMin Or $delay > $delayMax Then $delay = 0
$App = $CmdLine[2]
$Dir = $CmdLine[3]
Else
$App = $CmdLine[1]
$Dir = $CmdLine[2]
$title = $CmdLine[3]
EndIf
Case 2
If StringInStr($CmdLine[1], "-d=") Then _ShowUsage($iMsg)
$App = $CmdLine[1]
$Dir = $CmdLine[2]
Case Else
_ShowUsage($iMsg)
EndSwitch
$proc_Name = _FileNoPath($App)
$do_Kill = True
While $delay
TraySetToolTip(String($delay) & " Sec. to Launch " & _FileBaseName($App))
Sleep(1000)
$delay -= 1
WEnd
ShellExecute($App, "", $Dir)
Sleep(1000)
If $title <> "" Then
$handle = WinWait($title, "", 4)
If $handle = 0 Then
_ShowError("Could not get Handle for Window:" & @CRLF & @CRLF & $title)
EndIf
EndIf
If $handle = 0 Then
$handle = WinGetHandle(_WinGetByPID($proc_Name))
If $handle = "" Then
$iMsg = "Could Not Get Handle To: " & $proc_Name & @CRLF & @CRLF
$iMsg &= "Try adding Window Title to Command Line or Shortcut Target line"
_ShowError($iMsg)
EndIf
EndIf
TraySetIcon($App)
TraySetClick(8)
$hTray_Show_Item = TrayCreateItem("Hide")
$hTray_Donate_Item = TrayCreateItem("Donate")
TrayCreateItem("")
TrayCreateItem("Exit")
TrayItemSetOnEvent(-1, "On_Exit")
TrayItemSetOnEvent($hTray_Show_Item, "To_Tray")
TrayItemSetOnEvent($hTray_Donate_Item, "Donate")
TraySetOnEvent($TRAY_EVENT_PRIMARYUP, "To_Tray")
TraySetToolTip(_FileBaseName($App))
To_Tray()
While 1
Sleep(1000)
If Not ProcessExists($proc_Name) Then
$do_Kill = False
Exit
EndIf
$memCount += 1
If $memCount >= $MemCountMax Then
_ReduceMemory()
$memCount = 0
EndIf
WEnd
Func On_Exit()
If $do_Kill Then WinClose(_WinAPI_GetWindowText($handle))
Exit
EndFunc ;==>On_Exit
Func To_Tray()
If TrayItemGetText($hTray_Show_Item) = "Hide" Then
_WinAPI_ShowWindow($handle, @SW_HIDE)
TrayItemSetText($hTray_Show_Item, "Show")
Else
_WinAPI_ShowWindow($handle, @SW_SHOW)
TrayItemSetText($hTray_Show_Item, "Hide")
EndIf
EndFunc ;==>To_Tray
Func Donate()
ShellExecute("http://www.favessoft.com/donate.html")
EndFunc ;==>Donate
;-------------- Helper Functions Stripped from Includes ------------
Func _WinAPI_GetWindowText($hWnd)
Local $aResult = DllCall("user32.dll", "int", "GetWindowTextW", "hwnd", $hWnd, "wstr", "", "int", 4096)
If @error Then Return SetError(@error, @extended, "")
Return SetExtended($aResult[0], $aResult[2])
EndFunc ;==>_WinAPI_GetWindowText
Func _WinAPI_ShowWindow($hWnd, $iCmdShow = 5)
Local $aResult = DllCall("user32.dll", "bool", "ShowWindow", "hwnd", $hWnd, "int", $iCmdShow)
If @error Then Return SetError(@error, @extended, False)
Return $aResult[0]
EndFunc ;==>_WinAPI_ShowWindow
Func __Iif($fTest, $iTrue, $iFalse)
If $fTest Then
Return $iTrue
Else
Return $iFalse
EndIf
EndFunc ;==>__Iif
Func __Ver()
Local $tOSVI, $Ret
$tOSVI = DllStructCreate('dword Size;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128]')
DllStructSetData($tOSVI, 'Size', DllStructGetSize($tOSVI))
$Ret = DllCall('kernel32.dll', 'int', 'GetVersionExW', 'ptr', DllStructGetPtr($tOSVI))
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return BitOR(BitShift(DllStructGetData($tOSVI, 'MajorVersion'), -8), DllStructGetData($tOSVI, 'MinorVersion'))
EndFunc ;==>__Ver
Func _WinVersion($retAsString = 0)
Local $dwVersion = DllCall("kernel32.dll", "dword", "GetVersion")
Local $versionStr = String(BitAND($dwVersion[0], 0x00FF))
$versionStr &= "." & String(BitShift(BitAND($dwVersion[0], 0xFF00), 8))
If $retAsString Then Return $versionStr
Return Number($versionStr)
EndFunc ;==>_WinVersion
Func _ReduceMemory($i_PID = -1)
If _WinVersion() < 5 Then Return False
If $i_PID <> -1 Then
Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $i_PID)
Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0])
DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0])
Else
Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1)
EndIf
Return $ai_Return[0]
EndFunc ;==>_ReduceMemory
Func _FileBaseName($path)
If $path = "" Then Return ""
If StringLen($path) < 3 Then Return ""
Local $pos = StringInStr($path, "\", 0, -1)
$pos += 1
Local $tmp = StringMid($path, $pos)
Return StringLeft($tmp, StringInStr($tmp, ".", 0, -1) - 1)
EndFunc ;==>_FileBaseName
Func _FileNoPath($path)
Return StringMid($path, StringInStr($path, "\", 0, -1) + 1)
EndFunc ;==>_FileNoPath
Func _ScriptBaseName()
Return StringLeft(@ScriptName, (StringInStr(@ScriptName, ".") - 1))
EndFunc ;==>_ScriptBaseName
Func _ShowError($errorMsg, $title = "", $quit = True, $timeOut = 0)
If $title = "" Then $title = _ScriptBaseName()
MsgBox(0x1010, $title, $errorMsg, $timeOut)
If $quit Then Exit
EndFunc ;==>_ShowError
Func _ShowUsage($usageMsg, $title = "", $quit = True, $timeOut = 0)
If $title = "" Then $title = _ScriptBaseName()
MsgBox(0x1040, $title, $usageMsg, $timeOut)
If $quit Then Exit
EndFunc ;==>_ShowUsage
Func _WinGetByPID($iPID, $nArray = 1)
If IsString($iPID) Then $iPID = ProcessExists($iPID)
Local $aWList = WinList(), $sHold
For $iCC = 1 To $aWList[0][0]
If WinGetProcess($aWList[$iCC][1]) = $iPID And _
BitAND(WinGetState($aWList[$iCC][1]), 2) Then
If $nArray Then Return $aWList[$iCC][0]
$sHold &= $aWList[$iCC][0] & Chr(1)
EndIf
Next
If $sHold Then Return StringSplit(StringTrimRight($sHold, 1), Chr(1))
Return SetError(1, 0, 0)
EndFunc ;==>_WinGetByPID
Here's the source for the shortcut generator stripped of includes. See zip attachment for custom icon.
StartMinShortcut.au3
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=lightning.ico
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Res_Fileversion=1.1.0.0
#AutoIt3Wrapper_Res_Language=1033
#AutoIt3Wrapper_Res_Field=Productname|StartMinShortcut
#AutoIt3Wrapper_Res_Field=Productversion|1.1
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
Global Const $tagPOINT = "long X;long Y"
Global Const $tagGUID = "dword Data1;word Data2;word Data3;byte Data4[8]"
Global Const $HGDI_ERROR = Ptr(-1)
Global Const $INVALID_HANDLE_VALUE = Ptr(-1)
Global Const $KF_EXTENDED = 0x0100
Global Const $KF_ALTDOWN = 0x2000
Global Const $KF_UP = 0x8000
Global Const $LLKHF_EXTENDED = BitShift($KF_EXTENDED, 8)
Global Const $LLKHF_ALTDOWN = BitShift($KF_ALTDOWN, 8)
Global Const $LLKHF_UP = BitShift($KF_UP, 8)
Global Const $__WINVER = __Ver()
Global Const $tagNOTIFYICONDATA = 'dword Size;hwnd hWnd;uint ID;uint Flags;uint CallbackMessage;ptr hIcon;wchar Tip[128];dword State;dword StateMask;wchar Info[256];uint Version;wchar InfoTitle[64];dword InfoFlags;'
Global Const $tagPRINTDLG = 'align 2;dword_ptr Size;hwnd hOwner;ptr hDevMode;ptr hDevNames;hwnd hDC;dword Flags;ushort FromPage;ushort ToPage;ushort MinPage;ushort MaxPage;' & __Iif(@AutoItX64, 'uint', 'ushort') & ' Copies;ptr hInstance;lparam lParam;ptr PrintHook;ptr SetupHook;ptr PrintTemplateName;ptr SetupTemplateName;ptr hPrintTemplate;ptr hSetupTemplate;'
$delayStr = "0"
$delay = 0
$exe = ""
$work = ""
$target = ""
$title = ""
$shortname = ""
$shortcut = ""
$startfolder = @AppDataCommonDir & "\Microsoft\Windows\Start Menu"
If $CmdLine[0] Then
If FileExists($CmdLine[1]) And StringInStr($CmdLine[1], ".lnk") Then
$shortcut = $CmdLine[1]
EndIf
Else
$shortcut = FileOpenDialog("Select a Shortcut to Start Minimized in Tray", $startfolder, "Shortcuts (*.lnk)", 3, $startfolder & "\*.lnk")
If @error Then _ShowUsage("No Shortcut Chosen")
EndIf
$details = FileGetShortcut($shortcut)
If IsArray($details) Then
$exe = _QuoteStr($details[0])
$work = _QuoteStr($details[1])
If $work = "" Then
$work = _QuoteStr(_FileDirNoSlash($details[0]))
EndIf
$shortname = @DesktopDir & "\" & _FileBaseName($details[0]) & "_Trayed.lnk"
$delayStr = InputBox(_FileBaseName(@ScriptName), " Enter Start Delay in Seconds" _
& @CRLF & @CRLF & " ( Range 1 to 60 : 0 for No Delay )", $delayStr)
If $delayStr <> "" Then
$delay = Int($delayStr)
If $delay Then
$delayStr = "-d=" & String($delay)
Else
$delayStr = ""
EndIf
EndIf
If MsgBox(0x1024, _FileBaseName(@ScriptName), "Run Program to add Window Title ?") = 6 Then
ShellExecute($shortcut)
Sleep(4000)
$title = WinGetTitle("[Active]")
$title = InputBox(_FileBaseName(@ScriptName), "Enter Exact Window Title", $title)
EndIf
$target = $delayStr & " " & $exe & " " & $work
If $title <> "" Then $target &= " " & _QuoteStr($title)
FileCreateShortcut("RunInTrayMod.exe", $shortname, "", $target)
ShellExecute(@StartupDir)
EndIf
;-------------- Helper Functions ---------------
Func __Iif($fTest, $iTrue, $iFalse)
If $fTest Then
Return $iTrue
Else
Return $iFalse
EndIf
EndFunc ;==>__Iif
Func __Ver()
Local $tOSVI, $Ret
$tOSVI = DllStructCreate('dword Size;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128]')
DllStructSetData($tOSVI, 'Size', DllStructGetSize($tOSVI))
$Ret = DllCall('kernel32.dll', 'int', 'GetVersionExW', 'ptr', DllStructGetPtr($tOSVI))
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return BitOR(BitShift(DllStructGetData($tOSVI, 'MajorVersion'), -8), DllStructGetData($tOSVI, 'MinorVersion'))
EndFunc ;==>__Ver
Func _QuoteStr($str)
If StringInStr($str, " ") Then
Return '"' & $str & '"'
EndIf
Return $str
EndFunc ;==>_QuoteStr
;show usage msg and optionally quit with optional timeout
Func _ShowUsage($usageMsg, $title = "", $quit = True, $timeOut = 0)
If $title = "" Then $title = _ScriptBaseName()
MsgBox(0x1040, $title, $usageMsg, $timeOut)
If $quit Then Exit
EndFunc ;==>_ShowUsage
; Return Directory part of path without trailing slash
Func _FileDirNoSlash($path)
Return StringLeft($path, StringInStr($path, "\", 0, -1) - 1)
EndFunc ;==>_FileDirNoSlash
; return the basename part of a file path
; works only for files with extension
; e.g. returns "test" for c:\folder\test.exe path
;
Func _FileBaseName($path)
If $path = "" Then Return ""
If StringLen($path) < 3 Then Return ""
Local $pos = StringInStr($path, "\", 0, -1)
$pos += 1
Local $tmp = StringMid($path, $pos)
Return StringLeft($tmp, StringInStr($tmp, ".", 0, -1) - 1)
EndFunc ;==>_FileBaseName
;return @ScriptName without extension
;useful for MsgBox titles or path
;building
;
Func _ScriptBaseName()
Return StringLeft(@ScriptName, (StringInStr(@ScriptName, ".") - 1))
EndFunc ;==>_ScriptBaseName