﻿;-- TIME_STAMP   2021-01-24 00:07:11   v 0.2

#cs

• MinMax handling for resizeable windows
• Choose to set MinMax values for client- or window- size

----------------------------------------------------------------------------------------------------
Function List

_GuiMM_SetMinMax
	Sets the MinMax parameters for a window and register this for MinMax handling, if not done with other function.

_GuiMM_GetMinMax
	Returns an array with the min/max settings. [wMin, hMin, wMax, hMax, bMinimizeToMinSize, bModeWindow]

_GuiMM_Unregister
	Unregisters a window from MinMax handling

----------------------------------------------------------------------------------------------------

"_GuiMM_SetMinMax" allows the complete setting of all possible parameters at once.
The following functions can be used to set or change single parameters.

_GuiMM_SetMin
	Sets the minimum size parameters for a window and register this, if not done before

_GuiMM_SetMax
	Sets the maximum size parameters for a window and register this, if not done before

_GuiMM_SetMinimizeToMin
	Sets the behaviour of the Minimize-Button. Minimize to: Minimium Size (True)/ Taskbar(False-Default)

_GuiMM_SetWindowMode
	Sets the min/max handling by size of client or window. Client (False - Default) or Window (True)

----------------------------------------------------------------------------------------------------

For Debugging:

_GuiMM_DebugRegister
	Registers input IDs to receive the current window and/or client size

----------------------------------------------------------------------------------------------------
#ce



#include-once
#include <WinAPISysWin.au3>
#include <WindowsConstants.au3>


Opt('MustDeclareVars', 1)
OnAutoItExitRegister("__GuiMM_CleanUp")


Global $g_hMinMaxHook, $g_hMinMaxProc = Null
Global $g_aGuiMinMax[100][9] = [[0]] ; [[counter],[hWnd,widthMin,heightMin,widthMax,heightMax,bMinimizeToMinSize,bMinimized,tCurrPos,bModeWindow], ..]

Global $g_debugID_sizeW = Null  ; for debug: ID that receives the current window size
Global $g_debugID_sizeC = Null  ; for debug: ID that receives the current client size

;===================================================================================================
; Possible values for all min/max in _GuiMM_Set.. functions:
;
;  -1     Uses the current width/height.
;   0     The MinMax handling will ignored from this parameter.
;  Null   The already stored value will used. If not has done from User, the default value (0) will used.
;===================================================================================================
;
;===================================================================================================
; Function Name....: _GuiMM_SetMinMax
; Description......: Sets the MinMax parameters for a window and register this for MinMax handling, if not done before.
; Parameter(s).....: $_hWnd                The handle of the window
;                    $_wMin                The minimum width of the window.
;                    $_hMin                The minimum height of the window.
;                    $_wMax                The maximum width of the window.
;                    $_hMax                The maximum height of the window.
;                    $_bMinimizeToMinSize  The behaviour of the Minimize-Button. Minimize to: Minimium Size (True)/ Taskbar(False-Default)
;                    $_bModeWindow         Handles min/max values by size of client (False - Default) or window (True)
; Return Value(s)..: Success   1
;                    Failure   0 @error=1, hWnd is'nt a window handle
;                                @error=2, window is not resizeable
; Author...........: BugFix
;===================================================================================================
Func _GuiMM_SetMinMax($_hWnd, $_wMin=0, $_hMin=0, $_wMax=0, $_hMax=0, $_bMinimizeToMinSize=False, $_bModeWindow=False)
	If Not IsHWnd($_hWnd) Then Return SetError(1,0,0)
	Local $aParam[] = [$_wMin, $_hMin, $_wMax, $_hMax, $_bMinimizeToMinSize, False, _WinAPI_GetWindowRect($_hWnd), $_bModeWindow]
	Return __GuiMM_ManageWnd($_hWnd, 'setMinMax', $aParam)
EndFunc  ;==>_GuiMM_SetMinMax


;===================================================================================================
; Function Name....: _GuiMM_GetMinMax
; Description......: Returns an array with the min/max settings.
; Parameter(s).....: $_hWnd    The handle of the window
; Return Value(s)..: Success   Array [wMin, hMin, wMax, hMax, bMinimizeToMinSize, bModeWindow]
;                    Failure   set @error = 1 hWnd is'nt a window handle
;                                  @error = 2 (none registered window), empty array
; Author...........: BugFix
;===================================================================================================
Func _GuiMM_GetMinMax($_hWnd)
	If Not IsHWnd($_hWnd) Then Return SetError(1,0,0)
	Return __GuiMM_ManageWnd($_hWnd, 'getMinMax')
EndFunc  ;==>_GuiMM_GetMinMax


;===================================================================================================
; Function Name....: _GuiMM_SetMin
; Description......: Sets the minimum parameters for a window and register this, if not done before
; Parameter(s).....: $_hWnd    The handle of the window
;                    $_wMin    The minimum width of the window. -1 (Default) uses the current width.
;                    $_hMin    The minimum height of the window. -1 (Default) uses the current height.
; Return Value(s)..: Success   1
;                    Failure   0 @error = 1 hWnd is'nt a window handle
;                                @error = 2 window is not resizeable
; Author...........: BugFix
;===================================================================================================
Func _GuiMM_SetMin($_hWnd, $_wMin=-1, $_hMin=-1)
	Return _GuiMM_SetMinMax($_hWnd, $_wMin, $_hMin, Null, Null, Null)
EndFunc  ;==>_GuiMM_SetMin


;===================================================================================================
; Function Name....: _GuiMM_SetMax
; Description......: Sets the maximum parameters for a window and register this, if not done before
; Parameter(s).....: $_hWnd    The handle of the window
;                    $_wMax    The maximum width of the window. -1 (Default) uses the current width.
;                    $_hMax    The maximum height of the window. -1 (Default) uses the current height.
; Return Value(s)..: Success   1
;                    Failure   0 @error = 1 hWnd is'nt a window handle
;                                @error = 2 window is not resizeable
; Author...........: BugFix
;===================================================================================================
Func _GuiMM_SetMax($_hWnd, $_wMax=-1, $_hMax=-1)
	Return _GuiMM_SetMinMax($_hWnd, Null, Null, $_wMax, $_hMax, Null)
EndFunc  ;==>_GuiMM_SetMax


;===================================================================================================
; Function Name....: _GuiMM_SetMinimizeToMin
; Description......: Sets the behaviour of the Minimize-Button.
; Parameter(s).....: $_hWnd                The handle of the window
;                    $_bMinimizeToMinSize  Minimize to: minimium size (True-Default)/ Taskbar(False)
; Return Value(s)..: Success   1
;                    Failure   0 @error = 1 hWnd is'nt a window handle
;                                @error = 2 window is not resizeable
; Author...........: BugFix
;===================================================================================================
Func _GuiMM_SetMinimizeToMin($_hWnd, $_bMinimizeToMinSize=True)
	Return _GuiMM_SetMinMax($_hWnd, Null, Null, Null, Null, $_bMinimizeToMinSize)
EndFunc  ;==>_GuiMM_SetMinimizeToMin


;===================================================================================================
; Function Name....: _GuiMM_SetWindowMode
; Description......: Sets the min/max handling by size of client or window
; Parameter(s).....: $_hWnd           The handle of the window
;                    $_bModeWindow    Use size of: client (False - Default) or window (True)
; Return Value(s)..: Success   1
;                    Failure   0 @error = 1 hWnd is'nt a window handle
;                                @error = 2 window is not resizeable
; Author...........: BugFix
;===================================================================================================
Func _GuiMM_SetWindowMode($_hWnd, $_bModeWindow=False)
	Return _GuiMM_SetMinMax($_hWnd, Null, Null, Null, Null, Null, $_bModeWindow)
EndFunc  ;==>_GuiMM_SetWindowMode


;===================================================================================================
; Function Name....: _GuiMM_Unregister
; Description......: Unregisters a window from MinMax handling
; Parameter(s).....: $_hWnd    The handle of the window
; Return Value(s)..: Success   1
;                    Failure   0 @error = 1 hWnd is'nt a window handle
;                                @error = 2 hWnd is'nt registered
; Author...........: BugFix
;===================================================================================================
Func _GuiMM_Unregister($_hWnd)
	If Not IsHWnd($_hWnd) Then Return SetError(1,0,0)
	Return __GuiMM_ManageWnd($_hWnd, 'unRegister')
EndFunc  ;==>_GuiMM_Unregister


;===================================================================================================
; Function Name....: _GuiMM_DebugRegister
; Description......: For debugging: Registers input IDs to receive the current window and/or client size
; Parameter(s).....: $_ID_sizeW   ID to receive the window size, "-1" don't set this param
;                    $_ID_sizeC   ID to receive the client size, "-1" don't set this param
; Return Value(s)..: None
; Author...........: BugFix
;===================================================================================================
Func _GuiMM_DebugRegister($_ID_sizeW=-1, $_ID_sizeC=-1)
	If $_ID_sizeW <> -1 Then $g_debugID_sizeW = $_ID_sizeW
	If $_ID_sizeC <> -1 Then $g_debugID_sizeC = $_ID_sizeC
EndFunc  ;==>_GuiMM_DebugRegister


#Region - internal


; [[counter],[hWnd,widthMin,heightMin,widthMax,heightMax,bMinimizeToMinSize,bMinimized,tCurrPos,bModeWindow], ..]
Func __GuiMM_ManageWnd($_hWnd, $_action='getIndex', $_aParam=Null)
	Local $index = -1, $n
	Switch $_action
		Case 'getIndex'
			If $g_aGuiMinMax[0][0] = 0 Then
				Return -1
			Else
				For $i = 1 To $g_aGuiMinMax[0][0]
					If $g_aGuiMinMax[$i][0] = $_hWnd Then
						$index = $i
						ExitLoop
					EndIf
				Next
				Return $index
			EndIf
		Case 'setMinMax'
			; only resizeable windows will registered
			If Not __IsResizeable($_hWnd) Then Return SetError(2,0,0)
			$n = __GuiMM_ManageWnd($_hWnd)      ; get Index, if "-1": it's a new registered window
			__GuiMM_Set($n, $_hWnd, $_aParam)
			If $n = -1 Then
				; if it's the 1.st registered window, our own window procedure will now registered
				If $g_hMinMaxProc = Null Then $g_hMinMaxProc = DllCallbackRegister('__GuiMM_WinProc', 'ptr', 'hwnd;uint;wparam;lparam')
				; change the default window procedure to our own procedure
				$g_hMinMaxHook = _WinAPI_SetWindowLong($_hWnd, $GWL_WNDPROC, DllCallbackGetPtr($g_hMinMaxProc))
			EndIf
			Return 1
		Case 'getMinMax'
			Local $aRet[6] = [0,0,0,0,True,False]
			$index = __GuiMM_ManageWnd($_hWnd)
			If $index = -1 Then Return SetError(2,0,$aRet)
			$aRet[0] = $g_aGuiMinMax[$index][1] ; wMin
			$aRet[1] = $g_aGuiMinMax[$index][2] ; hMin
			$aRet[2] = $g_aGuiMinMax[$index][3] ; wMax
			$aRet[3] = $g_aGuiMinMax[$index][4] ; hMax
			$aRet[4] = $g_aGuiMinMax[$index][5] ; bMinimizeToMinSize
			$aRet[5] = $g_aGuiMinMax[$index][8] ; bModeWindow
			Return $aRet
		Case 'unRegister'
			$n = __GuiMM_ManageWnd($_hWnd)      ; get Index
			Return ($n = -1 ? SetError(2,0,0) : __GuiMM_UnRegister($n)) ; @error: a unregistered window cannot be removed
	EndSwitch
EndFunc  ;==>__GuiMM_ManageWnd


Func __GuiMM_Set($_index, $_hWnd, $_aParam)
	If $_index = -1 Then
		$g_aGuiMinMax[0][0] += 1
		$_index = $g_aGuiMinMax[0][0]
		If $g_aGuiMinMax[0][0] = UBound($g_aGuiMinMax) Then ReDim $g_aGuiMinMax[$g_aGuiMinMax[0][0]+100][9]
	EndIf
	Local $w = _WinAPI_GetWindowWidth($_hWnd)
	Local $h = _WinAPI_GetWindowHeight($_hWnd)
	$g_aGuiMinMax[$_index][0] = $_hWnd

	; param (min/max W/H): -1 = current W/H
	;                       0 = 0 (none min/max handling)
	;                    Null = use the already stored value
	$g_aGuiMinMax[$_index][1] = _ ; wMin
		$_aParam[0] = -1 ? $w : ($_aParam[0] <> Null ? $_aParam[0] : $g_aGuiMinMax[$_index][1])
	$g_aGuiMinMax[$_index][2] = _ ; hMin
		$_aParam[1] = -1 ? $w : ($_aParam[1] <> Null ? $_aParam[1] : $g_aGuiMinMax[$_index][2])
	$g_aGuiMinMax[$_index][3] = _ ; wMax
		$_aParam[2] = -1 ? $w : ($_aParam[2] <> Null ? $_aParam[2] : $g_aGuiMinMax[$_index][3])
	$g_aGuiMinMax[$_index][4] = _ ; hMax
		$_aParam[3] = -1 ? $w : ($_aParam[3] <> Null ? $_aParam[3] : $g_aGuiMinMax[$_index][4])
	$g_aGuiMinMax[$_index][5] = $_aParam[4] = Null ? $g_aGuiMinMax[$_index][5] : $_aParam[4]    ; bMinimizeToMinSize
	$g_aGuiMinMax[$_index][6] = $_aParam[5] = Null ? $g_aGuiMinMax[$_index][6] : $_aParam[5]    ; bMinimized
	$g_aGuiMinMax[$_index][7] = $_aParam[6] ; curr Rect
	$g_aGuiMinMax[$_index][8] = $_aParam[7] ; bModeWindow
EndFunc  ;==>__GuiMM_Set


Func __GuiMM_UnRegister($_index)
	; reset to default window procedure
	_WinAPI_SetWindowLong($g_aGuiMinMax[$_index][0], $GWL_WNDPROC, $g_hMinMaxHook)

	; move from last entry to index that should be removed
	For $i = 0 To 8
		$g_aGuiMinMax[$_index][$i] = $g_aGuiMinMax[$g_aGuiMinMax[0][0]][$i]
	Next

	; reset all entries from last used index
	For $i = 0 To 8
		If $i = 5 Or $i = 6 Or $i = 8 Then
			$g_aGuiMinMax[$g_aGuiMinMax[0][0]][$i] = False
		Else
			$g_aGuiMinMax[$g_aGuiMinMax[0][0]][$i] = 0
		EndIf
	Next

	; decrease the counter
	$g_aGuiMinMax[0][0] -= 1
	Return 1
EndFunc  ;==>__GuiMM_UnRegister


Func __GuiMM_WinProc($_hWnd, $_iMsg, $_iwParam, $_ilParam)
	If ($_iMsg <> $WM_WINDOWPOSCHANGING And $_iMsg <> $WM_WINDOWPOSCHANGED And $_iMsg <> $WM_SYSCOMMAND) Then _
		Return _WinAPI_CallWindowProc($g_hMinMaxHook, $_hWnd, $_iMsg, $_iwParam, $_ilParam)
	Local $index = __GuiMM_ManageWnd($_hWnd)
	If $index = -1 Then Return _WinAPI_CallWindowProc($g_hMinMaxHook, $_hWnd, $_iMsg, $_iwParam, $_ilParam) ; default Window processing

	Local $wMin               = $g_aGuiMinMax[$index][1]
	Local $hMin               = $g_aGuiMinMax[$index][2]
	Local $wMax               = $g_aGuiMinMax[$index][3]
	Local $hMax               = $g_aGuiMinMax[$index][4]
	Local $bMinimizeToMinSize = $g_aGuiMinMax[$index][5]
	Local $bMinimized         = $g_aGuiMinMax[$index][6]
	Local $tCurrRect          = $g_aGuiMinMax[$index][7]
	Local $bModeWindow        = $g_aGuiMinMax[$index][8]

	; if size is in client mode (NOT $bModeWindow) calculate the resulting min/max for the window
	; all calculations uses the bounding rect of the window
	If Not $bModeWindow Then
		Local $iW_Diff = _WinAPI_GetWindowWidth($_hWnd) - _WinAPI_GetClientWidth($_hWnd)
		Local $iH_Diff = _WinAPI_GetWindowHeight($_hWnd) - _WinAPI_GetClientHeight($_hWnd)
		$wMin = $wMin = 0 ? 0 : $wMin + $iW_Diff
		$wMax = $wMax = 0 ? 0 : $wMax + $iW_Diff
		$hMin = $hMin = 0 ? 0 : $hMin + $iH_Diff
		$hMax = $hMax = 0 ? 0 : $hMax + $iH_Diff
	EndIf

	If (Not $bMinimizeToMinSize) And $bMinimized Then ; now RESTORE, use size & pos from before minimized ($tCurrRect)
		$g_aGuiMinMax[$index][6] = False ; $bMinimized
		_WinAPI_SetWindowPos($_hWnd, $HWND_TOP, _
		                     $tCurrRect.Left, $tCurrRect.Top, $tCurrRect.Right - $tCurrRect.Left, $tCurrRect.Bottom - $tCurrRect.Top, _
							 BitOR($SWP_FRAMECHANGED,$SWP_NOSENDCHANGING,$SWP_SHOWWINDOW)) ; prevents 1-time from WM_WINDOWPOSCHANGING
		Return 0                         ; avoid default window processing
	EndIf
	Local $tRectWnd = _WinAPI_GetWindowRect($_hWnd)
	$g_aGuiMinMax[$index][7] = $tRectWnd ; $tCurrRect, store current rect to use for RESTORE
	Local $iW_Wnd = $tRectWnd.Right - $tRectWnd.Left
	Local $iH_Wnd = $tRectWnd.Bottom - $tRectWnd.Top
	Local $iX_Wnd = $tRectWnd.Left
	Local $iY_Wnd = $tRectWnd.Top

	If $_iMsg = $WM_SYSCOMMAND Then
		If $_iwParam = 0xF020 Then ; $SC_MINIMIZE
			If $bMinimizeToMinSize Then ; none MINIMIZE, instead move window to minimal size with current center point
				; center point of the current window position
				Local $xCenter = $iX_Wnd + Int($iW_Wnd/2)
				Local $yCenter = $iY_Wnd + Int($iH_Wnd/2)
				; if min/max = 0 ? ==> this value will not changed
				WinMove($_hWnd, '', ($wMin > 0 ? ($xCenter - Int($wMin/2)) : $iX_Wnd), _
									($hMin > 0 ? ($yCenter - Int($hMin/2)) : $iY_Wnd), _
									($wMin > 0 ? $wMin : $iW_Wnd), _
									($hMin > 0 ? $hMin : $iH_Wnd))
				__GuiMM_DebugSize($_hWnd)
				Return 0                        ; avoid default window processing
			Else                                ; the default behaviour of $SC_MINIMIZE (minimize to taskbar)
				$g_aGuiMinMax[$index][6] = True ; $bMinimized, trigger to detect the RESTORE (next window msg is the restore msg)
				Return _WinAPI_CallWindowProc($g_hMinMaxHook, $_hWnd, $_iMsg, $_iwParam, $_ilParam) ; default Window processing
			EndIf
		EndIf
	EndIf

	If $_iMsg = $WM_WINDOWPOSCHANGING Then
		Local $tWINDOWPOS = DllStructCreate("struct; HWND hwndInsertAfter;HWND hwnd;INT x;INT y;INT cx;INT cy;UINT flags; endstruct", $_ilParam)
		; undocumented flags: 0x8000, 0x1000 and 0x0800
		Local Const $SWP_FROZENWINDOW = 0x8000

		Local $tBorders = __GuiMM_GetBorders()
		Local $xBorderL = $tBorders.left
		Local $yBorderT = $tBorders.top
		Local $xBorderR = $tBorders.right
		Local $yBorderB = $tBorders.bottom
		; min/max = 0 ? ==> none min/max handling for this value, set to 0/real borders
		$wMin = $wMin = 0 ? 0 : $wMin
		$hMin = $hMin = 0 ? 0 : $hMin
		$wMax = $wMax = 0 ? ($xBorderR - $xBorderL) : $wMax
		$hMax = $hMax = 0 ? ($yBorderB - $yBorderT) : $hMax

		Local $aMaxPos = __GuiMM_MaxPosCalc($wMax, $hMax, $iX_Wnd + Int($iW_Wnd/2), $iY_Wnd + Int($iH_Wnd/2))
		If $tWINDOWPOS.cx < $wMin Then  ; target width too small
			$tWINDOWPOS.cx = $wMin      ; set to min
			$tWINDOWPOS.x = $iX_Wnd     ; keep the current x value
		EndIf
		If $tWINDOWPOS.cy < $hMin Then  ; target height too small
			$tWINDOWPOS.cy = $hMin      ; set to min
			$tWINDOWPOS.y = $iY_Wnd     ; keep the current y value
		EndIf
		If $tWINDOWPOS.cx > $wMax Then  ; target width too large
			$tWINDOWPOS.cx = $wMax      ; set to max
			$tWINDOWPOS.x = $aMaxPos[0] ; calculated by current center position
		EndIf
		If $tWINDOWPOS.cy > $hMax Then  ; target height too large
			$tWINDOWPOS.cy = $hMax      ; set to max
			$tWINDOWPOS.y = $aMaxPos[1] ; calculated by current center position
		EndIf
		If (BitAND($tWINDOWPOS.flags, $SWP_FROZENWINDOW)) Then _WinAPI_ShowWindow($_hWnd, @SW_RESTORE)

		Return 0 ; avoid default window processing
	EndIf

	If $_iMsg = $WM_WINDOWPOSCHANGED Then
		__GuiMM_DebugSize($_hWnd)
	EndIf
	Return _WinAPI_CallWindowProc($g_hMinMaxHook, $_hWnd, $_iMsg, $_iwParam, $_ilParam) ; default Window processing
EndFunc  ;==>__GuiMM_WinProc


Func __GuiMM_MaxPosCalc($_wMax, $_hMax, $_xCenter, $_yCenter)
	Local $tBorders = __GuiMM_GetBorders()
	Local $xBorderL = $tBorders.left
	Local $yBorderT = $tBorders.top
	Local $xBorderR = $tBorders.right
	Local $yBorderB = $tBorders.bottom

	; Try to use the same center point. If there is an overlap with the taskbar or desktop border, the position will be corrected
	Local $xMax = $_xCenter - (Int($_wMax/2))
	If $xMax < 0 Then
		$xMax = $xBorderL
	Else
		If $xMax + $_wMax > $xBorderR Then $xMax = $xBorderR - $_wMax
	EndIf
	Local $yMax = $_yCenter - (Int($_hMax/2))
	If $yMax < 0 Then
		$yMax = $yBorderT
	Else
		If $yMax + $_hMax > $yBorderB Then $yMax = $yBorderB - $_hMax
	EndIf
	Local $aRet[] = [$xMax,$yMax]
	Return $aRet
EndFunc  ;==>__GuiMM_MaxPosCalc


Func __GuiMM_GetBorders()
	Local Static $tBorders = DllStructCreate('struct;int left;int top;int right;int bottom;endstruct')
	Local Static $xBorderL = 0
	Local Static $yBorderT = 0
	Local Static $xBorderR = @DesktopWidth
	Local Static $yBorderB = @DesktopHeight

	; get Taskbar properties
	Local $tTB = _GetTaskBarProps(True)
	; if always on top: calculate borders
	If Not $tTB.autohide Then  ; .uEdge  0, 1, 2, 3 = 'LEFT', 'TOP', 'RIGHT', 'BOTTOM'
		If $tTB.uEdge = 0 Then $xBorderL  = ($tTB.right  - $tTB.left) ; left   (width of TB)
		If $tTB.uEdge = 1 Then $yBorderT  = ($tTB.bottom - $tTB.top)  ; top    (height of TB)
		If $tTB.uEdge = 2 Then $xBorderR -= ($tTB.right  - $tTB.left) ; right  (desk width - width of TB)
		If $tTB.uEdge = 3 Then $yBorderB -= ($tTB.bottom - $tTB.top)  ; bottom (desk height - height of TB)
	EndIf
	$tBorders.left   = $xBorderL
	$tBorders.top    = $yBorderT
	$tBorders.right  = $xBorderR
	$tBorders.bottom = $yBorderB

	Return $tBorders
EndFunc  ;==>__GuiMM_GetBorders


Func __GuiMM_CleanUp()
	If $g_hMinMaxProc = Null Then Return
	For $i = 1 To $g_aGuiMinMax[0][0]  ; reset to default window procedure
		If WinExists($g_aGuiMinMax[$i][0]) Then _WinAPI_SetWindowLong($g_aGuiMinMax[$i][0], $GWL_WNDPROC, $g_hMinMaxHook)
	Next
    DllCallbackFree($g_hMinMaxProc)
EndFunc  ;==>__GuiMM_CleanUp


Func __IsResizeable($_hWnd)
	Return (BitAND(_WinAPI_GetWindowLong($_hWnd, -16), 0x00040000) = 0x00040000)
EndFunc  ;==>__IsResizeable


Func __GuiMM_DebugSize($_hWnd)
	If $g_debugID_sizeW <> Null Then
		Local $tW = _WinAPI_GetWindowRect($_hWnd)
		GUICtrlSetData($g_debugID_sizeW, __RectToStr($tW))
	EndIf
	If $g_debugID_sizeC <> Null Then
		Local $tC = _WinAPI_GetClientRect($_hWnd)
		GUICtrlSetData($g_debugID_sizeC, __RectToStr($tC))
	EndIf
EndFunc  ;==>__GuiMM_DebugSize


Func __RectToStr($_tRect)
	Return StringFormat('%d, %d, %d, %d', $_tRect.left, $_tRect.top, $_tRect.right, $_tRect.bottom)
EndFunc  ;==>__RectToStr



#EndRegion - internal


;===================================================================================================
; Function Name....: _GetTaskBarProps
; Description......: gibt Eigenschaften und Position der Taskbar zurück
; Parameter(s).....: [optional] $_bReturnStruct - Rückgabe als (True) Struktur, (False - Standard) Array
; Return Value(s)..: Array / Struktur mit den Taskbarwerten
; Author...........: BugFix
;===================================================================================================
Func _GetTaskBarProps($_bReturnStruct=False)
	Local Const $ABM_GETSTATE = 0x4         ; specify the cbSize.
	Local Const $ABM_GETTASKBARPOS = 0x5    ; specify the cbSize.
	Local Const $ABM_GETAUTOHIDEBAR = 0x7   ; specify the cbSize and uEdge. Returns the handle to the autohide appbar

	; ABM_GETSTATE
	Local Const $ABS_AUTOHIDE = 0x1
	Local Const $ABS_ALWAYSONTOP = 0x2  ; ab Win7 nicht mehr!! --> wenn NICHT $ABS_AUTOHIDE ist es $ABS_ALWAYSONTOP

	; uEdge - ABM_GETAUTOHIDEBAR
	Local Const $ABE_LEFT = 0
	Local Const $ABE_TOP = 1
	Local Const $ABE_RIGHT = 2
	Local Const $ABE_BOTTOM = 3

	Local $hWndAppBar = DllCall("user32.dll", 'long', "FindWindowA", 'str', "Shell_traywnd", 'str', "")[0]
	Local $iState, $iEdge, $hWnd, $shell32 = DllOpen("shell32")
	Local $tRC = DllStructCreate("struct;int left;int top;int right;int bottom;endstruct")
	Local $tAPPBARDATA = DllStructCreate("dword cbSize;int hWnd;uint;uint uEdge;int left;int top;int right;int bottom;int")
	$tAPPBARDATA.cbSize = DllStructGetSize($tAPPBARDATA)
	$tAPPBARDATA.hWnd = $hWndAppBar

	; get pos
	Local $ret = DllCall($shell32, 'int', 'SHAppBarMessage', 'int', $ABM_GETTASKBARPOS, 'ptr', DllStructGetPtr($tAPPBARDATA))
	For $i = 1 To 4
		DllStructSetData($tRC, $i, DllStructGetData($tAPPBARDATA, $i+4))
	Next

	; get state
	$ret = DllCall($shell32, 'int', 'SHAppBarMessage', 'int', $ABM_GETSTATE, 'ptr', DllStructGetPtr($tAPPBARDATA))
	$iState = $ret[0]

	; get Edge
	If $iState = $ABS_AUTOHIDE Then
		For $i = $ABE_LEFT To $ABE_BOTTOM
			$tAPPBARDATA.uEdge = $i
			$ret = DllCall($shell32, 'int', 'SHAppBarMessage', 'int', $ABM_GETAUTOHIDEBAR, 'ptr', DllStructGetPtr($tAPPBARDATA))
			$hWnd = $ret[0]
			If $hWnd Then
				$iEdge = $i
				ExitLoop
			EndIf
		Next
	Else
		If $tRC.top < 1 And $tRC.left < 1 Then
				If $tRC.bottom > $tRC.right Then $iEdge = 0
				If $tRC.right > $tRC.bottom Then $iEdge = 1
		ElseIf $tRC.top < 1 And $tRC.left > 0 Then
			$iEdge = 2
		Else
			$iEdge = 3
		EndIf
	EndIf
	DllClose($shell32)

	; return array or structure: [.hWnd, .autohide(True/False), .uEdge(0..3), .sEdge(left..bottom), .left, .top, .right, .bottom]
	Local $aEdge[] = ['LEFT','TOP','RIGHT','BOTTOM']
	Local $aRet[] = [$hWndAppBar, ($iState = $ABS_AUTOHIDE), $iEdge, $aEdge[$iEdge], $tRC.left, $tRC.top, $tRC.right, $tRC.bottom]
	Local $tRet = DllStructCreate('int hWnd;bool autohide;uint uEdge;char sEdge[' & StringLen($aEdge[$iEdge]) & '];int left;int top;int right;int bottom;')
	For $i = 0 To UBound($aRet) -1
		DllStructSetData($tRet, $i+1, $aRet[$i])
	Next

	Return ($_bReturnStruct ? $tRet : $aRet)
EndFunc  ;==>_GetTaskBarProps
