Detect If Cursor is on Specified Window's Client Area

When writing a program which requires the user to intract with a Gui window, sometimes it needs to check whether the mouse cursor is on the client area of the window. 

Originally I wrote this function to detect if the user released a dragging control onto a script Gui window's client area for when I could not receive the WM_LBUTTONUP message accurately. However, it could be extended to other application windows by specifying the window handle. 

The following example periodically checks if the cursor is on the client area of a Notepad window.

```ahk:IsMouseOverClientArea.ahk
#Persistent
Run, notepad,,, nPIDNotepad
WinWait, ahk_pid %nPIDNotepad%
hWndNotepad := WinExist("ahk_pid " nPIDNotepad)
SetTimer, CheckCursorPos, 100
Return

CheckCursorPos:
	tooltip % "IsMouseOverClientArea: " IsMouseOverClientArea(hWndNotepad)
Return

IsMouseOverClientArea(hWnd, nOption=0) {
	;[Descriptions]
	;	Checks whether the current mouse cursor is within the client area of a specified window. 
	;	It can check even if the window is inactive or overlapped by other windows. 
	;[Parameters]
	;	hWnd:		the window handle of the subject window.
	;	nOption:	
	;		0: 		the normal mode.
	;		1: 		if the window is not active, the function returns an empty value.
	;[Return Value]
	;	If the window does not exist, it returns an empty value.
	;	Returns 1 if the mouse cursor is over the client area of the specified window; otherwise, it returns 0.
	
	; AutoHotkey Basic users should uncomment this line.
	;ptr := ptr ? "ptr" : "uint" 	
	
	; Check if the window exists.
	if !WinExist("ahk_id " hWnd)
		Return
	
	; if the option is set to 1, check if the window is active.
	if (nOption = 1) && !WinActive("ahk_id " hWnd)
		Return
		
	; Retrieve the window position and convert it to 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")
	
	; Retrieve the size of client area of the window.
    VarSetCapacity(rc, 16), DllCall("GetClientRect", ptr, hwnd, ptr, &rc)
	nClientW := NumGet(rc, 8, "int") , nClientH := NumGet(rc, 12, "int")	
	
	; Retrieve the mouse cursor position in screen coordinates. 
	; Use the GetCursorPos API function in order not to affect the coord mode of the script.
	VarSetCapacity(pos, 8), DllCall("GetCursorPos", ptr, &pos)
	nCursorX := NumGet(pos, 0, "int") , nCursorY := NumGet(pos, 4, "int")
	
	; Return True if the cursor is in the client are of the window.
	nCursorX := nCursorX - nClientX, nCursorY := nCursorY - nClientY		; Convert it to be client relative
	if (nCursorX >= 0) && (nCursorY >= 0) && (nCursorX <= nClientW) && (nCursorY <= nClientH)
		Return True
	else
		Return False
		
	; by A_Samurai 2012/2/16 licence: Public Domain	
}
```

[![Alt OnClientArea](http://lh3.googleusercontent.com/-A6MS3zlZkKA/Tz0DeaDUmaI/AAAAAAAAAYg/J4eqn6GWKNQ/s288/IsMouseOverClientArea01.jpg)](http://picasaweb.google.com/lh/photo/0ABTxnvg9lCeVqDGgU1JPFC3SJHtXOU11nyieEYZgDY?feat=directlink)
[![Alt NotOnClientArea](https://lh5.googleusercontent.com/-bCyOvZAVB6Y/Tz0DeT5W92I/AAAAAAAAAYc/fk6sCXloFSY/s288/IsMouseOverClientArea02.jpg)](http://picasaweb.google.com/lh/photo/DtfuD1fiB40XFP8Wyxy5hlC3SJHtXOU11nyieEYZgDY?feat=directlink)