Tabs: Difference between revisions

From AutoIt Wiki
Jump to navigation Jump to search
No edit summary
 
m (Added wiki headers, minor typos)
Line 1: Line 1:
[[Tabs and how to deal with them]]
=Tabs and how to deal with them=


Tabs are a valuable tool when you need to fit a lot of controls into a small GUI.  But inexperienced users often have problems with them - particularly in making sure that controls only appear on the correct tab.  This tutorial should help.
Tabs are a valuable tool when you need to fit a lot of controls into a small GUI.  But inexperienced users often have problems with them - particularly in making sure that controls only appear on the correct tab.  This tutorial should help. Before going further, it is important to understand the differences between controls created using the built-in AutoIt commands (''GUICtrlCreate*'') and those created with the UDFs.  The built-in commands produce controls which are managed internally by AutoIt - they return '''ControlID'''s.  The UDF commands create controls that are not in Autoit's internal management structure and need to be managed by the code - they normally return '''handles''' (the special unique identifier for all Windows components).


Before going further, it is important to understand the differences between controls created using the built-in AutoIt commands (''GUICtrlCreate*'') and those created with the UDFs.  The built-in commands produce controls which are managed internally by AutoIt - they return '''ControlID'''s.  The UDF commands create controls that are not in Autoit's internal management structure and need to be managed by the code - they normally return '''handles''' (the special unique identifier for all Windows components).
=Tabs Created With Native AutoIt Functions=
 
'''Tabs'''


Any tabs created by the built-in AutoIt commands ''GUICtrlCreateTab/TabItem'' will automatically take care of displaying any built-in controls created at the same time within the tab creation structure.  Here is an example:
Any tabs created by the built-in AutoIt commands ''GUICtrlCreateTab/TabItem'' will automatically take care of displaying any built-in controls created at the same time within the tab creation structure.  Here is an example:
-----------------------------------
  <syntaxhighlight lang="autoit">
  <syntaxhighlight lang="autoit">
#include <GUIConstantsEx.au3>
#include <GUIConstantsEx.au3>
Line 32: Line 29:
  WEnd
  WEnd
</syntaxhighlight>
</syntaxhighlight>
-----------------------------------
As you can see, the controls for each tab are created just after the TabItem on which they are to appear and before the next TabItem.  Do not forget to close the Tab definition - many tab problems are caused by omitting this vital line.
As you can see, the controls for each tab are created just after the TabItem on which they are to appear and before the next TabItem.  Do not forget to close the Tab definition - many tab problems are caused by omitting this vital line.


What happens if we add some UDF created controls to these tabs?
What happens if we add some UDF created controls to these tabs?
-----------------------------------
<syntaxhighlight lang="autoit">
<syntaxhighlight lang="autoit">
  #include <GUIConstantsEx.au3>
  #include <GUIConstantsEx.au3>
Line 62: Line 57:
  WEnd
  WEnd
</syntaxhighlight>
</syntaxhighlight>
-----------------------------------
As you can see, the UDF created controls appear on every tab.  Remember this is because they are not part of the internal AutoIt control management structure, so AutoIt does not know how to handle them.  It is up to you to manage them by seeing which tab is active and hiding/showing these controls as required:
As you can see, the UDF created controls appear on every tab.  Remember this is because they are not part of the internal AutoIt control management structure, so AutoIt does not know how to handle them.  It is up to you to manage them by seeing which tab is active and hiding/showing these controls as required:
-----------------------------------
<syntaxhighlight lang="autoit">
<syntaxhighlight lang="autoit">
  #include <GUIConstantsEx.au3>
  #include <GUIConstantsEx.au3>
Line 132: Line 125:
  WEnd
  WEnd
</syntaxhighlight>
</syntaxhighlight>
-----------------------------------
Note the lag in hiding/showing the UDF created controls if you use ''WinSetState'' - I would recommend using ''ControlShow/Hide'' which gives an instantaneous response.  Also how you do not need to create the UDF controls within the tab creation structure - as you have to look after them, there is no requirement to do so.
Note the lag in hiding/showing the UDF created controls if you use ''WinSetState'' - I would recommend using ''ControlShow/Hide'' which gives an instantaneous response.  Also how you do not need to create the UDF controls within the tab creation structure - as you have to look after them, there is no requirement to do so.
=Tabs Created With UDFs=


Now let us look at Tabs created with the ''GUITab'' UDF.  In this case you need to manage all of the controls on the tabs yourself, even if they are created using the built-in commands:
Now let us look at Tabs created with the ''GUITab'' UDF.  In this case you need to manage all of the controls on the tabs yourself, even if they are created using the built-in commands:
-----------------------------------
<syntaxhighlight lang="autoit">
<syntaxhighlight lang="autoit">
  #include <GUIConstantsEx.au3>
  #include <GUIConstantsEx.au3>
Line 211: Line 204:
  WEnd
  WEnd
</syntaxhighlight>
</syntaxhighlight>
-----------------------------------
A lot of work but a very satisfactory result.  Note the need to use different commands to hide/show the built-in and UDF created controls to avoid "lag" on the latter as was shown in the earlier example.
A lot of work but a very satisfactory result.  Note the need to use different commands to hide/show the built-in and UDF created controls to avoid "lag" on the latter as was shown in the earlier example.


So, a couple of lessons to draw from this:
So, a couple of lessons to draw from this:


- 1.  When using tabs, try and use built-in commands if at all possible.  If you do, AutoIt looks after the showing/hiding problem for you as long as you create the controls WITHIN the tab creation structure.  If you need to add controls after having ended the tab structure definiton, then you '''must''' use ''GUISwitch'' with the ''tabitemID'' parameter to select the correct tab before you create the control or you will find that it is visible on all tabs.
- 1.  When using tabs, try and use built-in commands if at all possible.  If you do, AutoIt looks after the showing/hiding problem for you as long as you create the controls ''within'' the tab creation structure.  If you need to add controls after having ended the tab structure definiton, then you ''must'' use ''GUISwitch'' with the ''tabitemID'' parameter to select the correct tab before you create the control or you will find that it is visible on all tabs.


- 2.  If you must use UDF created controls for any reason, you have to manage hiding/showing all controls yourself.
- 2.  If you must use UDF created controls for any reason, you have to manage hiding/showing all controls yourself.


'''Multiple tabs in a GUI'''
=Multiple tabs in a GUI=


Unfortunately, only one built-in tab control can be created per GUI - you cannot have several tabs on a single GUI.  But there is a way around this - just create child GUIs which can each hold a tab:
Unfortunately, only one built-in tab control can be created per GUI - you cannot have several tabs on a single GUI.  But there is a way around this - just create child GUIs which can each hold a tab:
-----------------------------------
<syntaxhighlight lang="autoit">
<syntaxhighlight lang="autoit">
#include <GUIConstantsEx.au3>
#include <GUIConstantsEx.au3>
Line 259: Line 250:
  WEnd
  WEnd
</syntaxhighlight>
</syntaxhighlight>
-----------------------------------
Easy when you know how!
Easy when you know how!
=Summary=


Tabs are useful controls, but can be difficult to master.  After this tutorial you should be well on your way!
Tabs are useful controls, but can be difficult to master.  After this tutorial you should be well on your way!

Revision as of 14:10, 11 November 2012

Tabs and how to deal with them

Tabs are a valuable tool when you need to fit a lot of controls into a small GUI. But inexperienced users often have problems with them - particularly in making sure that controls only appear on the correct tab. This tutorial should help. Before going further, it is important to understand the differences between controls created using the built-in AutoIt commands (GUICtrlCreate*) and those created with the UDFs. The built-in commands produce controls which are managed internally by AutoIt - they return ControlIDs. The UDF commands create controls that are not in Autoit's internal management structure and need to be managed by the code - they normally return handles (the special unique identifier for all Windows components).

Tabs Created With Native AutoIt Functions

Any tabs created by the built-in AutoIt commands GUICtrlCreateTab/TabItem will automatically take care of displaying any built-in controls created at the same time within the tab creation structure. Here is an example:

#include <GUIConstantsEx.au3>
 
 $hGUI = GUICreate("Built-In Tab Example", 500, 500)
 
 $hTab = GUICtrlCreateTab(10, 10, 480, 480)
 ; Create tabitems
 For $i = 0 To 2
     GUICtrlCreateTabItem("Tab " & $i)
     GUICtrlCreateButton("Button " & $i, 20 + ($i * 100), 40 + ($i * 50), 80, 30)
 Next
 ; Close Tab definiton
 GUICtrlCreateTabItem("") 
 
 GUISetState()
 
 While 1
     Switch GUIGetMsg()
         Case $GUI_EVENT_CLOSE
             Exit
     EndSwitch
 WEnd

As you can see, the controls for each tab are created just after the TabItem on which they are to appear and before the next TabItem. Do not forget to close the Tab definition - many tab problems are caused by omitting this vital line.

What happens if we add some UDF created controls to these tabs?

 #include <GUIConstantsEx.au3>
 #Include <GuiButton.au3>
 
 $hGUI = GUICreate("Built-In Tab Example", 500, 500)
 
 $hTab = GUICtrlCreateTab(10, 10, 480, 480)
 ; Create tabitems
 For $i = 0 To 2
     GUICtrlCreateTabItem("Tab " & $i)
     GUICtrlCreateButton("Built-In " & $i, 20 + ($i * 100), 40 + ($i * 50), 80, 30)
     _GUICtrlButton_Create($hGUI, "UDF " & $i, 20 + ($i * 100), 80 + ($i * 50),80, 30)
 Next
 ; Close Tab definiton
 GUICtrlCreateTabItem("")
 
 GUISetState()
 
 While 1
     Switch GUIGetMsg()
         Case $GUI_EVENT_CLOSE
             Exit
     EndSwitch
 WEnd

As you can see, the UDF created controls appear on every tab. Remember this is because they are not part of the internal AutoIt control management structure, so AutoIt does not know how to handle them. It is up to you to manage them by seeing which tab is active and hiding/showing these controls as required:

 #include <GUIConstantsEx.au3>
 #Include <GuiButton.au3>
 
 Global $hButtons[3]
 
 $hGUI = GUICreate("Built-In Tab Example", 500, 500)
 
 $hTab = GUICtrlCreateTab(10, 10, 480, 480)
 ; Create tabitems
 For $i = 0 To 2
     GUICtrlCreateTabItem("Tab " & $i)
     GUICtrlCreateButton("Built-In " & $i, 20 + ($i * 100), 40 + ($i * 50), 80, 30)
     ; Add a label to the first tab
     If $i = 0 Then GUICtrlCreateLabel("See how 'laggy' the UDF buttons are when selecting this tab because of using WinSetState", 20, 200, 150, 60)
 Next
 
 GUICtrlCreateTabItem("")
 
 ; Create UDF controls
 For $i = 0 To 2
     $hButtons[$i] = _GUICtrlButton_Create($hGUI, "UDF " & $i, 20 + ($i * 100), 80 + ($i * 50),80, 30)
 Next
 
 ; Hide the controls so only the one on the first tab is visible
 WinSetState($hButtons[1], "", @SW_HIDE)
 WinSetState($hButtons[2], "", @SW_HIDE)
 
 GUISetState()
 
 ; This is the current active tab
 $iLastTab = 0
 
 While 1
     Switch GUIGetMsg()
         Case $GUI_EVENT_CLOSE
             Exit
         Case $hTab
             ; Check which Tab is active
             $iCurrTab = GUICtrlRead($hTab)
             ; If the Tab has changed
             If $iCurrTab <> $iLastTab Then
                 ; Show/Hide controls as required
                 Switch $iCurrTab
                     Case 0
                         ; Note lag when WinSetState is used
                         WinSetState($hButtons[1], "", @SW_HIDE)
                         WinSetState($hButtons[2], "", @SW_HIDE)
                         WinSetState($hButtons[0], "", @SW_SHOW)
                     Case 1
                         ; No lag when using ControlHide/Show
                         ControlHide($hGUI, "", $hButtons[0])
                         ControlHide($hGUI, "", $hButtons[2])
                         ControlShow($hGUI, "", $hButtons[1])
                     Case 2
                         ; Nor when using this DLL
                         DllCall("User32.dll", "bool", "ShowWindowAsync", "hwnd", $hButtons[0], "int", @SW_HIDE)
                         DllCall("User32.dll", "bool", "ShowWindowAsync", "hwnd", $hButtons[1], "int", @SW_HIDE)
                         DllCall("User32.dll", "bool", "ShowWindowAsync", "hwnd", $hButtons[2], "int", @SW_SHOW)
 
                 EndSwitch
                 ; Store the value for future comparisons
                 $iLastTab = $iCurrTab
             EndIf
     EndSwitch
 WEnd

Note the lag in hiding/showing the UDF created controls if you use WinSetState - I would recommend using ControlShow/Hide which gives an instantaneous response. Also how you do not need to create the UDF controls within the tab creation structure - as you have to look after them, there is no requirement to do so.

Tabs Created With UDFs

Now let us look at Tabs created with the GUITab UDF. In this case you need to manage all of the controls on the tabs yourself, even if they are created using the built-in commands:

 #include <GUIConstantsEx.au3>
 #Include <GuiButton.au3>
 #include <GuiTab.au3>
 
 Global $hBuiltIn_Buttons[3]
 Global $hUDF_Buttons[3]
 
 $hGUI = GUICreate("Built-In Tab Example", 500, 500)
 
 $hTab = _GUICtrlTab_Create($hGUI, 10, 10, 480, 480)
 GUISetState()
 
 ; Add tabs
 _GUICtrlTab_InsertItem($hTab, 0, "Tab 0")
 _GUICtrlTab_InsertItem($hTab, 1, "Tab 1")
 _GUICtrlTab_InsertItem($hTab, 2, "Tab 2")
 
 ; Create the Built-in and UDF buttons
 For $i = 0 To 2
     $hBuiltIn_Buttons[$i] = GUICtrlCreateButton("Button " & $i, 20 + ($i * 100), 40 + ($i * 50), 80, 30)
     $hUDF_Buttons[$i] = _GUICtrlButton_Create($hGUI, "UDF " & $i, 20 + ($i * 100), 80 + ($i * 50),80, 30)
 Next
 
 ; Hide the controls so only the one on the first tab is visible
 GUICtrlSetState($hBuiltIn_Buttons[1], $GUI_HIDE)
 GUICtrlSetState($hBuiltIn_Buttons[2], $GUI_HIDE)
 ControlHide($hGUI, "", $hUDF_Buttons[1])
 ControlHide($hGUI, "", $hUDF_Buttons[2])
 
 GUISetState()
 
 ; This is the current active tab
 $iLastTab = 0
 
 While 1
     Switch GUIGetMsg()
         Case $GUI_EVENT_CLOSE
             Exit
     EndSwitch
 
     ; Check which Tab is active
     $iCurrTab = _GUICtrlTab_GetCurFocus($hTab)
     ; If the Tab has changed
     If $iCurrTab <> $iLastTab Then
         ; Store the value for future comparisons
         $iLastTab = $iCurrTab
         ; Show/Hide controls as required
         Switch $iCurrTab
             Case 0
                 GUICtrlSetState($hBuiltIn_Buttons[1], $GUI_HIDE)
                 GUICtrlSetState($hBuiltIn_Buttons[2], $GUI_HIDE)
                 GUICtrlSetState($hBuiltIn_Buttons[0], $GUI_SHOW)
                 ControlHide($hGUI, "", $hUDF_Buttons[1])
                 ControlHide($hGUI, "", $hUDF_Buttons[2])
                 ControlShow($hGUI, "", $hUDF_Buttons[0])
             Case 1
                 GUICtrlSetState($hBuiltIn_Buttons[0], $GUI_HIDE)
                 GUICtrlSetState($hBuiltIn_Buttons[2], $GUI_HIDE)
                 GUICtrlSetState($hBuiltIn_Buttons[1], $GUI_SHOW)
                 ControlHide($hGUI, "", $hUDF_Buttons[0])
                 ControlHide($hGUI, "", $hUDF_Buttons[2])
                 ControlShow($hGUI, "", $hUDF_Buttons[1])
            Case 2
                 GUICtrlSetState($hBuiltIn_Buttons[0], $GUI_HIDE)
                 GUICtrlSetState($hBuiltIn_Buttons[1], $GUI_HIDE)
                 GUICtrlSetState($hBuiltIn_Buttons[2], $GUI_SHOW)
                 ControlHide($hGUI, "", $hUDF_Buttons[0])
                 ControlHide($hGUI, "", $hUDF_Buttons[1])
                 ControlShow($hGUI, "", $hUDF_Buttons[2])
         EndSwitch
     EndIf
 WEnd

A lot of work but a very satisfactory result. Note the need to use different commands to hide/show the built-in and UDF created controls to avoid "lag" on the latter as was shown in the earlier example.

So, a couple of lessons to draw from this:

- 1. When using tabs, try and use built-in commands if at all possible. If you do, AutoIt looks after the showing/hiding problem for you as long as you create the controls within the tab creation structure. If you need to add controls after having ended the tab structure definiton, then you must use GUISwitch with the tabitemID parameter to select the correct tab before you create the control or you will find that it is visible on all tabs.

- 2. If you must use UDF created controls for any reason, you have to manage hiding/showing all controls yourself.

Multiple tabs in a GUI

Unfortunately, only one built-in tab control can be created per GUI - you cannot have several tabs on a single GUI. But there is a way around this - just create child GUIs which can each hold a tab:

#include <GUIConstantsEx.au3>
 #include <WindowsConstants.au3>
 
 $hGUI = GUICreate("Test", 500, 500)
 
 GUISetState()
 
 ; Create child GUIs to hold tabs
 $hTab_Win0 = GUICreate("", 400, 200, 50, 20, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)
 $hTab_0 = GUICtrlCreateTab(10, 10, 380, 180)
     $hTab_00 = GUICtrlCreateTabitem("00")
         GUICtrlCreateButton("00", 160, 90, 80, 30)
     $hTab_01 = GUICtrlCreateTabitem("01")
         GUICtrlCreateButton("01", 160, 90, 80, 30)
 
 GUICtrlCreateTabitem ("")
 GUISetState()
 
 $hTab_Win1 = GUICreate("", 400, 200, 50, 250, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)
 $hTab_1 = GUICtrlCreateTab(10, 10, 380, 180)
     $hTab_10 = GUICtrlCreateTabitem("10")
         GUICtrlCreateButton("10", 160, 90, 80, 30)
     $hTab_11 = GUICtrlCreateTabitem("11")
         GUICtrlCreateButton("11", 160, 90, 80, 30)
 GUICtrlCreateTabitem ("")
 GUISetState()
 
 While 1
     Switch GUIGetMsg()
         Case $GUI_EVENT_CLOSE
             Exit
     EndSwitch
 WEnd

Easy when you know how!

Summary

Tabs are useful controls, but can be difficult to master. After this tutorial you should be well on your way!