Jump to content

Recommended Posts

Posted

I have run into some issues with what I am attempting to do with the GUIFrame UDF. One of them might be a bug or something that could be improved possibly. By the way, this is not related to the WS_EX_COMPOSITED changes that we were discussing earlier.

The two examples that I am providing are designed to work with the original GUIFrame.au3 UDF (not the beta GUIFrame_WBD_Mod.au3 version).

Diagram of what I am attempting to do:

Spoiler
┌──────────────────────────────────────────────────────┐
│                                                      │
│          (1)                                         │
│                                                      │
┼────────────────┬─────────────────────────────────────┤
│                │                                     │
│                │                                     │
│                │                                     │
│                │                                     │
│                │                                     │
│                │                                     │
│                │                                     │
│      (2)       │                (3)                  │
│                │                                     │
│                │                                     │
│                │                                     │
│                │                                     │
│                │                                     │
│                │                                     │
└────────────────┴─────────────────────────────────────┘
  1. Top area (toolbar buttons, etc.)
    • Height must remain specific pixels (eg. 100px) when GUI resizes
    • Width can resize accordingly
  2. Left side (treeview)
    • Height and width can resize accordingly
    • Control will dock to all sides and resize
  3. Right side (listview)
    • Height and width can resize accordingly
    • Control will dock to all sides and resize

 

 

The first example is where I believe that there might be a bug. This example uses the _GUIFrame_Create feature that allows you to specify the Y coordinates of where the GUI frame (FrameParent) begins. In this example, I am using the variable $iTopSpace = 60

If you resize the width of the GUI only, you notice that the controls (labels) in the two bottom frames stay at the appropriate ratio. Keep in mind, this would also represent the same whether they are treeview controls or whatever. I just used labels to keep the example simple.

Now, if you resize the GUI height, bigger to smaller, smaller to bigger, etc., you will notice that the controls (labels) in the two bottom frames start to have their ratios significantly impaired. It still happens even if I don't use GUICtrlSetResizing to lock down the label size in the top section.

I feel like there must be something within _GUIFrame_SIZE_Handler that does not take into account the value, in this case $iTopSpace = 60, placed for the Y coordinates in the _GUIFrame_Create  function. I believe that it must be getting the height for the main GUI instead of the main GUI height minus the $iTopSpace = 60 (or whatever value the user puts there).

Example 1:

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

#include "GUIFrame.au3"

; DPI awareness
DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -2)

Global $iSep_Pos

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

GUISetState(@SW_SHOW, $hGUI)

$iTopSpace = 60
$aGUISize = WinGetClientSize($hGUI)
GUICtrlCreateLabel(" ", 0, 0, $aGUISize[0], $iTopSpace)
GUICtrlSetBkColor(-1, 0x808080)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKHEIGHT)

; Create a 1st level frame
$iFrame_A = _GUIFrame_Create($hGUI, 0, 100, 5, 0, $iTopSpace, 0, 0, 0, 0x02000000)
_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 - $iTopSpace)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
GUICtrlSetBkColor(-1, 0x00FF00)

_GUIFrame_Switch($iFrame_A, 2)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_A, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10 - $iTopSpace)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
GUICtrlSetBkColor(-1, 0xFF0000)
GUICtrlSetState(-1, $GUI_DISABLE)

; Set resizing flag for all created frames
_GUIFrame_ResizeSet(0) ; 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

 

Now for the second example. I had exhausted all of my attempts to get Example 1 to work properly over the course of a few days. So in Example 2, I am attempting to use the built-in GUIFrame UDF features to make the top section an actual frame.

So with this method, all of the mathematics works out perfectly as far as how the controls and everything measures up when resizing the GUI. This seems very promising.

The problem that I am having is getting that top section (frame) to stay at a locked height. For example, let's say that the top frame is 100 pixels, I don't want it to go any smaller or larger than the 100 pixel height. The width can resize, of course.

Resizing the width of the GUI is perfect and no issues there. The issue is when I resize the height of the GUI again. The control (label) measurements all stay proper ratio which is fantastic. But that top frame likes to grow and shrink.

In this example, I don't think that it is a bug. This is likely just me not knowing how to set it properly. Or possibly might be a good feature request if it's not yet possible.

Example 2:

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

#include "GUIFrame.au3"

; DPI awareness
DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -2)

$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, 1, 100, 5, 0, 0, 0, 0, 0, 0x02000000)
_GUIFrame_SetMin($iFrame_A, 100, 100)

_GUIFrame_Switch($iFrame_A, 1)

$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_A, 1))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
GUICtrlSetBkColor(-1, 0x00FF00)

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

_GUIFrame_Switch($iFrame_B, 1)

$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_B, 1))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
GUICtrlSetBkColor(-1, 0x0000BB)

_GUIFrame_Switch($iFrame_B, 2)

$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_B, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
GUICtrlSetBkColor(-1, 0x0000BB)

; Set resizing flag for all created frames
_GUIFrame_ResizeSet(1, 1)
_GUIFrame_ResizeSet(2, 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
    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

 

Thank you. :)

  • Moderators
Posted

WildByDesign,

Does this do what you want? Fixed Top Zone.au3  Basically it creates a single frameset 100 pixels down.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Posted
1 hour ago, Melba23 said:

Does this do what you want? Fixed Top Zone.au3  Basically it creates a single frameset 100 pixels down.

I appreciate you taking the time to respond, Melba. Thank you. :)

This helps a little bit with subtracting the value of the control height with the value of the top section. It gives me a better understanding of that aspect. However, once you add the resizing with:

_GUIFrame_ResizeSet(0)
_GUIFrame_ResizeReg()

The problem is still there with GUI height resizing. Resizing the GUI width is not an issue.

In my example, when resizing the GUI height, it would show the problem at the top and bottom of the controls that are in the two bottom frames.

With your example, there is an improvement, since the issue is now only present at the top of the controls (no longer an issue at the bottom).

The problem is that those label controls go under the top section when resizing the height of the GUI. They can also end up moving further down as well. But if you can imagine with a TreeView and ListView control in those bottom frames (instead of the labels), what happens is that the header for the ListView goes under the top section and some of the TreeView gets cut off as well.

Posted

I just did some digging. In the WM_SIZE function in GUIFrame.au3 I see:

Func _GUIFrame_SIZE_Handler($hWnd, $iMsg, $wParam, $lParam)
...
        ; Get new base GUI size
        Local $aSize = WinGetClientSize($hWnd)
...

So it pulls the width/height for the client area of the main GUI to do all of the math. I admit that I am terrible at all of the intricate math stuff involved here. However, it would seem that it may not take into consideration the values from:

$iFrame = _GUIFrame_Create($hGUI, 0, 0, 5, hereX, hereY, 0, 0, 0, 0x02000000)

The X and Y values from where FrameParent is positioned initially within that main GUI. So that could cause this problem vertically as I am experiencing but also horizontally if a user puts a value other than 0 for the X position.

  • Moderators
Posted

WildByDesign,

You could well be right - I will look into it.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Posted (edited)

@Melba23 I have a nice fix for you with regards to the separator GUI.

I noticed a few problems when moving the separator:

  • mouse cursor constantly switches from/to resize cursor to normal arrow (over and over)
  • mouse cursor can highlight items on either side of the separator while moving *

* In my example, I have a ListView on both sides. The columns are purposely larger to enable the scrollbars to appear. When you move the separator back and forth, you can see the items in the right ListView get highlighted briefly over and over. And on the left ListView, you can see the scrollbar arrows get triggered briefly each time. And of course, the mouse cursor changes with each of those movements.

The glitches appear in both light mode and dark mode GUI's. However, they are easier to see in dark mode. Therefore, I made the GUI and controls dark mode for the purpose of the example.

By the way, I am using your original GUIFrame UDF but simply passing the composited extended style:

_GUIFrame_Create($hGUI, 0, 0, 5, 0, 0, 0, 0, 0, $WS_EX_COMPOSITED)

Please try my example with your current GUIFrame.au3 UDF (not the beta WS_EX_COMPOSITED one). Drag the separator back and forth a bunch of times at varying speeds to see the visual glitches on both sides of the separator (and cursor changes).

After, try my example with my slightly modified GUIFrame.au3 to see all of those issues fixed.

The only (relevant) changes were added to _GUIFrame_SepWndProc function:

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

; Capture mouse within separator while dragging
_WinAPI_SetCapture($hSeparator)

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

Now, importantly, when the separator stops moving it does need:

_WinAPI_ReleaseCapture()

I have it placed within the While loop in the example script. But that may not be ideal. You understand the UDF the best and you will know where the best place to have the capture release. Essentially when the $hSeparator GUI has stopped moving.

Anyway, this solved my problems perfectly.

EDIT: I forgot to add the modified UDF and example script. Need more coffee. :)

Example:

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

#include "GUIFrame.au3"

; DPI awareness
DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -2)

; Set Global vars for separator child GUI ($hSeparator) and separator label control ($idSeparator)
; The purpose is just to make it easier to share the handle and CtrlID from the UDF script
Global $hSeparator, $idSeparator
Global $hListView, $hListView2

$hGUI = GUICreate("GUI_Frame Example", 800, 600, -1, -1, -1)
GUISetState()

; Create a 1st level frame
$iFrame_A = _GUIFrame_Create($hGUI, 0, 0, 5, 0, 0, 0, 0, 0, $WS_EX_COMPOSITED)
_GUIFrame_SetMin($iFrame_A, 50, 125, True)  ; This line sets the minima as absolute values <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

_GUIFrame_Switch($iFrame_A, 1)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_A, 1))
Local $idListview = GUICtrlCreateListView("col1  |col2|col3  ", 0, 0, $aWinSize[0], $aWinSize[1], BitOR($LVS_SHOWSELALWAYS, $LVS_NOCOLUMNHEADER), $LVS_EX_FULLROWSELECT)
$hListView = GUICtrlGetHandle($idListview)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
_WinAPI_SetWindowTheme(GUICtrlGetHandle($idListview), 'Explorer')
_GUICtrlListView_BeginUpdate($idListview)
For $i = 0 To 40
    _GUICtrlListView_AddItem( $idListview, "item" & $i & "-000000000Z", -1)
    For $j = 1 To 4
        _GUICtrlListView_AddSubItem($idListview, $i, "row" & $i & "-" & "col" & $j, $j)
    Next
Next
_GUICtrlListView_EndUpdate($idListview)
_GUICtrlListView_SetColumnWidth(GUICtrlGetHandle($idListview), 0, 300)
_GUICtrlListView_SetColumnWidth(GUICtrlGetHandle($idListview), 1, $LVSCW_AUTOSIZE)
_GUICtrlListView_SetColumnWidth(GUICtrlGetHandle($idListview), 2, $LVSCW_AUTOSIZE)

_GUIFrame_Switch($iFrame_A, 2)
$aWinSize2 = WinGetClientSize(_GUIFrame_GetHandle($iFrame_A, 2))
Local $idListview2 = GUICtrlCreateListView("col1  |col2|col3  ", 0, 0, $aWinSize2[0], $aWinSize2[1], BitOR($LVS_SHOWSELALWAYS, $LVS_NOCOLUMNHEADER), $LVS_EX_FULLROWSELECT)
$hListView2 = GUICtrlGetHandle($idListview2)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
_WinAPI_SetWindowTheme(GUICtrlGetHandle($idListview2), 'Explorer')
_GUICtrlListView_BeginUpdate($idListview2)
For $i = 0 To 40
    _GUICtrlListView_AddItem( $idListview2, "item" & $i & "-000000000Z", -1)
    For $j = 1 To 4
        _GUICtrlListView_AddSubItem($idListview2, $i, "row" & $i & "-" & "col" & $j, $j)
    Next
Next
_GUICtrlListView_EndUpdate($idListview2)
_GUICtrlListView_SetColumnWidth(GUICtrlGetHandle($idListview2), 0, 200)

GUICtrlSendMsg($idListview, $WM_CHANGEUISTATE, 65537, 0)
GUICtrlSendMsg($idListview2, $WM_CHANGEUISTATE, 65537, 0)

ConsoleWrite("Separator WS_CHILD Handle : " & $hSeparator & @CRLF)
ConsoleWrite("Separator Label Handle : " & GUICtrlGetHandle($idSeparator) & @CRLF)
ConsoleWrite("Separator Label CtrlID : " & $idSeparator & @CRLF)

DarkMode($hGUI, True)

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ; The UDF does all the tidying up as you exit
            Exit
        Case $idSeparator ; separator label control
            ConsoleWrite("Separator has finished moving." & @CRLF)
            ; this can be used to reestablish normal cursor stuff
            ;_MouseTrap()
            _WinAPI_ReleaseCapture()
    EndSwitch

WEnd

;--------------------------------------------------------------------------------------------------------------------------------
; https://www.autoitscript.com/forum/topic/211475-darkmode-udf-for-autoits-win32guis/#comment-1530103
;--------------------------------------------------------------------------------------------------------------------------------
Func DarkMode($hGUI, $bDarkMode = True)                               ; DarkMode

    Local Enum $DWMWA_USE_IMMERSIVE_DARK_MODE = (@OSBuild <= 18985) ? 19 : 20
    ;ConsoleWrite("$DWMWA_USE_IMMERSIVE_DARK_MODE=" & $DWMWA_USE_IMMERSIVE_DARK_MODE & @CRLF)
    ;       DWMWA_USE_IMMERSIVE_DARK_MODE ; https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
    ;       Use with DwmSetWindowAttribute. Allows the window frame for this window to be drawn in dark mode colors when the dark mode system setting is enabled.
    ;       For compatibility reasons, all windows default to light mode regardless of the system setting.
    ;       The pvAttribute parameter points to a value of type BOOL. TRUE to honor dark mode for the window, FALSE to always use light mode.
    ;       This value is supported starting with Windows 11 Build 22000.

    Local $iRet = _WinAPI_DwmSetWindowAttribute_unr($hGUI, $DWMWA_USE_IMMERSIVE_DARK_MODE, $bDarkMode)
    If Not $iRet Then Return SetError(1, 0, -1)

    _SetCtrlColorMode($hGUI, $bDarkMode)
    _SetCtrlColorMode(GUICtrlGetHandle($idListview), $bDarkMode)
    _SetCtrlColorMode(GUICtrlGetHandle($idListview2), $bDarkMode)
    GUICtrlSetColor($idListview, 0xFFFFFF)
    GUICtrlSetColor($idListview2, 0xFFFFFF)
    GUICtrlSetBkColor($idListview, 0x202020)
    GUICtrlSetBkColor($idListview2, 0x202020)

EndFunc   ;==>DarkMode
;--------------------------------------------------------------------------------------------------------------------------------
Func _SetCtrlColorMode($hWnd, $bDarkMode = True, $sName = Default)    ; 'Explorer', 'CFD', 'DarkMode_ItemsView', etc.
    If $sName = Default Then $sName = $bDarkMode ? 'DarkMode_Explorer' : 'Explorer'
    $bDarkMode = Not Not $bDarkMode ; https://www.vbforums.com/showthread.php?900444-Windows-10-Dark-Mode-amp-VB6-apps
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    Local Enum $eDefault, $eAllowDark, $eForceDark, $eForceLight, $eMax ; enum PreferredAppMode
    DllCall('uxtheme.dll', 'bool', 133, 'hwnd', $hWnd, 'bool', $bDarkMode) ; fnAllowDarkModeForWindow = 133
    DllCall('uxtheme.dll', 'int', 135, 'int', ($bDarkMode ? $eForceDark : $eForceLight)) ; fnAllowDarkModeForApp = 135
    _WinAPI_SetWindowTheme_unr($hWnd, $sName) ; https://www.autoitscript.com/forum/index.php?showtopic=211475&view=findpost&p=1530103
    DllCall('uxtheme.dll', 'none', 104) ; fnRefreshImmersiveColorPolicyState = 104  ; not needed ?
    _SendMessage($hWnd, $WM_THEMECHANGED, 0, 0) ; not needed ?
EndFunc   ;==>_SetCtrlColorMode
;--------------------------------------------------------------------------------------------------------------------------------
Func _WinAPI_SetWindowTheme_unr($hWnd, $sName = Null, $sList = Null)  ; #include <WinAPITheme.au3> ; unthoughtful unrestricting mod.
    ;Causes a window to use a different set of visual style information than its class normally uses
    Local $sResult = DllCall('UxTheme.dll', 'long', 'SetWindowTheme', 'hwnd', $hWnd, 'wstr', $sName, 'wstr', $sList)
    If @error Then Return SetError(@error, @extended, 0)
    If $sResult[0] Then Return SetError(10, $sResult[0], 0)
    Return 1
EndFunc   ;==>_WinAPI_SetWindowTheme_unr
;--------------------------------------------------------------------------------------------------------------------------------
Func _WinAPI_DwmSetWindowAttribute_unr($hWnd, $iAttribute, $iData)    ; #include <WinAPIGdi.au3> ; unthoughtful unrestricting mod.
    ;Sets the value of the specified attributes for non-client rendering to apply to the window
    Local $aCall = DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $hWnd, 'dword', $iAttribute, _
            'dword*', $iData, 'dword', 4)
    If @error Then Return SetError(@error, @extended, 0)
    If $aCall[0] Then Return SetError(10, $aCall[0], 0)
    Return 1
EndFunc   ;==>_WinAPI_DwmSetWindowAttribute_unr
;--------------------------------------------------------------------------------------------------------------------------------

 

GUIFrame.au3

Edited by WildByDesign
forgot to add modified UDF and example
Posted
On 12/21/2025 at 7:50 AM, WildByDesign said:

I have it placed within the While loop in the example script. But that may not be ideal. You understand the UDF the best and you will know where the best place to have the capture release. Essentially when the $hSeparator GUI has stopped moving.

I ended up finding the appropriate place to release the capture within the UDF. This way the _WinAPI_SetCapture and _WinAPI_ReleaseCapture are all contained within the UDF and function beautifully.

; Do until the mouse button is released
Until Not _WinAPI_GetAsyncKeyState(0x01)
...
; release mouse capture after separator has stopped moving
_WinAPI_ReleaseCapture()
...
ElseIf $aGF_SettingsIndex[$iIndex][0] = 1 Then
...
Until Not _WinAPI_GetAsyncKeyState(0x01)
...
; release mouse capture after separator has stopped moving
_WinAPI_ReleaseCapture()

Basically after the two calls to _WinAPI_GetAsyncKeyState which indicates that the separator has stopped moving.

  • 4 weeks later...
Posted
On 12/17/2025 at 9:10 AM, WildByDesign said:

I feel like there must be something within _GUIFrame_SIZE_Handler that does not take into account the value, in this case $iTopSpace = 60, placed for the Y coordinates in the _GUIFrame_Create  function. I believe that it must be getting the height for the main GUI instead of the main GUI height minus the $iTopSpace = 60 (or whatever value the user puts there).

 

On 12/18/2025 at 9:38 AM, Melba23 said:

You could well be right - I will look into it.

I have made a discovery today that should help you fix this bug. As a refresher, this bug relates to having the parent frame start anywhere other than the default 0, 0 positioning.

_GUIFrame_Create($hWnd, $iSepOrient, $iSepPos, $iSepSize, $iX, $iY, $iWidth, $iHeight, $iStyle, $iExStyle, $fShowWindow)
;                                                          ^    ^

I was thinking that is was going to be incredibly mathematical in fixing this, but it turns out to be quite a bit easier from what I can tell.

Keep in mind, my example has a top space of: $iTopSpace = 60

Fixing the problem, I added the following in the _GUIFrame_Move() function as follows:

_GUIFrame_Move($iFrame, $iX, $iY, $iWidth, $iHeight)
;                        ^    ^
    $iX = 0
    $iY = 60

The fix would involve making sure that the $iX and $iY values are passed from the _GUIFrame_Create() function to the _GUIFrame_Move() function. I think that that would make the most sense. Or, alternatively, another function to override the $iX and $iY values.

Here is currently what is being passed to _GUIFrame_Move() function based on WinGetClientSize:

_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])

; $iX = $aSize[0] * $aGF_SizingIndex[$iIndex][2]
; $iY = $aSize[1] * $aGF_SizingIndex[$iIndex][3]

Here is the example script to reproduce the issue (when resizing, particularly vertical resizing in this case):

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

#include "GUIFrame.au3"

; DPI awareness
DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -2)

Global $iSep_Pos

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

GUISetState(@SW_SHOW, $hGUI)

$iTopSpace = 60
$aGUISize = WinGetClientSize($hGUI)
GUICtrlCreateLabel(" ", 0, 0, $aGUISize[0], $iTopSpace)
GUICtrlSetBkColor(-1, 0x808080)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKHEIGHT)

; Create a 1st level frame
$iFrame_A = _GUIFrame_Create($hGUI, 0, 100, 5, 0, $iTopSpace, 0, 0, 0, 0x02000000)
_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 - $iTopSpace)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
GUICtrlSetBkColor(-1, 0x00FF00)

_GUIFrame_Switch($iFrame_A, 2)
$aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_A, 2))
GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10 - $iTopSpace)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
GUICtrlSetBkColor(-1, 0xFF0000)
GUICtrlSetState(-1, $GUI_DISABLE)

; Set resizing flag for all created frames
_GUIFrame_ResizeSet(0) ; 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

 

Now, in the GUIFrame.au3 UDF file within the _GUIFrame_Move() function, to reproduce the fix you can add the following $iX and $iY values at the top of the function:

; #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)
    $iX = 0
    $iY = 60

 

For the purpose of alternating between reproducing the issue and showing the fix working properly,  you can simply comment/uncomment the $iX and $iY lines and restart the example script.

  • 2 months later...
Posted (edited)

..in all the years I've never seen the value of this UDF. Awesome, just awesome.

image.thumb.png.48d4f6c861ec0bd0be21045d1aacd4da.png

..so, I tweaked the UDF to accommodate for dark mode:

Spoiler
#Region ; *** Dynamically added Include files ***
#include <WinAPISys.au3>                                     ; added:03/27/26 13:10:02
#EndRegion ; *** Dynamically added Include files ***
#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>
#include <GuiCtrls_HiDpi.au3>

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


Global $aGF_iSeparatorSize = 5 ; argumentum ; add default size
Global $aGF_iSeparatorBorder = 0x01 ; argumentum ; -1 to remove it

; 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 = $aGF_iSeparatorSize, $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 1 To 19
            $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, $aGF_iSeparatorBorder) ; $WS_EX_DLGMODALFRAME ; argumentum ;
        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, $aGF_iSeparatorBorder) ; $WS_EX_DLGMODALFRAME ; argumentum ;
        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, argumentum added "3, 0"
; 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, 3, 0 ; argumentum: added 0 (Parent GUI handle ) and 3 (Separator bar handle) for coloring ;
                    ; 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)
;~      ConsoleWrite('"GUIFrame.au3"(' & @ScriptLineNumber & ') : >>>' & @CRLF)
        ; 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)
;~      ConsoleWrite('"GUIFrame.au3"(' & @ScriptLineNumber & ') : >>>' & @CRLF)
        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   ;==>_GUIFrame_ResizeState

; #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_SeparatorBorder
; Description ...: Sets the default border
; Syntax.........: _GUIFrame_SeparatorBorder([$iValue])
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: The current value
; Author ........: argumentum
; Modified ......:
; Remarks .......: It does not reevaluate and apply on the fly. Preset before building the GUI.
; Example........: No
;=====================================================================================================================
Func _GUIFrame_SeparatorBorder($iValue = Default)
    If IsInt($iValue) Then $aGF_iSeparatorBorder = $iValue
    Return $aGF_iSeparatorBorder
EndFunc   ;==>_GUIFrame_SeparatorBorder

; #FUNCTION# =========================================================================================================
; Name...........: _GUIFrame_SeparatorSize
; Description ...: Sets the default border extended style
; Syntax.........: _GUIFrame_SeparatorSize([$iValue])
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: The current value
; Author ........: argumentum
; Modified ......:
; Remarks .......: It does not reevaluate and apply on the fly. Preset before building the GUI.
; Example........: No
;=====================================================================================================================
Func _GUIFrame_SeparatorSize($iValue = Default)
    If IsInt($iValue) Then $aGF_iSeparatorSize = $iValue
    Return $aGF_iSeparatorSize
EndFunc   ;==>_GUIFrame_SeparatorSize


; #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
;~              ConsoleWrite('"GUIFrame.au3"(' & @ScriptLineNumber & ') : >>>' & @CRLF)

                ; 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
;~          WinSetState($hFirstFrame, "", @SW_HIDE)
;~          WinSetState($hSecondFrame, "", @SW_HIDE)

            $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
;~              ConsoleWrite('"GUIFrame.au3"(' & @ScriptLineNumber & ') : >>>' & @CRLF)

                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)
;~          WinSetState($hFirstFrame, "", @SW_SHOW)
;~          WinSetState($hSecondFrame, "", @SW_SHOW)

            $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
;~  ConsoleWrite('"GUIFrame.au3"(' & @ScriptLineNumber & ') : >>>' & @CRLF)

    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
;~      ConsoleWrite('"GUIFrame.au3"(' & @ScriptLineNumber & ') : >>>' & @CRLF)

        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
;~      ConsoleWrite('"GUIFrame.au3"(' & @ScriptLineNumber & ') : >>>' & @CRLF)

        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

..also messed with Example 3:

Spoiler
#Region ; *** Dynamically added Include files ***
#include <WindowsStylesConstants.au3>                        ; added:03/27/26 12:58:47
#EndRegion ; *** Dynamically added Include files ***
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

#include "GUIFrame.au3"
;~ $g_iSeparatorBorder = -1 ; I added this to: GUICtrlCreateLabel("", 0, 0, $iSeparatorSize, $iHeight, -1, $g_iSeparatorBorder) ; $WS_EX_DLGMODALFRAME ; argumentum ;
_GUIFrame_SeparatorBorder(-1)
_GUIFrame_SeparatorSize(1)
;~ $g_iSeparatorSize = 1 ; I added this to:
;~ Func _GUIFrame_Create($hWnd, $iSepOrient = 0, $iSepPos = 0, $iSepSize = $g_iSeparatorSize, $iX = 0, $iY = 0, $iOrg_Width = 0, $iOrg_Height = 0, $iStyle = 0, $iExStyle = 0, $fShowWindow = False)


#include "GuiCtrls_HiDpi.au3" ; from: https://www.autoitscript.com/forum/topic/211475-darkmode-udf-for-autoits-win32guis/page/12/#findComment-1550698
#EndRegion INCLUDE

; initiate System DPI awareness and control scaling
_HiDpi_Ctrl_LazyInit()

; this must be set after DPI
#include "GUIDarkTheme.au3" ; from: https://www.autoitscript.com/forum/topic/211475-darkmode-udf-for-autoits-win32guis/page/12/#findComment-1550698

Global $iSep_Pos

$hGUI = _HiDpi_GUICreate("GUI_Frame Example 3", 500, 500, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX))
;~ GUISetBkColor(0x202020, $hGUI)
;~ GUISetBkColor(0xF00000) ; this is never going to show as it'll be covered by the child windows
;~ GUISetState()
;~ Sleep(1000)
; Create a 1st level frame
$iFrame_A = _GUIFrame_Create($hGUI, 1)
ConsoleWrite(VarGetType($iFrame_A) & ' - ' & $iFrame_A & @CRLF)
ConsoleWrite(VarGetType(_GUIFrame_GetHandle($iFrame_A, 2)) & ' - ' & _GUIFrame_GetHandle($iFrame_A, 2) & @CRLF)
;~ GUISetBkColor(0x00F000, _GUIFrame_GetHandle($iFrame_A, 1))
;~ GUISetBkColor(0x0000F0, _GUIFrame_GetHandle($iFrame_A, 2))
;~ Sleep(1000)
_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 <<<<<<<<<<<<<<<<<<<<<
;~ Sleep(1000)

_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)
$Tab1 = _HiDpi_GUICtrlCreateTab(70, 10, 300, 100)
$TabSheet1 = GUICtrlCreateTabItem("Frame 1 - TabSheet1")
$TabSheet2 = GUICtrlCreateTabItem("Frame 1 - TabSheet2")

;~ Sleep(1000)

_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)
$Tab2 = _HiDpi_GUICtrlCreateTab(10, 10, 300, 100)
$Tab2Sheet1 = GUICtrlCreateTabItem("Frame 2 - TabSheet1")
$Tab2Sheet2 = GUICtrlCreateTabItem("Frame 2 - TabSheet2")

; 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()

    ; apply dark theme to GUI and all controls using the newer DarkMode_DarkTheme
    _GUIDarkTheme_ApplyDark($hGUI, True)

GUISetBkColor(0x202020, _GUIFrame_GetHandle($iFrame_A, 0)) ; added this to _GUIFrame_GetHandle() to get the background GUI making it all flicker
GUISetBkColor(0x202020, _GUIFrame_GetHandle($iFrame_A, 1))
GUISetBkColor(0x202020, _GUIFrame_GetHandle($iFrame_A, 2))
GUISetBkColor(0x3F3F3F, _GUIFrame_GetHandle($iFrame_A, 3)) ; added this to _GUIFrame_GetHandle() :
;~      Case 1 To $aGF_HandleIndex[0][0]
;~          Switch $iElement
;~              Case 1, 2, 3, 0 ; argumentum ;

GUISetState(@SW_SHOW, $hGUI)

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ; The UDF does all the tidying up as you exit
            Exit
    EndSwitch

WEnd

Now I can have more than one GUICtrlCreateTab(), HiDPI and dark mode. Today am a happy coder :) 

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

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
×
×
  • Create New...