Sign in to follow this  
Followers 0
orbs

embedded child GUI wider than parent GUI - how?

9 posts in this topic

#1 ·  Posted

my first serious attempt to use child GUI, so bear with me here... trying to create a child GUI that:

1) is embedded in the parent GUI (i.e. moves with it)

2) extends beyond the width of the main GUI, but as per (1), only the part that is inside the main GUI should be shown

3) has an horizontal scrollbar to control which portion of the child GUI is shown

so far i got to here:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global Const $iGUI_W = 600
Global Const $iGUI_H = 450

Global $hGUI = GUICreate('test', $iGUI_W, $iGUI_H)
GUISetBkColor(0xFEDCBA)
Global $hGUI2 = GUICreate('', $iGUI_W * 2, 70, 0, 0, BitOR($WS_POPUP, $WS_HSCROLL), $WS_EX_MDICHILD, $hGUI)

For $i = 0 To 60
    GUICtrlCreateLabel($i, $i * 20, 10)
Next

GUISetState(@SW_SHOW, $hGUI)
GUISetState(@SW_SHOW, $hGUI2)
Global $msg = 0
While True
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

the child GUI is embedded, and there is an horizontal scrollbar, but it extends outside of the main GUI and the scrollbar is dysfunctional.

how do i make the child GUI show only the portion that is inside the main GUI, and make the scrollbar functional?

thanks for any hints!

P.S. also, the parent GUI loses focus when clicking in the child GUI. is this avoidable?

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Here's a script of mine just missusing the left param (#81) for the childs:

#include <WinAPI.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <Array.au3>
#include <Date.au3>

Opt('MustDeclareVars', 1)

Global $iWatch, $iRes, $bWorking

Global $sLocalPath = @ScriptDir & "\TestDLs\"
If Not FileExists($sLocalPath) Then DirCreate($sLocalPath)

Global $aFiles[5][6] ;zeile 0 für Gesamtgrösse Spalten 2=Grösse aller DownLoaddateien, 3=bereits downheloaded, 4 Bytes durch Neustart verworfen,
;danach Spalten 0=URL, 1=Lokaler Pfad, 2=DL-Grösse,3=DL-Bytes , 4=DL-Handle, 5=Fehler Anzahl
Global $aData[1]
Global $aKBs[10]
$aFiles[0][0] = 4 ;Anzahl der Downloads

$aFiles[1][0] = "http://download.bleepingcomputer.com/Xplode/AdwCleaner.exe"
$aFiles[1][1] = "AdwCleaner.exe"
$aFiles[2][0] = "http://download.iobit.com/action-center/asc920-0330.exe"
$aFiles[2][1] = "Advanced_SystemCare.exe"
$aFiles[3][0] = "http://download.geo.drweb.com/pub/drweb/cureit/drweb-cureit.exe"
$aFiles[3][1] = "DrWeb-CureIt.exe"
$aFiles[4][0] = "http://data-cdn.mbamupdates.com/web/JRT.exe"
$aFiles[4][1] = "JRT.exe"

Dim $hGUI_c[$aFiles[0][0] + 2]
Dim $idprgInfo[$aFiles[0][0] + 2]
Dim $idlblInfo[$aFiles[0][0] + 2]

Global $msg, $sLblText, $tdStart

Global $hGuiMain = GUICreate("Multi-Downloader 0.5.2.4", 325, 250)
Global $button = GUICtrlCreateButton("Start", 5, 20, 70, 20)
Global $Display = GUICtrlCreateButton("Debug", 5, 70, 70, 20)
Global $Arrival = GUICtrlCreateLabel("", 95, 25, 185, 50)
GUICtrlSetFont(-1, 15, 800)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)

For $i = 1 To $aFiles[0][0]
    _MakeDLPanel($i, $aFiles[$i][1])
    GUISwitch($hGuiMain)
Next
_MakeDLPanel($i, 'Gesamt')
Global $idlblKBs = GUICtrlCreateLabel('', 95, 4, 150, 60)
GUICtrlSetFont(-1, 15, 800)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUISwitch($hGuiMain)
GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            $iRes=$IDNO
            If $bWorking Then $iRes=MsgBox($MB_YESNO+$MB_ICONQUESTION,'Sure',"there are some DL's to be continued"&@CRLF&"Realy exit?")
            If $iRes=$IDYES Then Exit
        Case $Display
            _ArrayDisplay($aFiles)
        Case $button
            $tdStart = TimerInit()
            For $i = 1 To $aFiles[0][0]
                $aFiles[$i][4] = InetGet($aFiles[$i][0], $sLocalPath & $aFiles[$i][1], 1, 1)
                GUICtrlSetState($idlblInfo[$i], $GUI_SHOW)
            Next
            GUICtrlSetState($idlblInfo[$i], $GUI_SHOW)
            AdlibRegister('_WatchDL', 10)
            AdlibRegister('_checkArrival',1000)
            ;_ArrayDisplay($aFiles)
    EndSwitch
WEnd

Func _MakeDLPanel($iNo, $sText)
    $idprgInfo[$iNo] = GUICtrlCreateProgress(8, 70 + $iNo * 30, 310, 30)
;   $hGUI_c[$iNo] = GUICreate("", 309, 30, 8, 70 + $iNo * 30, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TRANSPARENT, $WS_EX_MDICHILD), $hGuiMain)
    $hGUI_c[$iNo] = GUICreate("", 309, 30, 698, 70 + $iNo * 30, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TRANSPARENT, $WS_EX_MDICHILD), $hGuiMain)
    GUISetBkColor(0x989898, $hGUI_c[$iNo])
    GUICtrlCreateLabel($sText, 0, 8, 220, 25, $ES_LEFT)
    GUICtrlSetFont(-1, 12, 1000)
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
    $idlblInfo[$iNo] = GUICtrlCreateLabel("0,0 % ", 221, 8, 90, 25, $ES_RIGHT)
    GUICtrlSetState(-1, $GUI_HIDE)
    GUICtrlSetFont(-1, 12, 1000)
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
    _WinAPI_SetLayeredWindowAttributes($hGUI_c[$iNo], 0x989898)
    GUISetState(@SW_SHOWNA, $hGUI_c[$iNo])
EndFunc   ;==>_MakeDLPanel

Func _WatchDL()
    ;Local Static $iOld
    Local $iDiff
    Local $nPercent
    $iWatch += 1
    If $iWatch > $aFiles[0][0] Then $iWatch = 1
    If $aFiles[$iWatch][4] > 0 Then
        $aData = InetGetInfo($aFiles[$iWatch][4], -1)
        If @error Then
            ConsoleWrite(@error & @TAB & @extended & @CRLF)
            Return
        EndIf
        If $aFiles[$iWatch][2] = 0 Then
            $aFiles[$iWatch][2] = $aData[1] ;Downloadgrösse ermittelt
            $aFiles[0][2] += $aFiles[$iWatch][2] ;und auch zur Gesamtdownloadgrösse hinzuzählen
        EndIf
        $nPercent = Round($aData[0] / $aFiles[$iWatch][2] * 100, 1)
        $nPercent = StringReplace($nPercent, '-1.#IND', '')
        $aFiles[$iWatch][3] = $aData[0]
        If Int($nPercent) <> GUICtrlRead($idprgInfo[$iWatch]) Then _
                GUICtrlSetData($idprgInfo[$iWatch], Int($nPercent))
        If $nPercent <> Number(GUICtrlRead($idlblInfo[$iWatch])) Then _
                GUICtrlSetData($idlblInfo[$iWatch], _FormatString($nPercent))
        If $aData[2] Then
            If $aData[3] Then
                InetClose($aFiles[$iWatch][4])
                $aFiles[$iWatch][4] = 'Erfolg'
                GUICtrlSetData($idprgInfo[$iWatch], 100)
            Else
                $aFiles[$iWatch][5] += 1
                If $aFiles[$iWatch][5] < 10 Then
                    $aFiles[$iWatch][4] = InetGet($aFiles[$iWatch][0], $sLocalPath & $aFiles[$iWatch][1], 1, 1)
                    $aFiles[0][4] += $aFiles[$iWatch][3]
                Else
                    $aFiles[0][2] -= $aFiles[$iWatch][2]; von gesamt DL-größe abziehen
                    $aFiles[$iWatch][2] = 0
                    $aFiles[$iWatch][3] = 0
                    $aFiles[$iWatch][4] = 'Abbruch'
                    GUICtrlSetData($idprgInfo[$iWatch], 0)
                    GUICtrlSetData($idlblInfo[$iWatch], 'Abbruch')
                EndIf
            EndIf
        EndIf
        $aFiles[0][3] = 0
        For $iWatch = 1 To $aFiles[0][0]
            $aFiles[0][3] += $aFiles[$iWatch][3]
        Next
        #cs
            If $aFiles[0][3] <> 0 Then $iDiff = $iOld - $aFiles[0][3]
            _ArrayPush($aKBs, $iDiff)
            Local $nKBs = 0
            For $i = 0 To UBound($aKBs) - 1
            $nKBs += $aKBs[$i]
            Next
            $nKBs = Round($nKBs / 10240, 2)
            GUICtrlSetData($idlblKBs, _FormatString($nKBs, 'KByte/sec'))
            $iOld=$aFiles[0][3]
        #ce
        $nPercent = Round($aFiles[0][3] / $aFiles[0][2] * 100, 1)
        $nPercent = StringReplace($nPercent, '-1.#IND', '')
        If Int($nPercent) <> GUICtrlRead($idprgInfo[$iWatch]) Then _
                GUICtrlSetData($idprgInfo[$iWatch], Int($nPercent))
        If $nPercent <> Number(GUICtrlRead($idlblInfo[$iWatch])) Then _
                GUICtrlSetData($idlblInfo[$iWatch], _FormatString($nPercent))
    EndIf
    $bWorking = False
    For $i = 1 To $aFiles[0][0]
        $bWorking = ($aFiles[$i][4] > 0)
        If $bWorking Then ExitLoop
    Next
    If Not $bWorking Then
        _ArrayDisplay($aFiles, 'Downloads beendet')
        AdlibUnRegister('_WatchDL')
        AdlibUnRegister('_checkArrival')
    EndIf
EndFunc   ;==>_WatchDL

Func _checkArrival()
    Local $iOld
        Local $iElapsed = TimerDiff($tdStart) / 1000
        Local $nKBs = Round(($aFiles[0][3] + $aFiles[0][4]) / $iElapsed / 1024, 1)
        If $nKBs <> Number(GUICtrlRead($idlblKBs)) Then _
                GUICtrlSetData($idlblKBs, _FormatString($nKBs, 'KB/s'))
        Local $iRemaining = Int(($aFiles[0][2] - $aFiles[0][3]) / $nKBs / 1024)
        if $iRemaining<>$iOld Then _
            GUICtrlSetData($Arrival, _FormartRestTime($iRemaining))
        $iOld=$iRemaining
        ConsoleWrite('noch: ' & $iRemaining & ' Sekunden!' & @CRLF)
EndFunc

Func _FormartRestTime($iSec)
    Local $sRet
    If $iSec<0 Then
        $sRet='unbekante Dauer'
        Return $sRet
    EndIf
    Local $iHour=Int($iSec/3600), $iMin
    if $iHour Then
        AdlibRegister('_checkArrival',60000)
        $iMin=Mod($iSec,3600)
        $sRet='noch ca. '&$iHour&','&$iMin &' Stunden'
    Else
        $iMin=Int($iSec/60)
        If $iMin Then
            AdlibRegister('_checkArrival',10000)
            $sRet='noch ca. '& $iMin &' Minuten'
        Else
            AdlibRegister('_checkArrival')
            $sRet='noch ca. '& $iSec &' Sekunden'
        EndIf
    EndIf
    Return $sRet
EndFunc

Func _FormatString($number, $sExt = '% ')
    If Not StringInStr($number, '.') Then $number &= '.0'
    If $number = '.0' Then $number = '0.0'
    Return StringReplace(StringFormat("%8s " & $sExt, $number), '.', ',')
EndFunc   ;==>_FormatString

and as you can see all 4 childs are not in the parent coordinates, all are moving with parent and parent don't lose focus. Have a look on #90+91. It's only a proof of concept script, but it show's  how to do.

Edited by AutoBert

Share this post


Link to post
Share on other sites

#3 ·  Posted

either i didn't understand your script, or that looks like the exact opposite of what i'm trying to do. let me explain better with a screenshot:

child_GUI.jpg

the child GUI is the white bar with numbers 0..59, what i want to do is make only the part 0..30 visible (because its inside the parent GUI), and use an horizontal scrollbar to get to the rest of the numbers back and forth.

 

Share this post


Link to post
Share on other sites

#4 ·  Posted

Sorry, i don't tested your script. I will do it asap.

  • Your child must be created with coordinates inside parent
  • you need a scrollbar. _GUIScrollBars_Init is a good example  (i think from @Melba23)
  • to avoid of parent losing focus line 90+91 of mine should do the job

 

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

the coordinates are (0,0) relative to the parent GUI. its the width that i need wider.

using the scrollbar UDF makes the scrollbar button width sensible, but is still dysfunctional, as the child GUI is still visible in full:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiScrollBars.au3>

Global Const $iGUI_W = 600
Global Const $iGUI_H = 450

Global $hGUI = GUICreate('test', $iGUI_W, $iGUI_H)
GUISetBkColor(0xFEDCBA)
Global $hGUI2 = GUICreate('', $iGUI_W * 2, 70, 0, 0, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)

; using the scrollbars UDF instead of the GUI style
_GUIScrollBars_Init($hGUI2)
_GUIScrollBars_ShowScrollBar($hGUI2, $SB_HORZ)
_GUIScrollBars_ShowScrollBar($hGUI2, $SB_VERT, False)


For $i = 0 To 60
    GUICtrlCreateLabel($i, $i * 20, 10)
Next

GUISetState(@SW_SHOW, $hGUI)
GUISetState(@SW_SHOW, $hGUI2)
Global $msg = 0
While True
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

i'm now struggling to understand the focus thing...

 

Edited by orbs

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Got it halfway there,  unfortunately it resizes the controls within the child GUI, looking into a fix

 

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiScrollBars.au3>

Global Const $iGUI_W = 600
Global Const $iGUI_H = 450

Global $hGUI = GUICreate('test', $iGUI_W, $iGUI_H)
GUISetBkColor(0xFEDCBA)
Global $hGUI2 = GUICreate('', $iGUI_W * 2, 70, 0, 0, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)

; using the scrollbars UDF instead of the GUI style
_GUIScrollBars_Init($hGUI2)
_GUIScrollBars_ShowScrollBar($hGUI2, $SB_HORZ)
_GUIScrollBars_ShowScrollBar($hGUI2, $SB_VERT, False)


For $i = 0 To 60
    GUICtrlCreateLabel($i, $i * 20, 10)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
Next

GUISetState(@SW_SHOW, $hGUI)
GUISetState(@SW_SHOW, $hGUI2)
Global $msg = 0


$aArray = WinGetPos($hGUI2)
WinMove($hGUI2, "", $aArray[0], $aArray[1], $iGUI_W, 70)

While True
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

 

EDIT: Fixed the resizing but now the scroll-bar is broke!

Edited by rcmaehl

My UDFs are generally for me. If they aren't updated for a while, it means I'm not using them myself. As soon as I start using them again, they'll get updated.

MY PROJECTS


Active: IRC UDF, WindowEx UDF
Discontinued: GithubBubbleSort UDF

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Edit: final solution:

#include <GUIConstantsEx.au3>
#include <GuiScrollBars.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>

#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

Global Const $iGUI_W = 600
Global Const $iGUI_H = 450

Example()

Func Example()
    Local $hGUIMsg, $hGUI, $hGui2
    $hGUI = GUICreate("ScrollBar Example", $iGUI_W, $iGUI_H)
    GUISetBkColor(0xFEDCBA)


    $hGui2 = GUICreate("Child GUI", $iGUI_W, 70, 0, 0, $WS_CHILD, $WS_EX_CLIENTEDGE, $hGUI)
    For $i = 0 To 60
        GUICtrlCreateLabel($i, $i * 20, 10)
    Next
    GUISetState(@SW_SHOW)
    GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL")
    _GUIScrollBars_Init($hGui2,$iGUI_W*2,0)
    GUISetState(@SW_SHOW,$hGUI)
    While 1
        $hGUIMsg = GUIGetMsg()

        Switch $hGUIMsg
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    Exit
EndFunc   ;==>Example

Func WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg, $lParam
    Local $iScrollCode = BitAND($wParam, 0x0000FFFF)

    Local $iIndex = -1, $iCharX, $iPosX
    Local $iMin, $iMax, $iPage, $iPos, $iTrackPos

    For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
        If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
            $iIndex = $x
            $iCharX = $__g_aSB_WindowInfo[$iIndex][2]
            ExitLoop
        EndIf
    Next
    If $iIndex = -1 Then Return 0

    ; ; Get all the horizontal scroll bar information
    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
    $iMin = DllStructGetData($tSCROLLINFO, "nMin")
    $iMax = DllStructGetData($tSCROLLINFO, "nMax")
    $iPage = DllStructGetData($tSCROLLINFO, "nPage")
    ; Save the position for comparison later on
    $iPosX = DllStructGetData($tSCROLLINFO, "nPos")
    $iPos = $iPosX
    $iTrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
    #forceref $iMin, $iMax
    Switch $iScrollCode

        Case $SB_LINELEFT ; user clicked left arrow
            DllStructSetData($tSCROLLINFO, "nPos", $iPos - 1)

        Case $SB_LINERIGHT ; user clicked right arrow
            DllStructSetData($tSCROLLINFO, "nPos", $iPos + 1)

        Case $SB_PAGELEFT ; user clicked the scroll bar shaft left of the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $iPos - $iPage)

        Case $SB_PAGERIGHT ; user clicked the scroll bar shaft right of the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $iPos + $iPage)

        Case $SB_THUMBTRACK ; user dragged the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $iTrackPos)
    EndSwitch

    ; // Set the position and then retrieve it.  Due to adjustments
    ; //   by Windows it may not be the same as the value set.

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
    ;// If the position has changed, scroll the window and update it
    $iPos = DllStructGetData($tSCROLLINFO, "nPos")
    If ($iPos <> $iPosX) Then _GUIScrollBars_ScrollWindow($hWnd, $iCharX * ($iPosX - $iPos), 0)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_HSCROLL

 

Edited by AutoBert
1 person likes this

Share this post


Link to post
Share on other sites

#8 ·  Posted

change line 25 to

_GUIScrollBars_Init($hGui2,$iGUI_W*2-16,0)  ;16 is the width of guiborders

 

Share this post


Link to post
Share on other sites

#9 ·  Posted

thanks @AutoBert, i'm studying your example in attempt to implement it. i understand the issue is not the child GUI by itself, but the functionality of the scrollbar, which - apparently - requires custom handling.

frankly, i never thought it would come to this... by far more complicated than i could ever figure out by myself. i thought it's just a matter of declaring GUI styles properly, maybe matching with coordinates and dimensions... :unsure:

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