E1M1 Posted January 14, 2021 Share Posted January 14, 2021 Hi! My goal is to make tabs that I can scroll. As I understand there there is no correct way of doing it so I have to use trick that uses child windows to do this. I use M23's code for my include: expandcollapse popup#include <GUIConstantsEx.au3> #include "GUIScrollbars_Ex.au3" Dim $tabWindows[2] $hGui = GUICreate("Scrollable tabs", 640, 480, -1, -1, $WS_CLIPCHILDREN + $WS_MINIMIZEBOX + $WS_CAPTION + $WS_POPUP + $WS_SYSMENU) GUICtrlCreateLabel("Label on main gui", 5, 5, Default, 20) $tabs = GUICtrlCreateTab(5, 25, 630, 450) $tab1 = GUICtrlCreateTabItem("Tab 1") $tab2 = GUICtrlCreateTabItem("Tab 2") $pos = ControlGetPos($hGui, "", $tabs) $tabWindows[0] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_POPUP, $WS_EX_MDICHILD, $hGui) GUISetBkColor(0xffffff) GUICtrlCreateLabel("Hello World!",10,10) $tabWindows[1] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_POPUP, $WS_EX_MDICHILD, $hGui) GUISetBkColor(0xffffff) GUICtrlCreateLabel("Label", 10, 10, 25, 25) GUICtrlSetTip(-1, "Label hint") GUISetState(@SW_SHOW, $hGui) _GUIScrollbars_Generate($tabWindows[1], 500, 1000) ; This is the current active tab $iLastTab = GUICtrlRead($tabs) GUISetState(@SW_SHOW, $tabWindows[$iLastTab]) $lastLabelIndex = -1 While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $tabs $currentTab = GUICtrlRead($tabs) If $currentTab <> $iLastTab Then GUISetState(@SW_HIDE, $tabWindows[$iLastTab]) GUISetState(@SW_SHOW, $tabWindows[$currentTab]) $iLastTab = $currentTab ; EndIf EndSwitch WEnd However when I click on labels under tabs then those child windows grab focus from parent. And whenever I switch tabs, parent window flashes focus. Is there way to prevent this or even better, add scrollbars directly to tabs instead of using GUIs to wrap content? edited Link to comment Share on other sites More sharing options...
pixelsearch Posted January 15, 2021 Share Posted January 15, 2021 Hi E1M1 I got a result which looks promising, based on pure Child windows (the ones created with $WS_CHILD style) As you noticed, the other kind of Child windows (the ones created with $WS_EX_MDICHILD extended style) grab focus when you click on controls they contain, which seems a normal behavior as they are totally separate windows. Here is a reworked version of your script. There's a hidden button when you scroll down in Tab2 : expandcollapse popup#include <GUIConstantsEx.au3> #include "GUIScrollbars_Ex.au3" Dim $tabWindows[2] $hGui = GUICreate("Scrollable tabs", 640, 480, -1, -1, _ $WS_CLIPCHILDREN + $WS_MINIMIZEBOX + $WS_CAPTION + $WS_POPUP + $WS_SYSMENU) GUICtrlCreateLabel("Label on main gui", 5, 5, Default, 20) Local $iXtabs = 5, $iYtabs = 25 $tabs = GUICtrlCreateTab($iXtabs, $iYtabs, 0 ,0) GUICtrlCreateTabItem("Tab 1") GUICtrlCreateTabItem("Tab 2") GUICtrlCreateTabItem("") ; end tabitem definition $pos = ControlGetPos($hGui, "", $tabs) Local $iHtabs = $pos[3] $tabWindows[0] = GUICreate("test", 600, 400, $iXtabs +2, $iYtabs + $iHtabs +1, $WS_CHILD, -1 , $hGUI) GUISetBkColor(0xffffff) GUICtrlCreateLabel("Hello World!", 10, 10) $tabWindows[1] = GUICreate("test", 600, 400, $iXtabs +2, $iYtabs + $iHtabs +1, $WS_CHILD, -1 , $hGUI) GUISetBkColor(0xffffff) GUICtrlCreateLabel("Label", 10, 10, 30, 25) GUICtrlSetTip(-1, "Label hint") $idButton = GUICtrlCreateButton("Hidden", 290, 650, 80, 30) _GUIScrollbars_Generate($tabWindows[1], 800, 1000) GUISetState(@SW_SHOW, $hGui) ; This is the current active tab $iLastTab = GUICtrlRead($tabs) GUISetState(@SW_SHOW, $tabWindows[$iLastTab]) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $tabs $currentTab = GUICtrlRead($tabs) If $currentTab <> $iLastTab Then GUISetState(@SW_HIDE, $tabWindows[$iLastTab]) GUISetState(@SW_SHOW, $tabWindows[$currentTab]) $iLastTab = $currentTab EndIf Case $idButton MsgBox($MB_TOPMOST, "Hidden Button", "Pressed") EndSwitch WEnd To make it convenient for our readers, I attach below Melba23's original UDF named GUIScrollbars_Ex.au3 (original dated 05/13/2018) as found in his thread. GUIScrollbars_Ex.au3 E1M1 1 Link to comment Share on other sites More sharing options...
E1M1 Posted January 16, 2021 Author Share Posted January 16, 2021 Thanks! It took me a while to figure out why simply updating window styles didnt fix it. Does anyone know why this new code requires GUICtrlCreateTab to be width = 0 and height = 0? And why now windows appear below it if I make it size 100,100 for example? Like previously they appeared on top of tab container. edited Link to comment Share on other sites More sharing options...
pixelsearch Posted January 16, 2021 Share Posted January 16, 2021 (edited) 9 hours ago, E1M1 said: It took me a while to figure out why simply updating window styles didnt fix it. Probably because child windows created with $WS_EX_MDICHILD or $WS_CHILD don't behave the same way at all. The script below corresponds to your initial script, plus 2 label controls added (1 in each Tab control) expandcollapse popup#include <GUIConstantsEx.au3> #include "GUIScrollbars_Ex.au3" Dim $tabWindows[2] $hGui = GUICreate("Scrollable tabs", 640, 480, -1, -1, _ $WS_CLIPCHILDREN + $WS_MINIMIZEBOX + $WS_CAPTION + $WS_POPUP + $WS_SYSMENU) GUICtrlCreateLabel("Label on main gui", 5, 5, Default, 20) $tabs = GUICtrlCreateTab(5, 25, 630, 450) GUICtrlCreateTabItem("Tab 1") GUICtrlCreateLabel("Label in Tab1", 100, 100) GUICtrlCreateTabItem("Tab 2") GUICtrlCreateLabel("Label in Tab2", 150, 150) GUICtrlCreateTabItem("") ; end tabitem definition $pos = ControlGetPos($hGui, "", $tabs) $tabWindows[0] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_POPUP, $WS_EX_MDICHILD, $hGui) ; $tabWindows[0] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_CHILD, -1, $hGUI) GUISetBkColor(0xffffff) GUICtrlCreateLabel("Label in Child1",10,10) $tabWindows[1] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_POPUP, $WS_EX_MDICHILD, $hGui) ; $tabWindows[1] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_CHILD, -1, $hGUI) GUISetBkColor(0xffffff) GUICtrlCreateLabel("Label in Child2", 10, 50) GUICtrlSetTip(-1, "Label hint") GUISetState(@SW_SHOW, $hGui) _GUIScrollbars_Generate($tabWindows[1], 500, 1000) ; This is the current active tab $iLastTab = GUICtrlRead($tabs) GUISetState(@SW_SHOW, $tabWindows[$iLastTab]) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $tabs $currentTab = GUICtrlRead($tabs) If $currentTab <> $iLastTab Then GUISetState(@SW_HIDE, $tabWindows[$iLastTab]) GUISetState(@SW_SHOW, $tabWindows[$currentTab]) $iLastTab = $currentTab ; EndIf EndSwitch WEnd 1) When you run the script like this : $tabWindows[0] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_POPUP, $WS_EX_MDICHILD, $hGui) ; $tabWindows[0] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_CHILD, -1, $hGUI) ... $tabWindows[1] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_POPUP, $WS_EX_MDICHILD, $hGui) ; $tabWindows[1] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_CHILD, -1, $hGUI) Then the labels displayed are the Child windows labels and the scrollbar is visible in Tab2, which means that the child windows created with $WS_EX_MDICHILD are in the foreground. Unfortunately they grab focus from parent and you don't want this behavior in your 1st post. 2) When you run the script like that : ; $tabWindows[0] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_POPUP, $WS_EX_MDICHILD, $hGui) $tabWindows[0] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_CHILD, -1, $hGUI) ... ; $tabWindows[1] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_POPUP, $WS_EX_MDICHILD, $hGui) $tabWindows[1] = GUICreate("test", $pos[2] - 10, $pos[3] - 30, 7, 50, $WS_CHILD, -1, $hGUI) Then the labels displayed are the Tab labels and the scrollbar is not visible in Tab2, which means that the child windows created with $WS_CHILD are in the background, covered by the Parent Tab control. This gave me the idea to create a Tab control having width = 0 and height = 0, so there will be no overlapping at all between the Tab control and the $WS_CHILD windows. Gladly it worked fine and the "grab focus" issue was solved too. 9 hours ago, E1M1 said: And why now windows appear below it if I make it size 100,100 for example? Like previously they appeared on top of tab container. This is because you use a constant (50) for the Y position of the Child Windows, while I use the variable $iHtabs (Tab control height) to calculate precisely the Y position of the Child windows, so they won't overlap the Tab control : $pos = ControlGetPos($hGui, "", $tabs) Local $iHtabs = $pos[3] $tabWindows[0] = GUICreate("test", 600, 400, $iXtabs +2, $iYtabs + $iHtabs +1, $WS_CHILD, -1 , $hGUI) Edited January 16, 2021 by pixelsearch typo E1M1 1 Link to comment Share on other sites More sharing options...
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