Flag: Null ist nicht Null - und wie frage ich Null ab?

    • Offizieller Beitrag

    Bei der Überschrift kann keiner widerstehen - alle gucken rein. :D

    Problem:
    Ich schreibe Text mit _WinAPI_DrawText() und kann per Flag die Textausrichtung setzen. Wie üblich können die Werte mit BitOR() kombiniert werden.
    Hier die möglichen Werte:

    Code
    $DT_BOTTOM = 0x8
    $DT_CENTER = 0x1
    $DT_LEFT = 0x0   <== wie abfragen?
    $DT_RIGHT = 0x2
    $DT_TOP = 0x0    <== wie abfragen?
    $DT_VCENTER = 0x4

    Sowohl LEFT, als auch TOP haben den Wert "0". Erstaunlicherweise ergibt die Kombination aus LEFT und TOP zwar weiterhin nur 1-mal "0" aber der Text wird richtig positioniert.
    In einer Funktion versuche ich die Ausrichtung auszulesen. Nur: Wie soll man mit BitAND() "0" abfragen - und: Welches "0" wäre das dann - LEFT oder TOP?

    Hier mal das Skript, vllt. hat jemand eine zündende Idee.

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <FontConstants.au3>

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

    Global $Gui, $Button, $tRECT, $hBrush = _WinAPI_CreateSolidBrush(0x000000)
    Global $hFont, $hOldFont, $hDC, $sText = "VCenter+HCenter", $iAlignment = BitOR($DT_CENTER,$DT_VCENTER)

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

    $tRECT = DllStructCreate($tagRect)
    DllStructSetData($tRECT, "Left", 100)
    DllStructSetData($tRECT, "Top", 80)
    DllStructSetData($tRECT, "Right", 250)
    DllStructSetData($tRECT, "Bottom", 130)

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

    $Gui = GUICreate('Test')
    $Button = GUICtrlCreateButton('Weiter', 125, 160, 80, 20)

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

    $hDC = _WinAPI_GetDC($Gui)
    $hFont = _WinAPI_CreateFont(20, 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, _
    $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Arial')
    $hOldFont = _WinAPI_SelectObject($hDC, $hFont)

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

    _WinAPI_SetTextColor($hDC, 0x0000FF)
    _WinAPI_SetBkColor($hDC, 0x000000)
    _WinAPI_SetBkMode($hDC, $TRANSPARENT)

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

    GUISetState()

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

    _WinAPI_DrawText($hDC, $sText, $tRECT, BitOR($DT_NOCLIP,$DT_SINGLELINE,$iAlignment))
    _WinAPI_FrameRect($hDC, DllStructGetPtr($tRECT), $hBrush)

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

    $counter = 0
    While 1
    Switch GUIGetMsg()
    Case -3
    _Exit()
    Case $Button
    $counter += 1
    If $counter = 9 Then $counter = 0
    Switch $counter
    Case 0
    $sText = 'VCenter+HCenter'
    _AlignmentSet(-1)
    ConsoleWrite('Ausrichtung: ' & $iAlignment & ': ' & _AlignmentGetAsStr($iAlignment) & @CRLF)
    Case 1
    $sText = 'Top+Left'
    _AlignmentSet(BitOR($DT_TOP,$DT_LEFT))
    ConsoleWrite('Ausrichtung: ' & $iAlignment & ': ' & _AlignmentGetAsStr($iAlignment) & @CRLF)
    Case 2
    $sText = 'Top+HCenter'
    _AlignmentSet(BitOR($DT_TOP,$DT_CENTER))
    ConsoleWrite('Ausrichtung: ' & $iAlignment & ': ' & _AlignmentGetAsStr($iAlignment) & @CRLF)
    Case 3
    $sText = 'Top+Right'
    _AlignmentSet(BitOR($DT_TOP,$DT_RIGHT))
    ConsoleWrite('Ausrichtung: ' & $iAlignment & ': ' & _AlignmentGetAsStr($iAlignment) & @CRLF)
    Case 4
    $sText = 'Left+VCenter'
    _AlignmentSet(BitOR($DT_LEFT,$DT_VCENTER))
    ConsoleWrite('Ausrichtung: ' & $iAlignment & ': ' & _AlignmentGetAsStr($iAlignment) & @CRLF)
    Case 5
    $sText = 'Right+VCenter'
    _AlignmentSet(BitOR($DT_RIGHT,$DT_VCENTER))
    ConsoleWrite('Ausrichtung: ' & $iAlignment & ': ' & _AlignmentGetAsStr($iAlignment) & @CRLF)
    Case 6
    $sText = 'Bottom+Left'
    _AlignmentSet(BitOR($DT_BOTTOM,$DT_LEFT))
    ConsoleWrite('Ausrichtung: ' & $iAlignment & ': ' & _AlignmentGetAsStr($iAlignment) & @CRLF)
    Case 7
    $sText = 'Bottom+HCenter'
    _AlignmentSet(BitOR($DT_BOTTOM,$DT_CENTER))
    ConsoleWrite('Ausrichtung: ' & $iAlignment & ': ' & _AlignmentGetAsStr($iAlignment) & @CRLF)
    Case 8
    $sText = 'Bottom+Right'
    _AlignmentSet(BitOR($DT_BOTTOM,$DT_RIGHT))
    ConsoleWrite('Ausrichtung: ' & $iAlignment & ': ' & _AlignmentGetAsStr($iAlignment) & @CRLF)
    EndSwitch
    EndSwitch
    WEnd

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

    Func _Exit()
    _WinAPI_SelectObject($hDC, $hOldFont)
    _WinAPI_DeleteObject($hFont)
    _WinAPI_ReleaseDC(0, $hDC)
    _WinAPI_InvalidateRect(0, 0)
    $tRECT = 0
    Exit
    EndFunc ;==>_Exit

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

    ;==================================================================================================
    ; mgl. Werte: $DT_BOTTOM, $DT_CENTER, $DT_LEFT, $DT_RIGHT, $DT_TOP, $DT_VCENTER
    ; -1/Default = BitOR($DT_CENTER,$DT_VCENTER)
    ;==================================================================================================
    Func _AlignmentSet($Alignment=-1)
    If IsKeyword($Alignment) Or $Alignment < 0 Then $Alignment = BitOR($DT_CENTER,$DT_VCENTER)
    $iAlignment = $Alignment
    _WinAPI_RedrawWindow($Gui, $tRECT)
    _WinAPI_DrawText($hDC, $sText, $tRECT, BitOR($DT_NOCLIP,$DT_SINGLELINE,$iAlignment))
    _WinAPI_FrameRect($hDC, DllStructGetPtr($tRECT), $hBrush)
    EndFunc

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

    Func _AlignmentGetAsStr($iAlignment)
    Local $sAlignment = ''
    If BitAND($iAlignment, $DT_BOTTOM) Then $sAlignment &= '$DT_BOTTOM '
    If BitAND($iAlignment, $DT_CENTER) Then $sAlignment &= '$DT_CENTER '
    If BitAND($iAlignment, $DT_LEFT) Then $sAlignment &= '$DT_LEFT '
    If BitAND($iAlignment, $DT_RIGHT) Then $sAlignment &= '$DT_RIGHT '
    If BitAND($iAlignment, $DT_TOP) Then $sAlignment &= '$DT_TOP '
    If BitAND($iAlignment, $DT_VCENTER) Then $sAlignment &= '$DT_VCENTER '
    Return StringTrimRight($sAlignment, 1)
    EndFunc

    [/autoit]
  • Ui da hat wohl ein Microsoft Programmierer gepennt als er die Flags vergeben hat.

    Also wenn man 2 mal 0 kombiniert und dann rausbekommen will ob 0 drinne ist kann man nicht wirklich ermitteln welche 0 die richtige Null ist.
    Und woher weiß eigentlich die Funktion ob es nun Left oder Top ist, es ist ja beides 0.

  • Ich würde das so sehen:
    Standardausrichtung ist LEFT-TOP, daher werden dafür keine speziellen Flags benötigt. Die Textausrichtung besteht ja immer aus 2 Werten, einmal vertikal und einmal horizontal.

  • Seh das so wie progandy, dann ergibt sich:

    $DT_LEFT = 0x0 +
    $DT_TOP = 0x0 = 0
    $DT_VCENTER = 0x4 = 4
    $DT_BOTTOM = 0x8 = 8

    $DT_CENTER = 0x1 +
    $DT_TOP = 0x0 = 1
    $DT_VCENTER = 0x4 = 5
    $DT_BOTTOM = 0x8 = 9

    $DT_RIGHT = 0x2 +
    $DT_TOP = 0x0 = 2
    $DT_VCENTER = 0x4 = 6
    $DT_BOTTOM = 0x8 = 10

    Jede mögliche Kombination ist nur einmal vergeben.

  • Ich habe gleich mal ein Skript dazu geschrieben ;)

    Spoiler anzeigen
    [autoit]

    #include<WindowsConstants.au3>
    Func _GetAlign($iBitMask)
    ; Author: ProgAndy
    Local $sResult=""
    Select
    Case BitAND($iBitMask, $DT_CENTER)=$DT_CENTER
    $sResult &= "CENTER"
    Case BitAND($iBitMask, $DT_RIGHT)=$DT_RIGHT
    $sResult &= "RIGHT"
    Case Else
    $sResult &= "LEFT"
    EndSelect
    $sResult&='-'
    Select
    Case BitAND($iBitMask, $DT_VCENTER)=$DT_VCENTER
    $sResult &= "VCENTER"
    Case BitAND($iBitMask, $DT_BOTTOM)=$DT_BOTTOM
    $sResult &= "BOTTOM"
    Case Else
    $sResult &= "TOP"
    EndSelect
    Return $sResult
    EndFunc

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

    MsgBox(0, '', _GetAlign(BitOR($DT_LEFT, $DT_VCENTER)))

    [/autoit]