Jump to content

How to create Child GUI on top of each Tab


wuruoyu
 Share

Recommended Posts

#NoTrayIcon
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiButton.au3>
#include <GuiTab.au3>
#include <EditConstants.au3>
#include <GUIToolbar.au3>
#include <ToolbarConstants.au3>
#include <GUIImageList.au3>

Opt("GUIOnEventMode", 1)

_main()

Func _main()
    $main = GUICreate("main", 368, 343, -1, -1, -1, -1)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_exit")

    $ToolbarGUI = GUICreate('', 350, 62, 1, 1, $WS_CHILD, 0, $main)
    $Toolbar = _GUICtrlToolbar_Create($ToolbarGUI, BitOR($BTNS_BUTTON, $BTNS_SHOWTEXT, $TBSTYLE_FLAT, $TBSTYLE_TOOLTIPS), $TBSTYLE_EX_DOUBLEBUFFER)

    $ToolbarImageList = _GUIImageList_Create(32, 32, 5, 1)

    _GUIImageList_AddIcon($ToolbarImageList, "C:\Windows\System32\mmc.exe", 0, 1)
    _GUIImageList_AddIcon($ToolbarImageList, "C:\Windows\System32\cmd.exe", 0, 1)
    _GUICtrlToolbar_SetImageList($Toolbar, $ToolbarImageList)
    _GUICtrlToolbar_AddString($Toolbar, 'MMC')
    _GUICtrlToolbar_AddString($Toolbar, 'CMD')
    _GUICtrlToolbar_AddButton($Toolbar, 10000, 0, 0)
    _GUICtrlToolbar_AddButton($Toolbar, 10001, 1, 1)
    _GUICtrlToolbar_SetButtonSize($Toolbar, 62, 50)
    _GUICtrlToolbar_SetMetrics($Toolbar, 0, 0, 1, 0)
    _GUICtrlToolbar_SetIndent($Toolbar, 1)
    _SendMessage($Toolbar, $TB_AUTOSIZE)

    GUISwitch($main)

    GUICtrlCreateLabel('', 0, 63, 368, 2, $SS_ETCHEDHORZ)

    GUICtrlCreateButton("button", 248, 313, 100, 20, -1, -1)

    $tab = GUICtrlCreateTab(4, 70, 363, 226, -1, -1)
    GUICtrlSetState(-1, 2048)
    GUICtrlCreateTabItem("Page 1")
    $pageOneGUI = GUICreate("", 352, 198, 9, 93, $WS_POPUP, $WS_EX_MDICHILD, $main)
    GUISetBkColor(0xCCFFCC)
    GUICtrlCreateGroup("Group", 6, 3, 341, 180, -1, -1)
    GUICtrlCreateEdit("this is an edit control", 15, 40, 325, 67, BitOR($ES_READONLY, $WS_VSCROLL), $WS_EX_CLIENTEDGE)
    GUICtrlCreateInput("This is an inputbox", 15, 130, 325, 20, -1, $WS_EX_CLIENTEDGE)

    GUICtrlCreateTabItem("Page 2")
    $pageTwoGUI = GUICreate("", 352, 198, 9, 93, $WS_POPUP, $WS_EX_MDICHILD, $main)

    GUISetBkColor(0xCCFFCC)

    GUICtrlCreateTabItem("")
    _GUICtrlTab_SetCurFocus($tab, 0)

    GUISetState(@SW_HIDE, $pageOneGUI)
    GUISetState(@SW_SHOW, $pageOneGUI)

    GUISetState(@SW_SHOWNOACTIVATE, $ToolbarGUI)
    GUISetState(@SW_SHOW, $main)

    While 1
        Sleep(100)
    WEnd
EndFunc   ;==>_main

Func _exit()
    Exit
EndFunc   ;==>_exit

I am trying to fix the missing border issue in above post with the workaround provided by LarsJ. The solution that I original went with can only fix the lock and unlock cycle, missing borders still occurring in some other cases.

LarsJ's suggestion is to create the controls in a child window and place the child window on top of the Tab control. Because the controls are created in a real window (and not a Tab control), there will not be any update issues.

 

Please see above for the reproducer script.

1. cannot manage to get both tabs to show at same time. 

2. When dragging and moving the main GUI, the toolbar on the top will disappear.

Really appreciate any help anyone can provide. Thank you!

 

Screen Shot 2016-09-29 at 2.56.46 PM.png

Link to comment
Share on other sites

Code rearranged a little bit:

#NoTrayIcon
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
;#include <GuiButton.au3>
;#include <GuiTab.au3>
#include <EditConstants.au3>
#include <GUIToolbar.au3>
;#include <ToolbarConstants.au3>
#include <GUIImageList.au3>

;Opt("GUIOnEventMode", 1)

Global $main

_main()

Func _main()
    $main = GUICreate("main", 368, 343, -1, -1, -1, -1)
    ;GUISetOnEvent($GUI_EVENT_CLOSE, "_exit")

    ;$ToolbarGUI = GUICreate('', 350, 62, 1, 1, $WS_CHILD, 0, $main)
    $Toolbar = _GUICtrlToolbar_Create($main, BitOR($BTNS_BUTTON, $BTNS_SHOWTEXT, $TBSTYLE_FLAT, $TBSTYLE_TOOLTIPS), $TBSTYLE_EX_DOUBLEBUFFER)

    $ToolbarImageList = _GUIImageList_Create(32, 32, 5, 1)

    _GUIImageList_AddIcon($ToolbarImageList, "C:\Windows\System32\mmc.exe", 0, 1)
    _GUIImageList_AddIcon($ToolbarImageList, "C:\Windows\System32\cmd.exe", 0, 1)
    _GUICtrlToolbar_SetImageList($Toolbar, $ToolbarImageList)
    _GUICtrlToolbar_AddString($Toolbar, 'MMC')
    _GUICtrlToolbar_AddString($Toolbar, 'CMD')
    _GUICtrlToolbar_AddButton($Toolbar, 10000, 0, 0)
    _GUICtrlToolbar_AddButton($Toolbar, 10001, 1, 1)
    _GUICtrlToolbar_SetButtonSize($Toolbar, 62, 50)
    _GUICtrlToolbar_SetMetrics($Toolbar, 0, 0, 1, 0)
    _GUICtrlToolbar_SetIndent($Toolbar, 1)
    _SendMessage($Toolbar, $TB_AUTOSIZE)

    GUICtrlCreateLabel('', 0, 63, 372, 1, $SS_ETCHEDHORZ)

    GUICtrlCreateButton("button", 248, 313, 100, 20, -1, -1)

    $tab = GUICtrlCreateTab(4, 70, 363, 226, -1, -1)
    GUICtrlCreateTabItem("Page 1")
    GUICtrlCreateTabItem("Page 2")
    GUICtrlCreateTabItem("")

    GuiRegisterMsg( $WM_NCACTIVATE, "WM_NCACTIVATE" ) ; Prevent child windows (for Tab items) in making main GUI title bar dimmed
    GUISetState(@SW_SHOW, $main)

    $pageOneGUI = GUICreate("", 352, 198, 9, 93, $WS_POPUP, $WS_EX_MDICHILD, $main)
    GUISetBkColor(0xCCFFCC)
    GUICtrlCreateGroup("Group", 6, 3, 341, 180, -1, -1)
    GUICtrlCreateEdit("this is an edit control", 15, 40, 325, 67, BitOR($ES_READONLY, $WS_VSCROLL), $WS_EX_CLIENTEDGE)
    GUICtrlCreateInput("This is an inputbox", 15, 130, 325, 20, -1, $WS_EX_CLIENTEDGE)
    GUISetState(@SW_SHOW, $pageOneGUI)

    $pageTwoGUI = GUICreate("", 352, 198, 9, 93, $WS_POPUP, $WS_EX_MDICHILD, $main)
    GUISetBkColor(0xCCFFCC)
    $idButPage2 = GUICtrlCreateButton( "Button page 2", 10, 10, 100, 20 )
    GUISetState( @SW_HIDE, $pageTwoGUI )

    GUISwitch($main)

    While 1
      Switch GUIGetMsg()
        Case $tab
          Switch GUICtrlRead( $tab )
            Case 0 ; Page 1
              GUISetState( @SW_HIDE, $pageTwoGUI )
              GUISetState( @SW_SHOW, $pageOneGUI )
            Case 1 ; Page 2
              GUISetState( @SW_HIDE, $pageOneGUI )
              GUISetState( @SW_SHOW, $pageTwoGUI )
          EndSwitch

        Case $idButPage2
          MsgBox( 0, "Page 2", "Button clicked", 0, $main )

        Case $GUI_EVENT_CLOSE
          ExitLoop
      EndSwitch
    WEnd

    #cs
    While 1
        Sleep(100)
    WEnd
    #ce
EndFunc   ;==>_main

Func _exit()
    Exit
EndFunc   ;==>_exit

; Prevent child windows (for Tab items) in making main GUI title bar dimmed
Func WM_NCACTIVATE( $hWnd, $iMsg, $wParam )
  If $hWnd = $main Then
    If Not $wParam Then Return 1
  EndIf
EndFunc

The reason for message loop mode is just that I was too lazy to create all the functions.

Link to comment
Share on other sites

Cool thank you LarsJ. I got it working with OnEventMode.

I also need to set the background of the child GUI transparent. I know there is an easy by setting background color of the child GUI to white, but running the program on an OS (Windows server 2008 Citrix environment) that uses "Windows Classic" theme, the white background color is not matching the tab color and the rest of the GUI.

I've tried following code but isn't working 

GUISetBkColor(0xABCDEF)
_WinAPI_SetLayeredWindowAttributes($pageOneGUI, 0xABCDEF, 255)

And another problem

If the screen resolution changed after program is launched, the child GUI has lost it's position to the parent window. I think might be caused by $WS_POPUP style, there is no problem when using $WS_CHILD

 

Screen Shot 2016-10-01 at 1.38.22 PM.png

 

OnEventMode

#NoTrayIcon
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
;#include <GuiButton.au3>
#include <GuiTab.au3>
#include <EditConstants.au3>
#include <GUIToolbar.au3>
;#include <ToolbarConstants.au3>
#include <GUIImageList.au3>

Opt("GUIOnEventMode", 1)

Global $tab, $currentTab, $pageOneGUI, $pageTwoGUI

_main()

Func _main()
    $main = GUICreate("main", 368, 343, -1, -1, -1, -1)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_exit")
    GUISetState()

    $ToolbarGUI = GUICreate('', 350, 62, 1, 1, $WS_CHILD, 0, $main)
    $Toolbar = _GUICtrlToolbar_Create($ToolbarGUI, BitOR($BTNS_BUTTON, $BTNS_SHOWTEXT, $TBSTYLE_FLAT, $TBSTYLE_TOOLTIPS), $TBSTYLE_EX_DOUBLEBUFFER)
    $ToolbarImageList = _GUIImageList_Create(32, 32, 5, 1)
    _GUIImageList_AddIcon($ToolbarImageList, "C:\Windows\System32\mmc.exe", 0, 1)
    _GUIImageList_AddIcon($ToolbarImageList, "C:\Windows\System32\cmd.exe", 0, 1)
    _GUICtrlToolbar_SetImageList($Toolbar, $ToolbarImageList)
    _GUICtrlToolbar_AddString($Toolbar, 'MMC')
    _GUICtrlToolbar_AddString($Toolbar, 'CMD')
    _GUICtrlToolbar_AddButton($Toolbar, 10000, 0, 0)
    _GUICtrlToolbar_AddButton($Toolbar, 10001, 1, 1)
    _GUICtrlToolbar_SetButtonSize($Toolbar, 62, 50)
    _GUICtrlToolbar_SetMetrics($Toolbar, 0, 0, 1, 0)
    _GUICtrlToolbar_SetIndent($Toolbar, 1)
    _SendMessage($Toolbar, $TB_AUTOSIZE)

    GUISwitch($main)

    GUICtrlCreateLabel('', 0, 63, 368, 2, $SS_ETCHEDHORZ)
    GUICtrlCreateButton("button", 248, 313, 100, 20, -1, -1)

    $pageOneGUI = GUICreate("", 352, 198, 9, 93, $WS_CHILD,-1, $main)
    GUISetBkColor(0xCCFFCC)
    GUICtrlCreateGroup("Group", 6, 3, 341, 180, -1, -1)
    GUICtrlCreateEdit("this is an edit control", 15, 40, 325, 67, BitOR($ES_READONLY, $WS_VSCROLL), $WS_EX_CLIENTEDGE)
    GUICtrlCreateInput("This is an inputbox", 15, 130, 325, 20, -1, $WS_EX_CLIENTEDGE)

    $pageTwoGUI = GUICreate("", 352, 198, 9, 93, $WS_CHILD,-1, $main)
    GUISetBkColor(0xCCFFCC)
    GUICtrlCreateInput("This is an inputbox", 15, 100, 325, 20, -1, $WS_EX_CLIENTEDGE)
    GUICtrlCreateInput("This is an inputbox", 15, 130, 325, 20, -1, $WS_EX_CLIENTEDGE)

    GUISwitch($main)
    $tab = GUICtrlCreateTab(4, 70, 363, 226, -1, -1)
    GUICtrlSetOnEvent($Tab, "_tabChangeDetected")
    GUICtrlCreateTabItem("Page 1")
    GUICtrlCreateTabItem("Page 2")
    GUICtrlCreateTabItem("")

    $currentTab = _GUICtrlTab_GetCurFocus($tab)

    GUISetState(@SW_SHOWNOACTIVATE, $ToolbarGUI)
    GUISetState(@SW_SHOW, $main)

    _GUICtrlTab_SetCurFocus($tab, 0)

    While 1
        Sleep(100)
    WEnd
EndFunc   ;==>_main

Func _exit()
    Exit
EndFunc   ;==>_exit

Func _tabChangeDetected()
    If _GUICtrlTab_GetCurFocus($tab) <> $currentTab Then
        $currentTab = _GUICtrlTab_GetCurFocus($tab)
        ;MsgBox(0, "", $currentTab)
        Switch $currentTab
            Case 0
                GUISetState(@SW_HIDE,$pageTwoGUI)
                GUISetState(@SW_SHOW,$pageOneGUI)
            Case 1
                GUISetState(@SW_HIDE,$pageOneGUI)
                GUISetState(@SW_SHOW,$pageTwoGUI)
        EndSwitch
    EndIf
EndFunc   ;==>_tabChangeDetected

 

Edited by wuruoyu
Link to comment
Share on other sites

You can't use the $WS_EX_LAYERED style for a child window before Windows 8. This means that you can't make the background of a child window transparent.

If you remove colors from the windows and remove theme from the Tab control the backgrounds should have the same colors. At least they have in both default Aero and Windows Classic themes on Windows 7.

You'll probably have to deal with Tab key with a little bit of code:

#NoTrayIcon
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
;#include <GuiButton.au3>
#include <GuiTab.au3>
#include <EditConstants.au3>
#include <GUIToolbar.au3>
;#include <ToolbarConstants.au3>
#include <GUIImageList.au3>
#include <WinAPITheme.au3>

Opt("GUIOnEventMode", 1)

Global $tab, $currentTab, $pageOneGUI, $pageTwoGUI
Global $idInput1P2, $idInput2P2, $idInput3P2

_main()

Func _main()
    $main = GUICreate("main", 368, 343, -1, -1, -1, -1)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_exit")
    GUISetState()

    $ToolbarGUI = GUICreate('', 350, 62, 1, 1, $WS_CHILD, 0, $main)
    $Toolbar = _GUICtrlToolbar_Create($ToolbarGUI, BitOR($BTNS_BUTTON, $BTNS_SHOWTEXT, $TBSTYLE_FLAT, $TBSTYLE_TOOLTIPS), $TBSTYLE_EX_DOUBLEBUFFER)
    $ToolbarImageList = _GUIImageList_Create(32, 32, 5, 1)
    _GUIImageList_AddIcon($ToolbarImageList, "C:\Windows\System32\mmc.exe", 0, 1)
    _GUIImageList_AddIcon($ToolbarImageList, "C:\Windows\System32\cmd.exe", 0, 1)
    _GUICtrlToolbar_SetImageList($Toolbar, $ToolbarImageList)
    _GUICtrlToolbar_AddString($Toolbar, 'MMC')
    _GUICtrlToolbar_AddString($Toolbar, 'CMD')
    _GUICtrlToolbar_AddButton($Toolbar, 10000, 0, 0)
    _GUICtrlToolbar_AddButton($Toolbar, 10001, 1, 1)
    _GUICtrlToolbar_SetButtonSize($Toolbar, 62, 50)
    _GUICtrlToolbar_SetMetrics($Toolbar, 0, 0, 1, 0)
    _GUICtrlToolbar_SetIndent($Toolbar, 1)
    _SendMessage($Toolbar, $TB_AUTOSIZE)

    GUISwitch($main)

    GUICtrlCreateLabel('', 0, 63, 368, 2, $SS_ETCHEDHORZ)
    GUICtrlCreateButton("button", 248, 313, 100, 20, -1, -1)

    $pageOneGUI = GUICreate("", 352, 198, 9, 93, $WS_CHILD,-1, $main)
    ;GUISetBkColor(0xCCFFCC)
    GUICtrlCreateGroup("Group", 6, 3, 341, 180, -1, -1)
    GUICtrlCreateEdit("this is an edit control", 15, 40, 325, 67, BitOR($ES_READONLY, $WS_VSCROLL), $WS_EX_CLIENTEDGE)
    GUICtrlCreateInput("This is an inputbox", 15, 130, 325, 20, -1, $WS_EX_CLIENTEDGE)

    $pageTwoGUI = GUICreate("", 352, 198, 9, 93, $WS_CHILD,-1, $main)
    ;GUISetBkColor(0xCCFFCC)
    $idInput1P2 = GUICtrlCreateInput("This is an inputbox", 15, 070, 325, 20, -1, $WS_EX_CLIENTEDGE)
    $idInput2P2 = GUICtrlCreateInput("This is an inputbox", 15, 100, 325, 20, -1, $WS_EX_CLIENTEDGE)
    $idInput3P2 = GUICtrlCreateInput("This is an inputbox", 15, 130, 325, 20, -1, $WS_EX_CLIENTEDGE)

    GUISwitch($main)
    $tab = GUICtrlCreateTab(4, 70, 363, 226, -1, -1)
    GUICtrlSetOnEvent($Tab, "_tabChangeDetected")
    GUICtrlCreateTabItem("Page 1")
    GUICtrlCreateTabItem("Page 2")
    GUICtrlCreateTabItem("")
    _WinAPI_SetWindowTheme(GUICtrlGetHandle( $tab ), "", "")

    $currentTab = _GUICtrlTab_GetCurFocus($tab)

    $idTabKeyP2 = GUICtrlCreateDummy()
    GUICtrlSetOnEvent( $idTabKeyP2, "TabKeyP2" )
    Local $aAccelKeys[1][2] = [["{Tab}", $idTabKeyP2]]
    GUISetAccelerators($aAccelKeys)

    GUISetState(@SW_SHOWNOACTIVATE, $ToolbarGUI)
    GUISetState(@SW_SHOW, $main)

    _GUICtrlTab_SetCurFocus($tab, 0)

    While 1
        Sleep(100)
    WEnd
EndFunc   ;==>_main

Func TabKeyP2()
  Switch _WinAPI_GetDlgCtrlID( ControlGetHandle( $pageTwoGUI, "", ControlGetFocus( $pageTwoGUI ) ) )
    Case $idInput1P2
      ControlFocus( $pageTwoGUI, "", $idInput2P2 )
    Case $idInput2P2
      ControlFocus( $pageTwoGUI, "", $idInput3P2 )
    Case $idInput3P2
      ControlFocus( $pageTwoGUI, "", $idInput1P2 )
    Case Else
  EndSwitch
EndFunc

Func _exit()
    Exit
EndFunc   ;==>_exit

Func _tabChangeDetected()
    If _GUICtrlTab_GetCurFocus($tab) <> $currentTab Then
        $currentTab = _GUICtrlTab_GetCurFocus($tab)
        ;MsgBox(0, "", $currentTab)
        Switch $currentTab
            Case 0
                GUISetState(@SW_HIDE,$pageTwoGUI)
                GUISetState(@SW_SHOW,$pageOneGUI)
            Case 1
                GUISetState(@SW_HIDE,$pageOneGUI)
                GUISetState(@SW_SHOW,$pageTwoGUI)
        EndSwitch
    EndIf
EndFunc   ;==>_tabChangeDetected

 

Link to comment
Share on other sites

Thank you for the reply again. I was able to fix the Tab focus issue by using ex_style: $WS_EX_CONTROLPARENT on the child GUI.

I still prefer the default white background for tabs when Aero is enabled. 

I am using _WinAPI_GetCurrentThemeName() to check if theme is used on program startup. Then set background color accordingly. And use $WM_THEMECHANGED to detect theme changes when program is running, but $WM_THEMECHANGED is being called multiple times (5-10 times) when theme changes, is there a way to filter out the calls to only one time?

Not sure if this is a good approach, but I am running out of ideas. 

Edited by wuruoyu
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...