 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Charon the Hand
Joined: 07 Aug 2007 Posts: 4
|
Posted: Tue Aug 07, 2007 8:51 pm Post subject: New hide windows script |
|
|
I know, just what the world needs is another script to hide windows. But this one is better.
| Code: | /*
Autohide, by Charon the Hand.
This script hides a window with {Win}F5. {Win}F6 brings up a listview with icons showing the windows that
have been hidden. You can select one by double clicking its row or highlighting the row with arrow keys and
hitting {Enter}. The script will keep a list of windows currently hidden; if it exits for any reason other
than system shutdown, it writes the names of hidden windows to an .ini file. On restarting, the script reads
those values and rebuilds the listview. {Win}F7 exits the script (mostly for testing purposes). {Win}F8
currently does nothing, but I used it extensively for testing. The hotkeys are customizable. The colors of
the listview (background, border, text) are customizable. Currently you can hide 10 windows, but that too
is customizable if necessary.
Credit to evl for his Alt-Tab Replacement, from which I borrowed the DllCall code to retrieve icons and much
help in building listviews. Also to the author (can't find his/her name anywhere) of Minimize Window to Tray
Menu from the script showcase for the trick of raising the next window in the z-order when hiding.
*/
#NoEnv
#NoTrayIcon
#InstallKeybdHook
#SingleInstance Force
DetectHiddenWindows On
SetTitleMatchMode 3
CoordMode, Mouse
OnExit, ch_SaveToIni
OnMessage( 0x06, "ch_WM_ACTIVATE" )
ch_totalWindows := 0
;================================Variables================================;
ch_hotkeyHide := "#F5" ;{Win}F5
ch_hotkeyShow := "#F6" ;{Win}F6
ch_hotkeyExit := "#F7" ;{Win}F7
ch_maxWindows := 10
ch_bgColor := "EBEBEB"
ch_borderColor := "B22222"
ch_textColor := "191919"
;================================Autoexecute================================;
Loop, %ch_maxWindows% ;read the ini file to see if there are any
{ ;windows to be restored, then erase contents
IniRead, ch_winNameFromIni, autohide.ini, Window%A_Index%, WinTitle
If ch_winNameFromIni = ERROR
continue
IniRead, ch_winIdFromIni, autohide.ini, Window%A_Index%, WinId
IniDelete, autohide.ini, Window%A_Index%
Loop %ch_maxWindows%
{
If ch_winName%A_Index% =
{
ch_winName%A_Index% := ch_winNameFromIni
ch_winId%A_Index% := ch_winIdFromIni
ch_winNameLength%A_Index% := StrLen(ch_winNameFromIni)
ch_totalWindows += 1
break
}
}
}
ch_BuildListView()
Hotkey, %ch_hotkeyHide%, ch_HideWindow
Hotkey, %ch_hotkeyShow%, ch_ShowWindow
Hotkey, %ch_hotkeyExit%, ch_SaveToIni
return
;================================Hotkeys================================;
#F8::
msgbox, %ch_longestName%
return
;================================Subroutines================================;
ch_HideWindow:
WinGetTitle, ch_winName, A
WinGetClass, ch_winClass, A
WinGet, ch_winId, Id, A
If ch_winClass in Progman,Shell_TrayWnd
return
Send, !{Esc}
WinHide, ahk_id %ch_winId%
Loop %ch_maxWindows%
{
If ch_winId%A_Index% = ;find an empty variable and put the window name in
{
ch_winId%A_Index% := ch_winId
ch_winName%A_Index% := ch_winName
ch_winNameLength%A_Index% := StrLen(ch_winName)
ch_totalWindows +=1
break
}
}
return
ch_ShowWindow:
If ch_totalWindows = 0
return
MouseGetPos, ch_xpos, ch_ypos ;put LV right under the mouse
ch_xpos -= 10
ch_ypos -= 10
ch_BuildListView()
Gui, Show, x%ch_xpos% y%ch_ypos%
return
ch_SaveToIni:
If A_ExitReason in Shutdown,Exit ;if shutting down the computer, skip
ExitApp
Loop, %ch_maxWindows% ;if closing for any other reason, store currently
{ ;hidden windows in ini file for restoration later
If ch_winName%A_Index% =
continue
ch_outerLoopA_Index := A_Index
Loop, %ch_maxWindows%
{
IniRead, ch_freeSpace, autohide.ini, Window%A_Index%, WinTitle
If ch_freeSpace = ERROR
{
IniWrite, % ch_winName%ch_outerLoopA_Index%, autohide.ini, Window%A_Index%, WinTitle
IniWrite, % ch_winId%ch_outerLoopA_Index%, autohide.ini, Window%A_Index%, WinId
break
}
}
}
ExitApp
ch_LVMenu:
If A_GuiEvent = DoubleClick ;restore window on double-click
{
ch_RestoreWindow(A_EventInfo)
}
return
ButtonOK: ;restore window on {Enter}
GuiControlGet, ch_FocusedControl, FocusV
If ch_FocusedControl <> ch_LVMenu
return
else
{
ch_RowNum := LV_GetNext(0, "Focused")
ch_RestoreWindow(ch_RowNum)
}
return
;================================Functions================================;
ch_WM_ACTIVATE(ch_wParam)
{
Global
If (ch_wParam = 0) ;if the listview loses focus, hide it
{
Gui, Hide
}
}
ch_BuildListView()
{
global
Gui, Destroy
ch_GetLongestName()
Gui, Color, %ch_borderColor%, %ch_bgColor%
Gui, Margin, 1,1
Gui, +ToolWindow -Caption
Gui, Font, s12 c%ch_textColor%
Gui, Add, ListView, Report -Hdr r%ch_totalWindows% w%ch_longestName% Count10 gch_LVMenu vch_LVMenu, |
Gui, Add, Button, w0 h0 x0 y-1 Hidden Default, OK
ch_ImageListID := IL_Create(10) ;invisible OK button, so you can use {Enter} to select
LV_SetImageList(ch_ImageListID) ;Create an ImageList to hold 10 small icons.
;Assign the above ImageList to the current ListView.
Loop, %ch_maxWindows%
{
If ch_winId%A_Index% =
continue
ch_winName := ch_winName%A_Index% ;this whole icon routine is from evl, I don't pretend to
ch_winId := ch_winId%A_Index% ;understand it, I just modified it until it worked for me
SendMessage, 0x7F, 2, 0,, ahk_id %ch_winId%
ch_hIcon := ErrorLevel
If ( ! ch_hIcon )
{
SendMessage, 0x7F, 0, 0,, ahk_id %ch_winId%
ch_hIcon := ErrorLevel
If ( ! ch_hIcon )
{
ch_hIcon := DllCall( "GetClassLong", "uint", ch_winId, "int", -34 ) ; GCL_HICONSM is -34
If ( ! ch_hIcon )
{
ch_hIcon := DllCall( "LoadIcon", "uint", 0, "uint", 32512 ) ; IDI_APPLICATION is 32512
}
}
}
;Add the HICON directly to the small-icon and large-icon lists.
;Below uses +1 to convert the returned index from zero-based to one-based:
;Create the new row in the ListView and assign it the icon number determined above ; Add 2 spaces for looks
ch_IconNumber := DllCall("ImageList_ReplaceIcon", UInt, ch_ImageListID, Int, -1, UInt, ch_hIcon) + 1
LV_Add("Icon" . ch_IconNumber, A_Space . A_Space . ch_winName)
continue
}
WinGetClass, ch_winClass, ahk_id %ch_winId%
If ch_winClass = #32770 ; fix for displaying control panel related windows (dialog class) that aren't on taskbar
{
ch_IconNumber := IL_Add(ch_ImageListID, "C:\WINDOWS\system32\shell32.dll" , 217) ; generic control panel icon
LV_Add("Icon" . ch_IconNumber, ch_winName)
}
return
}
ch_RestoreWindow(ch_RowNum)
{
global
LV_GetText(ch_RowText, ch_RowNum, 1) ;Get the text from the row's first field.
StringTrimLeft, ch_RowText, ch_RowText, 2 ;Remove the 2 spaces before using
WinGet, ch_winIdToRestore, Id, %ch_RowText%
WinShow, ahk_id %ch_winIdToRestore%
LV_Delete(ch_RowNum)
Loop, %ch_maxWindows% ;Delete the contents of the variables so the
{ ;row doesn't get recreated in the next call
If ch_winName%A_Index% = %ch_RowText%
{
ch_winName%A_Index% :=
ch_winId%A_Index% :=
ch_winNameLength%A_Index% :=
ch_totalWindows -= 1
break
}
}
Gui, Hide
return
}
ch_GetLongestName()
{
global
ch_longestName := 0
Loop, %ch_maxWindows%
{
If % ch_winName%A_Index% =
continue
If % ch_winNameLength%A_Index% >= ch_longestName
ch_longestName := ch_winNameLength%A_Index%
}
If ch_longestName <= 20 ;window names with fewer letters get a slightly bigger window built
ch_longestName := ((ch_longestName + 2) * 7) + 40
else
ch_longestName := ((ch_longestName + 2) * 7.75)
return
} |
I've been playing with AHK for a couple months, but this is the first script I've polished up enough to release to the world. Thanks to chris and the forum for constantly amazing me with AHK's versatility. |
|
| Back to top |
|
 |
Zusukar Guest
|
Posted: Mon May 12, 2008 6:20 pm Post subject: Modifications to Autohide |
|
|
I loved this script, but a few things bothered me enough to fix them. Here is an improved version that fixes a few bugs.
Notably:
The window titles will update if they change while hidden.
The width of the list is correctly determined.
If a window closes while hidden, it will automatically be removed from the list.
Don't hide a window if there are no available entries in the array.
The icon list will allocate enough entries based on the number of hidden windows instead of always 10.
Other minor changes.
| Code: |
/*
HideWinList, by Zusukar
Originally Autohide by Charon the Hand.
This script hides a window with {Win}Q. {Win}W brings up a listview with icons showing the windows that
have been hidden. You can select one by double clicking its row or highlighting the row with arrow keys and
hitting {Enter}. The script will keep a list of windows currently hidden; if it exits for any reason other
than system shutdown, it writes the names of hidden windows to an .ini file. On restarting, the script reads
those values and rebuilds the listview. {Win}F7 exits the script (mostly for testing purposes). The hotkeys
are customizable. The colors of the listview (background, border, text) are customizable. Currently you can
hide 10 windows, but that too is customizable if necessary.
Credit to evl for his Alt-Tab Replacement, from which I borrowed the DllCall code to retrieve icons and much
help in building listviews. Also to the author (can't find his/her name anywhere) of Minimize Window to Tray
Menu from the script showcase for the trick of raising the next window in the z-order when hiding.
Credit to Sean for his GetTextExtentPoint function that determines text height and width. This has been
modified to only return the width.
(http://www.autohotkey.com/forum/post-113847.html&sid=cb1840004443b42e1a730db24896b406#113847)
*/
#KeyHistory 0
#NoEnv
#NoTrayIcon
#InstallKeybdHook
#SingleInstance Force
DetectHiddenWindows On
SetTitleMatchMode 3
CoordMode, Mouse
OnExit, ch_Exit
OnMessage( 0x06, "ch_WM_ACTIVATE" )
;================================Variables================================;
ch_hotkeyHide := "#q" ;{Win}q
ch_hotkeyShow := "#w" ;{Win}w
ch_hotkeyExit := "#F7" ;{Win}F7
ch_maxWindows := 10
ch_bgColor := "EBEBEB"
ch_borderColor := "000000"
ch_textColor := "191919"
ch_textFont := "Microsoft Sans Serif"
ch_totalWindows := 0
;===============================Autoexecute===============================;
ch_LoadFromIni()
Hotkey, %ch_hotkeyHide%, ch_HideActiveWindow
Hotkey, %ch_hotkeyShow%, ch_ShowWindow
Hotkey, %ch_hotkeyExit%, ch_Exit
return
;=================================HotKeys=================================;
;===============================Subroutines===============================;
ch_HideActiveWindow:
WinGetClass, ch_winClass, A
If ch_winClass in Progman,Shell_TrayWnd
return
WinGet, ch_winId, Id, A
Send, !{Esc}
ch_HideWindow(ch_winId)
return
ch_ShowWindow:
If ch_totalWindows = 0
return
MouseGetPos, ch_xpos, ch_ypos ;put LV right under the mouse
ch_xpos -= 10
ch_ypos -= 10
ch_BuildListView()
if ch_totalWindows > 0
Gui, Show, x%ch_xpos% y%ch_ypos%
return
ch_Exit:
If A_ExitReason in Shutdown,Exit ;if shutting down the computer, skip
ExitApp
ch_SaveToIni() ;if closing for any other reason, save hidden windows
ExitApp
ch_LVMenu:
If A_GuiEvent = DoubleClick ;restore window on double-click
ch_RestoreWindow(A_EventInfo)
return
ButtonOK: ;restore window on {Enter}
GuiControlGet, ch_FocusedControl, FocusV
If ch_FocusedControl <> ch_LVMenu
{
ch_FocusedControl :=
return
}
else
{
ch_FocusedControl :=
ch_RestoreWindow(LV_GetNext(0, "Focused"))
}
return
GUIEscape:
GUI, Destroy
return
;================================Functions================================;
ch_HideWindow(ch_winId)
{
global
local ch_stored := 0
Loop, %ch_maxWindows%
{
If ch_winId%A_Index% = ;find an empty variable and put the window ID in
{
ch_winId%A_Index% := ch_winId
ch_totalWindows += 1
ch_stored := 1
Break
}
}
If ch_stored = 1
WinHide, ahk_id %ch_winId%
return
}
ch_SaveToIni()
{
global
local this_id
Loop, %ch_maxWindows% ;store currently
{ ;hidden windows in ini file for restoration later
this_id := ch_winId%A_Index%
IfWinNotExist, ahk_id %this_id%
continue
If ch_winId%A_Index% =
continue
IniWrite, % ch_winId%A_Index%, HideWinList.ini, Window%A_Index%, WinId
}
return
}
ch_LoadFromIni()
{
global
local this_id
Loop, %ch_maxWindows% ;read the ini file to see if there are any
{ ;windows to be restored, then erase contents
IniRead, this_id, HideWinList.ini, Window%A_Index%, WinId
If this_id = ERROR
continue
IniDelete, HideWinList.ini, Window%A_Index%
IfWinNotExist, ahk_id %this_id%
continue
ch_HideWindow(this_id)
}
return
}
ch_WM_ACTIVATE(ch_wParam)
{
If (ch_wParam = 0) ;if the listview loses focus, hide it
Gui, Destroy
return
}
ch_BuildListView()
{
global
Gui, Destroy
ch_GetLongestName()
If ch_longestName = 0
return
Gui, Color, %ch_borderColor%, %ch_bgColor%
Gui, Margin, 1,1
Gui, +ToolWindow -Caption
Gui, Font, s12 c%ch_textColor%, %ch_textFont%
Gui, Add, ListView, Report -Hdr r%ch_totalWindows% w%ch_longestName% Count%ch_totalWindows% gch_LVMenu vch_LVMenu, ||
ch_longestName :=
;invisible OK button, so you can use {Enter} to select
Gui, Add, Button, w0 h0 x0 y-1 Hidden Default, OK
;Create an ImageList to hold the small icons.
local ch_ImageListID := IL_Create(ch_totalWindows)
;Assign the above ImageList to the current ListView.
LV_SetImageList(ch_ImageListID)
Loop, %ch_maxWindows%
{
local this_id := ch_winId%A_Index%
If this_id =
continue
IfWinNotExist ahk_id %this_id%
{
ch_winId%A_Index% :=
ch_totalWindows -= 1
continue
}
local ch_winId := ch_winId%A_Index%
local ch_winClass
WinGetClass, ch_winClass, ahk_id %ch_winId%
If ch_winClass = #32770 ; fix for displaying control panel related windows (dialog class) that aren't on taskbar
local ch_IconNumber := IL_Add(ch_ImageListID, "C:\WINDOWS\system32\shell32.dll" , 217) ; generic control panel icon
Else
{
;this whole icon routine is from evl, I don't pretend to
;understand it, I just modified it until it worked for me
SendMessage, 0x7F, 2, 0,, ahk_id %ch_winId%
local ch_hIcon := ErrorLevel
If ( ! ch_hIcon )
{
SendMessage, 0x7F, 0, 0,, ahk_id %ch_winId%
ch_hIcon := ErrorLevel
If ( ! ch_hIcon )
{
ch_hIcon := DllCall( "GetClassLong", "uint", ch_winId, "int", -34 ) ; GCL_HICONSM is -34
If ( ! ch_hIcon )
{
ch_hIcon := DllCall( "LoadIcon", "uint", 0, "uint", 32512 ) ; IDI_APPLICATION is 32512
}
}
}
;Add the HICON directly to the small-icon and large-icon lists.
;Below uses +1 to convert the returned index from zero-based to one-based:
;Create the new row in the ListView and assign it the icon number determined above ; Add 2 spaces for looks
ch_IconNumber := DllCall("ImageList_ReplaceIcon", "uint", ch_ImageListID, "int", -1, "uint", ch_hIcon) + 1
}
local ch_winName
WinGetTitle, ch_winName, ahk_id %ch_winId%
LV_Add("Icon" . ch_IconNumber, A_Index . A_Space . ch_winName)
continue
}
LV_ModifyCol()
return
}
ch_RestoreWindow(ch_RowNum)
{
LV_GetText(ch_rowText, ch_RowNum, 1) ;Get the Info from the row's first field.
StringGetPos, ch_firstSpace, ch_rowText, %A_Space% ;These two lines extract the
StringLeft, ch_index, ch_rowText, ch_firstSpace ;array index for the selected window
ch_winId := ch_winId%ch_Index%
WinShow, ahk_id %ch_winId%
ch_winId%ch_index% := ;Delete the contents of the variable
global ch_totalWindows -= 1
Gui, Destroy
return
}
ch_GetLongestName()
{
global
ch_longestName := 0
Loop, %ch_maxWindows%
{
local this_id := ch_winId%A_Index%
If ch_winId%A_Index% =
continue
IfWinNotExist, ahk_id %this_id%
continue
local ch_winId := ch_winId%A_Index%
local ch_winName
WinGetTitle, ch_winName, ahk_id %ch_winId%
local ch_winNameLength := GetTextWidth(ch_winName, ch_textFont)
If (ch_winNameLength >= ch_longestName)
ch_longestName := ch_winNameLength
}
If ch_longestName <> 0
ch_longestName := ch_longestName + 50 ;add some room for the icon
return
}
;GetTextWidth by Sean: http://www.autohotkey.com/forum/post-113847.html&sid=cb1840004443b42e1a730db24896b406#113847
GetTextWidth(sString, sFaceName, nHeight = 12, bBold = False, bItalic = False, bUnderline = False, bStrikeOut = False, nCharSet = 0)
{
hDC := DllCall("GetDC", "Uint", 0)
nHeight := -DllCall("MulDiv", "int", nHeight, "int", DllCall("GetDeviceCaps", "Uint", hDC, "int", 90), "int", 72)
hFont := DllCall("CreateFont", "int", nHeight, "int", 0, "int", 0, "int", 0, "int", 400 + 300 * bBold, "Uint", bItalic, "Uint", bUnderline, "Uint", bStrikeOut, "Uint", nCharSet, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0, "str", sFaceName)
hFold := DllCall("SelectObject", "Uint", hDC, "Uint", hFont)
DllCall("GetTextExtentPoint32", "Uint", hDC, "str", sString, "int", StrLen(sString), "int64P", nSize)
DllCall("SelectObject", "Uint", hDC, "Uint", hFold)
DllCall("DeleteObject", "Uint", hFont)
DllCall("ReleaseDC", "Uint", 0, "Uint", hDC)
nWidth := nSize & 0xFFFFFFFF
Return nWidth
}
|
|
|
| Back to top |
|
 |
Charon the Hand
Joined: 07 Aug 2007 Posts: 4
|
Posted: Tue May 13, 2008 3:01 pm Post subject: |
|
|
| Thank you, Zusukar! It is gratifying to know that someone uses this script and found ways to improve it. I always knew a few things were a bit hacky, especially the window width, thank you for fixing it up. |
|
| Back to top |
|
 |
Guest
|
Posted: Wed Jun 04, 2008 7:35 pm Post subject: |
|
|
Nice, thank you Charon and Zusukar for the script and the fix. It's very simple and useful  |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|