GDI+: Filled Brushes

  • Ich habe mir mal die GDI+ Funktion _GDIPlus_HatchBrushCreate() näher angeschaut. Man kann den Pinsel jetzt mit 53 Muster füllen lassen!

    Nichts besonderes, aber erwähnenswert:

    Spoiler anzeigen
    [autoit]


    ;Coded by UEZ 2009.12.06
    #include <GDIplus.au3>
    Opt("GUIOnEventMode", 1)

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

    _GDIPlus_Startup()
    Global $width = @DesktopWidth * 0.75
    Global $height = @DesktopHeight * 0.75

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

    Global $hwnd = GUICreate("GDI+: Filled Brushes by UEZ", $width, $height, -1, -1, Default)
    GUISetOnEvent(-3, "_Exit")
    GUISetState()

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

    Global $graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
    _GDIPlus_GraphicsSetSmoothingMode($graphics, 4)

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

    Global $brush[53]
    For $i = 0 To UBound($brush) - 1
    $brush[$i] = _GDIPlus_HatchBrushCreate($i, 0xFF0000FF, 0xFFFFFFFF)
    Next

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

    $dx = Int($width / 8)
    $dy = Int($height / 7)

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

    _GDIPlus_GraphicsClear($graphics, 0xFF000000)

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

    $k = 0
    For $i = 0 To $height -1 Step $dy
    For $j = 0 To $width - 1 Step $dx
    If $k <= UBound($brush) -1 Then _GDIPlus_GraphicsFillEllipse($graphics, $j, $i, $dx, $dy, $brush[$k])
    $k += 1
    Next
    Next

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

    While Sleep(150)
    WEnd

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

    Func _Exit()
    For $i = 0 To UBound($brush) - 1
    _GDIPlus_BrushDispose($brush[$i])
    Next
    _GDIPlus_GraphicsDispose($graphics)
    _GDIPlus_Shutdown()
    Exit
    EndFunc

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

    Func _GDIPlus_HatchBrushCreate($iHatchStyle = 0, $iARGBForeground = 0xFFFFFFFF, $iARGBBackground = 0xFFFFFFFF)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateHatchBrush", "int", $iHatchStyle, "uint", $iARGBForeground, "uint", $iARGBBackground, "int*", 0)

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

    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[4])
    EndFunc ;==>_GDIPlus_HatchBrushCreate

    [/autoit]

    Viel Spaß und schönen Nikolaus!

    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    3 Mal editiert, zuletzt von UEZ (6. Dezember 2009 um 16:38)

  • Ein kleines Beispiel dazu:

    Spoiler anzeigen
    [autoit]


    ;coded by UEZ 2009
    #include <GDIplus.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    Opt("GUIOnEventMode", 1)

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

    Global Const $width = @DesktopWidth / 2
    Global Const $height = @DesktopHeight / 2
    Global Const $pi_div_180 = 4 * ATan(1) / 180

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

    Global $hwnd = GUICreate("Border Collision with Hatch Brushes!", $width, $height, -1, -1, Default, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
    GUISetOnEvent($GUI_EVENT_CLOSE, "Close") ;$GUI_EVENT_CLOSE = -3
    GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "Move") ;move main window
    GUISetState()

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

    _GDIPlus_Startup()
    Global $graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
    Global $bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $graphics)
    Global $backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
    _GDIPlus_GraphicsClear($backbuffer)
    _GDIPlus_GraphicsSetSmoothingMode($backbuffer, 4)

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

    Global $max_dots = 20
    Global $max_speed = 5
    Global $iWidth = 100
    Global $iHeight = 100
    Dim $coordinates[$max_dots][5], $angle
    Dim $brush[$max_dots]
    Global $hImage[$max_dots]
    Global $hContext
    Global $hBrush
    Global $sleep = 40

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

    Initialize()

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

    GUIRegisterMsg($WM_TIMER, "Draw") ;$WM_TIMER = 0x0113

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

    DllCall("User32.dll", "int", "SetTimer", "hwnd", $hwnd, "int", 0, "int", $sleep, "int", 0)
    ;~ $hCallBack = DllCallbackRegister("Draw", "none", "") ;crashing on exit
    ;~ DllCall("User32.dll", "int", "SetTimer", "hwnd", $hwnd, "int", 0, "int", $sleep, "ptr", DllCallbackGetPtr($hCallBack))

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

    Do
    Until False * Not Sleep(1000)

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

    Func Move() ;move whole window when pressed lmb and hold continuing drawing of window content
    DllCall("user32.dll", "int", "SendMessage", "hWnd", $hwnd, "int", $WM_NCLBUTTONDOWN, "int", 2, "int", 0) ;$WM_NCLBUTTONDOWN = 0x00A1
    EndFunc

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

    Func Draw()
    _GDIPlus_GraphicsClear($backbuffer, 0xFF000000)
    Draw_Dots()
    Calculate_New_Position()
    _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $width, $height)
    EndFunc

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

    Func Initialize()
    For $k = 0 To $max_dots - 1
    $hImage[$k] = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
    $hBrush = _GDIPlus_HatchBrushCreate(Random(0, 52, 1), "0xD0" & Hex(Random(0x400000, 0xFFFFFF, 1), 6), 0xFFFFFFFF)
    $hContext = _GDIPlus_ImageGetGraphicsContext($hImage[$k])
    _GDIPlus_GraphicsFillEllipse($hContext, 0, 0, $iWidth, $iWidth, $hBrush)
    _GDIPlus_GraphicsDispose($hContext)
    _GDIPlus_BrushDispose($hBrush)
    New_Coordinates($k)
    Next
    EndFunc ;==>Initialize

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

    Func Draw_Dots()
    Local $i, $temp_x, $temp_y
    For $i = 0 To $max_dots - 1
    _GDIPlus_GraphicsDrawImageRect($backbuffer, $hImage[$i], $coordinates[$i][0], $coordinates[$i][1], $iWidth, $iHeight)
    Next
    EndFunc ;==>Draw_Dots

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

    Func New_Coordinates($k)
    $coordinates[$k][0] = $width / 2 ;Random($width / 20, $width - $width / 20, 1);start x position
    $coordinates[$k][1] = $height / 2 ;Random($height / 20, $height - $height / 20, 1) ;start y position
    $coordinates[$k][2] = Random(1, $max_speed, 1) ;speed of pixel
    $angle = Random(0, 359, 1)
    ;~ ConsoleWrite("Angle: " & $angle & "°" & @CRLF)
    $coordinates[$k][3] = $coordinates[$k][2] * Cos($angle * $pi_div_180)
    $coordinates[$k][4] = $coordinates[$k][2] * Sin($angle * $pi_div_180)
    EndFunc ;==>New_Coordinates

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

    Func Calculate_New_Position()
    Local $k
    For $k = 0 To $max_dots - 1
    $coordinates[$k][0] += $coordinates[$k][3] ;increase x coordinate with appropriate slope
    $coordinates[$k][1] += $coordinates[$k][4] ;increase y coordinate with appropriate slope
    If $coordinates[$k][0] <= 0 Then ;border collision x left
    $coordinates[$k][0] = 1
    $coordinates[$k][3] *= -1
    ElseIf $coordinates[$k][0] >= $width - $iWidth Then ;border collision x right
    $coordinates[$k][0] = $width - ($iWidth + 1)
    $coordinates[$k][3] *= -1
    EndIf
    If $coordinates[$k][1] <= 0 Then ;border collision y top
    $coordinates[$k][1] = 1
    $coordinates[$k][4] *= -1
    ElseIf $coordinates[$k][1] >= $height - $iHeight Then ;border collision y bottom
    $coordinates[$k][1] = $height - ($iHeight + 1)
    $coordinates[$k][4] *= -1
    EndIf
    Next
    EndFunc ;==>Calculate_New_Position

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

    Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0)

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

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

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

    Func _GDIPlus_HatchBrushCreate($iHatchStyle = 0, $iARGBForeground = 0xFFFFFFFF, $iARGBBackground = 0xFFFFFFFF)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateHatchBrush", "int", $iHatchStyle, "uint", $iARGBForeground, "uint", $iARGBBackground, "int*", 0)

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

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

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

    Func close()
    GUIRegisterMsg($WM_TIMER, "")
    GUIRegisterMsg($WM_TIMER, "")
    ;~ DllCallbackFree($hCallBack)
    For $k = 0 To $max_dots-1
    _GDIPlus_ImageDispose($hImage[$k])
    Next
    _GDIPlus_BitmapDispose($bitmap)
    _GDIPlus_GraphicsDispose($graphics)
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>close

    [/autoit]

    Danke an Authenticity für die GDIp Bibliothek und die Hilfe die Kugel so zu füllen, dass die Muster nicht statisch im Hintergrund sind!

    Gruß,
    UEZ

    PS: GDIp.au3 + GDIpConstants.au3 werden für das Beispiel oben nicht mehr benötigt. Funktionen sind nun im Code integriert. Nichtsdestotrotz ein "must have" und sollte in keiner Sammlung fehlen!
    +: nun wird das Fenster weitergezeichnet, auch wenn das Fenster verschoben wird!

  • Ups, stimmt :whistling: Habe den Code + Anhang entsprechend aktualisiert!

    Nichtsdestotrotz danke für beide Dateien.

    Sorry,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (8. Dezember 2009 um 18:59)