Zeichnen ohne GDI+

  • Hallo,

    ich programmiere momentan ein Tool für Screenshots.
    Mit dem Tool ist es möglich einen Bereich auf dem Bildschirm auszuwählen und zu speichern.
    Dies funktioniert auch alles so weit.
    Momentan ist es so, dass man die Linke Maustaste für die Anfangsbildschirmposition verwendet und die Mitteltaste für die Endposition des Bereiches.
    Es wäre gut, wenn man um diesen Bereich dann ein farbliches Rechteck zeichnen könnte um den User aufzuzeigen welchen Bereich er genau ausgewählt hat.

    Ich weiss, dass es schon mehrer Beiträge dazu gibt. Keiner der Beiträge hat aber bis Jetzt zu meinem Problem gepasst.

    Vielleicht könnt Ihr mir ja helfen :)

    Gruß

  • Warum willst du kein GDI+ verwenden? Geht doch damit perfekt?

    Ohne GDI+, könnte mans glaubich mit meiner UDF und nem Popup Window auch machen, aber GDI+ ist da besser geeignet.

    Du könntest es auch so als Beispiel machen:

    Spoiler anzeigen
    [autoit]

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

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

    Global Const $WS_EX_COMPOSITED = 0x2000000

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

    Dim $Child[301]
    Global $i = 0, $PosBuff, $w = 100, $h = 100
    $Form1 = GUICreate("Test", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, BitOR ($WS_EX_TOPMOST, $WS_EX_LAYERED,$WS_EX_COMPOSITED))
    GUISetBkColor ( 0x000000 )
    GUISetState()
    $Pos = MouseGetPos()
    _DrawTransparentRect($Form1, $Pos[0]-($w/2),$Pos[1]-($h/2),$w,$h, 100)

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

    While 1
    sleep(10)
    $Pos = MouseGetPos()
    If $PosBuff <> $Pos Then
    _DrawTransparentRect ($Form1, $Pos[0]-($w/2),$Pos[1]-($h/2),$w,$h, 100)
    EndIf
    $msg=GUIGetMsg()
    Switch $msg
    Case $GUI_EVENT_CLOSE
    Exit
    EndSwitch
    If _isPressed("BB") Then
    _expand()
    EndIf
    If _isPressed("BD") Then
    _shrink()
    EndIf
    If _isPressed("01") Then
    _ScreenCapture_Capture(@ScriptDir & "\" & $i &".jpg", $Pos[0]-($w/2), $Pos[1]-($h/2), $w + $Pos[0]-($w/2), $h + $Pos[1]-($h/2))
    EndIf
    $Pos = $PosBuff
    WEnd

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

    Func _DrawTransparentRect($hwnd, $x,$y,$w,$h,$Transparency=255)
    $i += 1
    If $i = 301 Then
    $i = 1
    GuiDelete($Child[300])
    EndIf
    If $Transparency > 255 Then $Transperency = 255
    $Child[$i] =GUICreate ( "", $w, $h, $x, $y, $WS_CHILD, -1, $hwnd )
    _WinAPI_SetLayeredWindowAttributes($Form1, 0xABCDEF, $Transparency)
    GUISetBkColor ( 0xABCDEF, $Child[$i] )
    GUISetState()
    sleep(10)
    If $i <> 0 Then
    GuiDelete($Child[$i-1])
    EndIf
    Return $Child
    EndFunc

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

    Func _WinAPI_SetLayeredWindowAttributes($hwnd, $i_transcolor, $Transparency = 255, $dwFlages = 0x03, $isColorRef = False)
    ; progandy
    If $dwFlages = Default Or $dwFlages = "" Or $dwFlages < 0 Then $dwFlages = 0x03
    If Not $isColorRef Then
    $i_transcolor = Hex(String($i_transcolor), 6)
    $i_transcolor = Execute('0x00' & StringMid($i_transcolor, 5, 2) & StringMid($i_transcolor, 3, 2) & StringMid($i_transcolor, 1, 2))
    EndIf
    Local $Ret = DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $hwnd, "long", $i_transcolor, "byte", $Transparency, "long", $dwFlages)
    Select
    Case @error
    Return SetError(@error, 0, 0)
    Case $Ret[0] = 0
    Return SetError(4, _WinAPI_GetLastError(), 0)
    Case Else
    Return 1
    EndSelect
    EndFunc ;==>_WinAPI_SetLayeredWindowAttributes

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

    Func _expand()
    $Pos = MouseGetPos()
    If $w < 391 And $h < 391 Then
    $w += 10
    $h += 10
    _DrawTransparentRect($Form1, $Pos[0]-($w/2),$Pos[1]-($h/2),$w,$h, 100)
    GuiDelete($Child[$i-1])
    EndIf
    EndFunc

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

    Func _shrink()
    $Pos = MouseGetPos()
    If $w > 11 And $h > 11 Then
    $w -= 10
    $h -= 10
    _DrawTransparentRect($Form1, $Pos[0]-($w/2),$Pos[1]-($h/2),$w,$h, 100)
    EndIf
    EndFunc

    [/autoit]
  • Hallo,
    danke für eure Hilfe.
    Das ist allerdings noch nicht das was ich eigentlich gerne hätte.
    Du hast jetzt GuiCreate gemacht und hast jetzt das Form über den ganzen Bildschirm. Ich würde es gerne ohne GuiCreate machen.
    Man muss doch irgendwie direkt auf dem Bildschirm zeichnen können oder?

    gruß Tobsl


  • Man muss doch irgendwie direkt auf dem Bildschirm zeichnen können oder?

    GUI brauchst du, hier ma nen Beispiel um direkt auf den Bildschirm zu zeichnen: Auf den Bildschirm zeichen

    Edit:

    Hier mal nen einfacheres Beispiel

    Spoiler anzeigen
    [autoit]

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

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

    HotKeySet("{ESC}", "_ende")

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

    _GDIPlus_Startup()

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

    Global $hGui = GUICreate("Rahmen", @DesktopWidth, @DesktopHeight, -1, -1, $WS_POPUP, BitOR($WS_EX_TOPMOST,$WS_EX_LAYERED))
    GUISetBkColor(0xABCDEF)
    _WinAPI_SetLayeredWindowAttributes($hGui, 0xABCDEF, 255)
    GUISetState()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGui)
    $Pinsel = _GDIPlus_PenCreate(0xFF0000FF, 20)
    $vanish = _GDIPlus_PenCreate(0xFF000000, 20)

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

    _GDIPlus_GraphicsDrawArc ( $hGraphic,@DesktopWidth/2, @DesktopHeight/2, 70, 70, 180, 360, $Pinsel )

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

    While 1
    Sleep(40)
    WEnd

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

    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_BrushDispose($Pinsel)
    _GDIPlus_BrushDispose($vanish)

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

    Func _ende()
    _GDIPlus_BrushDispose($Pinsel)
    _GDIPlus_BrushDispose($vanish)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_ende

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

    Func _WinAPI_SetLayeredWindowAttributes($hwnd, $i_transcolor, $Transparency = 255, $dwFlages = 0x03, $isColorRef = False)
    ; progandy
    If $dwFlages = Default Or $dwFlages = "" Or $dwFlages < 0 Then $dwFlages = 0x03
    If Not $isColorRef Then
    $i_transcolor = Hex(String($i_transcolor), 6)
    $i_transcolor = Execute('0x00' & StringMid($i_transcolor, 5, 2) & StringMid($i_transcolor, 3, 2) & StringMid($i_transcolor, 1, 2))
    EndIf
    Local $Ret = DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $hwnd, "long", $i_transcolor, "byte", $Transparency, "long", $dwFlages)
    Select
    Case @error
    Return SetError(@error, 0, 0)
    Case $Ret[0] = 0
    Return SetError(4, _WinAPI_GetLastError(), 0)
    Case Else
    Return 1
    EndSelect
    EndFunc ;==>_WinAPI_SetLayeredWindowAttributes

    [/autoit]
  • Hi,
    Danke für eure Antworten.
    Wenns halt nicht anders geht,dann muss ich es so machen :)

    Gruß Tobsl :D

  • Moin,

    selbstverständlich geht es auch anders.

    Du nimmst einfach das "+" von der GDI+ und schon geht's. ;)

    GDI Beispiel:

    Spoiler anzeigen
    [autoit]

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

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

    Global $tagRECT = _
    'long left;' & _
    'long top;' & _
    'long right;' & _
    'long bottom;'
    ;

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

    ; Unser Rechteck.
    $rcFrame = DllStructCreate ($tagRECT)

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

    DllStructSetData ($rcFrame, "left", 150)
    DllStructSetData ($rcFrame, "top", 150)
    DllStructSetData ($rcFrame, "right", @DesktopWidth - 150)
    DllStructSetData ($rcFrame, "bottom", @DesktopHeight - 150)

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

    ; Rahmen zeichnen.
    DrawXorFrame (DllStructGetPtr ($rcFrame))

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

    Sleep (3000)

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

    ; Rahmen wieder löschen.
    InvalidateRect (0, 0, TRUE)

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

    ; Aufräumen.
    $rcFrame = 0

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

    Exit (0)

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

    Func DrawXorFrame ($lpRect)

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

    Local $dotPatternBmp = DllStructCreate ("ushort [8]")
    Local $rect = DllStructCreate ($tagRECT, $lpRect)
    Local $hbm
    Local $hbr
    Local $hbrushOld

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

    Local $width, $height, $x, $y
    Local $border = 3

    For $i = 1 To 7 Step 2

    DllStructSetData ($dotPatternBmp, 1, 0x00aa, $i)
    DllStructSetData ($dotPatternBmp, 1, 0x0055, $i + 1)
    Next

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

    $x = DllStructGetData ($rect, "left")
    $y = DllStructGetData ($rect, "top" )
    $width = DllStructGetData ($rect, "right" ) - $x
    $height = DllStructGetData ($rect, "bottom") - $y

    $hdc = GetDC (0)

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

    $hbm = CreateBitmap (8, 8, 1, 1, DllStructGetPtr ($dotPatternBmp))
    $hbr = CreatePatternBrush ($hbm)

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

    SetBrushOrgEx ($hdc, $x, $y, 0)
    $hbrushOld = SelectObject ($hdc, $hbr)

    PatBlt ($hdc, $x+$border, $y, $width-$border, $border, $PATINVERT)
    PatBlt ($hdc, $x+$width-$border, $y+$border, $border, $height-$border, $PATINVERT)
    PatBlt ($hdc, $x, $y+$height-$border, $width-$border, $border, $PATINVERT)
    PatBlt ($hdc, $x, $y, $border, $height-$border, $PATINVERT)

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

    SelectObject ($hdc, $hbrushOld)
    DeleteObject ($hbr)
    DeleteObject ($hbm)
    ReleaseDC (0, $hdc)

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

    EndFunc

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

    Func GetDC ($hWnd)

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

    Local $aRes = DllCall ('user32.dll', 'ptr', 'GetDC', _
    'hwnd', $hWnd) ; handle to window
    Return $aRes[0]

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

    EndFunc

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

    Func ReleaseDC ($hWnd, $hDC)

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

    Local $aRes = DllCall ("user32.dll", 'int', 'ReleaseDC', _
    'hwnd', $hWnd, _ ; handle to window
    'ptr', $hDC) ; handle to DC
    Return $aRes[0]

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

    EndFunc

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

    Func CreateBitmap ($nWidth, $nHeight, $cPlanes, $cBitsPerPel, $lpvBits)

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

    Local $aRes = DllCall ('gdi32.dll', 'ptr', 'CreateBitmap', _
    'int', $nWidth, _ ; bitmap width, in pixels
    'int', $nHeight, _ ; bitmap height, in pixels
    'uint', $cPlanes, _ ; number of color planes
    'uint', $cBitsPerPel, _ ; number of bits to identify color
    'ptr', $lpvBits) ; color data array
    Return $aRes[0]

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

    EndFunc

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

    Func CreatePatternBrush ($hbmp)

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

    Local $aRes = DllCall ("gdi32.dll", 'ptr', 'CreatePatternBrush', _
    'ptr', $hbmp) ; handle to bitmap
    Return $aRes[0]

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

    EndFunc

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

    Func DeleteObject ($hObject)

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

    Local $aRes = DllCall ('gdi32.dll', 'int', 'DeleteObject', _
    'ptr', $hObject) ; handle to graphic object
    Return $aRes[0]

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

    EndFunc

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

    Func SelectObject ($hdc, $hgdiobj)

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

    Local $aRes = DllCall ('gdi32.dll', 'ptr', 'SelectObject', _
    'ptr', $hdc, _ ; handle to DC
    'ptr', $hgdiobj) ; handle to object
    Return $aRes[0]

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

    EndFunc

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

    Func PatBlt ($hdc, $nXLeft, $nYLeft, $nWidth, $nHeight, $dwRop)

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

    Local $aRes = DllCall ("gdi32.dll", 'int', 'PatBlt', _
    'ptr', $hdc, _ ; handle to DC
    'int', $nXLeft, _ ; x-coord of upper-left rectangle corner
    'int', $nYLeft, _ ; y-coord of upper-left rectangle corner
    'int', $nWidth, _ ; width of rectangle
    'int', $nHeight, _ ; height of rectangle
    'dword', $dwRop) ; raster operation code
    Return $aRes[0]

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

    EndFunc

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

    Func SetBrushOrgEx ($hdc, $nXOrg, $nYOrg, $lppt)

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

    Local $aRes = DllCall ("gdi32.dll", 'int', 'SetBrushOrgEx', _
    'ptr', $hdc, _ ; handle to device context
    'int', $nXOrg, _ ; x-coord of new origin
    'int', $nYOrg, _ ; y-coord of new origin
    'ptr', $lppt) ; points to previous brush origin
    Return $aRes[0]

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

    EndFunc

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

    Func InvalidateRect ($hWnd, $lpRect, $bErase)

    Local $aResult = DllCall("user32.dll", 'int', 'InvalidateRect', _
    'hwnd', $hWnd, _
    'ptr', $lpRect, _
    'int', $bErase)
    Return $aResult[0]

    EndFunc

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

    ;

    [/autoit]


    Gruß
    Greenhorn