;http://www.autoit.de/index.php?page=Thread&threadID=17855
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <GDIPlusConstants.au3>
#include <GUIConstantsEx.au3>
Opt("GUIOnEventMode", 1)

Local $fps = 0, $fps_diff, $fps_maintimer, $fps_timer, $display_FPS = -1, $average_FPS, $i = 1
Local $w = 1024
Local $h = 384
Local $iX = 0, $iW, $iStep = 24
_GDIPlus_Startup()
Local $hGui = GUICreate("LED Laufschrift", $w, $h)
GUISetBkColor(0x000000)
GUISetOnEvent(-3, "_Exit")
GUISetState()

;~ Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
;~ Local $hBitmapBuffer = _GDIPlus_BitmapCreateFromGraphics($w, $h, $hGraphics)
;~ Local $hGraphicsBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmapBuffer)

Local $hDC = _WinAPI_GetWindowDC($hGUI)
Local $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)

Local $hBMP = _WinAPI_CreateBitmap($w, $h) ;create a dummy bitmap
Local $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
Local $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)

Local $hScrDC = _WinAPI_GetDC(0)
Local $hDC_backbuffer  = _WinAPI_CreateCompatibleDC($hScrDC)
Local $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hBitmap)
Local $hGraphicsBuffer = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer)

_GDIPlus_GraphicsClear($hGraphics, 0xFF000000)
Local $hBitmapLed = _CreateLedBitmap($hGraphics, "LED Laufschrift mit GDI+ erstellt von Eukalyptus ;-)         ", $w, $h, $iStep, $iStep, 0xFFFFF030, 0x90101000)
;Local $hBitmapLed = _CreateLedBitmap($hGraphics, "Dies ist eine Laufschrift!", 800, 200, $iStep, $iStep, 0xFF00FF00, 0x66000000)
$iW = @extended

;~ GUIRegisterMsg($WM_PAINT, "_WM_PAINT")
$fps_maintimer = TimerInit()
While 1
	$fps_timer = TimerInit()
    $iX -= $iStep
    If $iX + $iW < 0 Then $iX += $iW
    _GDIPlus_GraphicsDrawImage($hGraphicsBuffer, $hBitmapLed, $iX, 0)
;~     _GDIPlus_GraphicsDrawImage($hGraphicsBuffer, $hBitmapLed, $iX + $iW, 0)
;~     _WinAPI_RedrawWindow($hGui, 0, 0, $RDW_INTERNALPAINT)
;~ 	_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmapBuffer, 0, 0, $w, $h)
	_WinAPI_BitBlt($hDC, 3, 23, $w, $h, $hDC_backbuffer, 0, 0, 0x00CC0020)
	$fps_diff = TimerDiff($fps_timer)
	If TimerDiff($fps_maintimer) >= 1000 Then ;calculate FPS
		$fps = Round(1000 / $fps_diff, 2)
		WinSetTitle($hGui, "", "LED Laufschrift: " & $fps & " FPS (ø " & Round($average_FPS / $i, 2) & " FPS)")
		$fps_maintimer = TimerInit()
	EndIf
	$average_FPS += $fps
	$i += 1
    Sleep(50)
WEnd

;~ Func _WM_PAINT($hWnd, $Msg, $wParam, $lParam)
;~     _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmapBuffer, 0, 0, $w, $h)
;~     Return $GUI_RUNDEFMSG
;~ EndFunc   ;==>_WM_PAINT

Func _CreateLedBitmap($hGraphics, $sText, $iW, $iH, $iLedOffSet, $iLedSize, $iOnColor = 0xF0FFFF00, $iOffColor = 0x88111122, $sFont = "Arial")
    $sText = StringUpper(StringReplace($sText,@LF,""))
    Local $hBrushOff = _GDIPlus_BrushCreateSolid($iOffColor)
    Local $hFormat = _GDIPlus_StringFormatCreate()
    Local $hFamily = _GDIPlus_FontFamilyCreate($sFont)
    Local $hFont = _GDIPlus_FontCreate($hFamily, $iH, 1, 2)
    Local $tLayout = _GDIPlus_RectFCreate($iW, 0, 0, 0)
    Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sText, $hFont, $tLayout, $hFormat)
    Local $iWidth = Ceiling(DllStructGetData($aInfo[0], "Width")) + $iW
    $iWidth -= Mod($iWidth, $iLedOffSet)
    Local $iHeight = Ceiling(DllStructGetData($aInfo[0], "Height"))
    DllStructSetData($aInfo[0], "Y", -Round(($iHeight - $iH) / 3))
    Local $hBitmapTxt = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    Local $hBitmapLed = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    Local $hGraphicsTxt = _GDIPlus_ImageGetGraphicsContext($hBitmapTxt)
    Local $hGraphicsLed = _GDIPlus_ImageGetGraphicsContext($hBitmapLed)
    Local $hBrush = _GDIPlus_BrushCreateSolid($iOnColor)
    Local $hPen = _GDIPlus_PenCreate()
    _GDIPlus_GraphicsClear($hGraphicsTxt, $iOffColor)
    _GDIPlus_GraphicsDrawStringEx($hGraphicsTxt, $sText, $hFont, $aInfo[0], $hFormat, $hBrush)
    Local $BitmapData = _GDIPlus_BitmapLockBits($hBitmapTxt, 0, 0, $iWidth, $iHeight, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
    Local $Stride = DllStructGetData($BitmapData, "Stride")
    Local $Width = DllStructGetData($BitmapData, "Width")
    Local $Height = DllStructGetData($BitmapData, "Height")
    Local $Scan0 = DllStructGetData($BitmapData, "Scan0")
    Local $PixelData, $Color = Hex($iOnColor)
    Local $hBrushGrad, $hPath
	Local $progress = ($Height * $Width  - 2) / ($iLedOffSet ^ 2), $c = 1
    For $row = 0 To $Height - 1 Step $iLedOffSet
        For $col = 0 To $Width - 1 Step $iLedOffSet
            $PixelData = DllStructCreate("dword", $Scan0 + ($row * $Stride) + ($col * 4))
            If Hex(DllStructGetData($PixelData, 1)) = $Color Then
                    $hPath = _GDIPlus_CreatePath()
                    _GDIPlus_AddPathEllipse($hPath, $col, $row, $iLedSize, $iLedSize)
                    $hBrushGrad = _GDIPlus_CreatePathGradientFromPath($hPath)
                    _GDIPlus_SetLineGammaCorrection($hBrushGrad, True)
                    _GDIPlus_SetPathGradientSurroundColorsWithCount($hBrushGrad, $iOffColor)
                    _GDIPlus_SetPathGradientCenterColor($hBrushGrad, $iOnColor)
                    _GDIPlus_FillPath($hGraphicsLed, $hBrushGrad, $hPath)
                    _GDIPlus_ClosePathFigure($hPath)
                _GDIPlus_GraphicsDrawEllipse($hGraphicsLed, $col, $row, $iLedSize, $iLedSize, $hPen)
            Else
                _GDIPlus_GraphicsFillEllipse($hGraphicsLed, $col, $row, $iLedSize, $iLedSize, $hBrushOff)
            EndIf
			WinSetTitle($hGui, "", "LED Laufschrift: " & Int($c / $progress * 100) & " %")
			$c += 1
        Next
    Next
    _GDIPlus_BitmapUnlockBits($hBitmapTxt, $BitmapData)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_PenDispose($hPen)
     _GDIPlus_BrushDispose($hBrushGrad)
     _GDIPlus_PathDispose($hPath)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_BrushDispose($hBrushOff)
    _GDIPlus_BitmapDispose($hBitmapTxt)
    _GDIPlus_GraphicsDispose($hGraphicsTxt)
    _GDIPlus_GraphicsDispose($hGraphicsLed)
    Return SetExtended($iWidth, $hBitmapLed)
EndFunc   ;==>_CreateLedBitmap

Func _Exit()
	_WinAPI_ReleaseDC($hGUI, $hDC)
	_WinAPI_DeleteObject($hBMP)
	_GDIPlus_BitmapDispose($hImage)
	_WinAPI_DeleteObject($hBitmap)
	_WinAPI_ReleaseDC(0, $hScrDC)
	_WinAPI_DeleteDC($hDC_backbuffer)
	_GDIPlus_GraphicsDispose($hGraphicsBuffer)

    _GDIPlus_BitmapDispose($hBitmapLed)
;~     _GDIPlus_GraphicsDispose($hGraphicsBuffer)
;~     _GDIPlus_BitmapDispose($hBitmapBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>_Exit

Func _GDIPlus_CreatePath($brushMode=0)
    Local $hPath
    $hPath = DllCall($ghGDIPDll, "int", "GdipCreatePath", "int", $brushMode, "handle*", 0)
    If @error Then Return SetError(1,@error,0)
    Return SetError($hPath[0], 0, $hPath[2])
EndFunc

Func _GDIPlus_AddPathEllipse($hPath, $iX, $iY, $iWidth, $iHeight)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipAddPathEllipse", "handle", $hPath, "float", $iX, "float", $iY, "float", $iWidth, "float", $iHeight)
    If @error Then Return SetError(1,@error,0)
    Return SetError($aResult[0], 0, $aResult[0]=0)
EndFunc

Func _GDIPlus_CreatePathGradientFromPath($hPath)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreatePathGradientFromPath", "handle", $hPath, "int*", 0)
    If @error Then Return SetError(1,@error,0)
    Return SetError($aResult[0], 0, $aResult[2])
EndFunc

Func _GDIPlus_SetLineGammaCorrection($hBrush, $useGammaCorrection = True)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipSetLineGammaCorrection", "handle", $hBrush, "int", $useGammaCorrection)
    If @error Then Return SetError(1,@error,0)
    Return SetError($aResult[0], 0, $aResult[0]=0)
EndFunc

Func _GDIPlus_SetPathGradientCenterColor($hBrush, $iARGB)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipSetPathGradientCenterColor", "handle", $hBrush, "int", $iARGB)
    If @error Then Return SetError(1,@error,0)
    Return SetError($aResult[0], 0, $aResult[0]=0)
EndFunc

Func _GDIPlus_FillPath($hGraphic, $hBrushGrad, $hPath)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipFillPath", "handle", $hGraphic, "handle", $hBrushGrad, "handle", $hPath)
    If @error Then Return SetError(1,@error,0)
    Return SetError($aResult[0], 0, $aResult[0]=0)
EndFunc

Func _GDIPlus_SetPathGradientSurroundColorsWithCount($hBrush, $aArgb)
    Local $iI, $iCount, $aResult, $res, $x, $pArgb
    If IsArray($aArgb) Then
        $iCount = UBound($aArgb)
        $tArgb = DllStructCreate("int[" & $iCount & "]")
        $pArgb = DllStructGetPtr($tArgb)
        For $iI = 0 To $iCount - 1
            DllStructSetData($tArgb, 1, $aArgb[$iI], $iI + 1)
        Next
    Else
        $iCount = 1
        $tArgb = DllStructCreate("int")
        $pArgb = DllStructGetPtr($tArgb)
        DllStructSetData($tArgb, 1, $aArgb, 1)
    EndIf
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetPathGradientSurroundColorsWithCount", "handle", $hBrush, "int", $pArgb, "int*", $iCount)
    If @error Then Return SetError(1,@error,0)
    Return SetError($aResult[0], $aResult[3], $aResult[0]=0)
EndFunc

Func _GDIPlus_ClosePathFigure($hPath)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipClosePathFigure", "handle", $hPath)
    If @error Then Return SetError(1,@error,0)
    Return SetError($aResult[0], 0, $aResult[0]=0)
EndFunc

Func _GDIPlus_PathDispose($hPath)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipDeletePath", "handle", $hPath)
    If @error Then Return SetError(1,@error,0)
    Return SetError($aResult[0], 0, $aResult[0]=0)
EndFunc