Sign in to follow this  
Followers 0
Melba23

Placing controls in tabs when resizing the GUI

2 posts in this topic

Hi,

I came across a question in the GUI section about ListViews on tabs. The problem was to place the ListViews on the tabs so that their vertical position changed with the number of levels needed for the tab headers after a GUI resize. An rough example of what I mean:

; Wide GUI = single row of tab headers
| Tab 1 |  Tab 2    | Tab 3 | Tab 4 | Tab 5 | Tab 6 | Tab 7 | Tab 8 | Tab 9 |
-----------------------------------------------------------------------------------------------------
| List View

After resize, narrow GUI forces 2 rows of headers
| Tab 1 |  Tab 2    | Tab 3 | Tab 4 | Tab 5 | Tab 6 |
|   Tab 7           |   Tab 8           |   Tab 9            |
--------------------------------------------------------------------
| ListView

As searching produced nothing overly helpful, I came up with the following code - which could be used for other things than ListViews, of course. I hope it might be useful to others:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <TabConstants.au3>
#include <GuiListView.au3>
#include <GuiTab.au3>

Opt("GUIResizeMode", $GUI_DOCKBORDERS)

; When window is resized, run this function
GUIRegisterMsg($WM_SIZE, "MY_WM_SIZE")

Global $iGUIWidth = 800, $iGUIHeight = 500, $fResized = False

$MainGUI = GUICreate("Tab Row Example", $iGUIWidth, $iGUIHeight, Default, Default, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX))
$TAB = GUICtrlCreateTab(1, 1, $iGUIWidth - 2, $iGUIHeight - 50, BitOR($GUI_SS_DEFAULT_TAB, $TCS_MULTILINE, $TCS_RIGHTJUSTIFY))

; Set number of TabItems
Global $iTabNumber = 15

; Create array holding dummy tabitem titles
Global $aTitles[$iTabNumber + 1]
For $i = 1 To $iTabNumber
    $aTitles[$i] = ""
    For $j = 1 To Random(4, 10, 1)
        $aTitles[$i] &= String($i) & " "
    Next
Next
    
; Determine initial TabTop value
$iTabTop = Tab_Sizer($iTabNumber, $aTitles)

; Create array to hold ListView handles
Global $aListView[$iTabNumber + 1] = [$iTabNumber]

; Create tabitems
For $i = 1 To $iTabNumber

    GUICtrlCreateTabItem($aTitles[$i])
    $aListView[$i] = GUICtrlCreateListView("Filelist", 10, $iTabTop, $iGUIWidth - 22, $iGUIHeight - $iTabTop - 50, -1, $LVS_EX_CHECKBOXES)
        _GUICtrlListView_SetColumnWidth($aListView[$i], 0, $LVSCW_AUTOSIZE_USEHEADER)
        _GUICtrlListView_SetBkColor($aListView[$i], 0xFF0000) ; Just to show the size
        GUICtrlSetResizing($aListView[$i], BitOR($GUI_DOCKBORDERS, $GUI_DOCKLEFT))

; Fill ListView with items
    For $j = 1 To 25
        GUICtrlCreateListViewItem("Item " & $j & " - ListView " & $i & "    Blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah", $aListView[$i])
    Next

Next

; Close Tab definiton
GUICtrlCreateTabItem("")

; Create dummy button 
$hButton = GUICtrlCreateButton("Button", 10, $iGUIHeight - 40, 120, 30)
GUICtrlSetResizing(-1, BitOR($GUI_DOCKWIDTH, $GUI_DOCKHEIGHT, $GUI_DOCKBOTTOM))

GUISetState(@SW_SHOW)

While 1
    
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $hButton
        ; dummy
    EndSwitch
    
; Look for resize message
    If $fResized Then

    ; Determine new TabTop value
        $iTabTop = Tab_Sizer($iTabNumber, $aTitles)
    ; Reposition all Listviews to fit new Tab dimensions
        For $i = 1 To $aListView[0]
            GUICtrlSetPos($aListView[$i], 10, $iTabTop, $iGUIWidth - 22, $iGUIHeight - $iTabTop - 50)
            _GUICtrlListView_SetColumnWidth($aListView[$i], 0, $LVSCW_AUTOSIZE_USEHEADER)
        Next
    ; Reset flag
        $fResized = False
    EndIf

WEnd

Func Tab_Sizer($iTabTotal, $aTabTitles)
    
; Create test GUI
    $TestGUI = GUICreate("", $iGUIWidth, 500)
; Create test Tab
    $TestTAB = GUICtrlCreateTab(1, 1, $iGUIWidth - 2, 500, BitOR($GUI_SS_DEFAULT_TAB, $TCS_MULTILINE, $TCS_RIGHTJUSTIFY))
; Create correct number of TabItems
    For $i = 1 To $iTabTotal
        GUICtrlCreateTabItem($aTabTitles[$i])
    Next
; Measure the client area of the Tab
    $aPos = _GUICtrlTab_GetDisplayRect(ControlGetHandle($TestGUI, "", $TestTAB))
; Delete test GUI
    GUIDelete($TestGUI)
; Return new TabTop value
    Return $aPos[1]
    
EndFunc
    
Func MY_WM_SIZE($hWnd, $Msg, $wParam, $lParam)
    
    $iGUIWidth = BitAND($lParam, 0xFFFF)
    $iGUIHeight = BitShift($lParam, 16)
; Set flag
    $fResized = True
        
    Return $GUI_RUNDEFMSG
    
EndFunc  ;==>MY_WM_SIZE

Once you have determined the number of tabs and their titles you run the function Tab_Sizer which tells you where the user area of the tabs starts. The function creates a dummy GUI and then draws the tabs before using _GUICtrlTab_GetDisplayRect to find the vertical position of the Tab user area . Note that you must pass the number of tabs and their titles to the Tab_Sizer function, otherwise the dummy tabs will not be the same as in the GUI you are creating. Once you have the tab vertical position you can create the real tabs and set the ListViews in the right place.

Then in the While...WEnd loop you look for the $fResized flag to be set by the MY_WM_SIZE function when you resize the window. The MY_WM_SIZE function also resets the width and height values of the GUI to their new values.

If the flag is set, the Tab_Sizer function is called again to get the new location for the ListViews. Then we reposition the ListViews and reset the column width so that they fit nicely into the new GUI size. Finally we reset the $fResized flag until the next resize.

Comments and improvements welcome as always. One thing I would like to fix is the flickering of the ListView during the resizing - I tried hiding it before the resize and then showing it again, but could not get it to work well.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites



Well, good job!

I exactly surched for something like this.

I hope I can use this to eleminate a problem of mine, wich i have with a multiline tab.

Go on like this :P

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

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

Create an account

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


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0