Collapse Window by Clicking on the Title Bar

In [the previous post](http://qiita.com/items/2558), I showed a way to check whether the cursor is on the client area of a target window. The method can be applied similarly to detect if the cursor is on the title bar of a window. Once the position of the client top-left corner is retrieved, it is merely a subtraction to get the height of the title bar of the window. 

The below script lets you un/fold a window with a middle click on the title bar.

```ahk:WindowCollapse.ahk
#Noenv
SetWorkingDir %A_ScriptDir%

Hotkey, ~MButton, CollapseWindow	; set the hotkey
oCollapsedWindows := []			; a stack object for collapsed windows
Loop, %A_WinDir%\Media\*.wav	; find the sound file to play when the window gets un/folded
	if InStr(A_LoopFileName, "Information Bar") {
		sSoundFile := A_LoopFileLongPath
		Break
	}
Return

CollapseWindow:
	; This label is called when the user presses the middle button of the mouse
	; If the clicked area is not the title bar, just return
	if !IsCursorOnWindowTopBorder(hWndActive := WinExist("A")) 
		Return
	
	SoundPlay, % sSoundFile
	WinGetPos,,,, nWndActiveH, ahk_id %hWndActive%		; Retrieve the current height of the active window.
	WinGet, nStyle, Style, ahk_id %hWndActive%		
	if !oCollapsedWindows[hWndActive] {
		; Collapse the window
		; Resizable window -> 0 Non-resizablw window -> Top-border height
		WinMove, ahk_id %hWndActive%,,,,, % (nStyle & 0x40000) ? 0 : GetTopBorderHight(hWndActive)	
		oCollapsedWindows[hWndActive] := nWndActiveH		; Store the current height
		SetTimer, WinExistCheck, 60000				; Set a timer to check stored windows still exist
	} else 
		; Unfold the window.
		WinMove, ahk_id %hWndActive%,,,,, % oCollapsedWindows.Remove(hWndActive)		; The remove method returns the stored value
Return
WinExistCheck:
	oRemove := []		; Create an object to store removing keys.
	DHW := A_DetectHiddenWindows
	DetectHiddenWIndows, On
	For hWnd in oCollapsedWindows						
		if !WinExist("ahk_id " hWnd)					; Check if the window still exists
			oRemove.Insert(hWnd)
	Loop, % oRemove.MaxIndex()
		oCollapsedWindows.Remove(oRemove[A_Index])		; Remove the item from the stack object
	DetectHiddenWindows, % DHW
	if !oCollapsedWindows.MaxIndex() 
		SetTimer,, Off								; If the stack object is empty, turn off the timer
Return
GetTopBorderHight(hWnd) {
	;[Descriptions]
	;	Retrieves the top-border height of a specified window.
	;[Parameters]
	;	hWnd:		the subject window handle.
	;[Return Value]
	;	the height of the top-border 

	; AutoHotkey Basic users should uncomment this line.
	;ptr := A_PtrSize ? "ptr" : "uint"    
	
	; Retrieve the window position.
	WinGetPos,, nWndY,,, ahk_id %hWnd%

	; Retrieve the client top-left position in screen coordinate.
	VarSetCapacity(pt, 16), NumPut(0, pt, 0), NumPut(0, pt, 4)
	DllCall("ClientToScreen", ptr, hwnd, ptr, &pt)
	nClientY := NumGet(pt, 4, "int")
	
	Return nClientY - nWndY
	
	; by A_Samurai 2012/2/16 licence: Public Domain	
}
IsCursorOnWindowTopBorder(hWnd) {
	;[Descriptions]
	;	Checks whether the position of the current mouse cursor is within the top-border of a specified window. 
	;[Parameters]
	;	hWnd:		the window handle of the subject window.
	;[Return Value]
	;	If the window is not active, it returns an empty value.
	;	Returns True if the mouse cursor is on the top-border of the specified window; otherwise, it returns False.
	
	; AutoHotkey Basic users should uncomment this line.
	;ptr := A_PtrSize ? "ptr" : "uint" 	
	
	; Check if the window is active.
	if !WinActive("ahk_id " hWnd)
		Return

	; Retrieve the window position and the width.
	WinGetPos, nWndX, nWndY, nWndW,, ahk_id %hWnd%

	; Retrieve the client top-left position in screen coordinate.
    VarSetCapacity(pt, 16), NumPut(0, pt, 0), NumPut(0, pt, 4)
    DllCall("ClientToScreen", ptr, hwnd, ptr, &pt)
    nClientX := NumGet(pt, 0, "int") ,	nClientY := NumGet(pt, 4, "int")		

	; Calculate the top-border height.
	nBorderTopH := nClientY - nWndY

	; Retrieve the mouse cursor position and convert it to be window relative.
	VarSetCapacity(pos, 8), DllCall("GetCursorPos", ptr, &pos)
	nCursorX := NumGet(pos, 0, "int") , nCursorY := NumGet(pos, 4, "int")
	nCursorX := nCursorX - nWndX, nCursorY := nCursorY - nWndY

	; Return True if the cursor is on the top-border of the window. 
	if (nCursorX >= 0) && (nCursorY >= 0) && (nCursorX <= nWndW) && (nCursorY <= nBorderTopH)
		Return True
	Else
		Return False
		
	; by A_Samurai 2012/2/16 licence: Public Domain		
}
```

[![Alt OnClientArea](http://lh3.googleusercontent.com/-elaewTbKqOQ/Tz2ZbT3QytI/AAAAAAAAAZg/X22b7RF2EF0/s288/CollapseWindow01.jpg)](http://picasaweb.google.com/lh/photo/UNSICF0SOYER0tAambsWwlC3SJHtXOU11nyieEYZgDY?feat=directlink)
[![Alt NotOnClientArea](http://lh3.googleusercontent.com/-LJzlp88SEjc/Tz2ZbgG3lrI/AAAAAAAAAZc/vXBW5CUwIXk/s288/CollapseWindow02.jpg)](http://picasaweb.google.com/lh/photo/e8egb-kYuTbQrMWXoGDFzFC3SJHtXOU11nyieEYZgDY?feat=directlink)