home *** CD-ROM | disk | FTP | other *** search
/ PCNET 2006 August - Disc 1 / PCNET_CD_2006_08_1.iso / shareware / AutoHotkey104407_Install.exe / AutoHotkey.chm / docs / scripts / minimizetotraymenu.ahk < prev    next >
Encoding:
Text File  |  2006-06-17  |  7.3 KB  |  221 lines

  1. ; Minimize Window to Tray Menu
  2. ; http://www.autohotkey.com
  3. ; This script assigns a hotkey of your choice to hide any window so that
  4. ; it becomes an entry at the bottom of the script's tray menu.  Hidden
  5. ; windows can then be restored individually or all at once by selecting
  6. ; the corresponding item on the menu.  If the script exits for any reason,
  7. ; all the windows that it hid will be restored automatically.
  8.  
  9. ; CHANGES:
  10. ; November 3, 2004 (changes provided by trogdor):
  11. ; - Program manager is prevented from being hidden.
  12. ; - If there is no active window, the minimize-to-tray hotkey will have
  13. ;   no effect rather than waiting indefinitely.
  14. ;
  15. ; October 23, 2004:
  16. ; - The taskbar is prevented from being hidden.
  17. ; - Some possible problems with long window titles have been fixed.
  18. ; - Windows without a title can be hidden without causing problems.
  19. ; - If the script is running under AHK v1.0.22 or greater, the
  20. ;   maximum length of each menu item is increased from 100 to 260.
  21.  
  22. ; CONFIGURATION SECTION: Change the below values as desired.
  23.  
  24. ; This is the maximum number of windows to allow to be hidden (having a
  25. ; limit helps performance):
  26. mwt_MaxWindows = 50
  27.  
  28. ; This is the hotkey used to hide the active window:
  29. mwt_Hotkey = #h  ; Win+H
  30.  
  31. ; If you prefer to have the tray menu empty of all the standard items,
  32. ; such as Help and Pause, use N.  Otherwise, use Y:
  33. mwt_StandardMenu = N
  34.  
  35. ; These next few performance settings help to keep the action within the
  36. ; #HotkeyModifierTimeout period, and thus avoid the need to release and
  37. ; press down the hotkey's modifier if you want to hide more than one
  38. ; window in a row.  These settings are not needed you choose to have the
  39. ; script use the keyboard hook via #InstallKeybdHook or other means:
  40. #HotkeyModifierTimeout 100
  41. SetWinDelay 10
  42. SetKeyDelay 0
  43.  
  44. #SingleInstance  ; Allow only one instance of this script to be running.
  45.  
  46. ; END OF CONFIGURATION SECTION (do not make changes below this point
  47. ; unless you want to change the basic functionality of the script).
  48.  
  49. Hotkey, %mwt_Hotkey%, mwt_Minimize
  50.  
  51. ; If the user terminates the script by any means, unhide all the
  52. ; windows first:
  53. OnExit, mwt_RestoreAllThenExit
  54.  
  55. if mwt_StandardMenu = Y
  56.     Menu, Tray, Add
  57. else
  58. {
  59.     Menu, Tray, NoStandard
  60.     Menu, Tray, Add, E&xit and Restore All, mwt_RestoreAllThenExit
  61. }
  62. Menu, Tray, Add, &Restore All Hidden Windows, mwt_RestoreAll
  63. Menu, Tray, Add  ; Another separator line to make the above more special.
  64.  
  65. if a_AhkVersion =   ; Since it's blank, version is older than 1.0.22.
  66.     mwt_MaxLength = 100
  67. else
  68.     mwt_MaxLength = 260  ; Reduce this to restrict the width of the menu.
  69.  
  70. return  ; End of auto-execute section.
  71.  
  72.  
  73. mwt_Minimize:
  74. if mwt_WindowCount >= %mwt_MaxWindows%
  75. {
  76.     MsgBox No more than %mwt_MaxWindows% may be hidden simultaneously.
  77.     return
  78. }
  79.  
  80. ; Set the "last found window" to simplify and help performance.
  81. ; Since in certain cases it is possible for there to be no active window,
  82. ; a timeout has been added:
  83. WinWait, A,, 2
  84. if ErrorLevel <> 0  ; It timed out, so do nothing.
  85.     return
  86.  
  87. ; Otherwise, the "last found window" has been set and can now be used:
  88. WinGet, mwt_ActiveID, ID
  89. WinGetTitle, mwt_ActiveTitle
  90. WinGetClass, mwt_ActiveClass
  91. if mwt_ActiveClass in Shell_TrayWnd,Progman
  92. {
  93.     MsgBox The desktop and taskbar cannot be hidden.
  94.     return
  95. }
  96. ; Because hiding the window won't deactivate it, activate the window
  97. ; beneath this one (if any). I tried other ways, but they wound up
  98. ; activating the task bar.  This way sends the active window (which is
  99. ; about to be hidden) to the back of the stack, which seems best:
  100. Send, !{esc}
  101. ; Hide it only now that WinGetTitle/WinGetClass above have been run (since
  102. ; by default, those commands cannot detect hidden windows):
  103. WinHide
  104.  
  105. ; If the title is blank, use the class instead.  This serves two purposes:
  106. ; 1) A more meaningful name is used as the menu name.
  107. ; 2) Allows the menu item to be created (otherwise, blank items wouldn't
  108. ;    be handled correctly by the various routines below).
  109. if mwt_ActiveTitle =
  110.     mwt_ActiveTitle = ahk_class %mwt_ActiveClass%
  111. ; Ensure the title is short enough to fit. mwt_ActiveTitle also serves to
  112. ; uniquely identify this particular menu item.
  113. StringLeft, mwt_ActiveTitle, mwt_ActiveTitle, %mwt_MaxLength%
  114.  
  115. ; In addition to the tray menu requiring that each menu item name be
  116. ; unique, it must also be unique so that we can reliably look it up in
  117. ; the array when the window is later unhidden.  So make it unique if it
  118. ; isn't already:
  119. Loop, %mwt_MaxWindows%
  120. {
  121.     if mwt_WindowTitle%a_index% = %mwt_ActiveTitle%
  122.     {
  123.         ; Match found, so it's not unique.
  124.         ; First remove the 0x from the hex number to conserve menu space:
  125.         StringTrimLeft, mwt_ActiveIDShort, mwt_ActiveID, 2
  126.         StringLen, mwt_ActiveIDShortLength, mwt_ActiveIDShort
  127.         StringLen, mwt_ActiveTitleLength, mwt_ActiveTitle
  128.         mwt_ActiveTitleLength += %mwt_ActiveIDShortLength%
  129.         mwt_ActiveTitleLength += 1 ; +1 the 1 space between title & ID.
  130.         if mwt_ActiveTitleLength > %mwt_MaxLength%
  131.         {
  132.             ; Since menu item names are limted in length, trim the title
  133.             ; down to allow just enough room for the Window's Short ID at
  134.             ; the end of its name:
  135.             TrimCount = %mwt_ActiveTitleLength%
  136.             TrimCount -= %mwt_MaxLength%
  137.             StringTrimRight, mwt_ActiveTitle, mwt_ActiveTitle, %TrimCount%
  138.         }
  139.         ; Build unique title:
  140.         mwt_ActiveTitle = %mwt_ActiveTitle% %mwt_ActiveIDShort%
  141.         break
  142.     }
  143. }
  144.  
  145. ; First, ensure that this ID doesn't already exist in the list, which can
  146. ; happen if a particular window was externally unhidden (or its app unhid
  147. ; it) and now it's about to be re-hidden:
  148. mwt_AlreadyExists = n
  149. Loop, %mwt_MaxWindows%
  150. {
  151.     if mwt_WindowID%a_index% = %mwt_ActiveID%
  152.     {
  153.         mwt_AlreadyExists = y
  154.         break
  155.     }
  156. }
  157.  
  158. ; Add the item to the array and to the menu:
  159. if mwt_AlreadyExists = n
  160. {
  161.     Menu, Tray, add, %mwt_ActiveTitle%, RestoreFromTrayMenu
  162.     mwt_WindowCount += 1
  163.     Loop, %mwt_MaxWindows%  ; Search for a free slot.
  164.     {
  165.         ; It should always find a free slot if things are designed right.
  166.         if mwt_WindowID%a_index% =  ; An empty slot was found.
  167.         {
  168.             mwt_WindowID%a_index% = %mwt_ActiveID%
  169.             mwt_WindowTitle%a_index% = %mwt_ActiveTitle%
  170.             break
  171.         }
  172.     }
  173. }
  174. return
  175.  
  176.  
  177. RestoreFromTrayMenu:
  178. Menu, Tray, delete, %A_ThisMenuItem%
  179. ; Find window based on its unique title stored as the menu item name:
  180. Loop, %mwt_MaxWindows%
  181. {
  182.     if mwt_WindowTitle%a_index% = %A_ThisMenuItem%  ; Match found.
  183.     {
  184.         StringTrimRight, IDToRestore, mwt_WindowID%a_index%, 0
  185.         WinShow, ahk_id %IDToRestore%
  186.         WinActivate ahk_id %IDToRestore%  ; Sometimes needed.
  187.         mwt_WindowID%a_index% =  ; Make it blank to free up a slot.
  188.         mwt_WindowTitle%a_index% =
  189.         mwt_WindowCount -= 1
  190.         break
  191.     }
  192. }
  193. return
  194.  
  195.  
  196. mwt_RestoreAllThenExit:
  197. Gosub, mwt_RestoreAll
  198. ExitApp  ; Do a true exit.
  199.  
  200.  
  201. mwt_RestoreAll:
  202. Loop, %mwt_MaxWindows%
  203. {
  204.     if mwt_WindowID%a_index% <>
  205.     {
  206.         StringTrimRight, IDToRestore, mwt_WindowID%a_index%, 0
  207.         WinShow, ahk_id %IDToRestore%
  208.         WinActivate ahk_id %IDToRestore%  ; Sometimes needed.
  209.         ; Do it this way vs. DeleteAll so that the sep. line and first
  210.         ; item are retained:
  211.         StringTrimRight, MenuToRemove, mwt_WindowTitle%a_index%, 0
  212.         Menu, Tray, delete, %MenuToRemove%
  213.         mwt_WindowID%a_index% =  ; Make it blank to free up a slot.
  214.         mwt_WindowTitle%a_index% =
  215.         mwt_WindowCount -= 1
  216.     }
  217.     if mwt_WindowCount = 0
  218.         break
  219. }
  220. return
  221.