[gdiplus] Bewegender Transparenter Kreis , der Rest Schwarz

  • guten morgen

    ich suche verzweifelt an einer möglichkeit in gdiplus einen kreis transprarent zu machen und den rest schwarz. der transparente kreis soll sich auch bewegen können. also ungefähr so wie eine fernrohransicht in einem computerspiel.

    ich habe mal ein beispiel gemacht damit ihr versteht was ich meine. wie man sieht ist das nicht sehr schön geskriptet und der kreis ist ein rechteck.
    ich würde mich freuen wenn mir jemand ein tipp geben könnte wie ich das machen könnte.

    example

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>

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

    Opt("GUIOnEventMode", 1)
    $gui = GUICreate("Example", 400, 400)
    GUISetOnEvent(-3, "close")
    _GDIPlus_Startup()
    $graphics = _GDIPlus_GraphicsCreateFromHWND($gui)
    $bitmap = _GDIPlus_BitmapCreateFromGraphics(400, 400, $graphics)
    $buffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
    $rot = _GDIPlus_BrushCreateSolid(0xFF0000FF)
    GUISetState()

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

    $x = 0
    $y = 0

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

    While True
    $info = GUIGetCursorInfo($gui)
    If $info <> 0 Then
    If $x <> $info[0] Or $y <> $info[1] Then
    _GDIPlus_GraphicsClear($buffer, 0xFFFFFFFF)

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

    _GDIPlus_GraphicsFillRect($buffer, 100, 100, 100, 100, $rot)

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

    _GDIPlus_GraphicsFillRect($buffer, 0, 0, $x - 100, 400)
    _GDIPlus_GraphicsFillRect($buffer, $x + 100, 0, 400 - $x + 100, 400)
    _GDIPlus_GraphicsFillRect($buffer, $x - 100, 0, 200, $y - 100)
    _GDIPlus_GraphicsFillRect($buffer, $x - 100, $y + 100, 200, 400 - $y + 100)

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

    _GDIPlus_GraphicsDrawImage($graphics, $bitmap, 0, 0)
    $x = $info[0]
    $y = $info[1]
    EndIf
    EndIf
    WEnd

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

    Func Close()
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>Close

    [/autoit]

    Einmal editiert, zuletzt von gem (9. Dezember 2012 um 22:51)

  • Ich würde das so lösen:

    Spoiler anzeigen
    [autoit]


    #include <GDIPlus.au3>

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

    Opt("GUIOnEventMode", 1)
    $gui = GUICreate("Example", 400, 400)
    GUISetOnEvent(-3, "close")
    _GDIPlus_Startup()
    $graphics = _GDIPlus_GraphicsCreateFromHWND($gui)
    $bitmap = _GDIPlus_BitmapCreateFromGraphics(400, 400, $graphics)
    $buffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
    $rot = _GDIPlus_BrushCreateSolid(0xFF0000FF)

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

    $hBrushLamp = _GDIPlus_BrushCreateSolid(0x33000000)

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

    $hCirclePen = _GDIPlus_PenCreate(0xFF000000, 100)

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

    GUISetState()

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

    $x = 0
    $y = 0

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

    While True
    $info = GUIGetCursorInfo($gui)
    If $info <> 0 Then
    If $x <> $info[0] Or $y <> $info[1] Then
    _GDIPlus_GraphicsClear($buffer, 0xFFFFFFFF)

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

    _GDIPlus_GraphicsFillRect($buffer, 100, 100, 100, 100, $rot) ;Objekt


    _GDIPlus_GraphicsFillEllipse($buffer, $x - 50, $y - 50, 100, 100, $hBrushLamp)

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

    _GDIPlus_GraphicsDrawEllipse($buffer, $x - 100, $y - 100, 200, 200, $hCirclePen)
    _GDIPlus_GraphicsFillRect($buffer, 0, 0, $x - 100, 400)
    _GDIPlus_GraphicsFillRect($buffer, $x + 100, 0, 400 - $x + 100, 400)
    _GDIPlus_GraphicsFillRect($buffer, $x - 100, 0, 200, $y - 100)
    _GDIPlus_GraphicsFillRect($buffer, $x - 100, $y + 100, 200, 400 - $y + 100)

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

    _GDIPlus_GraphicsDrawImage($graphics, $bitmap, 0, 0)
    $x = $info[0]
    $y = $info[1]
    EndIf
    EndIf
    WEnd

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

    Func Close()
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>Close

    [/autoit]

    Kann man natürlich auch so machen, dass das DrawEllipse alles umschließt, und die 4 Außenvierecke nicht mehr gebraucht werden.

    lg chess

  • Wie es der Zufall so will, hab ich so etwas schon mal geschrieben. Allerdings hab ich irgendwann damit herumexperimentiert und dabei das Script auf den Kopf gestellt. Hat mich einige Zeit gekostet es wieder zum Laufen zu bringen.

    Spoiler anzeigen
    [autoit]

    #include <WindowsConstants.au3>
    #include <GUIConstants.au3>
    #include <GDIPlus.au3>
    #include <WinAPI.au3>

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

    ; -Author: name22 (http://www.autoit.de)

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

    Opt("GUIOnEventMode", 1)

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

    Global $hWnd, $hDC_Window, $hDC_Bitmap, $hDC_Background, $hBitmap, $hBitmap_BG, $hImage_BG, $hOldObj, $hOldObj2, $hGraphics, $hPath_Hole, $sFile_BG

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

    $sFile_BG = FileOpenDialog("Image Selection", "", "Images (*.*)")
    If @error Then Exit

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

    Global $iWidth = 400
    Global $iHeight = 400
    Global $iRadiusHole = 80

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

    $hWnd = GUICreate("name22 example", $iWidth, $iHeight)
    GUISetState()

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

    $hDC_Window = _WinAPI_GetDC($hWnd)
    $hDC_Bitmap = _WinAPI_CreateCompatibleDC($hDC_Window)
    $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Window, $iWidth, $iHeight)
    $hOldObj = _WinAPI_SelectObject($hDC_Bitmap, $hBitmap)

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

    _GDIPlus_Startup()

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

    $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC_Bitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2)

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

    $hImage_BG = _GDIPlus_ImageLoadFromFile($sFile_BG)
    $hBitmap_BG = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage_BG)
    _GDIPlus_ImageDispose($hImage_BG)

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

    $hDC_Background = _WinAPI_CreateCompatibleDC($hDC_Window)
    $hOldObj2 = _WinAPI_SelectObject($hDC_Background, $hBitmap_BG)

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

    $hPath_Hole = _GDIPlus_PathCreate()

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

    OnAutoItExitRegister("_Shutdown")
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Close")

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

    While Sleep(20)
    _WinAPI_BitBlt($hDC_Bitmap, 0, 0, $iWidth, $iHeight, $hDC_Background, 0, 0, $SRCCOPY)

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

    _GDIPlus_PathReset($hPath_Hole)
    _GDIPlus_PathAddEllipse($hPath_Hole, _WinAPI_GetMousePosX(True, $hWnd) - $iRadiusHole, _WinAPI_GetMousePosY(True, $hWnd) - $iRadiusHole, $iRadiusHole * 2, $iRadiusHole * 2)
    _GDIPlus_GraphicsSetClipPath($hGraphics, $hPath_Hole, 4)
    _GDIPlus_GraphicsClear($hGraphics)
    _GDIPlus_GraphicsResetClip($hGraphics)

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

    _WinAPI_BitBlt($hDC_Window, 0, 0, $iWidth, $iHeight, $hDC_Bitmap, 0, 0, $SRCCOPY)
    WEnd

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

    Func _Close()
    Exit
    EndFunc

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

    Func _Shutdown()
    _WinAPI_SelectObject($hDC_Bitmap, $hOldObj)
    _WinAPI_SelectObject($hDC_Background, $hOldObj2)
    _WinAPI_ReleaseDC($hWnd, $hDC_Window)
    _WinAPI_DeleteDC($hDC_Bitmap)
    _WinAPI_DeleteDC($hDC_Background)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteObject($hBitmap_BG)

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

    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_PathDispose($hPath_Hole)
    _GDIPlus_Shutdown()
    EndFunc

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GDIPlus_PathCreate
    ; Description ...: Creates a GraphicsPath object and initializes the fill mode
    ; Syntax.........: _GDIPlus_PathCreate([$iFillMode = 0])
    ; Parameters ....: $iFillMode - Fill mode of the interior of the path figures:
    ; |0 - The areas are filled according to the even-odd parity rule
    ; |1 - The areas are filled according to the nonzero winding rule
    ; Return values .: Success - Pointer to a new GraphicsPath object
    ; Failure - 0 and either:
    ; |@error and @extended are set if DllCall failed
    ; |$GDIP_STATUS contains a non zero value specifying the error code
    ; Remarks .......: After you are done with the object, call _GDIPlus_PathDispose to release the object resources
    ; Related .......: _GDIPlus_PathCreate2, _GDIPlus_PathDispose
    ; Link ..........; @@MsdnLink@@ GdipCreatePath
    ; Example .......; No
    ; ===============================================================================================================================
    Func _GDIPlus_PathCreate($iFillMode = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreatePath", "int", $iFillMode, "int*", 0)

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

    If @error Then Return SetError(@error, @extended, 0)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[2]
    EndFunc ;==>_GDIPlus_PathCreate

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GDIPlus_PathDispose
    ; Description ...: Releases a GraphicsPath object
    ; Syntax.........: _GDIPlus_PathDispose($hPath)
    ; Parameters ....: $hPath - Pointer to a GraphicsPath object
    ; Return values .: Success - True
    ; Failure - False and either:
    ; |@error and @extended are set if DllCall failed
    ; |$GDIP_STATUS contains a non zero value specifying the error code
    ; Remarks .......: None
    ; Related .......: _GDIPlus_PathCreate
    ; Link ..........; @@MsdnLink@@ GdipDeletePath
    ; Example .......; No
    ; ===============================================================================================================================
    Func _GDIPlus_PathDispose($hPath)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipDeletePath", "hwnd", $hPath)

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

    If @error Then Return SetError(@error, @extended, False)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[0] = 0
    EndFunc ;==>_GDIPlus_PathDispose

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GDIPlus_PathAddEllipse
    ; Description ...: Adds an ellipse to the current figure a path
    ; Syntax.........: _GDIPlus_PathAddEllipse($hPath, $nX, $nY, $nWidth, $nHeight)
    ; Parameters ....: $hPath - Pointer to a GraphicsPath object
    ; $nX - The X coordinate of the upper left corner of the rectangle that bounds the ellipse
    ; $nY - The Y coordinate of the upper left corner of the rectangle that bounds the ellipse
    ; $nWidth - The width of the rectangle that bounds the ellipse
    ; $nHeight - The height of the rectangle that bounds the ellipse
    ; Return values .: Success - True
    ; Failure - False and either:
    ; |@error and @extended are set if DllCall failed
    ; |$GDIP_STATUS contains a non zero value specifying the error code
    ; Remarks .......: None
    ; Related .......: None
    ; Link ..........; @@MsdnLink@@ GdipAddPathEllipse
    ; Example .......; No
    ; ===============================================================================================================================
    Func _GDIPlus_PathAddEllipse($hPath, $nX, $nY, $nWidth, $nHeight)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipAddPathEllipse", "hwnd", $hPath, "float", $nX, "float", $nY, "float", $nWidth, "float", $nHeight)

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

    If @error Then Return SetError(@error, @extended, False)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[0] = 0
    EndFunc ;==>_GDIPlus_PathAddEllipse

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GDIPlus_PathReset
    ; Description ...: Empties a path and sets the fill mode to alternate (0)
    ; Syntax.........: _GDIPlus_PathReset($hPath)
    ; Parameters ....: $hPath - Pointer to a GraphicsPath object
    ; Return values .: Success - True
    ; Failure - False and either:
    ; |@error and @extended are set if DllCall failed
    ; |$GDIP_STATUS contains a non zero value specifying the error code
    ; Remarks .......: None
    ; Related .......: None
    ; Link ..........; @@MsdnLink@@ GdipResetPath
    ; Example .......; No
    ; ===============================================================================================================================
    Func _GDIPlus_PathReset($hPath)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipResetPath", "hwnd", $hPath)

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

    If @error Then Return SetError(@error, @extended, False)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[0] = 0
    EndFunc ;==>_GDIPlus_PathReset

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GDIPlus_GraphicsSetClipPath
    ; Description ...: Updates the clipping region of this Graphics object to a region that is the combination of itself and the
    ; +region specified by a graphics path
    ; Syntax.........: _GDIPlus_GraphicsSetClipPath($hGraphics, $hPath[, $iCombineMode = 0])
    ; Parameters ....: $hGraphics - Pointer to a Graphics object
    ; $hPath - Pointer to a GraphicsPath object that specifies the region to be combined with the clipping
    ; +region of the Graphics object
    ; $iCombineMode - Regions combination mode:
    ; |0 - The existing region is replaced by the new region
    ; |1 - The existing region is replaced by the intersection of itself and the new region
    ; |2 - The existing region is replaced by the union of itself and the new region
    ; |3 - The existing region is replaced by the result of performing an XOR on the two regions
    ; |4 - The existing region is replaced by the portion of itself that is outside of the new region
    ; |5 - The existing region is replaced by the portion of the new region that is outside of the existing region
    ; Return values .: Success - True
    ; Failure - False and either:
    ; |@error and @extended are set if DllCall failed
    ; |$GDIP_STATUS contains a non zero value specifying the error code
    ; Remarks .......: If a figure in the path is not closed, this method treats the nonclosed figure as if it were closed by a
    ; +straight line that connects the figure's starting and ending points
    ; Related .......: None
    ; Link ..........; @@MsdnLink@@ GdipSetClipPath
    ; Example .......; No
    ; ===============================================================================================================================
    Func _GDIPlus_GraphicsSetClipPath($hGraphics, $hPath, $iCombineMode = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetClipPath", "hwnd", $hGraphics, "hwnd", $hPath, "int", $iCombineMode)

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

    If @error Then Return SetError(@error, @extended, False)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[0] = 0
    EndFunc ;==>_GDIPlus_GraphicsSetClipPath

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GDIPlus_GraphicsResetClip
    ; Description ...: Sets the clipping region of a Graphics object to an infinite region
    ; Syntax.........: _GDIPlus_GraphicsResetClip($hGraphics)
    ; Parameters ....: $hGraphics - Pointer to a Graphics object
    ; Return values .: Success - True
    ; Failure - False and either:
    ; |@error and @extended are set if DllCall failed
    ; |$GDIP_STATUS contains a non zero value specifying the error code
    ; Remarks .......: None
    ; Related .......: None
    ; Link ..........; @@MsdnLink@@ GdipResetClip
    ; Example .......; No
    ; ===============================================================================================================================
    Func _GDIPlus_GraphicsResetClip($hGraphics)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipResetClip", "hwnd", $hGraphics)

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

    If @error Then Return SetError(@error, @extended, False)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[0] = 0
    EndFunc ;==>_GDIPlus_GraphicsResetClip

    [/autoit]


    Das Script sieht vermutlich komplizierter aus, als es ist. Eigentlich muss man nur eine beliebige Form als Pfad-Objekt erstellen und damit per _GDIPlus_GraphicsSetClipPath den Bereich beschränken in dem gezeichnet werden darf. Wenn du nun eine Ellipse um den Mauszeiger als Form wählst, wird nur außerhalb (oder innerhalb, je nach Modus) dieser Ellipse gezeichnet. Ich habe Modus 5 genommen mit welchem alle folgenden Funktiopnen nur außerhalb der Ellipse zeichnen. Dann hab ich alles (außer der Ellipse ;)) schwarz gefärbt.
    Man kann es auch andersrum machen und den Modus 0 verwenden. Dann wird innerhalb der Ellipse gezeichnet, und man kann dann einfach das gewollte Bild wie gewohnt auf die GUI zeichnen.
    Falls du durch das (nicht sehr sauber geschriebene) Beispiel nicht durchblickst, dann sag Bescheid ^^.