Moderators Melba23 Posted December 14, 2014 Author Moderators Posted December 14, 2014 sycam0inc,Just divide one of the halves into two - then you have 3 sections: #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include "GUIFrame.au3" $hGUI = GUICreate("GUI_Frame 3 Sections", 600, 500, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX)) GUISetState() ; Create a 1st level frame $iFrame_A = _GUIFrame_Create($hGUI) _GUIFrame_SetSepPos($iFrame_A, 400) GUISetBkColor(0xFF0000, _GUIFrame_GetHandle($iFrame_A, 2)) ; Create a 2nd level frame $iFrame_B = _GUIFrame_Create(_GUIFrame_GetHandle($iFrame_A, 1)) GUISetBkColor(0x0000FF, _GUIFrame_GetHandle($iFrame_B, 1)) ; Set resizing flag for all created frames _GUIFrame_ResizeSet(0) ; 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 WEndM23 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
TheDcoder Posted April 20, 2017 Posted April 20, 2017 Hi, Sorry for bump posting but I had a really crazy coincidence ... Long story short, I made an UDF with the exact same name, file name and UDF naming scheme of _GUIFrame_*! I swear that I did not copy the idea of the name from this UDF. My GUIFrame UDF has a different goal that this one though, I wanted to create a GUI framework which can take care of stuff "out of the box". I was planning to make most of the parameters which define the size and position of a control optional by using a "layout" engine thing... crazy idea right? . That is when I found this UDF, I was looking for M23's excellent StringSize UDF which can give me the size of the rectangle required for a given piece of text... I was surprised to see my UDF's name listed in @Melba23's signature My UDF is just a crazy idea at this stage and the script has a lot of room for improvement, you can find it at GitHub where I published it under an open source licence: https://github.com/AutoIt4Life/GUIFrame Time to think of a new name for the UDF! EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion
WildByDesign Posted February 8 Posted February 8 @Melba23 Thank you for sharing this great UDF. It might be a bit of an older UDF at this point, but it still works great on the latest Windows 11. The only significant problem was flickering when resizing of apps when in dark mode. I was able to successfully smooth out the dark mode resizing issue by extending the UDF: auto-detection of when Windows is in Dark Mode or Light Mode apply Dark or Light mode styling early in the init process apply to all GUI frames individually ($hParent, $hSeparator, $hFirstFrame and $hSecondFrame) all applied before controls are even created The project that I am working on is not complete yet, so I might still have to modify GUIFrame.au3 some more. I would be happy to share my modifications when I am done. However, I don't know exactly how to share my changes in a proper way. My changes rely on (and require) the awesome Dark Mode UDF: Screenshot (not finished app):
WildByDesign Posted November 23 Posted November 23 I needed to use this UDF in another project so I decided to dig into the flickering issue. The flickering is quite significant anytime the separator is used to resize the GUI frames. Anyway, although this UDF is quite old and hasn't been updated for quite some time, it still works incredibly well. Therefore, I came up with a fix for the flickering issue for use in my own project and wanted to share here the fixed version. Resizing the GUI frames with the separator is smooth like butter now. Silky smooth. 🫠 GUIFrame.au3 expandcollapse popup#include <WindowsConstants.au3> #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 Local $hParent = GUICreate("FrameParent", $iWidth, $iHeight, $iX, $iY, BitOR(0x40000000, $iStyle), BitOR(0x02000000, $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 $hSeparator = GUICreate("", $iSeparatorSize, $iHeight, $iSeperator_Pos, 0, 0x40000000, 0x02000000, $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 $hFirstFrame = GUICreate("", $iSeperator_Pos, $iHeight, 0, 0, 0x40000000, 0x02000000, $hParent) ;$WS_CHILD GUISetState(@SW_SHOW, $hFirstFrame) ;$hSecondFrame = GUICreate("", $iWidth - ($iSeperator_Pos + $iSeparatorSize), $iHeight, $iSeperator_Pos + $iSeparatorSize, 0, 0x40000000, -1, $hParent) ;$WS_CHILD $hSecondFrame = GUICreate("", $iWidth - ($iSeperator_Pos + $iSeparatorSize), $iHeight, $iSeperator_Pos + $iSeparatorSize, 0, 0x40000000, 0x02000000, $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 $hSeparator = GUICreate("", $iWidth, $iSeparatorSize, 0, $iSeperator_Pos, 0x40000000, 0x02000000, $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 $hFirstFrame = GUICreate("", $iWidth, $iSeperator_Pos, 0, 0, 0x40000000, 0x02000000, $hParent) ;$WS_CHILD GUISetState(@SW_SHOW, $hFirstFrame) ;$hSecondFrame = GUICreate("", $iWidth, $iHeight - ($iSeperator_Pos + $iSeparatorSize), 0, $iSeperator_Pos + $iSeparatorSize, 0x40000000, -1, $hParent) ;$WS_CHILD $hSecondFrame = GUICreate("", $iWidth, $iHeight - ($iSeperator_Pos + $iSeparatorSize), 0, $iSeperator_Pos + $iSeparatorSize, 0x40000000, 0x02000000, $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
Moderators Melba23 Posted Tuesday at 05:38 PM Author Moderators Posted Tuesday at 05:38 PM WildByDesign, Thanks for the compliments - and may I return them for the changes to the code which remove the flicker. If you are content I will release a new version including the COMPOSITED extended style and credit you with the addition. M23 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
WildByDesign Posted Tuesday at 06:15 PM Posted Tuesday at 06:15 PM You’re very welcome, Melba. And thank you as well. I just have one concern before release. I’ve noticed that it works great for all controls types, with the exception of ListView controls. That could cause some problems. Do you think that it would be possible to somehow make COMPOSITED as an option per-frame? That way it would be easy for the user to enable or disable that fix per-frame on one of the functions where the frames are created. It would be good as a default but I’m thinking it would also be nice if it’s easy to disable on a specific frame just in case someone is using a ListView. And in that case, COMPOSITED could be disabled on just the one affected frame and the person using the UDF can simply enable the double buffering extended style on just the ListView itself.
Moderators Melba23 Posted Tuesday at 06:56 PM Author Moderators Posted Tuesday at 06:56 PM WildByDesign, Sounds possible - I will take a look over the next few days to see how it could be done. M23 WildByDesign 1 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
Moderators Melba23 Posted Wednesday at 06:26 PM Author Moderators Posted Wednesday at 06:26 PM (edited) WildByDesign, Try this Beta version - there is an added $fListView parameter in _GUIFrame_Create to NOT use the WS_EX_COMPOSITED style when set: M23 Edited Thursday at 05:01 PM by Melba23 Beta code removed 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
WildByDesign Posted Thursday at 03:25 AM Posted Thursday at 03:25 AM (edited) 9 hours ago, Melba23 said: Try this Beta version - there is an added $fListView parameter in _GUIFrame_Create to NOT use the WS_EX_COMPOSITED style when set: This is perfect. I tested with and without ListViews and tested with that new parameter as True and False. Every possible test and scenario worked exactly as expected. I think that is the best solution. Thank you. On a side note: I found the problem (and solution) to the longstanding issue with the frames not showing. Issue with the frames not showing: Does not occur when running script from SciTE or VSCode Frames fail to show 100% of the time when running script from Explorer (or other programs as well) The previously proposed fix _WinAPI_ShowWindow does not work (confirmed) Also tried _WinAPI_SetFocus and various mouse clicking methods and all failed to resolve issue How did I track down the issue? Well, since the issue only occurs when executing the script (from Explorer, etc.), I could not use ConsoleWrite unfortunately. So I had to place a bunch of MsgBox's in various places until I nailed it down. The script is failing in the _GUIFrame_Create function. It basically pauses the script until you click anywhere in the GUI or titlebar. Failing line: GUISetState(@SW_SHOW, $hParent) It doesn't make sense to me why it fails (or technically pauses the script there). But if you put a MsgBox after it, you wont see the MsgBox pop up until you click somewhere in the GUI even if it's many minutes later. It pauses forever until you click. Very, very odd. I've never seen GUISetState just pause like that before. It doesn't even return a 1 or 0 until you click somewhere in the GUI. Solution: WinSetState($hParent, "", @SW_SHOW) Now why does this work and continue the script while the other one pauses the entire script? I have no idea. It really shocked me when I narrowed it down to GUISetState because that is not what I was expecting. Please keep in mind that this issue does not affect running the script from SciTE or VSCode. The GUI frames not showing issue only happens when running the scripts from Explorer or other programs where you are executing them. It probably would also affect running them from ShellExecute from another script as well. Anyway, I run a lot of scripts through VSCode but I also run an equal amount of scripts by double-clicking in Explorer. So in my opinion, this simple one-line fix is pretty important. I am very curious (and wish) that somebody could explain why this issue does not affect SciTE or VSCode but does happen when running from Explorer. I assumed that the command lines to the AutoIt binaries would be similar. Edited Thursday at 03:27 AM by WildByDesign argumentum 1
pixelsearch Posted Thursday at 09:05 AM Posted Thursday at 09:05 AM (edited) @Melba23 & @WildByDesign Hi For the record, a test I just did : 5 hours ago, WildByDesign said: Issue with the frames not showing: Does not occur when running script from SciTE [...] I'm not sure of that, because if you run M23's script "GUIFrame_Example_1.au3" by pressing F5 from Scite, then you can easily prevent the frames to appear. To do this, just left click inside the Scite Window (immediately after you pressed F5 to run the script) and keep the left mouse button pressed until the blank GUI (unframed) appears. The line where the script is waiting can be seen in SysTray (AutoIt icon), after you add this line to "GUIFrame_Example_1.au3" : Opt("TrayIconDebug", 1) ;0=no info, 1=debug line info As WildByDesign noticed, the 1st "waiting" line indicated by TrayIconDebug is line 123 with M23's original script, or line 129 with the modified UDF (which includes WS_EX_COMPOSITED) . Anyway 123 or 129, it's the same line, i.e. the 1st GUISetState(@SW_SHOW, $hParent) found in the _GUIFrame_Create() function. My attempt to always have the frames visible is this : replace everywhere in the function ... 0x40000000 ; WS_CHILD ...with 0x40000000 + 0x10000000 ; WS_CHILD + WS_VISIBLE BitOr should be preferred to "+" but you got the idea : it concerns 7 GuiCreate(...) lines Usually we don't need to indicate by ourselves the WS_VISIBLE style (probably AutoIt adds it automatically in plenty of cases) but in this case, it seems to force the frames to always be visible. Hope it helps and fingers crossed Edited Thursday at 09:15 AM by pixelsearch typo "I think you are searching a bug where there is no bug... don't listen to bad advice."
WildByDesign Posted Thursday at 10:30 AM Posted Thursday at 10:30 AM @pixelsearch This is really quite remarkable. Brilliant! First of all, I was not even aware of Opt("TrayIconDebug", 1) . So that is something that would have saved me time last night but will definitely help me again one day, I'm sure. I had a feeling that it had something to do with WS_CHILD, but that was as far as I understood it. Your suggestion (and fix) works beautifully, 100% of the time. And the frames load faster with your fix. Basically instantaneous. As you suggested, I changed: 6 instances of 0x40000000 to BitOR(0x40000000, 0x10000000) 1 instance of BitOR(0x40000000, $iStyle) to BitOR(0x40000000, 0x10000000, $iStyle) Not needed anymore: GUISetState(@SW_SHOW, $hParent) If $fShowWindow Then _WinAPI_ShowWindow($hParent, @SW_SHOW) I have one big project that uses GUIFrame UDF and I'm about to start another. Thank you so much for this fix. It fixes the original problem with the GUI frames not showing, it's faster plus we also have the benefit of composited frames which makes everything smoother.
WildByDesign Posted Thursday at 10:46 AM Posted Thursday at 10:46 AM Oh by the way, I actually discovered something related last night. So we all know that the composited extended style does not work at all with ListViews. Well, I figured out a way to do it and still keep composited. This is something that would be up the individual developers using GUIFrame UDF and not something that Melba needs to do. I created the initial frames, everything composited. I created an MDI GUI with WS_EX_MDICHILD that contained the ListView which is attached to one of the WS_CHILD frames as if the child frame were the parent. The ListView has LVS_EX_DOUBLEBUFFER which keeps it smooth and is essentially like composited but for ListViews. And I used a WM_SIZE handler to automatically size it when the frames are resized. Anyway, normally this ListView would not work with the composited extended style on the frames. However, it is the WS_EX_MDICHILD that allows it to survive this.
Moderators Melba23 Posted Thursday at 05:00 PM Author Moderators Posted Thursday at 05:00 PM WildByDesign, pixelsearch, I think this new Beta incorporates all of your detective work: GUIFrame_WBD_Mod.au3 Please test it to death. WildByDesign, Could you please post the code that got your ListViews working correctly - I would like to add an example to the UDF showing how it can be done. M23 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
pixelsearch Posted yesterday at 12:07 AM Posted yesterday at 12:07 AM (edited) 7 hours ago, Melba23 said: Please test it to death. That one made me laugh Hey @Melba23 always a pleasure to have you around ! I just "hovered" quickly over the pages of this thread, focusing on the script you provided on page 6 in this post, which includes a ListView inside one of the frames. Now this "script with ListView" doesn't work anymore with the WS_EX_COMPOSITED ExStyle forced in each frame. On my computer, the script hangs (it doesn't even display the LV), its GUI won't close with [X] , AutoIt in SysTray won't exit and only Task Manager allowed me to kill the AutoIt process. Without WS_EX_COMPOSITED everything works fine. Tested by switching between these 2 lines in the UDF : Local $iFrame_Ext_Style = 0x02000000 ; WS_EX_COMPOSITED ; Local $iFrame_Ext_Style = 0 Also, "GUIFrame_Example_3.au3" shows another bad behavior of WS_EX_COMPOSITED, as you can see in the pic below : * left part of the pic : without WS_EX_COMPOSITED, the blue label 50x50 appears on top (correct) * right part of the pic : with WS_EX_COMPOSITED, the blue label 50x50 is covered by the green frame There will probably be other cases where side effects of WS_EX_COMPOSITED will appear. I understand it reduces flickering while resizing the GUI/frames but it seems there are side effects. That's why imho WS_EX_COMPOSITED shouldn"t be mandatory in the function (as it is in the last beta) but optional, maybe something like the following (though not really satisfying either) : Func _GUIFrame_Create($hWnd, ..., $iExStyle = 0, $iFrame_Ext_Style = 0) ; not script breaking. or Func _GUIFrame_Create($hWnd, ..., $iExStyle = 0, $iFrame_Ext_Style = 0x02000000) On 11/25/2025 at 7:15 PM, WildByDesign said: It would be good as a default [WS_EX_COMPOSITED] but I’m thinking it would also be nice if it’s easy to disable on a specific frame just in case someone is using a ListView. And in that case, COMPOSITED could be disabled on just the one affected frame and the person using the UDF can simply enable the double buffering extended style on just the ListView itself. @WildByDesign: that's why I'm asking : why the need of an additional MDI GUI in your project to take care of the LV ? Why not simply place your LV in a frame that doesn't have the WS_EX_COMPOSITED style and use LVS_EX_DOUBLEBUFFER to reduce its flicker when resizing ? Edited yesterday at 12:27 AM by pixelsearch typo "I think you are searching a bug where there is no bug... don't listen to bad advice."
WildByDesign Posted yesterday at 12:34 AM Posted yesterday at 12:34 AM 16 minutes ago, pixelsearch said: Also, "GUIFrame_Example_3.au3" shows another bad behavior of WS_EX_COMPOSITED, as you can see in the pic below : A lot of controls can be fixed with WS_EX_COMPOSITED by changing the order. Since that is essentially what it does for the most part. So for example, I fixed Example 3 by changing the following: _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) To the following: _GUIFrame_Switch($iFrame_A, 1) GUICtrlCreateLabel("", 0, 0, 50, 50) GUICtrlSetBkColor(-1, 0x0000FF) GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetState(-1, $GUI_DISABLE) $aWinSize = WinGetClientSize(_GUIFrame_GetHandle($iFrame_A, 2)) GUICtrlCreateLabel("", 5, 5, $aWinSize[0] - 10, $aWinSize[1] - 10) GUICtrlSetBkColor(-1, 0x00FF00) This will work now as was the original version of Example 3. It just changes the order. 20 minutes ago, pixelsearch said: that's why I'm asking : why the need of an additional MDI GUI in your project to take care of the LV ? Why not simply place your LV in a frame that doesn't have the WS_EX_COMPOSITED style and use LVS_EX_DOUBLEBUFFER to reduce its flicker when resizing ? The problem is that I was hoping to start some sort of community project here which was essentially a File Explorer in AutoIt. As soon as I remove the WS_EX_COMPOSITED, the TreeView side flickers to the point where I don't want to continue with the project. The problem between WS_EX_COMPOSITED and ListViews is a double-edge sword. I was able to avoid the problem and still use composited by putting the ListView in a WS_EX_MDICHILD on top of the right-side child window. But now I have the problem of not knowing how to resize the WS_EX_MDICHILD window when the child (frame) window resizes. If I could solve that problem, it would be great. I started the help topic Need help synchronizing MDI (WS_EX_MDICHILD) window with Child Window (WS_CHILD) for this exact issue but I think my idea of a community Files Au3 project is stuck in the mud.
WildByDesign Posted 7 hours ago Posted 7 hours ago On 11/27/2025 at 12:00 PM, Melba23 said: Please test it to death. I've tested it thoroughly but no death. So I'd say it passed the test. On 11/27/2025 at 12:00 PM, Melba23 said: Could you please post the code that got your ListViews working correctly - I would like to add an example to the UDF showing how it can be done. Sorry for the delay on my end on this. The ListView stuff has been very successful, however I have asked for help on the resizing/moving of the MDI window over in Need help synchronizing MDI (WS_EX_MDICHILD) window with Child Window (WS_CHILD). Thankfully @pixelsearch has been a great help (as always) with the moving of the MDI window. I'm still stuck on resizing the MDI window based on the Child window. I'll share some working code here because the resizing part would likely be easy for you since you've done a tremendous amount of work with resizing child windows. For reference: The light gray (0x606060) WS_CHILD window is intended to represent one of your GUI frames This is the one that I would like to resize with the parent GUI (to simulate how your GUI frames automatically resize The pink-ish (0xff00ff) WS_EX_MDICHILD window moves with the WS_CHILD window now thanks to @pixelsearch This also holds the ListView control which, ideally, I would like the WS_EX_MDICHILD and ListView to resize as well expandcollapse popup#include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <GuiListView.au3> ; DPI DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -2) Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declaration Global $g_hGUI, $g_hChild, $g_hChildMDI, $g_aPosChild, $g_iDeltaX, $g_iDeltaY Example() Func Example() $g_hGUI = GUICreate("Example", 400, 400, -1, -1, $WS_OVERLAPPEDWINDOW, $WS_EX_COMPOSITED) GUISetBkColor(0x202020) GUISetState(@SW_SHOW, $g_hGUI) $g_hChild = GUICreate("ChildWindow", 320, 320, 40, 40, $WS_CHILD, -1, $g_hGUI) GUISetBkColor(0x606060) GUISetState(@SW_SHOW, $g_hChild) ;$g_hChildMDI = GUICreate("", 280, 280, 20, 20, $WS_POPUP, BitOr($WS_EX_MDICHILD, $WS_EX_CONTROLPARENT), $g_hChild) $g_hChildMDI = GUICreate("", 280, 280, 20, 20, $WS_POPUP, $WS_EX_MDICHILD, $g_hChild) GUISetBkColor(0xff00ff) ; add listview Local $idListview = GUICtrlCreateListView("Column1|Column2", 20, 20, 240, 240, -1, BitOR($LVS_EX_FULLROWSELECT, $WS_EX_CLIENTEDGE, $LVS_EX_DOUBLEBUFFER, $LVS_EX_CHECKBOXES)) Local $idLVi_Item1 = GUICtrlCreateListViewItem("1|1", $idListview) Local $idLVi_Item2 = GUICtrlCreateListViewItem("2|2", $idListview) Local $idLVi_Item3 = GUICtrlCreateListViewItem("3|3", $idListview) ; get rid of selection rectangle on listview GUICtrlSendMsg($idListview, $WM_CHANGEUISTATE, 65537, 0) GUISetState(@SW_SHOW, $g_hChildMDI) _CalcPosAndDelta() GUIRegisterMsg($WM_ENTERSIZEMOVE, "WM_ENTERSIZEMOVE") GUIRegisterMsg($WM_EXITSIZEMOVE, "WM_ENTERSIZEMOVE") GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUIRegisterMsg($WM_MOVE, "WM_SIZE") While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete($g_hChildMDI) GUIDelete($g_hChild) GUIDelete($g_hGUI) EndFunc ;==>Example Func _CalcPosAndDelta() Local $aPosChildMDI = WinGetPos($g_hChildMDI) $g_aPosChild = WinGetPos($g_hChild) $g_iDeltaX = $g_aPosChild[0] - $aPosChildMDI[0] $g_iDeltaY = $g_aPosChild[1] - $aPosChildMDI[1] EndFunc ;==>_CalcPosAndDelta Func WM_ENTERSIZEMOVE($hWnd, $iMsg, $wParam, $lParam) _CalcPosAndDelta() EndFunc ;==>WM_ENTERSIZEMOVE Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) If $hWnd = $g_hGUI Then $g_aPosChild = WinGetPos($g_hChild) WinMove($g_hChildMDI, "", $g_aPosChild[0] - $g_iDeltaX, $g_aPosChild[1] - $g_iDeltaY) EndIf EndFunc ;==>WM_SIZE
WildByDesign Posted 6 hours ago Posted 6 hours ago 54 minutes ago, WildByDesign said: I'm still stuck on resizing the MDI window based on the Child window. @pixelsearch has posted a new example that solves this problem as well. Please test that example, @Melba23. Thank you.
Moderators Melba23 Posted 2 hours ago Author Moderators Posted 2 hours ago WildByDesign, Rainy day forecast tomorrow - something to keep me occupied! M23 WildByDesign 1 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now