Sign in to follow this  
Followers 0

GUIFrame UDF - Melba23 version - 19 May 14

141 posts in this topic

Posted (edited)

[NEW VERSION] - 19 May 14

Added:

- 1. A new function _GUIFrame_ResizeState to indicate when frames have been resized and the resizing is complete. The idea is to help users who fill frames with elements which require heavy processing (e.g. GDI images) and where continually rewriting the content would cause severe slowdowns. The function is called in the script idle loop and returns an array of flags indicating that a resizing action is complete.

- 2. A new parameter ($fShowWindow) in the _GUIFrame_Create function. A few people have found that the frames do not always appear on creation - particularly if the GUI does not have focus during this process. KaFu came up with a workaround, not approved by the AutoIt devs, using the API to confirm the frame display. Setting this new parameter to True uses the API call - use it at your own risk and peril!

Fixed: A couple of minor bugs which no-one had noticed - and now never will. :)

New code below and in the attached zip. :)

Previous changes: Changelog.txt


Before we start, my sincere thanks to Kip who wrote the first version of this UDF and who very kindly allowed me to build on it to produce this new version. ;)

Many GUIs are divided into frames, where you can drag a separator bar to alter the relative sizes of the elements displayed within the GUI. Think of an Explorer window where the folder list is on one side and the files in the selected folder on the other - or SciTE with its editing and Director areas.

The GUIFrame UDF allows you to divide your own GUIs into 2 frames with a separator bar.

- The frames can be full-frame or set to a user-defined position and size within the GUI.

- The minimum size of each frame can be specified.

- The separator bar can be horizontal or vertical and its size and initial position set.

- The frames can resize as the main GUI resizes or can remain at their original position and size.

- You can even divide existing frames into further frames until you run out of space.

- x86 and x64 compatible. [New]

The frames themselves are normal AutoIt GUIs. You can colour them and create controls within them just as you would in any other script - functions are provided for easy navigation between them (think of GUISwitch).

Here is an example script to show the UDF working:

#include <guiconstantsex.au3>
#include <windowsconstants.au3>

#include "GUIFrame.au3"

Global $iSep_Pos

$hGUI = GUICreate("GUI_Frame Example 1", 500, 500, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX))
GUISetState()

; Create a 1st level frame
$iFrame_A = _GUIFrame_Create($hGUI)
_GUIFrame_SetMin($iFrame_A, 50, 100)

_GUIFrame_Switch($iFrame_A, 2)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_A, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0xFF0000)
GUICtrlSetState(-1, $GUI_DISABLE)
$hButton_1 = GUICtrlCreateButton("Pos Sep", 10, 10, 50, 30)

; Create a 2nd level frame
$iFrame_B = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_A, 1), 1)
GUISetBkColor(0x00FF00, _GUIFrame_GetHandle($iFrame_B, 1))
_GUIFrame_SetMin($iFrame_B, 100, 100)

_GUIFrame_Switch($iFrame_B, 1)
$hButton_2 = GUICtrlCreateButton("Pos Sep", 10, 10, 50, 30)

; Create a 3rd level frame
$iFrame_C = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_B, 2))
_GUIFrame_Switch($iFrame_C, 2)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_C, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0xD0D000)

; Create a 4th level frame
$iFrame_D = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_C, 1), 1)
_GUIFrame_Switch($iFrame_D, 1)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_D, 1))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0x00FFFF)
_GUIFrame_Switch($iFrame_D, 2)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_D, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0xFF00FF)

; Set resizing flag for all created frames
_GUIFrame_ResizeSet(0)

; Create a non-resizable 2nd level frame
$iFrame_E = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_B, 1), 0, 0, 5, 5, 55, 200, 100)
_GUIFrame_Switch($iFrame_E, 1)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_E, 1))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0xFF8000)
_GUIFrame_Switch($iFrame_E, 2)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_E, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0xD0C0D0)

; Register the $WM_SIZE handler to permit resizing
_GUIFrame_ResizeReg()

While 1

	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			; The UDF does all the tidying up as you exit
			Exit
		Case $hButton_1
			_GUIFrame_SetSepPos($iFrame_A, 300)
			$iSep_Pos = _GUIFrame_GetSepPos($iFrame_A)
			GUICtrlSetData($hButton_1, $iSep_Pos)
			Sleep(1000)
			GUICtrlSetData($hButton_1, "Sep Pos")
		Case $hButton_2
			$iRet = _GUIFrame_SetSepPos($iFrame_B, 310)
			$iSep_Pos = _GUIFrame_GetSepPos($iFrame_
			GUICtrlSetData($hButton_2, $iSep_Pos)
			Sleep(1000)
			GUICtrlSetData($hButton_2, "Sep Pos")
	EndSwitch

WEnd
The UDF uses the WM_SIZE message sent by the original GUIs to determine when to resize frames. If you want to register the same message within your script, you can still use this UDF. All you have to do is call a specific UDF function within your own message handler, as you can see here:

#include <guiconstantsex.au3>
#include <windowsconstants.au3>

#include "GUIFrame.au3"

Global $iSep_Pos

$hGUI = GUICreate("GUI_Frame Example 2", 500, 500, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX))
GUISetState()

; Register WM_SIZE to simulate the script requiring it
GUIRegisterMsg($WM_SIZE, "_WM_SIZE")

; Create a 1st level frame
$iFrame_A = _GUIFrame_Create($hGUI)
_GUIFrame_SetMin($iFrame_A, 50, 100)

_GUIFrame_Switch($iFrame_A, 2)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_A, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0xFF0000)
GUICtrlSetState(-1, $GUI_DISABLE)
$hButton_1 = GUICtrlCreateButton("Sep Pos", 10, 10, 50, 30)

; Create a 2nd level frame
$iFrame_B = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_A, 1), 1)
GUISetBkColor(0x00FF00, _GUIFrame_GetHandle($iFrame_B, 1))
_GUIFrame_SetMin($iFrame_B, 100, 100)

_GUIFrame_Switch($iFrame_B, 1)
$hButton_2 = GUICtrlCreateButton("Pos Sep", 10, 10, 50, 30)

; Create a 3rd level frame
$iFrame_C = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_B, 2))
_GUIFrame_Switch($iFrame_C, 2)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_C, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0xD0D000)

; Create a 4th level frame
$iFrame_D = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_C, 1), 1)
_GUIFrame_Switch($iFrame_D, 1)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_D, 1))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0x00FFFF)
_GUIFrame_Switch($iFrame_D, 2)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_D, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0xFF00FF)

; Set resizing flag for all created frames
_GUIFrame_ResizeSet(0)

; Create a non-resizable 2nd level frame
$iFrame_E = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_B, 1), 0, 0, 5, 5, 55, 200, 100)
_GUIFrame_Switch($iFrame_E, 1)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_E, 1))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0xFF8000)
_GUIFrame_Switch($iFrame_E, 2)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_E, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0xD0C0D0)

; DO NOT Register the $WM_SIZE handler to permit resizing as the message is already registered
;_GUIFrame_ResizeReg()

While 1

	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			; The UDF does all the tidying up as you exit
			Exit
		Case $hButton_1
			_GUIFrame_SetSepPos($iFrame_A, 300)
			$iSep_Pos = _GUIFrame_GetSepPos($iFrame_A)
			GUICtrlSetData($hButton_1, $iSep_Pos)
			Sleep(1000)
			GUICtrlSetData($hButton_1, "Sep Pos")
		Case $hButton_2
			$iRet = _GUIFrame_SetSepPos($iFrame_B, 310)
			$iSep_Pos = _GUIFrame_GetSepPos($iFrame_
			GUICtrlSetData($hButton_2, $iSep_Pos)
			Sleep(1000)
			GUICtrlSetData($hButton_2, "Sep Pos")
	EndSwitch

WEnd

; This is the already registered WM_SIZE handler
Func _WM_SIZE($hWnd, $iMsg, $wParam, $lParam)

	; Just call the GUIFrame resizing function here - do NOT use the _GUIFrame_ResizeReg function in the script
	_GUIFrame_SIZE_Handler($hWnd, $iMsg, $wParam, $lParam)

	Return "GUI_RUNDEFMSG"

EndFunc   ;==>_WM_SIZE
An example to show how to set absolute/relative minimum frame sizes and the different behaviours available on GUI resizing:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

#include "GUIFrame.au3"

Global $iSep_Pos

$hGUI = GUICreate("GUI_Frame Example 3", 500, 500, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX))
GUISetState()

; Create a 1st level frame
$iFrame_A = _GUIFrame_Create($hGUI, 1)
_GUIFrame_SetMin($iFrame_A, 50, 125, True) ; This line sets the minima as absolute values <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;_GUIFrame_SetMin($iFrame_A, 50, 125) ; This line adjusts the minima to equivalent percentages on resizing <<<<<<<<<<<<<<<<<<<<<

_GUIFrame_Switch($iFrame_A, 1)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_A, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0x00FF00)
GUICtrlCreateLabel("", 0, 0, 50, 50)
GUICtrlSetBkColor(-1, 0x0000FF)
GUICtrlSetResizing(-1, $GUI_DOCKSIZE)
GUICtrlSetState(-1, $GUI_DISABLE)

_GUIFrame_Switch($iFrame_A, 2)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_A, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetBkColor(-1, 0xFF0000)
GUICtrlSetState(-1, $GUI_DISABLE)

; Set resizing flag for all created frames
_GUIFrame_ResizeSet(0, 2) ; Adjust the second parameter to change the resizing behaviour <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; Register the $WM_SIZE handler to permit resizing
_GUIFrame_ResizeReg()

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			; The UDF does all the tidying up as you exit
			Exit
	EndSwitch
WEnd
[New] An example to show the resizing callback in action:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

#include "GUIFrame.au3"

$hGUI = GUICreate("GUI_Frame Example #", 500, 500, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX))
GUISetState()

; Create a 1st level frame
$iFrame_A = _GUIFrame_Create($hGUI)
_GUIFrame_SetMin($iFrame_A, 50, 100)

; Create a 2nd level frame
$iFrame_B = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_A, 1), 1)
GUISetBkColor(0xCCFFCC, _GUIFrame_GetHandle($iFrame_B, 1))

_GUIFrame_Switch($iFrame_B, 2)
$cSetSize = GUICtrlCreateButton("Set Sep", 10, 10, 80, 30)

; Create another 2nd level frame
$iFrame_C = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_A, 2), 1)
GUISetBkColor(0xCCCCFF, _GUIFrame_GetHandle($iFrame_C, 2))

; Set resizing flag for all created frames
_GUIFrame_ResizeSet(0)

; Register the WM_SIZE handler
_GUIFrame_ResizeReg()

While 1

	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			; The UDF does all the tidying up as you exit
			Exit
		Case $cSetSize
			; Set separator position
			_GUIFrame_SetSepPos($iFrame_B, 100)
	EndSwitch

	; Get resize flags
	$aResize = _GUIFrame_ResizeState()
	; If a frame has been resized then the [0] element = 1
	If $aResize[0] Then _Check_Frames($aResize)

WEnd

Func _Check_Frames($aFlags)
	; Check specific frame flags
	If $aFlags[$iFrame_B] And $aFlags[$iFrame_C] Then
		MsgBox(0, "Resize", "Green and blue areas have been resized")
	Elseif $aFlags[$iFrame_B] Then
		MsgBox(0, "Resize", "Green area has been resized")
	ElseIf $aFlags[$iFrame_C] Then
		MsgBox(0, "Resize", "Blue area has been resized")
	EndIf
EndFunc
[New] Here is the GUIFrame UDF itself:

#include-once
; #INDEX# ============================================================================================================
; Title .........: GUIFrame
; AutoIt Version : 3.3 +
; Language ......: English
; Description ...: Splits a GUI into slideable and resizable 2 part frames which can be further split if required
; Remarks .......: - The UDF uses OnAutoItExitRegister to call _GUIFrame_Exit to delete subclassed separator bars
;                    using the UDF created WndProc and to release the Callback on exit
;                  - The UDF can indicate when a specific fram has been resized
;                  - If the script already has a WM_SIZE message handler then do NOT use _GUIFrame_ResizeReg,
;                    but call the _GUIFrame_SIZE_Handler function from within the existing handler
; Author ........: Original UDF by Kip
; Modified ......; This version by Melba23 - using x64 compatible code drawn from Yashied's WinAPIEx library
; ====================================================================================================================

; #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

; #INCLUDES# =========================================================================================================
#include <WinAPI.au3>

; #GLOBAL VARIABLES# =================================================================================================

; Array to hold handles for each frame set
Global $aGF_HandleIndex[1][8] = [[0, 0, 0]]
; [0][0] = 0 ; Count of frames      [0][1] = Move registered flag
;
; [n][0] = Parent GUI handle        [n][4] = Original GUI handle
; [n][1] = First frame handle       [n][5] = Indices of first frame internal frames
; [n][2] = Second frame handle      [n][6] = Indices of second frame internal frames
; [n][3] = Separator bar handle		[n][7] = Frame resize flag

; Array to hold sizing percentages for each frame set
Global $aGF_SizingIndex[1][8]
; [n][0] = First frame min      [n][2] = X coord    [n][4] = Width		[n][6] = Seperator percentage position
; [n][1] = Second frame min     [n][3] = Y coord    [n][5] = Height		[n][7] = Resize type (0/1/2)

; Array to hold other settings for each frame set
Global $aGF_SettingsIndex[1][3]
; [n][0] = Separator orientation (vert/horz = 0/1)
; [n][1] = Resizable frame flag (0/1)
; [n][2] = Separator size (default = 5)

; Array to hold WinProc handles for each separator
Global $aGF_SepProcIndex[1][2] = [[0, 0]]

; Store registered Callback handle
Global $hGF_RegCallBack = DllCallbackRegister("_GUIFrame_SepWndProc", "lresult", "hwnd;uint;wparam;lparam")
$aGF_SepProcIndex[0][1] = DllCallbackGetPtr($hGF_RegCallBack)

; #ONAUTOITEXIT FUNCTIONS# ===========================================================================================
OnAutoItExitRegister("_GUIFrame_Exit")

; #CURRENT# ==========================================================================================================
; _GUIFrame_Create:       Splits a GUI into 2 frames
; _GUIFrame_SetMin:       Sets minimum sizes for each frame
; _GUIFrame_ResizeSet:    Sets resizing flag for all or specified frame sets
; _GUIFrame_GetHandle:    Returns the handle of a frame element (required for further splitting)
; _GUIFrame_Switch:       Sets a frame element as current GUI
; _GUIFrame_GetSepPos:    Returns the current position of the separator
; _GUIFrame_SetSepPos:    Moves the separator bar to adjust frame sizes
; _GUIFrame_ResizeState:  Returns the resize state of the frames
; _GUIFrame_ResizeReg:    Registers WM_SIZE message for resizing
; _GUIFrame_SIZE_Handler: WM_SIZE message handler to resize frames using _GUIFrame_Move
; ====================================================================================================================

; #INTERNAL_USE_ONLY#=================================================================================================
; _GUIFrame_SepSubClass:   Sets new WndProc for frame separator bar
; _GUIFrame_SepWndProc:    New WndProc for frame separator bar
; _GUIFrame_SepPassMsg:    Passes Msg to original frame WndProc for action
; _GUIFrame_Move:          Moves and resizes frame elements and separator bars
; _GUIFrame_Exit:          Deletes all subclassed separator bars to free UDF WndProc and frees registered callback handle
; ====================================================================================================================

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_Create
; Description ...: Splits a GUI into 2 frames
; Syntax.........: _GUIFrame_Create($hWnd, $iSepOrient = 0, $iSepPos = 0, $iSepSize = 5, $iX = 0, $iY = 0, $iWidth = 0, $iHeight = 0, $iStyle = 0, $iExStyle = 0, $fShowWindow)
; Parameters ....: $hWnd - Handle of GUI to split
;                  $iSepOrient - Orientation of separator bar: 0 = Vertical (default), 1 = Horizontal
;                  $iSepPos - Required initial position of separator (default = centre of frame GUI)
;                  $iSepSize - Size of separator bar (default = 5, min = 3, max = 9)
;                  $iX - Left of frame area (default = 0)
;                  $iY - Top of frame area (default = 0)
;                  $iWidth - Width of frame area (default = full width)
;                  $iHeight - Height of frame area (default = full height)
;                  SiStyle - Required style value for frame elements
;                  SiExStyle - Required extended style value for frame elements
;                  $fShowWindow - True = Use API call to display frame if not displayed on start
;                               - False (default) - Do not use API call
; Requirement(s).: v3.3 +
; Return values .: Success:  Returns index number of frame/separator set
;                  Failure:  Returns 0 and sets @error as follows:
;                  1 = Deprecated
;                  2 = GUI creation failed
;                  2 = Separator subclassing failed
; Author ........: Kip
; Modified ......: Melba23
; Remarks .......:
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_Create($hWnd, $iSepOrient = 0, $iSepPos = 0, $iSepSize = 5, $iX = 0, $iY = 0, $iOrg_Width = 0, $iOrg_Height = 0, $iStyle = 0, $iExStyle = 0, $fShowWindow = False)

	Local $iSeperator_Pos, $hSeparator, $hFirstFrame, $hSecondFrame, $nSepPercent

	; Set separator size
	Local $iSeparatorSize = 5
	Switch $iSepSize
		Case 3 To 9
			$iSeparatorSize = $iSepSize
	EndSwitch

	; Set default sizing if no parameters set
	Local $iWidth = $iOrg_Width
	Local $iHeight = $iOrg_Height
	Local $aFullSize = WinGetClientSize($hWnd)
	If Not $iOrg_Width Then $iWidth = $aFullSize[0]
	If Not $iOrg_Height Then $iHeight = $aFullSize[1]

	; Create parent GUI within client area
	Local $hParent = GUICreate("FrameParent", $iWidth, $iHeight, $iX, $iY, BitOR(0x40000000, $iStyle), $iExStyle, $hWnd) ; $WS_CHILD
	If $fShowWindow Then _WinAPI_ShowWindow($hParent, @SW_SHOW) ; Possible fix if frames do not display on start
	GUISetState(@SW_SHOW, $hParent)

	; Confirm size of frame parent client area
	Local $aSize = WinGetClientSize($hParent)
	$iWidth = $aSize[0]
	$iHeight = $aSize[1]

	If $iSepOrient = 0 Then

		; Set initial separator position
		$iSeperator_Pos = $iSepPos
		; Adjust position if not within GUI or default set (=0)
		If $iSepPos > $iWidth Or $iSepPos < 1 Then
			$iSeperator_Pos = Round(($iWidth / 2) - ($iSeparatorSize / 2))
		EndIf
		; Create separator bar and force cursor change over separator
		$hSeparator = GUICreate("", $iSeparatorSize, $iHeight, $iSeperator_Pos, 0, 0x40000000, -1, $hParent) ;$WS_CHILD
		GUICtrlCreateLabel("", 0, 0, $iSeparatorSize, $iHeight, -1, 0x00000001) ; $WS_EX_DLGMODALFRAME
		GUICtrlSetCursor(-1, 13)
		GUISetState(@SW_SHOW, $hSeparator)
		; Create the sizable frames
		$hFirstFrame = GUICreate("", $iSeperator_Pos, $iHeight, 0, 0, 0x40000000, -1, $hParent) ;$WS_CHILD
		GUISetState(@SW_SHOW, $hFirstFrame)
		$hSecondFrame = GUICreate("", $iWidth - ($iSeperator_Pos + $iSeparatorSize), $iHeight, $iSeperator_Pos + $iSeparatorSize, 0, 0x40000000, -1, $hParent) ;$WS_CHILD
		GUISetState(@SW_SHOW, $hSecondFrame)
		; Set seperator position percentage
		$nSepPercent = $iSeperator_Pos / $iWidth

	Else

		$iSeperator_Pos = $iSepPos
		If $iSepPos > $iHeight Or $iSepPos < 1 Then
			$iSeperator_Pos = Round(($iHeight / 2) - ($iSeparatorSize / 2))
		EndIf
		$hSeparator = GUICreate("", $iWidth, $iSeparatorSize, 0, $iSeperator_Pos, 0x40000000, -1, $hParent) ;$WS_CHILD
		GUICtrlCreateLabel("", 0, 0, $iWidth, $iSeparatorSize, -1, 0x01) ; $WS_EX_DLGMODALFRAME
		GUICtrlSetCursor(-1, 11)
		GUISetState(@SW_SHOW, $hSeparator)
		$hFirstFrame = GUICreate("", $iWidth, $iSeperator_Pos, 0, 0, 0x40000000, -1, $hParent) ;$WS_CHILD
		GUISetState(@SW_SHOW, $hFirstFrame)
		$hSecondFrame = GUICreate("", $iWidth, $iHeight - ($iSeperator_Pos + $iSeparatorSize), 0, $iSeperator_Pos + $iSeparatorSize, 0x40000000, -1, $hParent) ;$WS_CHILD
		GUISetState(@SW_SHOW, $hSecondFrame)
		$nSepPercent = $iSeperator_Pos / $iHeight

	EndIf

	; Check for error creating GUIs
	If $hParent = 0 Or $hSeparator = 0 Or $hFirstFrame = 0 Or $hSecondFrame = 0 Then
		; Delete all GUIs and return error
		GUIDelete($hParent)
		GUIDelete($hSeparator)
		GUIDelete($hFirstFrame)
		GUIDelete($hSecondFrame)
		Return SetError(2, 0, 0)
	EndIf

	; Subclass the separator
	If _GUIFrame_SepSubClass($hSeparator) = 0 Then
		; If Subclassing failed then delete all GUIs and return error
		GUIDelete($hParent)
		GUIDelete($hSeparator)
		GUIDelete($hFirstFrame)
		GUIDelete($hSecondFrame)
		Return SetError(3, 0, 0)
	EndIf

	; Create new lines in the storage arrays for this frame set
	Local $iIndex = $aGF_HandleIndex[0][0] + 1
	ReDim $aGF_HandleIndex[$iIndex + 1][8]
	ReDim $aGF_SizingIndex[$iIndex + 1][8]
	ReDim $aGF_SettingsIndex[$iIndex + 1][3]

	; Store this frame set handles/variables/defaults in the new lines
	$aGF_HandleIndex[0][0] = $iIndex
	$aGF_HandleIndex[$iIndex][0] = $hParent
	$aGF_HandleIndex[$iIndex][1] = $hFirstFrame
	$aGF_HandleIndex[$iIndex][2] = $hSecondFrame
	$aGF_HandleIndex[$iIndex][3] = $hSeparator
	$aGF_HandleIndex[$iIndex][4] = $hWnd
	$aGF_HandleIndex[$iIndex][5] = 0
	$aGF_HandleIndex[$iIndex][6] = 0
	$aGF_SizingIndex[$iIndex][0] = 0
	$aGF_SizingIndex[$iIndex][1] = 0
	$aGF_SizingIndex[$iIndex][6] = $nSepPercent
	$aGF_SettingsIndex[$iIndex][0] = $iSepOrient
	$aGF_SettingsIndex[$iIndex][1] = 0
	$aGF_SettingsIndex[$iIndex][2] = $iSeparatorSize

	; Store this frame index in parent line if parent is an existing frame
	For $i = 1 To $aGF_HandleIndex[0][0] - 1
		If $aGF_HandleIndex[$i][1] = $hWnd Then
			If $aGF_HandleIndex[$i][5] = 0 Then
				$aGF_HandleIndex[$i][5] = $iIndex
			Else
				$aGF_HandleIndex[$i][5] &= "|" & $iIndex
			EndIf
			ExitLoop
		EndIf
		If $aGF_HandleIndex[$i][2] = $hWnd Then
			If $aGF_HandleIndex[$i][6] = 0 Then
				$aGF_HandleIndex[$i][6] = $iIndex
			Else
				$aGF_HandleIndex[$i][6] &= "|" & $iIndex
			EndIf
			ExitLoop
		EndIf
	Next

	; Store coordinate and size fractions
	If $iX Then
		$aGF_SizingIndex[$iIndex][2] = $iX / $aFullSize[0]
	Else
		$aGF_SizingIndex[$iIndex][2] = 0
	EndIf
	If $iY Then
		$aGF_SizingIndex[$iIndex][3] = $iY / $aFullSize[1]
	Else
		$aGF_SizingIndex[$iIndex][3] = 0
	EndIf
	If $iOrg_Width Then
		$aGF_SizingIndex[$iIndex][4] = $iOrg_Width / $aFullSize[0]
	Else
		$aGF_SizingIndex[$iIndex][4] = 1
	EndIf
	If $iOrg_Height Then
		$aGF_SizingIndex[$iIndex][5] = $iOrg_Height / $aFullSize[1]
	Else
		$aGF_SizingIndex[$iIndex][5] = 1
	EndIf

	; Switch back to main GUI
	GUISwitch($hWnd)

	; Return the index for this frame
	Return $iIndex

EndFunc   ;==>_GUIFrame_Create

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_SetMin
; Description ...: Sets minimum sizes for frames
; Syntax.........: _GUIFrame_SetMin($iFrame, $iFirstMin = 0, $iSecondMin = 0, $fAbsolute = False)
; Parameters ....: $iFrame - Index of frame set as returned by _GUIFrame_Create
;                  $iFirstMin - Min size of first (left/top) frame - max half size
;                  $iSecondMin - Min Size of second (right/bottom) frame - max half size
;                  $fAbsolute - True = Minima fixed when GUI resized
;                             - False = Minima adjusted on resize to equivalent percentage of new GUI size (default)
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23 based on some original code by Kip
; Modified ......:
; Remarks .......: If the frame is resized, these minima are adjusted accordingly unless $fAbsolute is set
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_SetMin($iFrame, $iFirstMin = 0, $iSecondMin = 0, $fAbsolute = False)

	; Check for valid frame index
	If $iFrame < 1 Or $iFrame > $aGF_HandleIndex[0][0] Then Return 0
	; Get size of parent
	Local $aSize = WinGetClientSize($aGF_HandleIndex[$iFrame][0])
	; Now check orientation and determine
	Local $iMax, $iFullSize
	If $aGF_SettingsIndex[$iFrame][0] = 0 Then
		$iMax = Floor(($aSize[0] / 2) - $aGF_SettingsIndex[$iFrame][2])
		$iFullSize = $aSize[0]
	Else
		$iMax = Floor(($aSize[1] / 2) - $aGF_SettingsIndex[$iFrame][2])
		$iFullSize = $aSize[1]
	EndIf
	; Set minimums
	If $fAbsolute Then
		$aGF_SizingIndex[$iFrame][0] = Int($iFirstMin)
		$aGF_SizingIndex[$iFrame][1] = Int($iSecondMin)
	Else
		If $iFirstMin > $iMax Then
			$aGF_SizingIndex[$iFrame][0] = $iMax / $iFullSize
		Else
			$aGF_SizingIndex[$iFrame][0] = $iFirstMin / $iFullSize
		EndIf
		If $iSecondMin > $iMax Then
			$aGF_SizingIndex[$iFrame][1] = $iMax / $iFullSize
		Else
			$aGF_SizingIndex[$iFrame][1] = $iSecondMin / $iFullSize
		EndIf
	EndIf

EndFunc   ;==>_GUIFrame_SetMin

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_ResizeSet
; Description ...: Sets resizing flag for frames
; Syntax.........: _GUIFrame_ResizeSet($iFrame = 0[, $iType = 0])
; Parameters ....: $iFrame - Index of frame set as returned by _GUIFrame_Create (Default - 0 = all existing frames)
;                  $iType  - Separator behaviour on GUI resize
;                            0 = Frames retain percentage size (default)
;                            1 = Top/left frame fixed size
;                            2 = Bottom/right frame fixed size
; Requirement(s).: v3.3 +
; Return values .: Success: 2 - All existing frame flags set
;                           1 - Specified flag set
;                  Failure: 0 with @error set to:
;                           1 - Invalid frame specified
;                           2 - Invalid type parameter
; Author ........: Melba23
; Modified ......:
; Remarks .......:
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_ResizeSet($iFrame = 0, $iType = 0)

	Switch $iType
		Case 0, 1, 2
			; Valid
		Case Else
			Return SetError(2, 0, 0)
	EndSwitch

	Switch $iFrame
		Case 0 ; Set all frames
			For $i = 1 To $aGF_HandleIndex[0][0]
				$aGF_SettingsIndex[$i][1] = 1
				$aGF_SizingIndex[$i][7] = $iType
			Next
			Return 2
		Case 1 To $aGF_HandleIndex[0][0] ; Only valid frames accepted
			$aGF_SettingsIndex[$iFrame][1] = 1
			$aGF_SizingIndex[$iFrame][7] = $iType
			Return 1
		Case Else ; Error
			Return SetError(1, 0, 0)
	EndSwitch

EndFunc   ;==>_GUIFrame_ResizeSet

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_GetHandle
; Description ...: Returns the handle of a frame element (required for further splitting)
; Syntax.........: _GUIFrame_GetHandle($iFrame, $iElement)
; Parameters ....: $iFrame - Index of frame set as returned by _GUIFrame_Create
;                  $iElement - 1 = first (left/top) frame, 2 = second (right/bottom) frame
; Requirement(s).: v3.3 +
; Return values .: Success: Handle of frame
;                  Failure: 0 with @error set as follows
;                           1 - Invalid frame specified
;                           2 - Invalid element specified
; Author ........: Kip
; Modified ......: Melba23
; Remarks .......: _GUIFrame_Create requires a GUI handle as a parameter
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_GetHandle($iFrame, $iElement)

	; Check valid frame index and element
	Switch $iFrame
		Case 1 To $aGF_HandleIndex[0][0]
			Switch $iElement
				Case 1, 2
					; Return handle
					Return $aGF_HandleIndex[$iFrame][$iElement]
			EndSwitch
			Return SetError(2, 0, 0)
	EndSwitch
	Return SetError(1, 0, 0)

EndFunc   ;==>_GUIFrame_GetHandle

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_Switch
; Description ...: Sets a frame element as current GUI
; Syntax.........: _GUIFrame_Switch($iFrame, $iElement)
; Parameters ....: $iFrame - Index of frame set as returned by _GUIFrame_Create
;                  $iElement - 1 = first (left/top) frame, 2 = second (right/bottom) frame
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Kip
; Modified ......: Melba23
; Remarks .......: Subsequent controls are created in the specified frame element
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_Switch($iFrame, $iElement)

	; Check valid frame index and element
	Switch $iFrame
		Case 1 To $aGF_HandleIndex[0][0]
			Switch $iElement
				Case 1, 2
					; Switch to specified element
					Return GUISwitch($aGF_HandleIndex[$iFrame][$iElement])
			EndSwitch
			Return SetError(2, 0, 0)
	EndSwitch
	Return SetError(1, 0, 0)

EndFunc   ;==>_GUIFrame_Switch

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_GetSepPos()
; Description ...: Returns the current position of the separator
; Syntax.........: _GUIFrame_GetSepPos($iFrame)
; Parameters ....: $iFrame - Index of frame set as returned by _GUIFrame_Create
; Requirement(s).: v3.3 +
; Return values .: Success: Position of separator
;                  Failure: -1 = Invalid frame specified
; Author ........: Melba23
; Remarks .......: This value can be stored and used as the initial separator position parameter in _GUIFrame_Create
;                  to restore exit position on restart
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_GetSepPos($iFrame)

	Local $iSepPos

	; Check for valid frame index
	If $iFrame < 1 Or $iFrame > $aGF_HandleIndex[0][0] Then Return -1

	; Get position of first frame
	Local $aFrame_Pos = WinGetPos($aGF_HandleIndex[$iFrame][1])
	; Get position of separator
	Local $aSep_Pos = WinGetPos($aGF_HandleIndex[$iFrame][3])
	; Check on separator orientation
	If $aGF_SettingsIndex[$iFrame][0] Then
		$iSepPos = $aSep_Pos[1] - $aFrame_Pos[1]
	Else
		$iSepPos = $aSep_Pos[0] - $aFrame_Pos[0]
	EndIf
	Return $iSepPos

EndFunc   ;==>_GUIFrame_GetSepPos

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_SetSepPos()
; Description ...: Moves the separator bar to adjust frame sizes
; Syntax.........: _GUIFrame_SetSepPos($iFrame, $iSepPos)
; Parameters ....: $iFrame - Index of frame set as returned by _GUIFrame_Create
;                  $iSepos - Position of separator bar within frame
; Requirement(s).: v3.3 +
; Return values .: Success: 1
;                  Failure: 0 with @error set as follows
;                           1 - Invalid frame specified
;                           2 - Invalid separator position (outside frame)
;                           3 - Invalid separator position (below frame minimum size)
; Author ........: Melba23
; Remarks .......: This value can be stored and used as the initial separator position parameter in _GUIFrame_Create
;                  to restore exit position on restart
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_SetSepPos($iFrame, $iSepPos)

	Local $iFirstMin, $iSecondMin

	; Check for valid frame index
	If $iFrame < 1 Or $iFrame > $aGF_HandleIndex[0][0] Then Return SetError(1, 0, 0)

	; Check separator actually needs to move
	If $iSepPos = _GUIFrame_GetSepPos($iFrame) Then Return 1

	; Get frame GUI size
	Local $aWinPos = WinGetPos($aGF_HandleIndex[$iFrame][0])
	; Depending on separator orientation
	If $aGF_SettingsIndex[$iFrame][0] Then
		; Check sep position is valid
		If $iSepPos < 0 Or $iSepPos > $aWinPos[3] Then Return SetError(2, 0, 0)
		; Determine minima for frames
		$iFirstMin = $aWinPos[3] * $aGF_SizingIndex[$iFrame][0]
		$iSecondMin = ($aWinPos[3] * (1 - $aGF_SizingIndex[$iFrame][1])) - $aGF_SettingsIndex[$iFrame][2]
		; Check required value is valid
		If $iSepPos < $iFirstMin Or $iSepPos > $iSecondMin Then Return SetError(3, 0, 0)
		; Move frames and seperator
		WinMove($aGF_HandleIndex[$iFrame][1], "", 0, 0, $aWinPos[2], $iSepPos)
		WinMove($aGF_HandleIndex[$iFrame][2], "", 0, $iSepPos + $aGF_SettingsIndex[$iFrame][2], $aWinPos[2], $aWinPos[3] - ($iSepPos + $aGF_SettingsIndex[$iFrame][2]))
		WinMove($aGF_HandleIndex[$iFrame][3], "", 0, $iSepPos, $aWinPos[2], $aGF_SettingsIndex[$iFrame][2])
		; Store new separator position
		$aGF_SizingIndex[$iFrame][6] = $iSepPos / $aWinPos[3]
	Else
		If $iSepPos < 0 Or $iSepPos > $aWinPos[2] Then Return SetError(2, 0, 0)
		$iFirstMin = $aWinPos[2] * $aGF_SizingIndex[$iFrame][0]
		$iSecondMin = ($aWinPos[2] * (1 - $aGF_SizingIndex[$iFrame][1])) - $aGF_SettingsIndex[$iFrame][2]
		If $iSepPos < $iFirstMin Or $iSepPos > $iSecondMin Then Return SetError(3, 0, 0)
		WinMove($aGF_HandleIndex[$iFrame][1], "", 0, 0, $iSepPos, $aWinPos[3])
		WinMove($aGF_HandleIndex[$iFrame][2], "", $iSepPos + $aGF_SettingsIndex[$iFrame][2], 0, $aWinPos[2] - ($iSepPos + $aGF_SettingsIndex[$iFrame][2]), $aWinPos[3])
		WinMove($aGF_HandleIndex[$iFrame][3], "", $iSepPos, 0, $aGF_SettingsIndex[$iFrame][2], $aWinPos[3])
		$aGF_SizingIndex[$iFrame][6] = $iSepPos / $aWinPos[2]
	EndIf

	; Set callback
	$aGF_HandleIndex[$iFrame][7] = 1

	Return 1

EndFunc   ;==>_GUIFrame_SetSepPos

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_ResizeState
; Description ...: Returns the resize state of the frames
; Syntax.........: _GUIFrame_ResizeState()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: Success: Array of frame resize flags
; Author ........: Melba23
; Remarks .......: An array is always returned - the user must query the flag for the relevant frame to detect resizing
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_ResizeState()

	; Create array to hold resize flags
	Local $aRet[$aGF_HandleIndex[0][0] + 1] = [0]
	For $i = 1 To $aGF_HandleIndex[0][0]
		; Read state
		$aRet[$i] = $aGF_HandleIndex[$i][7]
		; Set flag is resized
		If $aGF_HandleIndex[$i][7] Then $aRet[0] = 1
		; Clear resized flag
		$aGF_HandleIndex[$i][7] = 0
	Next
	; Return array of flags
	Return $aRet

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_ResizeReg
; Description ...: Registers WM_SIZE message for resizing
; Syntax.........: _GUIFrame_ResizeReg()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: Success: 1 - Message handler registered
;                  Failure: 0 with @error set to 1 - Message handler already registered
; Author ........: Melba23
; Modified ......:
; Remarks .......:
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_ResizeReg()

	; Register the WM_SIZE message
	If $aGF_HandleIndex[0][1] = 0 Then
		Local $iRet = GUIRegisterMsg(0x05, "_GUIFrame_SIZE_Handler") ; $WM_SIZE
		If $iRet Then
			$aGF_HandleIndex[0][1] = 1
			Return 1
		EndIf
	EndIf
	Return SetError(1, 0, 0)

EndFunc   ;==>_GUIFrame_ResizeReg

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_SIZE_Handler
; Description ...: Used to resize frames when resizing of holding GUI occurs
; Syntax.........: _GUIFrame_SIZE_Handler($hWnd, $iMsg, $wParam, $lParam)
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Modified ......:
; Remarks .......: If the script already has a WM_SIZE handler, then just call this function from within it
;                  and do NOT use the _GUIFrame_ResizeReg function
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_SIZE_Handler($hWnd, $iMsg, $wParam, $lParam)

	#forceref $iMsg, $wParam, $lParam
	Local $iIndex

	; Get index of base frame GUI
	For $iIndex = 1 To $aGF_HandleIndex[0][0]
		If $aGF_HandleIndex[$iIndex][4] = $hWnd Then ExitLoop
	Next

	; If handle not found
	If $iIndex > $aGF_HandleIndex[0][0] Then Return "GUI_RUNDEFMSG"

	; Check if we should resize this set
	If $aGF_SettingsIndex[$iIndex][1] = 1 Then

		; Get new base GUI size
		Local $aSize = WinGetClientSize($hWnd)
		; Resize frames
		_GUIFrame_Move($iIndex, $aSize[0] * $aGF_SizingIndex[$iIndex][2], $aSize[1] * $aGF_SizingIndex[$iIndex][3], $aSize[0] * $aGF_SizingIndex[$iIndex][4], $aSize[1] * $aGF_SizingIndex[$iIndex][5])

		; Adjust any resizeable internal frames - array elements are adjacent for ease of coding
		For $i = 0 To 1
			; Adjust internal frames of first/second frame if any exist
			If $aGF_HandleIndex[$iIndex][5 + $i] <> 0 Then
				; StringSplit the element content on "|"
				Local $aInternal = StringSplit($aGF_HandleIndex[$iIndex][5 + $i], "|")
				; Then loop though the Number(values) found
				For $j = 1 To $aInternal[0]
					Local $iIntIndex = Number($aInternal[$j])
					; Check if internal frame is resizable
					If $aGF_SettingsIndex[$iIntIndex][1] = 1 Then
						; And change if so
						_GUIFrame_SIZE_Handler($aGF_HandleIndex[$iIntIndex][4], $iMsg, $wParam, $lParam)
					EndIf
				Next
			EndIf
		Next

		; Set callback
		$aGF_HandleIndex[$iIndex][7] = 1

	EndIf

	Return "GUI_RUNDEFMSG"

EndFunc   ;==>_GUIFrame_SIZE_Handler

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _GUIFrame_SepSubClass
; Description ...: Sets new WndProc for frame separator bar
; Author ........: Kip
; Modified.......: Melba23, using SetWindowLongPtr x64 compatible code drawn from Yashied's WinAPIEx library
; Remarks .......: This function is used internally by _GUIFrame_Create
; ===============================================================================================================================
Func _GUIFrame_SepSubClass($hWnd)

	Local $aRet

	; Check separator has not already been used
	For $i = 1 To $aGF_SepProcIndex[0][0]
		If $aGF_SepProcIndex[$i][0] = $hWnd Then Return 0
	Next

	; Store current WinProc handle in new array line
	Local $iIndex = $aGF_SepProcIndex[0][0] + 1
	ReDim $aGF_SepProcIndex[$iIndex + 1][2]
	$aGF_SepProcIndex[0][0] = $iIndex
	$aGF_SepProcIndex[$iIndex][0] = $hWnd
	; Subclass separator bar
	If @AutoItX64 Then
		$aRet = DllCall('user32.dll', 'long_ptr', 'SetWindowLongPtrW', 'hwnd', $hWnd, 'int', -4, 'long_ptr', $aGF_SepProcIndex[0][1]) ; $GWL_WNDPROC
	Else
		$aRet = DllCall('user32.dll', 'long', 'SetWindowLongW', 'hwnd', $hWnd, 'int', -4, 'long', $aGF_SepProcIndex[0][1]) ; $GWL_WNDPROC
	EndIf
	; Check for subclassing error
	If @error Or $aRet[0] = 0 Then Return 0
	; Return success
	$aGF_SepProcIndex[$iIndex][1] = $aRet[0]
	Return 1

EndFunc   ;==>_GUIFrame_SepSubClass

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _GUIFrame_SepWndProc
; Description ...: New WndProc for frame separator bar
; Author ........: Kip
; Modified.......: Melba23
; Remarks .......: This function is used internally by _GUIFrame_SepSubClass
; ===============================================================================================================================
Func _GUIFrame_SepWndProc($hWnd, $iMsg, $wParam, $lParam)

	Local $iSubtract, $fAbsolute = False

	If $iMsg = 0x0111 Then ; WM_COMMAND

		; Check if hWnd is a Separator bar
		For $iIndex = 1 To $aGF_HandleIndex[0][0]
			If $aGF_HandleIndex[$iIndex][3] = $hWnd Then ExitLoop
		Next
		; If not then pass message on to org WndProc
		If $iIndex > $aGF_HandleIndex[0][0] Then Return _GUIFrame_SepPassMsg($hWnd, $iMsg, $wParam, $lParam)

		; Extract values from array
		Local $hParent = $aGF_HandleIndex[$iIndex][0]
		Local $hFirstFrame = $aGF_HandleIndex[$iIndex][1]
		Local $hSecondFrame = $aGF_HandleIndex[$iIndex][2]
		Local $hSeparator = $aGF_HandleIndex[$iIndex][3]
		Local $iFirstMin = $aGF_SizingIndex[$iIndex][0]
		Local $iSecondMin = $aGF_SizingIndex[$iIndex][1]
		If $iFirstMin > 1 Or $iSecondMin > 1 Then
			$fAbsolute = True
		EndIf
		Local $iSeparatorSize = $aGF_SettingsIndex[$iIndex][2]

		; Get client size of the parent
		Local $aClientSize = WinGetClientSize($hParent)
		Local $iWidth = $aClientSize[0]
		Local $iHeight = $aClientSize[1]

		; Get cursor info for the Separator
		Local $aCInfo = GUIGetCursorInfo($hSeparator)

		; Depending on separator orientation
		If $aGF_SettingsIndex[$iIndex][0] = 0 Then

			; Get Separator X-coord
			$iSubtract = $aCInfo[0]

			Do
				; Get parent X-coord
				$aCInfo = GUIGetCursorInfo($hParent)
				Local $iCursorX = $aCInfo[0]

				; Determine width of first frame
				Local $iFirstWidth = $iCursorX - $iSubtract
				; And ensure it is at least minimum
				If $fAbsolute Then
					If $iFirstWidth < $iFirstMin Then $iFirstWidth = $iFirstMin
					If $iWidth - $iFirstWidth - $iSeparatorSize < $iSecondMin Then $iFirstWidth = $iWidth - $iSeparatorSize - $iSecondMin
				Else
					If $iFirstWidth < $iWidth * $iFirstMin Then $iFirstWidth = $iWidth * $iFirstMin
					If $iWidth - ($iFirstWidth + $iSeparatorSize) < $iWidth * $iSecondMin Then $iFirstWidth = $iWidth - ($iWidth * $iSecondMin) - $iSeparatorSize
				EndIf

				; Move the GUIs to the correct places
				WinMove($hFirstFrame, "", 0, 0, $iFirstWidth, $iHeight)
				WinMove($hSecondFrame, "", $iFirstWidth + $iSeparatorSize, 0, $iWidth - ($iFirstWidth + $iSeparatorSize), $iHeight)
				WinMove($hSeparator, "", $iFirstWidth, 0, $iSeparatorSize, $iHeight)

				; Do until the mouse button is released
			Until Not _WinAPI_GetAsyncKeyState(0x01)

			; Store current separator percentage position
			$aGF_SizingIndex[$iIndex][6] = $iFirstWidth / $iWidth

		ElseIf $aGF_SettingsIndex[$iIndex][0] = 1 Then

			$iSubtract = $aCInfo[1]
			Do
				$aCInfo = GUIGetCursorInfo($hParent)
				Local $iCursorY = $aCInfo[1]
				Local $iFirstHeight = $iCursorY - $iSubtract
				If $fAbsolute Then
					If $iFirstHeight < $iFirstMin Then $iFirstHeight = $iFirstMin
					If $iHeight - $iFirstHeight - $iSeparatorSize < $iSecondMin Then $iFirstHeight = $iHeight - $iSeparatorSize - $iSecondMin
				Else
					If $iFirstHeight < $iHeight * $iFirstMin Then $iFirstHeight = $iHeight * $iFirstMin
					If $iHeight - ($iFirstHeight + $iSeparatorSize) < $iHeight * $iSecondMin Then $iFirstHeight = $iHeight - ($iHeight * $iSecondMin) - $iSeparatorSize
				EndIf
				WinMove($hFirstFrame, "", 0, 0, $iWidth, $iFirstHeight)
				WinMove($hSecondFrame, "", 0, $iFirstHeight + $iSeparatorSize, $iWidth, $iHeight - ($iFirstHeight + $iSeparatorSize))
				WinMove($hSeparator, "", 0, $iFirstHeight, $iWidth, $iSeparatorSize)
			Until Not _WinAPI_GetAsyncKeyState(0x01)
			$aGF_SizingIndex[$iIndex][6] = $iFirstHeight / $iHeight

		EndIf

		; Set callback
		$aGF_HandleIndex[$iIndex][7] = 1

	EndIf

	; Pass the message on to org WndProc
	Return _GUIFrame_SepPassMsg($hWnd, $iMsg, $wParam, $lParam)

EndFunc   ;==>_GUIFrame_SepWndProc

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _GUIFrame_SepPassMsg
; Description ...: Passes Msg to frame parent WndProc for action
; Author ........: Kip
; Modified.......: Melba23
; Remarks .......: This function is used internally by _GUIFrame_SepWndProc
; ===============================================================================================================================
Func _GUIFrame_SepPassMsg($hWnd, $iMsg, $wParam, $lParam)

	For $i = 1 To $aGF_SepProcIndex[0][0]
		If $aGF_SepProcIndex[$i][0] = $hWnd Then Return _WinAPI_CallWindowProc($aGF_SepProcIndex[$i][1], $hWnd, $iMsg, $wParam, $lParam)
	Next

EndFunc   ;==>_GUIFrame_SepPassMsg

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _GUIFrame_Move
; Description ...: Moves and resizes frame elements and separator bars
; Author ........: Kip
; Modified.......: Melba23
; Remarks .......: This function is used internally by _GUIFrame_SIZE_Handler
; ===============================================================================================================================
Func _GUIFrame_Move($iFrame, $iX, $iY, $iWidth = 0, $iHeight = 0)

	If $iFrame < 1 Or $iFrame > $aGF_HandleIndex[0][0] Then Return 0

	Local $fAbsolute = False, $iDimension, $iActual_Size_1, $iActual_Size_2, $iSize
	Local $iOrientation = $aGF_SettingsIndex[$iFrame][0]
	Local $iSeparatorSize = $aGF_SettingsIndex[$iFrame][2]

	; Set size if not specified
	If Not $iWidth Then $iWidth = _WinAPI_GetWindowWidth($aGF_HandleIndex[$iFrame][0])
	If Not $iHeight Then $iHeight = _WinAPI_GetWindowHeight($aGF_HandleIndex[$iFrame][0])

	; Move parent
	WinMove($aGF_HandleIndex[$iFrame][0], "", $iX, $iY, $iWidth, $iHeight)

	; Depending on separator orientation get required width/height values
	If $iOrientation = 1 Then
		$iDimension = $iHeight
		$iActual_Size_1 = _WinAPI_GetWindowHeight($aGF_HandleIndex[$iFrame][1])
		$iActual_Size_2 = _WinAPI_GetWindowHeight($aGF_HandleIndex[$iFrame][2])
	Else
		$iDimension = $iWidth
		$iActual_Size_1 = _WinAPI_GetWindowWidth($aGF_HandleIndex[$iFrame][1])
		$iActual_Size_2 = _WinAPI_GetWindowWidth($aGF_HandleIndex[$iFrame][2])
	EndIf

	; Check resize type required
	Switch $aGF_SizingIndex[$iFrame][7]
		Case 0
			; Determine new size for first frame using separator position percentage
			$iSize = Int($iDimension * $aGF_SizingIndex[$iFrame][6])
		Case 1
			; Get current fixed first frame size
			$iSize = $iActual_Size_1
		Case 2
			; Determine new first frame size with fixed second frame size
			$iSize = $iDimension - $iSeparatorSize - $iActual_Size_2
	EndSwitch

	; Set frame min percentages
	Local $iFirstMin = $aGF_SizingIndex[$iFrame][0]
	Local $iSecondMin = $aGF_SizingIndex[$iFrame][1]
	If $iFirstMin > 1 Or $iSecondMin > 1 Then
		$fAbsolute = True
	EndIf

	; Check for minimum size of first frame
	Local $iAdjust_Other = True
	Local $fSep_Adjusted = False

	; Adjust first frame size
	If $fAbsolute Then
		If $iSize < $iFirstMin Then
			$iSize = $iFirstMin
			$iAdjust_Other = False
			$fSep_Adjusted = True
		EndIf
	Else
		If $iSize < $iDimension * $iFirstMin Then
			$iSize = $iDimension * $iFirstMin
			$iAdjust_Other = False
			$fSep_Adjusted = True
		EndIf
	EndIf

	; Now adjust second frame if first not adjusted
	If $iAdjust_Other Then

		; Find max available size for this frame
		Local $iSecondMax = $iDimension - $iFirstMin - $iSeparatorSize
		If $iSecondMax < $iSecondMin Then
			$iSecondMin = $iSecondMax
		EndIf

		; Adjust second frame size
		If $fAbsolute Then
			If $iActual_Size_2 < $iSecondMin Then
				$iSize = $iDimension - $iSecondMin - $iSeparatorSize
				$fSep_Adjusted = True
			EndIf
		Else
			If $iActual_Size_2 < $iDimension * $iSecondMin Then
				$iSize = $iDimension - ($iDimension * $iSecondMin) - $iSeparatorSize
				$fSep_Adjusted = True
			EndIf
		EndIf
	EndIf

	; If the separator has been moved programatically then reset percentage size of first frame
	If $fSep_Adjusted Then
		$aGF_SizingIndex[$iFrame][6] = $iSize / $iDimension
	EndIf

	; Move and resize GUIs according to orientation
	If $iOrientation = 1 Then
		WinMove($aGF_HandleIndex[$iFrame][1], "", 0, 0, $iWidth, $iSize)
		WinMove($aGF_HandleIndex[$iFrame][2], "", 0, $iSize + $iSeparatorSize, $iWidth, $iHeight - $iSize - $iSeparatorSize)
		WinMove($aGF_HandleIndex[$iFrame][3], "", 0, $iSize, $iWidth, $iSeparatorSize)
	Else
		WinMove($aGF_HandleIndex[$iFrame][1], "", 0, 0, $iSize, $iHeight)
		WinMove($aGF_HandleIndex[$iFrame][2], "", $iSize + $iSeparatorSize, 0, $iWidth - $iSize - $iSeparatorSize, $iHeight)
		WinMove($aGF_HandleIndex[$iFrame][3], "", $iSize, 0, $iSeparatorSize, $iHeight)
	EndIf

EndFunc   ;==>_GUIFrame_Move

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _GUIFrame_Exit()
; Description ...: Deletes all subclassed separator bars to free UDF WndProc and frees registered callback handle
; Author ........: Melba23
; Remarks .......: Called by OnAutoItExitRegister to delete all subclassed separator bars and to free the UDF created WndProc.
; Example........: Yes
;================================================================================================================================
Func _GUIFrame_Exit()

	; Delete all subclassed separator bars
	For $i = $aGF_HandleIndex[0][0] To 1 Step -1
		GUIDelete($aGF_HandleIndex[$i][3])
	Next
	; Free registered Callback handle
	DllCallbackFree($hGF_RegCallBack)

EndFunc   ;==>_GUIFrame_Exit
[New] And finally all 5 files in zip format: GUIFrame.zip

I hope you find this UDF useful. As always brickbats and bouquets welcomed. o:)

M23

Edited by Melba23
Sannie72, Xandy and Leagnus like this

Share this post


Link to post
Share on other sites



Posted

Great job Melba23!

And sincere thanks to Kip for his foundational work in this area!

Your comments throughout examples really help

My 1st evaluations show some significant improvements, and though have not had lots of time

at it so far, did notice a few things right away..

1) the bar between the frames is not expanding with the borders of the frame when main Gui enlarged..

2) GUIFrame_Create($hGUI_2,1, 1, 10, 10, 200, 200) param#2 if set to > 1 makes a rectangle

3) played a bit to see if could lock the size of the individual frames when main Gui resized,

used GuiCtrlSetResizing(-1,$Gui_Dockall) to no effect..

Sorry but that is all the time I have right now, I'll try some more as I have time this weekend..

Thank you again,

RoyS

Share this post


Link to post
Share on other sites

Posted (edited)

RoyS,

the bar between the frames is not expanding with the borders of the frame when main Gui enlarged

It is not supposed to and I see no reason why it should. After all, it is only there to act as the grab point for resizing. ;)

Or do you mean that it no longer stretches across the frame? If so, I am very surprised as it is resized to the same dimensions as the frames themselves. ;)

GUIFrame_Create($hGUI_2, 1, 1, 10, 10, 200, 200) param#2 if set to > 1 makes a rectangle

I am afraid I do not understand what you mean. o:)

If you write:

GUIFrame_Create($hGUI_2, 2, 1, ....

You get no frames created and the function returns 0 with an error of 2 (GUI creation failed). This is because the $iSepOrient parameter only accepts 0/1 as explained in the function header.

If you write:

GUIFrame_Create($hGUI_2, 1, 2, ....

you get the normal square GUI with 2 frames and a separator bar 3 pixels wide ($iSepSize - Size of separator bar (default = 5, min = 3, max = 9))

Could you explain your comment further? :)

if could lock the size of the individual frames when main Gui resized

Easy - do not set the resizing flag with _GUIFrame_ResizeSet for that frame. The top frame that appears when you press Button 1 is non-resizing - as you will see if you try it. Note the use of _GUIFrame_ResizeSet(0) to set the flag for all existing frames when the script starts. o:)

GuiCtrlSetResizing will not work as these are GUIs, not controls. :party:

I hope that explains most of what you asked. :P

M23

Edit: Guess!

Edited by Melba23

Share this post


Link to post
Share on other sites

Posted

Hi Melba23 !

Thanks for your guiframe, it's a nice work ! ;)

Share this post


Link to post
Share on other sites

Posted

Wow. Nice work Melba23 and Kip. I have been looking for an easy way to implement this in my GUI I will give this a shot. The varied examples you gave should make that very easy.

Thanks,

cj

Share this post


Link to post
Share on other sites

Posted

Melba23, This is really amazing! Thank you so much for sharing. All the commenting is very helpful. Posted Image

Share this post


Link to post
Share on other sites

Posted

Melba23,

Thank you for answering my initial comments,repeated here..

My 1st evaluations show some significant improvements, and though have not had lots of time

at it so far, did notice a few things right away..

1) the bar between the frames is not expanding with the borders of the frame when main Gui enlarged..

2) GUIFrame_Create($hGUI_2,1, 1, 10, 10, 200, 200) param#2 if set to > 1 makes a rectangle

3) played a bit to see if could lock the size of the individual frames when main Gui resized,

used GuiCtrlSetResizing(-1,$Gui_Dockall) to no effect..

Further evaluations this weekend I only could get it to do item #1 intermittently when playing with the parameters in

the examples.. sorry so new that I could not document what I did the 1st time to make this happen.. but

the bar did not expand with the frame when the main re-sizable Gui was enlarged, leaving a line between the

what was the original size and worked to resize, and a line to the frame edge that the mouse pointer did not change when over it.

The item 2 was an accidental use of a wrong value, easy thing to do so easy to correct .. just did not error out like

I expected and make nothing, it does make a main Child Gui to hold the frames.. I dont think either of these are critical.

In example script GuiFrame2_Example At line 11

Or

In example script GUIFrame1_Example_Reg At line 13

$iFrame_A = _GUIFrame_Create($hGUI_1,2) ;<= added ,2 got a single blank window

Item 3 was just a wish.. when min size set for both at 200 and window is 400 or less, the resize bar between the frames

still is active and gives some flicker trying to adjust.. hope that explains what I observed..

I really like the UDF, have learned a lot form the coding used about Gui .. noticed all the frames are Child in Style,

Would it be possible to have the frames come up with an option to change the size of the frames and lock them there so

the adjustment bar is there but does nothing? That way cold come back and unlock in script, change the sizes, and relock

them as desired..

Separate issue for me right now is how to Center a Gui on a monitor other than the primary one.. the @DesktopHeight and

@DesktopWidth only give Screen Size of the primary monitor, and do not account for the Tool bar in windows.. However

when a GuiCreate("",-1,-1) is used, it does center on the free area of the desktop but only on the primary monitor.. so the

Toolbar width/height is in the developers use on the primary monitor when Guicreate is used.

Further digging reveals if my main Gui is on another monitor and a msgbox is called it is centered on the non primary monitor

so the msgbox must use screen sizes of the non primary monitor to do this..

Any Thoughts? You have done so much digging into the internals of Autoit I am hoping this has been addressed at some point.

Wow.. did not mean to be so long winded when I started, please forgive... am on a deadline to finish my scripting so have

limited time, but wanted to let you know I really am thankful and appreciate your UDF's..

RoyS

Share this post


Link to post
Share on other sites

Posted

Melba23, Do you think you could take a look at this? When implementing statusbars I keep getting a little glich. Whenever the Middle frame is resized the very bottom statusbar goes away. When the Main Gui is resized it comes back. I can't figure out how to refresh the main gui after everything is done. Thanks a lot.

include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiStatusBar.au3>
#include "GUIFrame.au3"

$hGUI_1 = GUICreate("GUI Frames", 600, 500, 100, 100, $WS_SIZEBOX)

;create frames
$iFrame_A = _GUIFrame_Create($hGUI_1, 1);split gui horizontally
$iFrame_B = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_A, 1));split top frame vertically
$iFrame_C = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_A, 2), 1);split bottom frame horizontally again

;set mins
_GUIFrame_SetMin($iFrame_A, 75, 75)
_GUIFrame_SetMin($iFrame_B, 75, 75)
_GUIFrame_SetMin($iFrame_C, 75, 75)

;get handles to each frame
$hTopLeft = _GUIFrame_GetHandle($iFrame_B, 1)
$hTopright = _GUIFrame_GetHandle($iFrame_B, 2)
$hMiddleFrame = _GUIFrame_GetHandle($iFrame_C, 1)
$hBottomFrame = _GUIFrame_GetHandle($iFrame_C, 2)

;create status bars
Global $Status1, $Status2, $Status3, $Status4
Global $aStatuswidths[3] = [75,150,225]
Global $aStatusText[3] = ['One', 'Two', 'Three']
$Status1 = _GUICtrlStatusBar_Create($hTopLeft, $aStatuswidths, $aStatusText)
$Status2 = _GUICtrlStatusBar_Create($hTopright, $aStatuswidths, $aStatusText)
$Status3 = _GUICtrlStatusBar_Create($hMiddleFrame, $aStatuswidths, $aStatusText)
$Status4 = _GUICtrlStatusBar_Create($hGUI_1, $aStatuswidths, $aStatusText)
;~ $Status4 = _GUICtrlStatusBar_Create($hBottomFrame, $aStatuswidths, $aStatusText)

;Set backgound colors
GUISetBkColor(0xC0C0C0, $hTopLeft)
GUISetBkColor(0xFFC4FF, $hTopright)
GUISetBkColor(0x00D0FF, $hMiddleFrame)
GUISetBkColor(0x80FF00, $hBottomFrame)

GUISetState(@SW_SHOW, $hGUI_1)
GUIRegisterMsg($WM_SIZE, "_WM_SIZE")

_GUIFrame_ResizeSet(0)

While 1
    Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			_GUIFrame_Exit()
			_GUICtrlStatusBar_Destroy($Status1)
			_GUICtrlStatusBar_Destroy($Status2)
			_GUICtrlStatusBar_Destroy($Status3)
			_GUICtrlStatusBar_Destroy($Status4)
            Exit
    EndSwitch
WEnd

Func _WM_SIZE($hWnd, $iMsg, $wParam, $lParam)

	_GUIFrame_SIZE_Handler($hWnd, $iMsg, $wParam, $lParam)
	_GUICtrlStatusBar_Resize ($Status4)
	_GUICtrlStatusBar_Resize ($Status1)
	_GUICtrlStatusBar_Resize ($Status2)
	_GUICtrlStatusBar_Resize ($Status3)

	Return $GUI_RUNDEFMSG

EndFunc

Share this post


Link to post
Share on other sites

Posted (edited)

RoyS,

#1. As I explained above, the sep bar and the frames are resized using the same variables to set their common dimensions, so I cannot see how it could have happened. If you ever do find the magic combination of parameters to make it occur again, please let me know. o:)

#2. I see where the problem is here. I will alter the next release to default to a vertical sep bar if the $iSepOrient parameter is not 1. Thanks for pointing it out. ;)

#3. At present, if you set a min value which is greater than half the total size, the value is reduced to Floor((max available / 2) - sep size). Because there is often a rounding error involved here, if you do the same for both frames you might get a couple of pixels free play in the sep bar movement. I did this to cater for the user setting min values for both frames which added to more than the available size. If I were to look into changing this behaviour, what would you like to see? No promises, mind! :P

As to the lock function, I can see a number of ways to do this and could easily add a further function to the UDF, but would you mind giving me an example of when you might want to do this? To my mind, the whole idea of frames is to have dynamic adjustments to the display area. :)

M23

Edit: No idea about secondary monitors. I suggest a new topic in the Support forum asking the question. ;)

Edited by Melba23

Share this post


Link to post
Share on other sites

Posted

Beege,

That one is easy! :)

Creating the status bar for the main GUI reduces the client size available for the frames. You have already created the frames before you add the main GUI status bar, so the frames overwrite the status bar added later when they use the original client area on resize. Resizing the whole GUI overwrites the frames again.

Solution: Place the status bar on the main GUI BEFORE you create the frames:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiStatusBar.au3>
#include "GUIFrame.au3"

Global $Status1, $Status2, $Status3, $Status4
Global $aStatuswidths[3] = [75,150,225]
Global $aStatusText[3] = ['One', 'Two', 'Three']

$hGUI_1 = GUICreate("GUI Frames", 600, 500, 100, 100, $WS_SIZEBOX)
; Create main GUI status bar
$Status4 = _GUICtrlStatusBar_Create($hGUI_1, $aStatuswidths, $aStatusText) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<< Here

;create frames
$iFrame_A = _GUIFrame_Create($hGUI_1, 1);split gui horizontally
$iFrame_B = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_A, 1));split top frame vertically
$iFrame_C = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_A, 2), 1);split bottom frame horizontally again

;set mins
_GUIFrame_SetMin($iFrame_A, 75, 75)
_GUIFrame_SetMin($iFrame_B, 75, 75)
_GUIFrame_SetMin($iFrame_C, 75, 75)

;get handles to each frame
$hTopLeft = _GUIFrame_GetHandle($iFrame_B, 1)
$hTopright = _GUIFrame_GetHandle($iFrame_B, 2)
$hMiddleFrame = _GUIFrame_GetHandle($iFrame_C, 1)
$hBottomFrame = _GUIFrame_GetHandle($iFrame_C, 2)

;create frame status bars

$Status1 = _GUICtrlStatusBar_Create($hTopLeft, $aStatuswidths, $aStatusText)
$Status2 = _GUICtrlStatusBar_Create($hTopright, $aStatuswidths, $aStatusText)
$Status3 = _GUICtrlStatusBar_Create($hMiddleFrame, $aStatuswidths, $aStatusText)
;~ $Status4 = _GUICtrlStatusBar_Create($hBottomFrame, $aStatuswidths, $aStatusText) ; <<<<<<<<<<<<<<<<<< Not here

;Set backgound colors
GUISetBkColor(0xC0C0C0, $hTopLeft)
GUISetBkColor(0xFFC4FF, $hTopright)
GUISetBkColor(0x00D0FF, $hMiddleFrame)
GUISetBkColor(0x80FF00, $hBottomFrame)

GUISetState(@SW_SHOW, $hGUI_1)
GUIRegisterMsg($WM_SIZE, "_WM_SIZE")

_GUIFrame_ResizeSet(0)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _GUIFrame_Exit()
            _GUICtrlStatusBar_Destroy($Status1)
            _GUICtrlStatusBar_Destroy($Status2)
            _GUICtrlStatusBar_Destroy($Status3)
            _GUICtrlStatusBar_Destroy($Status4)
            Exit
	EndSwitch
WEnd

Func _WM_SIZE($hWnd, $iMsg, $wParam, $lParam)

    _GUIFrame_SIZE_Handler($hWnd, $iMsg, $wParam, $lParam)
    _GUICtrlStatusBar_Resize ($Status4)
    _GUICtrlStatusBar_Resize ($Status1)
    _GUICtrlStatusBar_Resize ($Status2)
    _GUICtrlStatusBar_Resize ($Status3)

    Return $GUI_RUNDEFMSG

EndFunc

All clear? ;)

M23

Share this post


Link to post
Share on other sites

Posted

We are all clear! Thanks again. Posted Image

Share this post


Link to post
Share on other sites

Posted

Melba23,

Thank you for your reply and I will let you know the parameters for the "possible" problem

I saw with the sizing bar..

The use of a single child Gui is solution to my "would be nice" request, have used this now

in my program and so you sure dont need to add such into the frames udf.

Found member "Motuatronic2010" had posted in the General Help forum a helpful zipped file of

udf library of monitor access and parameters. It is a bit over my head but am evaluating

and learning from it.. may have a solution there to my question about centering on multiple

monitors.

At any rate, you have really helped me to better understand how child gui integrations work.

Keep up the great work, it is really appreciated, Thank you.

RoyS

Share this post


Link to post
Share on other sites

Posted

Again Awesome Job! Excellent and very usefull!

Really ;).

Thank you very much again M23.

Share this post


Link to post
Share on other sites

Posted

Melba23, I got another glitch similar to the last. When trying to resize the main GUI, the ListViews I created that take up the entire client area are geting resized wrong.

In the example below, when it first starts you should see vertical and horizontal scroll bars for both frames. Once any resize happens to the main GUI, the Listviews are resized to large or something because all both horizontal scroll bars and one vertical disappear. Hopefully its as easy as the last one to fix. Thanks ;)

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include "GUIFrame.au3"

Global $g_hGUI = GUICreate("GUI Frames", 300, 300, -1, -1, $WS_SIZEBOX)
GUISetState(@SW_SHOW)

;create frames
$g_Frames = _GUIFrame_Create($g_hGUI);split gui horizontally
_GUIFrame_SetMin($g_Frames, 75, 75)

;get handles to each frame
$g_hLeft = _GUIFrame_GetHandle($g_Frames, 1)
$g_hRight = _GUIFrame_GetHandle($g_Frames, 2)

;create Listview 1
_GUIFrame_Switch($g_Frames, 1)
$aClient = WinGetClientSize($g_hLeft)
$listview = GUICtrlCreateListView('column 1 | column  2 | column 3', 0, 0, $aClient[0], $aClient[1])
GUICtrlSetResizing(-1, 102)

;create Listview 2
_GUIFrame_Switch($g_Frames, 2)
$aClient = WinGetClientSize($g_hRight)
$listview2 = GUICtrlCreateListView('column 1 | column  2 | column 3', 0, 0, $aClient[0], $aClient[1])
GUICtrlSetResizing(-1, 102)

;Add some items to listviews
For $i = 1 to 20
	GUICtrlCreateListViewItem('item ' & $i, $listview)
	GUICtrlCreateListViewItem('item ' & $i, $listview2)
Next

GUIRegisterMsg($WM_SIZE, "_WM_SIZE")
_GUIFrame_ResizeSet(0)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
_GUIFrame_Exit()

Func _WM_SIZE($hWnd, $iMsg, $wParam, $lParam)

	_GUIFrame_SIZE_Handler($hWnd, $iMsg, $wParam, $lParam)

	Return $GUI_RUNDEFMSG

EndFunc

Share this post


Link to post
Share on other sites

Posted

Beege,

Thanks for finding that bug - not too difficult to find and fix. I was using WinGetPos and not WinGetClientSize in part of the resizing code and so the frames were incorrectly resized too large - as you noticed. :)

New version in the first post - your script works fine for me with this version. ;)

M23

Share this post


Link to post
Share on other sites

Posted

;)

Nice work Melba... looks really cool

8)

Share this post


Link to post
Share on other sites

Posted

Beege,

Thanks for finding that bug - not too difficult to find and fix. I was using WinGetPos and not WinGetClientSize in part of the resizing code and so the frames were incorrectly resized too large - as you noticed. :)

New version in the first post - your script works fine for me with this version. ;)

M23

Excellent! Posted Image

Share this post


Link to post
Share on other sites

Posted

Very cool UDF.

Thanks for this share:rolleyes:

Share this post


Link to post
Share on other sites

Posted

[NEW VERSION - 4 Nov 10] - Added user-defined intial position of separator bar within Frame. New UDF & example code and zip in first post.

Warning: Script-breaking syntax change. You need to adjust the calling syntax if you used any parameters other than the separator orientation.

Sorry about that, but I felt keeping the various parameters in logical groups was more important. :graduated:

M23

Share this post


Link to post
Share on other sites

Posted

Melba23,

Good idea about the intial position. Do you know of a way that I could retrieve or calculate the current position of the separator? My goal is to be able to save and then restore positioning.. ThanksPosted Image

Share this post


Link to post
Share on other sites

Posted

Beege,

retrieve or calculate the current position of the separator

No problem to do this with a small UDF function _GUIFrame_GetSepPos - all the values required are already stored within the UDF. :(

New UDF:

#include-once
; #INDEX# ============================================================================================================
; Title .........: GUIFrame
; AutoIt Version : 3.3 +
; Language ......: English
; Description ...: Splits GUI into slideable and resizable 2 part frames
; Remarks .......: - The user must call _GUIFrame_Exit on exit to delete subclassed separator bars to the
;                  UDF created WndProc and to release the Callback.
;                  - Only 2 levels of frames supported
;                  - If the script already has a WM_SIZE handler then do NOT use _GUIFrame_ResizeReg, but call
;                  _GUIFrame_SIZE_Handler from within it
; Author ........: Original UDF by Kip
; Modified ......; This version by Melba23
; ====================================================================================================================

;#AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

; #INCLUDES# =========================================================================================================
#include <WinAPI.au3>

; #GLOBAL VARIABLES# =================================================================================================

; Array to hold handles for each frame set
Global $aGF_HandleIndex[1][7]
; [0][0] = 0 ; Count of frames      [0][1] = Move registered flag
; [n][0] = Parent GUI handle        [n][4] = Original GUI handle
; [n][1] = First frame handle       [n][5] = Indices of first frame internal frames
; [n][2] = Second frame handle      [n][6] = Indices of second frame internal frames
; [n][3] = Separator bar handle

; Array to hold sizing percentages for each frame set
Global $aGF_SizingIndex[1][6]
; [n][0] = First frame min      [n][2] = X coord    [n][4] = Width
; [n][1] = Second frame min     [n][3] = Y coord    [n][5] = Height

; Array to hold other settings for each frame set
Global $aGF_SettingsIndex[1][3]
; [n][0] = Separator orientation (vert/horz = 0/1)
; [n][1] = Resizable frame flag (0/1)
; [n][2] = Separator size (default = 5)

; Array to hold WinProc handles for each separator
Global $aGF_SepProcIndex[1][2] = [[0, 0]]

; Store registered Callback handle
Global $hGF_RegCallBack = DllCallbackRegister("_GUIFrame_SepWndProc", "int", "hwnd;uint;wparam;lparam")
$aGF_SepProcIndex[0][1] = DllCallbackGetPtr($hGF_RegCallBack)

; #CURRENT# ==========================================================================================================
; _GUIFrame_Create:       Splits a GUI into 2 frames
; _GUIFrame_SetMin:       Sets minimum sizes for frames
; _GUIFrame_ResizeSet:    Sets resizing flag for all or specified frames
; _GUIFrame_ResizeReg:    Registers WM_SIZE mesasge for resizing
; _GUIFrame_SIZE_Handler: Resizes frames when a top-level GUI is resized
; _GUIFrame_GetHandle:    Returns the handle of a frame element (required for further splitting)
; _GUIFrame_Switch:       Sets a frame element as current GUI
; _GUIFrame_GetSepPos:    Returns the current position of the separator
; _GUIFrame_Exit:         Deletes all subclassed separator bars to free UDF WndProc and frees registered callback handle
; ====================================================================================================================

; #INTERNAL_USE_ONLY#=================================================================================================
; _GUIFrame_SepSubClass:   Sets new WndProc for frame separator bar
; _GUIFrame_SepWndProc:    New WndProc for frame separator bar
; _GUIFrame_SepPassMsg:    Passes Msg to original WndProc for action
; _GUIFrame_Move:          Moves and resizes frame elements and separator bars
; _GUIFrame_AdjIntFrames:  Moves and resizes internal frame elements when parent frame is resized
; ====================================================================================================================

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_Create
; Description ...: Splits a GUI into 2 frames
; Syntax.........: _GUIFrame_Create($hWnd, $iSepOrient = 0, $iSepPos = 0, $iSepSize = 5, $iX = 0, $iY = 0, $iWidth = 0, $iHeight = 0, $iStyle = 0, $iExStyle = 0)
; Parameters ....: $hWnd - Handle of GUI to split
;                  $iSepOrient - Orientation of separator bar: 0 = Vertical (default), 1 = Horizontal
;                  $iSepPos - Required initial position of separator (default = centre of frame GUI)
;                  $iSepSize - Size of separator bar (default = 5, min = 3, max = 9)
;                  $iX - Left of frame area (default = 0)
;                  $iY - Top of frame area (default = 0)
;                  $iWidth - Width of frame area (default = full width)
;                  $iHeight - Height of frame area (default = full height)
;                  SiStyle - Required style value for frame elements
;                  SiExStyle - Required extended style value for frame elements
; Requirement(s).: v3.3 +
; Return values .: Success:  Returns index number of frame/separator set
;                  Failure:  Returns 0 and sets @error as follows:
;                  1 = Child limit exceeded
;                  2 = GUI creation failed
;                  2 = Separator subclassing failed
; Author ........: Kip
; Modified ......: Melba23
; Remarks .......: - The user must call _GUIFrame_Exit on exit to delete subclassed separator bars to free the
;                  UDF created WndProc and to release the registered Callback.
;                  - Only 1 level of child frames is supported
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_Create($hWnd, $iSepOrient = 0, $iSepPos = 0, $iSepSize = 5, $iX = 0, $iY = 0, $iOrg_Width = 0, $iOrg_Height = 0, $iStyle = 0, $iExStyle = 0)

    Local $iSeperator_Pos, $hSeparator, $hFirstFrame, $hSecondFrame

    ; Check we are not creating a 3rd level frame
    For $i = $aGF_HandleIndex[0][0] To 1 Step -1
        ; Check previous frames
        If $aGF_HandleIndex[$i][1] = $hWnd Or $aGF_HandleIndex[$i][2] = $hWnd Then
            ; Now see if these frames have a parent
            For $j = 1 To $aGF_HandleIndex[0][0]
                ; If so return
                If $aGF_HandleIndex[$j][1] = $hWnd Or $aGF_HandleIndex[$j][2] = $hWnd Then
                    If $j <> 1 Then Return SetError(1, 0, 0)
                EndIf
            Next
        EndIf
    Next

    ; Set separator size
    Local $iSeparatorSize = 5
    Switch $iSepSize
        Case 3 To 9
            $iSeparatorSize = $iSepSize
    EndSwitch

    ; Set default sizing if no parameters set
    Local $iWidth = $iOrg_Width
    Local $iHeight = $iOrg_Height
    Local $aFullSize = WinGetClientSize($hWnd)
    If Not $iOrg_Width Then $iWidth = $aFullSize[0]
    If Not $iOrg_Height Then $iHeight = $aFullSize[1]

    ; Create parent GUI within client area
    Local $hParent = GUICreate("FrameParent", $iWidth, $iHeight, $iX, $iY, BitOR(0x40000000, $iStyle), $iExStyle, $hWnd) ; $WS_CHILD
    GUISetState(@SW_SHOW, $hParent)

    ; Confirm size of frame parent client area
    Local $aSize = WinGetClientSize($hParent)
    $iWidth = $aSize[0]
    $iHeight = $aSize[1]

    If $iSepOrient = 0 Then

        ; Set initial separator position
		$iSeperator_Pos = $iSepPos
		; Adjust position if not within GUI or default set (=0)
        If $iSepPos > $iWidth Or $iSepPos < 1 Then
            $iSeperator_Pos = Round(($iWidth / 2) - ($iSeparatorSize / 2))
        EndIf
        ; Create separator bar and force cursor change over separator
        $hSeparator = GUICreate("", $iSeparatorSize, $iHeight, $iSeperator_Pos, 0, 0x40000000, -1, $hParent) ;$WS_CHILD
        GUICtrlCreateLabel("", 0, 0, $iSeparatorSize, $iHeight, -1, 0x00000001) ; $WS_EX_DLGMODALFRAME
        GUICtrlSetCursor(-1, 13)
        GUISetState(@SW_SHOW, $hSeparator)
        ; Create the sizable frames
        $hFirstFrame = GUICreate("", $iSeperator_Pos, $iHeight, 0, 0, 0x40000000, -1, $hParent) ;$WS_CHILD
        GUISetState(@SW_SHOW, $hFirstFrame)
        $hSecondFrame = GUICreate("", $iWidth - ($iSeperator_Pos + $iSeparatorSize), $iHeight, $iSeperator_Pos + $iSeparatorSize, 0, 0x40000000, -1, $hParent) ;$WS_CHILD
        GUISetState(@SW_SHOW, $hSecondFrame)

    Else

        $iSeperator_Pos = $iSepPos
        If $iSepPos > $iHeight Or $iSepPos < 1 Then
            $iSeperator_Pos = Round(($iHeight / 2) - ($iSeparatorSize / 2))
        EndIf
		$hSeparator = GUICreate("", $iWidth, $iSeparatorSize, 0, $iSeperator_Pos, 0x40000000, -1, $hParent) ;$WS_CHILD
        GUICtrlCreateLabel("", 0, 0, $iWidth, $iSeparatorSize, -1, 0x01) ; $WS_EX_DLGMODALFRAME
        GUICtrlSetCursor(-1, 11)
        GUISetState(@SW_SHOW, $hSeparator)
        $hFirstFrame = GUICreate("", $iWidth, $iSeperator_Pos, 0, 0, 0x40000000, -1, $hParent) ;$WS_CHILD
        GUISetState(@SW_SHOW, $hFirstFrame)
        $hSecondFrame = GUICreate("", $iWidth, $iHeight - ($iSeperator_Pos + $iSeparatorSize), 0, $iSeperator_Pos + $iSeparatorSize, 0x40000000, -1, $hParent) ;$WS_CHILD
        GUISetState(@SW_SHOW, $hSecondFrame)

    EndIf

    ; Check for error creating GUIs
    If $hParent = 0 Or $hSeparator = 0 Or $hFirstFrame = 0 Or $hSecondFrame = 0 Then
        ; Delete all GUIs and return error
        GUICreate($hParent)
        GUIDelete($hSeparator)
        GUIDelete($hFirstFrame)
        GUICreate($hSecondFrame)
        Return SetError(2, 0, 0)
    EndIf

    ; Subclass the separator
    If _GUIFrame_SepSubClass($hSeparator) = 0 Then
        ; If Subclassing failed then delete all GUIs and return error
        GUICreate($hParent)
        GUIDelete($hSeparator)
        GUIDelete($hFirstFrame)
        GUICreate($hSecondFrame)
        Return SetError(3, 0, 0)
    EndIf

    ; Create a new line in the arrays
    Local $iIndex = $aGF_HandleIndex[0][0] + 1
    ReDim $aGF_HandleIndex[$iIndex + 1][7]
    ReDim $aGF_SizingIndex[$iIndex + 1][6]
    ReDim $aGF_SettingsIndex[$iIndex + 1][3]

    ; Store this frame set variables/defaults in the new lines
    $aGF_HandleIndex[0][0] = $iIndex
    $aGF_HandleIndex[$iIndex][0] = $hParent
    $aGF_HandleIndex[$iIndex][1] = $hFirstFrame
    $aGF_HandleIndex[$iIndex][2] = $hSecondFrame
    $aGF_HandleIndex[$iIndex][3] = $hSeparator
    $aGF_HandleIndex[$iIndex][5] = 0
    $aGF_HandleIndex[$iIndex][6] = 0
    $aGF_SizingIndex[$iIndex][0] = 0
    $aGF_SizingIndex[$iIndex][1] = 0
    $aGF_SettingsIndex[$iIndex][0] = $iSepOrient
    $aGF_SettingsIndex[$iIndex][1] = 0
    $aGF_SettingsIndex[$iIndex][2] = $iSeparatorSize

    ; Store this frame index in parent line if parent is an existing frame
    For $i = 1 To $aGF_HandleIndex[0][0] - 1
        If $aGF_HandleIndex[$i][1] = $hWnd Then
            If $aGF_HandleIndex[$i][5] = 0 Then
                $aGF_HandleIndex[$i][5] = $iIndex
            Else
                $aGF_HandleIndex[$i][5] &= "|" & $iIndex
            EndIf
            ExitLoop
        EndIf
        If $aGF_HandleIndex[$i][2] = $hWnd Then
            If $aGF_HandleIndex[$i][6] = 0 Then
                $aGF_HandleIndex[$i][6] = $iIndex
            Else
                $aGF_HandleIndex[$i][6] &= "|" & $iIndex
            EndIf
            ExitLoop
        EndIf
    Next

    ; If neither index set, it is a base level GUI so store it
    If $aGF_HandleIndex[$i][5] + $aGF_HandleIndex[$i][6] = 0 Then $aGF_HandleIndex[$iIndex][4] = $hWnd

    ; Store coordinate and size fractions
    If $iX Then
        $aGF_SizingIndex[$iIndex][2] = $iX / $aFullSize[0]
    Else
        $aGF_SizingIndex[$iIndex][2] = 0
    EndIf
    If $iY Then
        $aGF_SizingIndex[$iIndex][3] = $iY / $aFullSize[1]
    Else
        $aGF_SizingIndex[$iIndex][3] = 0
    EndIf
    If $iOrg_Width Then
        $aGF_SizingIndex[$iIndex][4] = $iOrg_Width / $aFullSize[0]
    Else
        $aGF_SizingIndex[$iIndex][4] = 1
    EndIf
    If $iOrg_Height Then
        $aGF_SizingIndex[$iIndex][5] = $iOrg_Height / $aFullSize[1]
    Else
        $aGF_SizingIndex[$iIndex][5] = 1
    EndIf

    ; Switch back to main GUI
    GUISwitch($hWnd)

    ; Return the index for this frame
    Return $iIndex

EndFunc   ;==>_GUIFrame_Create

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_SetMin
; Description ...: Sets minimum sizes for frames
; Syntax.........: _GUIFrame_SetMin($iFrame, $iFirstMin = 0, $iSecondMin = 0)
; Parameters ....: $iFrame - Index of frame set as returned by _GUIFrame_Create
;                  $iFirstMin - Min size of first (left/top) frame - max half size
;                  $iSecondMin - Min Size of second (right/bottom) frame - max half size
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23 based on some original code by Kip
; Modified ......:
; Remarks .......: If the frame is resized, these minima are adjusted accordingly
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_SetMin($iFrame, $iFirstMin = 0, $iSecondMin = 0)

    ; Check for valid frame index
    If $iFrame < 1 Or $iFrame > $aGF_HandleIndex[0][0] Then Return 0
    ; Get size of parent
    Local $aSize = WinGetClientSize($aGF_HandleIndex[$iFrame][0])
    ; Now check orientation and determine
    Local $iMax, $iFullSize
    If $aGF_SettingsIndex[$iFrame][0] = 0 Then
        $iMax = Floor(($aSize[0] / 2) - $aGF_SettingsIndex[$iFrame][2])
        $iFullSize = $aSize[0]
    Else
        $iMax = Floor(($aSize[1] / 2) - $aGF_SettingsIndex[$iFrame][2])
        $iFullSize = $aSize[1]
    EndIf
    ; Set minimums
    If $iFirstMin > $iMax Then
        $aGF_SizingIndex[$iFrame][0] = $iMax / $iFullSize
    Else
        $aGF_SizingIndex[$iFrame][0] = $iFirstMin / $iFullSize
    EndIf
    If $iSecondMin > $iMax Then
        $aGF_SizingIndex[$iFrame][1] = $iMax / $iFullSize
    Else
        $aGF_SizingIndex[$iFrame][1] = $iSecondMin / $iFullSize
    EndIf

EndFunc   ;==>_GUIFrame_SetMin

; #FUNCTION# =========================================================================================================
; Name...........:  _GUIFrame_ResizeSet
; Description ...: Sets resizing flag for frames
; Syntax.........:  _GUIFrame_ResizeSet($iFrame = 0)
; Parameters ....: $iFrame - Index of frame set as returned by _GUIFrame_Create
;                  (Default - 0 = all existing frames)
; Requirement(s).: v3.3 +
; Return values .: Success: 2 - All existing frame flags set
;                           1 - Specified flag set
;                  Failure: 0 with @error set to 1 - Invalid frame specified
; Author ........: Melba23
; Modified ......:
; Remarks .......:
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_ResizeSet($iFrame = 0)

    Switch $iFrame
        Case 0 ; Set all frames
            For $i = 1 To $aGF_HandleIndex[0][0]
                $aGF_SettingsIndex[$i][1] = 1
            Next
            Return 2
        Case 1 To $aGF_HandleIndex[0][0] ; Only valid frames accepted
            $aGF_SettingsIndex[$iFrame][1] = 1
            Return 1
        Case Else ; Error
            Return SetError(1, 0, 0)
    EndSwitch

EndFunc   ;==>_GUIFrame_ResizeSet

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_ResizeReg
; Description ...: Registers WM_SIZE message for resizing
; Syntax.........:  _GUIFrame_ResizeReg()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: Success: 1 - Message handler registered
;                  Failure: 0 with @error set to 1
; Author ........: Melba23
; Modified ......:
; Remarks .......:
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_ResizeReg()

    ; Register the WM_SIZE message
    If $aGF_HandleIndex[0][1] = 0 Then
        Local $iRet = GUIRegisterMsg(0x05, "_GUIFrame_SIZE_Handler") ; $WM_SIZE
        If $iRet Then
            $aGF_HandleIndex[0][1] = 1
            Return 1
        EndIf
    EndIf
    Return SetError(1, 0, 0)

EndFunc   ;==>_GUIFrame_ResizeReg

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_SIZE_Handler
; Description ...: Used to resize frames when a top-level GUI is resized
; Syntax.........: _GUIFrame_SIZE_Handler($hWnd, $iMsg, $wParam, $lParam)
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Modified ......:
; Remarks .......: If the script already has a WM_SIZE handler, then just call this function from within it
;                  and do NOT use the _GUIFrame_ResizeReg function
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_SIZE_Handler($hWnd, $iMsg, $wParam, $lParam)

    #forceref $iMsg, $wParam, $lParam

    Local $iIndex

    ; Get index of base frame set
    For $iIndex = 1 To $aGF_HandleIndex[0][0]
        If $aGF_HandleIndex[$iIndex][4] = $hWnd Then ExitLoop
    Next

    ; If handle not found
    If $iIndex > $aGF_HandleIndex[0][0] Then Return "GUI_RUNDEFMSG"

    ; Get new GUI size
    Local $aSize = WinGetClientSize($hWnd)

    ; Resize frame
    _GUIFrame_Move($iIndex, $aSize[0] * $aGF_SizingIndex[$iIndex][2], $aSize[1] * $aGF_SizingIndex[$iIndex][3], $aSize[0] * $aGF_SizingIndex[$iIndex][4], $aSize[1] * $aGF_SizingIndex[$iIndex][5])

    ; Adjust any resizeable internal framess
    _GUIFrame_AdjIntFrames($iIndex)

    Return "GUI_RUNDEFMSG"

EndFunc   ;==>_GUIFrame_SIZE_Handler

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_GetHandle
; Description ...: Returns the handle of a frame element (required for further splitting)
; Syntax.........: _GUIFrame_GetHandle($iFrame, $iElement)
; Parameters ....: $iFrame - Index of frame set as returned by _GUIFrame_Create
;                  $iElement - 1 = first (left/top) frame, 2 = second (right/bottom) frame
; Requirement(s).: v3.3 +
; Return values .: Success: Handle of frame
;                  Failure: 0 with @error set as follows
;                           1 - Invalid frame specified
;                           2 - Invalid element specified
; Author ........: Kip
; Modified ......: Melba23
; Remarks .......: _GUIFrame_Create requires a GUI handle as a parameter
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_GetHandle($iFrame, $iElement)

    ; Check valid frame index and element
    Switch $iFrame
        Case 1 To $aGF_HandleIndex[0][0]
            Switch $iElement
                Case 1, 2
                    ; Return handle
                    Return $aGF_HandleIndex[$iFrame][$iElement]
            EndSwitch
            Return SetError(2, 0, 0)
    EndSwitch
    Return SetError(1, 0, 0)

EndFunc   ;==>_GUIFrame_GetHandle

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_Switch
; Description ...: Sets a frame element as current GUI
; Syntax.........: _GUIFrame_Switch($iFrame, $iElement)
; Parameters ....: $iFrame - Index of frame set as returned by _GUIFrame_Create
;                  $iElement - 1 = first (left/top) frame, 2 = second (right/bottom) frame
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Kip
; Modified ......: Melba23
; Remarks .......: Subsequent controls are created in the specified frame element
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_Switch($iFrame, $iElement)

    ; Check valid frame index and element
    Switch $iFrame
        Case 1 To $aGF_HandleIndex[0][0]
            Switch $iElement
                Case 1, 2
                    ; Switch to specified element
                    Return GUISwitch($aGF_HandleIndex[$iFrame][$iElement])
            EndSwitch
            Return SetError(2, 0, 0)
    EndSwitch
    Return SetError(1, 0, 0)

EndFunc   ;==>_GUIFrame_Switch

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_GetSepPos()
; Description ...: Returns the current position of the separator
; Syntax.........:_GUIFrame_GetSepPos($iFrame)
; Parameters ....: $iFrame - Index of frame set as returned by _GUIFrame_Create
; Requirement(s).: v3.3 +
; Return values .: Success: Position of separator
;                  Failure: -1
; Author ........: Melba23
; Remarks .......: This value can be stored and used as the initial separator position parameter in _GUIFrame_Create
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_GetSepPos($iFrame)

	Local $iSepPos

	; Check for valid frame index
    If $iFrame < 1 Or $iFrame > $aGF_HandleIndex[0][0] Then Return -1

	; Get position of first frame
	Local $aFrame_Pos = WinGetPos($aGF_HandleIndex[$iFrame][1])
	; Get position of separator
	Local $aSep_Pos = WinGetPos($aGF_HandleIndex[$iFrame][3])
	; Check on separator orientation
	If $aGF_SettingsIndex[$iFrame][0] Then
		$iSepPos = $aSep_Pos[1] - $aFrame_Pos[1]
	Else
		$iSepPos = $aSep_Pos[0] - $aFrame_Pos[0]
	EndIf
	Return $iSepPos

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_Exit()
; Description ...: Deletes all subclassed separator bars to free UDF WndProc and frees registered callback handle
; Syntax.........:_GUIFrame_Exit()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Kip
; Modified ......: Melba23
; Remarks .......: The user must call _GUIFrame_Exit on exit to delete all subclassed separator bars and so free the
;                  UDF created WndProc.
; Example........: Yes
;=====================================================================================================================
Func _GUIFrame_Exit()

    ; Delete all subclassed separator bars
    For $i = $aGF_HandleIndex[0][0] To 1 Step -1
        GUIDelete($aGF_HandleIndex[$i][3])
    Next
    ; Free registered Callback handle
    DllCallbackFree($hGF_RegCallBack)

EndFunc   ;==>_GUIFrame_Exit

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _GUIFrame_SepSubClass
; Description ...: Sets new WndProc for frame separator bar
; Author ........: Kip
; Modified.......: Melba23
; Remarks .......: This function is used internally by _GUIFrame_Create
; ===============================================================================================================================
Func _GUIFrame_SepSubClass($hWnd)

    ; Check separator has not already been used
    For $i = 1 To $aGF_SepProcIndex[0][0]
        If $aGF_SepProcIndex[$i][0] = $hWnd Then Return 0
    Next

    ; Store current WinProc handle in new array line
    Local $iIndex = $aGF_SepProcIndex[0][0] + 1
    ReDim $aGF_SepProcIndex[$iIndex + 1][2]
    $aGF_SepProcIndex[0][0] = $iIndex
    $aGF_SepProcIndex[$iIndex][0] = $hWnd
    $aGF_SepProcIndex[$iIndex][1] = _WinAPI_SetWindowLong($hWnd, -4, $aGF_SepProcIndex[0][1]) ; $GWL_WNDPROC

    ; Check for subclassing error
    If @error Or $aGF_SepProcIndex[$iIndex][1] = 0 Then Return 0
    ; Return success
    Return 1

EndFunc   ;==>_GUIFrame_SepSubClass

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _GUIFrame_SepWndProc
; Description ...: New WndProc for frame separator bar
; Author ........: Kip
; Modified.......: Melba23
; Remarks .......: This function is used internally by _GUIFrame_SepSubClass
; ===============================================================================================================================
Func _GUIFrame_SepWndProc($hWnd, $iMsg, $wParam, $lParam)

    Local $iSubtract

    If $iMsg = 0x0111 Then ; WM_COMMAND

        ; Check if hWnd is a Separator bar
        For $iIndex = 1 To $aGF_HandleIndex[0][0]
            If $aGF_HandleIndex[$iIndex][3] = $hWnd Then ExitLoop
        Next
        ; If not then pass message on to org WndProc
        If $iIndex > $aGF_HandleIndex[0][0] Then Return _GUIFrame_SepPassMsg($hWnd, $iMsg, $wParam, $lParam)

        ; Extract values from array
        Local $hParent = $aGF_HandleIndex[$iIndex][0]
        Local $hFirstFrame = $aGF_HandleIndex[$iIndex][1]
        Local $hSecondFrame = $aGF_HandleIndex[$iIndex][2]
        Local $hSeparator = $aGF_HandleIndex[$iIndex][3]
        Local $iFirstMin = $aGF_SizingIndex[$iIndex][0]
        Local $iSecondMin = $aGF_SizingIndex[$iIndex][1]
        Local $iSeparatorSize = $aGF_SettingsIndex[$iIndex][2]

        ; Get client size of the parent
        Local $aClientSize = WinGetClientSize($hParent)
        Local $iWidth = $aClientSize[0]
        Local $iHeight = $aClientSize[1]

        ; Get cursor info for the Separator
        Local $aCInfo = GUIGetCursorInfo($hSeparator)

        ; Depending on separator orientation
        If $aGF_SettingsIndex[$iIndex][0] = 0 Then

            ; Get Separator X-coord
            $iSubtract = $aCInfo[0]

            Do

                ; Get parent X-coord
                $aCInfo = GUIGetCursorInfo($hParent)
                Local $iCursorX = $aCInfo[0]

                ; Determine width of first frame
                Local $iFirstWidth = $iCursorX - $iSubtract
                ; And ensure it is at least minimum
                If $iFirstWidth < $iWidth * $iFirstMin Then $iFirstWidth = $iWidth * $iFirstMin
                If $iWidth - ($iFirstWidth + $iSeparatorSize) < $iWidth * $iSecondMin Then $iFirstWidth = $iWidth - ($iWidth * $iSecondMin) - $iSeparatorSize

                ; Move the GUIs to the correct places
                WinMove($hFirstFrame, "", 0, 0, $iFirstWidth, $iHeight)
                WinMove($hSecondFrame, "", $iFirstWidth + $iSeparatorSize, 0, $iWidth - ($iFirstWidth + $iSeparatorSize), $iHeight)
                WinMove($hSeparator, "", $iFirstWidth, 0, $iSeparatorSize, $iHeight)

                ; Adjust any resizeable internal frames
                _GUIFrame_AdjIntFrames($iIndex)

                ; Do until the mouse button is released
            Until Not _WinAPI_GetAsyncKeyState(0x01)

        ElseIf $aGF_SettingsIndex[$iIndex][0] = 1 Then

            $iSubtract = $aCInfo[1]
            Do
                $aCInfo = GUIGetCursorInfo($hParent)
                Local $iCursorY = $aCInfo[1]
                Local $iFirstHeight = $iCursorY - $iSubtract
                If $iFirstHeight < $iHeight * $iFirstMin Then $iFirstHeight = $iHeight * $iFirstMin
                If $iHeight - ($iFirstHeight + $iSeparatorSize) < $iHeight * $iSecondMin Then $iFirstHeight = $iHeight - ($iHeight * $iSecondMin) - $iSeparatorSize
                WinMove($hFirstFrame, "", 0, 0, $iWidth, $iFirstHeight)
                WinMove($hSecondFrame, "", 0, $iFirstHeight + $iSeparatorSize, $iWidth, $iHeight - ($iFirstHeight + $iSeparatorSize))
                WinMove($hSeparator, "", 0, $iFirstHeight, $iWidth, $iSeparatorSize)
                _GUIFrame_AdjIntFrames($iIndex)
            Until Not _WinAPI_GetAsyncKeyState(0x01)

        EndIf

    EndIf

    ; Pass the message on to org WndProc
    Return _GUIFrame_SepPassMsg($hWnd, $iMsg, $wParam, $lParam)

EndFunc   ;==>_GUIFrame_SepWndProc

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _GUIFrame_SepPassMsg
; Description ...: Passes Msg to frame parent WndProc for action
; Author ........: Kip
; Modified.......: Melba23
; Remarks .......: This function is used internally by _GUIFrame_SepWndProc
; ===============================================================================================================================
Func _GUIFrame_SepPassMsg($hWnd, $iMsg, $wParam, $lParam)

    For $i = 1 To $aGF_SepProcIndex[0][0]
        If $aGF_SepProcIndex[$i][0] = $hWnd Then Return _WinAPI_CallWindowProc($aGF_SepProcIndex[$i][1], $hWnd, $iMsg, $wParam, $lParam)
    Next

EndFunc   ;==>_GUIFrame_SepPassMsg

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _GUIFrame_Move
; Description ...: Moves and resizes frame elements and separator bars
; Author ........: Kip
; Modified.......: Melba23
; Remarks .......: This function is used internally by _GUIFrame_SepWndProc and _GUIFrame_SIZE_Handler
; ===============================================================================================================================
Func _GUIFrame_Move($iFrame, $iX, $iY, $iWidth = 0, $iHeight = 0)

    ; Check valid frame index
    If $iFrame < 1 Or $iFrame > $aGF_HandleIndex[0][0] Then Return 0

    Local $iSeparatorSize = $aGF_SettingsIndex[$iFrame][2]
    Local $iTotal

    ; Set size if not specified
    If Not $iWidth Then $iWidth = _WinAPI_GetWindowWidth($aGF_HandleIndex[$iFrame][0])
    If Not $iHeight Then $iHeight = _WinAPI_GetWindowHeight($aGF_HandleIndex[$iFrame][0])

    ; Move parent
    WinMove($aGF_HandleIndex[$iFrame][0], "", $iX, $iY, $iWidth, $iHeight)

    ; Get size of first frame depending on orientation
    Local $aWinPos = WinGetClientSize($aGF_HandleIndex[$iFrame][1])
    Local $iSize = $aWinPos[0]
    If $aGF_SettingsIndex[$iFrame][0] = 1 Then $iSize = $aWinPos[1]

    ; Set frame min percentages
    Local $iFirstMin = $aGF_SizingIndex[$iFrame][0]
    Local $iSecondMin = $aGF_SizingIndex[$iFrame][1]

    ; Depending on separator orientation
    If $aGF_SettingsIndex[$iFrame][0] = 0 Then

        ; Move frames and separator as required
        $iTotal = $iWidth
        If $iSize < $iWidth * $iFirstMin Then $iSize = $iWidth * $iFirstMin
        If $iTotal - $iSize - $iSeparatorSize < $iWidth * $iSecondMin Then $iSize = $iTotal - ($iWidth * $iSecondMin) - $iSeparatorSize
        WinMove($aGF_HandleIndex[$iFrame][1], "", 0, 0, $iSize, $iHeight)
        WinMove($aGF_HandleIndex[$iFrame][2], "", $iSize + $iSeparatorSize, 0, $iTotal - $iSize - $iSeparatorSize, $iHeight)
        WinMove($aGF_HandleIndex[$iFrame][3], "", $iSize, 0, $iSeparatorSize, $iHeight)

    ElseIf $aGF_SettingsIndex[$iFrame][0] = 1 Then

        $iTotal = $iHeight
        If $iSize < $iHeight * $iFirstMin Then $iSize = $iHeight * $iFirstMin
        If $iTotal - $iSize - $iSeparatorSize < $iHeight * $iSecondMin Then $iSize = $iTotal - ($iHeight * $iSecondMin) - $iSeparatorSize
        WinMove($aGF_HandleIndex[$iFrame][1], "", 0, 0, $iWidth, $iSize)
        WinMove($aGF_HandleIndex[$iFrame][2], "", 0, $iSize + $iSeparatorSize, $iWidth, $iTotal - $iSize - $iSeparatorSize)
        WinMove($aGF_HandleIndex[$iFrame][3], "", 0, $iSize, $iWidth, $iSeparatorSize)

    EndIf

EndFunc   ;==>_GUIFrame_Move

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _GUIFrame_AdjIntFrames
; Description ...: Moves and resizes internal frame elements when parent frame is resized
; Author ........: Melba23
; Modified.......:
; Remarks .......: This function is called by _GUIFrame_SepWndProc and _GUIFrame_SIZE_Handler
; ===============================================================================================================================
Func _GUIFrame_AdjIntFrames($iIndex)

    Local $aInternal, $iIntIndex, $aPos

    ; Array elements are adjacent for ease of coding
    For $i = 0 To 1

        ; Adjust internal frames of first/second frame if any exist
        If $aGF_HandleIndex[$iIndex][5 + $i] <> 0 Then
            ; StringSplit the element content on "|"
            $aInternal = StringSplit($aGF_HandleIndex[$iIndex][5 + $i], "|")
            ; Then loop though the Number(values) found
            For $j = 1 To $aInternal[0]
                $iIntIndex = Number($aInternal[$j])
                ; Check if internal frame is resizable
                If $aGF_SettingsIndex[$iIntIndex][1] = 1 Then
                    ; Get size of first/second frame
                    $aPos = WinGetPos($aGF_HandleIndex[$iIndex][1 + $i])
                    ; Adjust sizes of the separator and frames
                    _GUIFrame_Move($iIntIndex, $aPos[2] * $aGF_SizingIndex[$iIntIndex][2], $aPos[3] * $aGF_SizingIndex[$iIntIndex][3], $aPos[2] * $aGF_SizingIndex[$iIntIndex][4], $aPos[3] * $aGF_SizingIndex[$iIntIndex][5])
                EndIf
            Next
        EndIf
    Next

EndFunc   ;==>_GUIFrame_AdjIntFrames

New example (last few lines show the new function):

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

#include "GUIFrame.au3"

Global $hButton_3 = 9999, $hButton_4 = 9999

; Create the main GUI
$hGUI_1 = GUICreate("GUI Frames", 600, 500, 100, 100, $WS_SIZEBOX)
GUISetState(@SW_SHOW, $hGUI_1)

; Create a full size vertically-divided frame within the main GUI
$iFrame_A = _GUIFrame_Create($hGUI_1)
; Set min sizes for the frames
_GUIFrame_SetMin($iFrame_A, 100, 100)
; Switch to first (left) frame of Frame_A
_GUIFrame_Switch($iFrame_A, 1)
GUISetBkColor(0xC0C0C0)
$hLabel_1 = GUICtrlCreateLabel("First frame within frame_A", 10, 10, 120, 100)
$hButton_1 = GUICtrlCreateButton("Frame", 10, 200, 80, 30)
GUICtrlSetResizing(-1, $GUI_DOCKSIZE)
; Switch to second (right) frame of Frame_A
_GUIFrame_Switch($iFrame_A, 2)
GUISetBkColor(0xFFC4FF)
$hlabel_2 = GUICtrlCreateLabel("Second frame within frame_A", 10, 10, 120, 100)
$hButton_2 = GUICtrlCreateButton("Frame", 10, 200, 80, 30)
GUICtrlSetResizing(-1, $GUI_DOCKSIZE)

$hGUI_2 = GUICreate("GUI Frames", 400, 400, 900, 100, $WS_SIZEBOX)
GUISetBkColor(0x00D0FF)
GUISetState(@SW_SHOW, $hGUI_2)

; Create a sized horizontally-divided frame within the main GUI
$iFrame_B = _GUIFrame_Create($hGUI_2, 1, 50, 9, 10, 10, 200, 200)
; Set min sizes for the frames
_GUIFrame_SetMin($iFrame_B, 50, 50)
; Switch to first (top) frame of Frame_B
_GUIFrame_Switch($iFrame_B, 1)
GUISetBkColor(0xFF8000)
GUICtrlCreateLabel("First frame within frame_B", 10, 10, 120, 100)
; Switch to second (bottom) frame of Frame_B
_GUIFrame_Switch($iFrame_B, 2)
GUISetBkColor(0x80FF00)
GUICtrlCreateLabel("Second frame within frame_B", 10, 10, 120, 100)

; Register the WM_MOVE message as we do not register it elsewhere in the script
_GUIFrame_ResizeReg()
; Set all existing frames to resizeable
_GUIFrame_ResizeSet(0)


While 1
    Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			; Delete all subclassed separators and free Callback
			_GUIFrame_Exit()
            Exit

		Case $hButton_1
			GUICtrlDelete($hLabel_1)
			GUICtrlDelete($hButton_1)

			; Create a sized horizontally-divided frame control within the left (first) frame of Frame_A
			$iFrame_C = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_A, 1), 0, 0, 3, 10, 10, 200, 200)
			; Set min sizes for the frames
			_GUIFrame_SetMin($iFrame_C, 50, 50)
			; Switch to first (top) frame of Frame_B
			_GUIFrame_Switch($iFrame_C, 1)
			GUISetBkColor(0xC4C4FF)
			GUICtrlCreateLabel("First frame within frame_C", 10, 10, 100, 100)
			; Switch to second (bottom) frame of Frame_C
			_GUIFrame_Switch($iFrame_C, 2)
			GUISetBkColor(0xC4FFC4)
			GUICtrlCreateLabel("Second frame within frame_C", 10, 10, 100, 100)

			; Create another sized horizontally-divided frame control within the left (first) frame of Frame_A
			$iFrame_D = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_A, 1), 0, 200, 9, 10, 250, 270, 100)
			; Set min sizes for the frames
			_GUIFrame_SetMin($iFrame_D, 50, 50)
			; Switch to first (top) frame of Frame_D
			_GUIFrame_Switch($iFrame_D, 1)
			GUISetBkColor(0xC4C480)
			GUICtrlCreateLabel("First frame within frame_D", 10, 10, 100, 100)
			GUICtrlSetState(-1, $GUI_DISABLE)
			$hButton_3 = GUICtrlCreateButton("Pos", 10, 70, 30, 20)
			; Switch to second (bottom) frame of Frame_D
			_GUIFrame_Switch($iFrame_D, 2)
			GUISetBkColor(0xC480C4)
			GUICtrlCreateLabel("Second frame within frame_D", 10, 10, 50, 100)

			; Set this lower frame to resizeable
			_GUIFrame_ResizeSet($iFrame_D)

		Case $hButton_2
			GUICtrlDelete($hLabel_2)
			GUICtrlDelete($hButton_2)

			; Create a full size horizontally-divided frame control within the right (second) frame of Frame_A
			$iFrame_E = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_A, 2), 1)
			; Set min sizes for the frames
			_GUIFrame_SetMin($iFrame_E, 100, 100)
			; Switch to first (top) frame of Frame_E - all commands now affect that frame
			_GUIFrame_Switch($iFrame_E, 1)
			GUISetBkColor(0xFFFFC4)
			GUICtrlCreateLabel("First frame within frame_E", 10, 10, 150, 100)
			GUICtrlSetState(-1, $GUI_DISABLE)
			$hButton_4 = GUICtrlCreateButton("Pos", 10, 70, 30, 20)
			; Switch to second (bottom) frame of Frame_E
			_GUIFrame_Switch($iFrame_E, 2)
			GUISetBkColor(0xFFC4C4)
			GUICtrlCreateLabel("Second frame within frame_E", 10, 10, 150, 100)

			; Set this frame to resizeable
			_GUIFrame_ResizeSet($iFrame_E)

			; Try to create a 3rd level frame within Frame_E
			$iFrame_F = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_E, 1))
			If @error = 1 Then MsgBox(0, "Error = 1", "3rd level frame within Frame_E denied")

		Case $hButton_3
			ConsoleWrite("Current SepPos D: " & _GUIFrame_GetSepPos($iFrame_D) & @CRLF) ; <<<<<<<<<<<<<<<<< New function <<<<<<<<<<<<<<<<<<

		Case $hButton_4
			ConsoleWrite("Current SepPos E: " & _GUIFrame_GetSepPos($iFrame_E) & @CRLF) ; <<<<<<<<<<<<<<<<< New function <<<<<<<<<<<<<<<<<<

	EndSwitch

WEnd

Play around with it and see if it does what you want. :graduated:

M23

Share this post


Link to post
Share on other sites

Posted (edited)

Hi all,

See even newer version below! :graduated:

M23

Edited by Melba23

Share this post


Link to post
Share on other sites

Posted

@Melba23,

This is realy a great UDF ! :graduated:

Rgsd,

ptrex

Share this post


Link to post
Share on other sites

Posted (edited)

Hi all,

An even newer beta version of the UDF with the following changes:

- Removal of the limit on child frames. You can now have as many as you can fit in! [New] :graduated:

- Automatic exit clean up by using OnAutoItExitRegister to call the required function. [New]

- Ability to get current separator position within the frame to permit GUI to be recreated as it was left (see post above).[New]

- Ability to set the separator position programatically. [Newest]

Now released - see first post.

M23

Edit: Released.

Edited by Melba23

Share this post


Link to post
Share on other sites

Posted (edited)

It's great melba.

There are only 2 problems:

- I don't can test so fast as you can write (also if it is also could here, -5 Grad celsius, snowing).

- I don't have the time to rewrite my frame-scripts.

But next time I will use it.

It's surely interesting to see how it works in a "real world" script.

Thanks for all the work you have done on it and - as I can see on a quick view - I coudn't do.

Reinhard

Edited by ReFran

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0