/docs/scripts/MinimizeToTrayMenu.htm
HTML | 266 lines | 232 code | 34 blank | 0 comment | 0 complexity | 4f1fe240544f67626b06849c613ea2eb MD5 | raw file
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
- "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <title>Minimize Window to Tray Menu</title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <link rel="alternate" type="application/rss+xml" title="AutoHotkey Forum RSS" href="/forum/rss.php">
- <link href="/docs/css/default.css" rel="stylesheet" type="text/css">
- <link href="/docs/css/print.css" rel="stylesheet" type="text/css" media="print">
- </head>
- <body>
-
- <h6>Minimize Window to Tray Menu</h6>
-
- <p> This script assigns a hotkey of your choice to hide any window so that
- it becomes an entry at the bottom of the script's tray menu. Hidden
- windows can then be unhidden individually or all at once by selecting
- the corresponding item on the menu. If the script exits for any reason,
- all the windows that it hid will be unhidden automatically.
- </p>
- <p><a href="MinimizeToTrayMenu.ahk">Download This Script</a> | <a href="index.htm">Other Sample Scripts</a> | <a href="http://www.autohotkey.com">Home</a></p>
-
- <pre class="NoIndent"><em>; CHANGES:</em>
- <em>; July 22, 2005 (changes provided by egilmour):</em>
- <em>; - Added new hotkey to unhide the last hidden window (Win+U)</em>
- <em>;</em>
- <em>; November 3, 2004 (changes provided by trogdor):</em>
- <em>; - Program manager is prevented from being hidden.</em>
- <em>; - If there is no active window, the minimize-to-tray hotkey will have</em>
- <em>; no effect rather than waiting indefinitely.</em>
- <em>;</em>
- <em>; October 23, 2004:</em>
- <em>; - The taskbar is prevented from being hidden.</em>
- <em>; - Some possible problems with long window titles have been fixed.</em>
- <em>; - Windows without a title can be hidden without causing problems.</em>
- <em>; - If the script is running under AHK v1.0.22 or greater, the</em>
- <em>; maximum length of each menu item is increased from 100 to 260.</em>
-
- <em>; CONFIGURATION SECTION: Change the below values as desired.</em>
-
- <em>; This is the maximum number of windows to allow to be hidden (having a</em>
- <em>; limit helps performance):</em>
- mwt_MaxWindows = 50
-
- <em>; This is the hotkey used to hide the active window:</em>
- mwt_Hotkey = #h <em>; Win+H</em>
-
- <em>; This is the hotkey used to unhide the last hidden window:</em>
- mwt_UnHotkey = #u <em>; Win+U</em>
-
- <em>; If you prefer to have the tray menu empty of all the standard items,</em>
- <em>; such as Help and Pause, use N. Otherwise, use Y:</em>
- mwt_StandardMenu = N
-
- <em>; These next few performance settings help to keep the action within the</em>
- <em>; #HotkeyModifierTimeout period, and thus avoid the need to release and</em>
- <em>; press down the hotkey's modifier if you want to hide more than one</em>
- <em>; window in a row. These settings are not needed you choose to have the</em>
- <em>; script use the keyboard hook via #InstallKeybdHook or other means:</em>
- #HotkeyModifierTimeout 100
- SetWinDelay 10
- SetKeyDelay 0
-
- #SingleInstance <em>; Allow only one instance of this script to be running.</em>
-
- <em>; END OF CONFIGURATION SECTION (do not make changes below this point</em>
- <em>; unless you want to change the basic functionality of the script).</em>
-
- Hotkey, %mwt_Hotkey%, mwt_Minimize
- Hotkey, %mwt_UnHotkey%, mwt_UnMinimize
-
- <em>; If the user terminates the script by any means, unhide all the</em>
- <em>; windows first:</em>
- OnExit, mwt_RestoreAllThenExit
-
- if mwt_StandardMenu = Y
- Menu, Tray, Add
- else
- {
- Menu, Tray, NoStandard
- Menu, Tray, Add, E&xit and Unhide All, mwt_RestoreAllThenExit
- }
- Menu, Tray, Add, &Unhide All Hidden Windows, mwt_RestoreAll
- Menu, Tray, Add <em>; Another separator line to make the above more special.</em>
-
- if a_AhkVersion = <em>; Since it's blank, version is older than 1.0.22.</em>
- mwt_MaxLength = 100
- else
- mwt_MaxLength = 260 <em>; Reduce this to restrict the width of the menu.</em>
-
- return <em>; End of auto-execute section.</em>
-
-
- mwt_Minimize:
- if mwt_WindowCount >= %mwt_MaxWindows%
- {
- MsgBox No more than %mwt_MaxWindows% may be hidden simultaneously.
- return
- }
-
- <em>; Set the "last found window" to simplify and help performance.</em>
- <em>; Since in certain cases it is possible for there to be no active window,</em>
- <em>; a timeout has been added:</em>
- WinWait, A,, 2
- if ErrorLevel <> 0 <em>; It timed out, so do nothing.</em>
- return
-
- <em>; Otherwise, the "last found window" has been set and can now be used:</em>
- WinGet, mwt_ActiveID, ID
- WinGetTitle, mwt_ActiveTitle
- WinGetClass, mwt_ActiveClass
- if mwt_ActiveClass in Shell_TrayWnd,Progman
- {
- MsgBox The desktop and taskbar cannot be hidden.
- return
- }
- <em>; Because hiding the window won't deactivate it, activate the window</em>
- <em>; beneath this one (if any). I tried other ways, but they wound up</em>
- <em>; activating the task bar. This way sends the active window (which is</em>
- <em>; about to be hidden) to the back of the stack, which seems best:</em>
- Send, !{esc}
- <em>; Hide it only now that WinGetTitle/WinGetClass above have been run (since</em>
- <em>; by default, those commands cannot detect hidden windows):</em>
- WinHide
-
- <em>; If the title is blank, use the class instead. This serves two purposes:</em>
- <em>; 1) A more meaningful name is used as the menu name.</em>
- <em>; 2) Allows the menu item to be created (otherwise, blank items wouldn't</em>
- <em>; be handled correctly by the various routines below).</em>
- if mwt_ActiveTitle =
- mwt_ActiveTitle = ahk_class %mwt_ActiveClass%
- <em>; Ensure the title is short enough to fit. mwt_ActiveTitle also serves to</em>
- <em>; uniquely identify this particular menu item.</em>
- StringLeft, mwt_ActiveTitle, mwt_ActiveTitle, %mwt_MaxLength%
-
- <em>; In addition to the tray menu requiring that each menu item name be</em>
- <em>; unique, it must also be unique so that we can reliably look it up in</em>
- <em>; the array when the window is later unhidden. So make it unique if it</em>
- <em>; isn't already:</em>
- Loop, %mwt_MaxWindows%
- {
- if mwt_WindowTitle%a_index% = %mwt_ActiveTitle%
- {
- <em>; Match found, so it's not unique.</em>
- <em>; First remove the 0x from the hex number to conserve menu space:</em>
- StringTrimLeft, mwt_ActiveIDShort, mwt_ActiveID, 2
- StringLen, mwt_ActiveIDShortLength, mwt_ActiveIDShort
- StringLen, mwt_ActiveTitleLength, mwt_ActiveTitle
- mwt_ActiveTitleLength += %mwt_ActiveIDShortLength%
- mwt_ActiveTitleLength += 1 <em>; +1 the 1 space between title & ID.</em>
- if mwt_ActiveTitleLength > %mwt_MaxLength%
- {
- <em>; Since menu item names are limted in length, trim the title</em>
- <em>; down to allow just enough room for the Window's Short ID at</em>
- <em>; the end of its name:</em>
- TrimCount = %mwt_ActiveTitleLength%
- TrimCount -= %mwt_MaxLength%
- StringTrimRight, mwt_ActiveTitle, mwt_ActiveTitle, %TrimCount%
- }
- <em>; Build unique title:</em>
- mwt_ActiveTitle = %mwt_ActiveTitle% %mwt_ActiveIDShort%
- break
- }
- }
-
- <em>; First, ensure that this ID doesn't already exist in the list, which can</em>
- <em>; happen if a particular window was externally unhidden (or its app unhid</em>
- <em>; it) and now it's about to be re-hidden:</em>
- mwt_AlreadyExists = n
- Loop, %mwt_MaxWindows%
- {
- if mwt_WindowID%a_index% = %mwt_ActiveID%
- {
- mwt_AlreadyExists = y
- break
- }
- }
-
- <em>; Add the item to the array and to the menu:</em>
- if mwt_AlreadyExists = n
- {
- Menu, Tray, add, %mwt_ActiveTitle%, RestoreFromTrayMenu
- mwt_WindowCount += 1
- Loop, %mwt_MaxWindows% <em>; Search for a free slot.</em>
- {
- <em>; It should always find a free slot if things are designed right.</em>
- if mwt_WindowID%a_index% = <em>; An empty slot was found.</em>
- {
- mwt_WindowID%a_index% = %mwt_ActiveID%
- mwt_WindowTitle%a_index% = %mwt_ActiveTitle%
- break
- }
- }
- }
- return
-
-
- RestoreFromTrayMenu:
- Menu, Tray, delete, %A_ThisMenuItem%
- <em>; Find window based on its unique title stored as the menu item name:</em>
- Loop, %mwt_MaxWindows%
- {
- if mwt_WindowTitle%a_index% = %A_ThisMenuItem% <em>; Match found.</em>
- {
- StringTrimRight, IDToRestore, mwt_WindowID%a_index%, 0
- WinShow, ahk_id %IDToRestore%
- WinActivate ahk_id %IDToRestore% <em>; Sometimes needed.</em>
- mwt_WindowID%a_index% = <em>; Make it blank to free up a slot.</em>
- mwt_WindowTitle%a_index% =
- mwt_WindowCount -= 1
- break
- }
- }
- return
-
-
- <em>;; This will pop the last minimized window off the stack and unhide it.</em>
- mwt_UnMinimize:
- <em>;; Make sure there's something to unhide.</em>
- if mwt_WindowCount > 0
- {
- <em>;; Get the id of the last window minimized and unhide it</em>
- StringTrimRight, IDToRestore, mwt_WindowID%mwt_WindowCount%, 0
- WinShow, ahk_id %IDToRestore%
- WinActivate ahk_id %IDToRestore%
-
- <em>;; Get the menu name of the last window minimized and remove it</em>
- StringTrimRight, MenuToRemove, mwt_WindowTitle%mwt_WindowCount%, 0
- Menu, Tray, delete, %MenuToRemove%
-
- <em>;; clean up our 'arrays' and decrement the window count</em>
- mwt_WindowID%mwt_WindowCount% =
- mwt_WindowTitle%mwt_WindowCount% =
- mwt_WindowCount -= 1
- }
- return
-
-
- mwt_RestoreAllThenExit:
- Gosub, mwt_RestoreAll
- ExitApp <em>; Do a true exit.</em>
-
-
- mwt_RestoreAll:
- Loop, %mwt_MaxWindows%
- {
- if mwt_WindowID%a_index% <>
- {
- StringTrimRight, IDToRestore, mwt_WindowID%a_index%, 0
- WinShow, ahk_id %IDToRestore%
- WinActivate ahk_id %IDToRestore% <em>; Sometimes needed.</em>
- <em>; Do it this way vs. DeleteAll so that the sep. line and first</em>
- <em>; item are retained:</em>
- StringTrimRight, MenuToRemove, mwt_WindowTitle%a_index%, 0
- Menu, Tray, delete, %MenuToRemove%
- mwt_WindowID%a_index% = <em>; Make it blank to free up a slot.</em>
- mwt_WindowTitle%a_index% =
- mwt_WindowCount -= 1
- }
- if mwt_WindowCount = 0
- break
- }
- return
- </pre>
- </body>
- </html>