Fehlerhafte Werte von _GUICtrlTab_GetItemRect() und _GUICtrlTab_GetItemRectEx()

    • Offizieller Beitrag

    Hi,
    ich bin fast schon an mir selbst verzweifelt, weil ich einen Fehler nicht fand. Dabei kommt der Fehler von den oben genannten Funktionen.
    Im folgenden Bsp. könnt ihr es selbst testen:
    Der Code dient dazu, bei Rechtsklick festzustellen über welchem Tabitem der Rechtsklick erfolgt, da dabei das Item nicht aktiviert wird.
    Klickt mit re. Maustaste in die Mitte der Tabbezeichnung (Buchstabe 'a'), dann wird mit _GUICtrlTab_GetItemRect() die Abmessung/Position des Tabitem ermittelt. Bei 'Tab 0' wird dort left=2, top=2 zurückgegeben obwohl das Tab an Position 8,8 erstellt wurde!
    Laut Rect-Funktion befindet man sich bereits bei Schriftende eines Tabs im nächsten Tab. :wacko:
    (Die beiden Funktionen sind identisch - nur gibt eine ein Array und die andere eine Struktur zurück.)

    Hat jemand dafür eine Erklärung/ Lösung parat?

    Spoiler anzeigen
    [autoit]

    #include <GuiConstantsEx.au3>
    #include <GuiTab.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <StructureConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $Form1 = GUICreate("Test", 297, 341, 210, 144)
    $Tab = GUICtrlCreateTab(8, 8, 280, 240)
    $hTab = GUICtrlGetHandle($Tab)
    GUICtrlSetResizing(-1, $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
    $tab1 = GUICtrlCreateTabItem("Tab 0")
    $tab2 = GUICtrlCreateTabItem("Tab 1")
    $tab3 = GUICtrlCreateTabItem("Tab 2")
    $tab4 = GUICtrlCreateTabItem("Tab 3")
    GUICtrlCreateTabItem("")
    $labelRect = GUICtrlCreateLabel('', 8, 270, 280, 17)
    $labelMouse = GUICtrlCreateLabel('', 8, 305, 280, 17)
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $GUI_EVENT_SECONDARYUP
    For $i = 0 To 3
    $old = Opt('MouseCoordMode', 2)
    $mouse = MouseGetPos()
    Opt('MouseCoordMode', $old)
    GUICtrlSetData($labelMouse, 'MousePos: ' & $mouse[0] & ', ' & $mouse[1])
    If _MouseOverTabItem($Form1, $hTab, $i) Then
    WinSetTitle($Form1, '', 'Right clicked Index: ' & $i)
    $rect = _GUICtrlTab_GetItemRect($hTab, $i)
    GUICtrlSetData($labelRect, 'ItemRECT: ' & $rect[0] & ', ' & $rect[1] & ', ' & $rect[2] & ', ' & $rect[3])
    ExitLoop
    EndIf
    Next
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _MouseOverTabItem($GUI, $hWnd, $iTabItem)
    If Not BitAND(WinGetState($GUI), 8) Then Return False
    Local $old = Opt('MouseCoordMode', 2)
    Local $posM = MouseGetPos(), $tMouse = DllStructCreate($tagPOINT)
    DllStructSetData($tMouse, 1, $posM[0])
    DllStructSetData($tMouse, 2, $posM[1])
    Opt('MouseCoordMode', $old)
    Local $tTabItem = _GUICtrlTab_GetItemRectEx($hWnd, $iTabItem)
    If _WinAPI_PtInRect($tTabItem, $tMouse) Then
    Return True
    Else
    Return False
    EndIf
    EndFunc ;==>_MouseOverTabItem

    [/autoit]
  • Damit werden die Werte der Items innerhalb eines Tab's zurückgegeben.
    Item 0 beginnt mit der Standardfunktion immer bei 2|2, innerhalb des Controls.

    edit \ Irgendwie funktioniert die Funktion trotzdem nicht richtig. :wacko:

    Aus der Hilfe:

    Spoiler anzeigen
    [autoit]


    #AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
    #include <GuiConstantsEx.au3>
    #include <GuiTab.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt('MustDeclareVars', 1)

    [/autoit] [autoit][/autoit] [autoit]

    $Debug_TAB = False ; Check ClassName being passed to functions, set to True and use a handle to another control to see it work

    [/autoit] [autoit][/autoit] [autoit]

    _Main()

    [/autoit] [autoit][/autoit] [autoit]

    Func _Main()
    Local $aRect, $aRect2, $sRect, $sRect2, $hTab

    [/autoit] [autoit][/autoit] [autoit]

    ; Create GUI
    GUICreate("Tab Control Get Item Rect", 400, 300)
    $hTab = GUICtrlCreateTab(2, 2, 396, 296)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    ; Add tabs
    _GUICtrlTab_InsertItem($hTab, 0, "Tab00000000 1")
    _GUICtrlTab_InsertItem($hTab, 1, "Tab 2")
    _GUICtrlTab_InsertItem($hTab, 2, "Tab 3")

    [/autoit] [autoit][/autoit] [autoit]

    ; Get tab 0 rectangle
    $aRect = _GUICtrlTab_GetItemRect($hTab, 0)
    $sRect = StringFormat("[%d, %d, %d, %d]", $aRect[0], $aRect[1], $aRect[2], $aRect[3])
    $aRect2 = _GUICtrlTab_GetItemRect($hTab, 1)
    $sRect2 = StringFormat("[%d, %d, %d, %d]", $aRect2[0], $aRect2[1], $aRect2[2], $aRect2[3])
    MsgBox(4160, "Information", "Tab 0 rectangle: " & $sRect & @crlf & $sRect2)

    [/autoit] [autoit][/autoit] [autoit]

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
    EndFunc ;==>_Main

    [/autoit]


    Demnach ist der Lösungsweg nicht zielführend? Man müsste an die Koordinaten relativ zur GUI rankommen.

    Einmal editiert, zuletzt von nuts (15. April 2010 um 12:11)

    • Offizieller Beitrag

    Man müsste an die Koordinaten relativ zur GUI rankommen.


    Hab jetzt nochmal verschiedene Positionen getestet. Es ist wirklich ein Unding, die Funktion gibt Breite und Höhe der Items korrekt zurück aber die Left/Top-Position beginnt für Item0 immer mit 2,2.

  • Mit Top, Left vom Tabcontrol + dem bekannten 2|2 Paramter fürs Standardtabitem + den gelieferten Werten aus der Funktion lässt sich die absolute Position des Tabitems doch berechnen und z.B. in ein Array ablegen?

    • Offizieller Beitrag

    lässt sich die absolute Position des Tabitems doch berechnen und z.B. in ein Array ablegen?


    Könnte man machen, ist aber nicht flexibel. Wenn der User z.B. die Möglichkeit hat die Registertitel zu ändern, ändern sich auch die Positionen aller Item.

    Ich habe deshalb jetzt eine Funktion erstellt, die die Koordianten relativ zum Fenster ermittelt und bei der Gelegenheit habe ich aus den beiden Funktionen eine gemacht. Ist doch blödsinnig, nur wegen eines anderen Returntypes eine neue Funktion zu verwenden.

    So klappt es jetzt:

    Spoiler anzeigen
    [autoit]

    #include <GuiConstantsEx.au3>
    #include <GuiTab.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <StructureConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $Form1 = GUICreate("Test", 297, 341, 210, 144)
    $TabID = GUICtrlCreateTab(18, 18, 280, 240)
    GUICtrlSetResizing(-1, $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
    $tab1 = GUICtrlCreateTabItem("Tab 0")
    $tab2 = GUICtrlCreateTabItem("Tab 1")
    $tab3 = GUICtrlCreateTabItem("Tab 2")
    $tab4 = GUICtrlCreateTabItem("Tab 3")
    GUICtrlCreateTabItem("")
    $labelRect = GUICtrlCreateLabel('', 8, 270, 280, 17)
    $labelMouse = GUICtrlCreateLabel('', 8, 305, 280, 17)
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $GUI_EVENT_SECONDARYUP
    For $i = 0 To 3
    $old = Opt('MouseCoordMode', 2)
    $mouse = MouseGetPos()
    Opt('MouseCoordMode', $old)
    GUICtrlSetData($labelMouse, 'MousePos: ' & $mouse[0] & ', ' & $mouse[1])
    If _MouseOverTabItem($Form1, $TabID, $i) Then
    WinSetTitle($Form1, '', 'Right clicked Index: ' & $i)
    $rect = _GUICtrlTab_GetItemRectRelativ($Form1, $TabID, $i)
    GUICtrlSetData($labelRect, 'ItemRECT: ' & $rect[0] & ', ' & $rect[1] & ', ' & $rect[2] & ', ' & $rect[3])
    ExitLoop
    EndIf
    Next
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _MouseOverTabItem($GUI, $TabID, $iTabItem)
    If Not BitAND(WinGetState($GUI), 8) Then Return False
    Local $old = Opt('MouseCoordMode', 2)
    Local $posM = MouseGetPos(), $tMouse = DllStructCreate($tagPOINT)
    DllStructSetData($tMouse, 1, $posM[0])
    DllStructSetData($tMouse, 2, $posM[1])
    Opt('MouseCoordMode', $old)
    Local $tTabItem = _GUICtrlTab_GetItemRectRelativ($GUI, $TabID, $iTabItem, 1)
    If _WinAPI_PtInRect($tTabItem, $tMouse) Then
    Return True
    Else
    Return False
    EndIf
    EndFunc ;==>_MouseOverTabItem

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; Function Name: _GUICtrlTab_GetItemRectRelativ($GUI, $TabID, $iTabItem, $iReturnType=0)
    ; Description: Gibt die Koordinaten eines TabItem relativ zu den GUI-Koordinaten zurück
    ; Parameter(s): $GUI - Fensterhandle
    ; $TabID - ID des Tab (nicht Handle!)
    ; $iTabItem - Tabitem Index
    ; $iReturnType - Rückgabetyp Array=0 (Standard), RECT-Struktur=1
    ; Return Value(s): Array oder Struktur mit den TabItem Koordinaten (left, top, right, bottom)
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _GUICtrlTab_GetItemRectRelativ($GUI, $TabID, $iTabItem, $iReturnType=0)
    Local $hWnd = GUICtrlGetHandle($TabID)
    Local $TabPos = ControlGetPos($GUI, '', $TabID)
    Local $tRECT = _GUICtrlTab_GetItemRectEx($hWnd, $iTabItem)
    Local $posLeft = $TabPos[0]+2, $posTop = $TabPos[1]+2
    Local $width = (DllStructGetData($tRECT,3) - DllStructGetData($tRECT,1))
    Local $height = DllStructGetData($tRECT,4) - DllStructGetData($tRECT,2)
    If $iTabItem > 0 Then
    For $i = 0 To $iTabItem -1
    $tRECT = _GUICtrlTab_GetItemRectEx($hWnd, $i)
    $posLeft += (DllStructGetData($tRECT,3) - DllStructGetData($tRECT,1))
    Next
    EndIf
    If $iReturnType Then
    DllCall("user32", 'long', 'SetRect', 'ptr', DllStructGetPtr($tRECT), _
    'long', $posLeft, 'long', $posTop, 'long', $posLeft+$width, 'long', $posTop +$height)
    Return $tRECT
    Else
    Local $aOut[4] = [$posLeft, $posTop, $posLeft +$width, $posTop +$height]
    Return $aOut
    EndIf
    EndFunc ;==>_GUICtrlTab_GetItemRectRelativ

    [/autoit]