Jump to content
Sign in to follow this  
Malkey

A Pretty Desktop Border

Recommended Posts

Malkey

Press Ctrl + Alt + c to change the displays of circles and stars, blank, circles only, and stars only.

Press Esc to exit.

Explanation

Initially, five coloured , reducing visibility to edge of circle circles, and five stars are created as graphics on ten individual 70x70 bitmaps.

In the loop, these 70x70 bitmaps are repeated drawn around the border on the graphics buffer of the GDIPlus desktop size bitmap.

Then, the handle of this GDIPlus bitmap is selected into a compatible device content (dc).

This device content in then updated to the display device content for the create layered, desktop size GUI using _WinAPI_UpdateLayeredWindow().

This method gives true partial transparency at the edges of the circles. There is no transparent color-key colour appearing through the transparency.near the edges of the circles. Also, the cursor can be used through the transparent parts of the layered GUI.

By drawing the 70x70 bitmaps to the graphics of the desktop bitmap CPU usage is reduced, because the individual 70x70 graphics do not have to be created each time within the loop. But more physical memory is used to store all the bitmaps.

Enjoy.

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

Opt("GUIOnEventMode", 1)

HotKeySet("{ESC}", "close")
HotKeySet(("^!c"), "ToggleDisplay"); Ctrl+Alt+C  Change display

Global Const $Width = @DesktopWidth
Global Const $Height = @DesktopHeight
Global Const $PI = 3.14159265

Global $Col[5] = ["0xFFFF0000", "0xFFFFFF00", "0xFF00FF00", "0xFF0000FF", "0x00000000"]
Global $hBitmap1[5][3], $hBitStar[5][3], $iChange = 3
Global $aPoints[11][2] = [[10, 0],[35, 3],[45, 22],[67, 22],[50, 40],[67, 67],[35, 50], _
        [3, 67],[20, 40],[3, 22],[25, 22]]

$hWnd = GUICreate("Double buffering with GDI(+)", $Width, $Height, -1, -1, 0, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))

GUISetOnEvent(-3, "close")

_GDIPlus_Startup()
$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($Width, $Height, $hGraphics)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
$ScreenDc = _WinAPI_GetDC($hWnd)

;Create 5 coloured, circular 70x70 bitmaps
For $x = 0 To 4
    $hBitmap1[$x][0] = _GDIPlus_GraphicsCreateFromHWND($hWnd); $hGraphics1
    $hBitmap1[$x][1] = _GDIPlus_BitmapCreateFromGraphics(70, 70, $hBitmap1[$x][0]); $hBitmap1
    $hBitmap1[$x][2] = _GDIPlus_ImageGetGraphicsContext($hBitmap1[$x][1]); $hBackbuffer1
    GraphicInit($x, $Col[$x])
Next

;Create 5 stars 70x70 bitmaps
For $x = 0 To 4
    $hBitStar[$x][0] = _GDIPlus_GraphicsCreateFromHWND($hWnd); $hGraphics1
    $hBitStar[$x][1] = _GDIPlus_BitmapCreateFromGraphics(70, 70, $hBitStar[$x][0]); $hBitmap1
    $hBitStar[$x][2] = _GDIPlus_ImageGetGraphicsContext($hBitStar[$x][1]); $hBackbuffer1
    StarInit($x, $Col[$x])
Next

$gdibitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
$dc = _WinAPI_CreateCompatibleDC($ScreenDc)
_WinAPI_SelectObject($dc, $gdibitmap)

; _WinAPI_UpdateLayeredWindow parameters
$tSize = DllStructCreate($tagSIZE)
$pSize = DllStructGetPtr($tSize)
DllStructSetData($tSize, "X", $Width)
DllStructSetData($tSize, "Y", $Height)
$tSource = DllStructCreate($tagPOINT)
$pSource = DllStructGetPtr($tSource)
$tBlend = DllStructCreate($tagBLENDFUNCTION)
$pBlend = DllStructGetPtr($tBlend)
DllStructSetData($tBlend, "Alpha", 255)
DllStructSetData($tBlend, "Format", 1)
$tPoint = DllStructCreate($tagPOINT)
$pPoint = DllStructGetPtr($tPoint)
DllStructSetData($tPoint, "X", 0)
DllStructSetData($tPoint, "Y", 0)

GUISetState()

Local $y = 0

Do
    _WinAPI_DeleteObject($gdibitmap)
    _GDIPlus_GraphicsClear($hBackbuffer, 0x00000000)

    If $iChange = 1 Or $iChange = 3 Then; Circles
        For $x = 0 To 39
            If $x = $y Or $x = Mod($y + 19, 39) Then; or $x = mod($y + 1,39) or $x = mod($y + 20,39)
                _GDIPlus_GraphicsDrawImage($hBackbuffer, $hBitmap1[4][1], BPos($x, 0), BPos($x, 1))
            Else
                _GDIPlus_GraphicsDrawImage($hBackbuffer, $hBitmap1[Mod($x + $y, 4)][1], BPos($x, 0), BPos($x, 1))
            EndIf
        Next
    EndIf

    If $iChange = 2 Or $iChange = 3 Then; Stars
        For $x = 0 To 39
            If $x = $y Or $x = Mod($y + 19, 39) Then; or $x = mod($y + 1,39) or $x = mod($y + 20,39)
                _GDIPlus_GraphicsDrawImage($hBackbuffer, $hBitStar[4][1], BPos($x, 0), BPos($x, 1))
            Else
                _GDIPlus_GraphicsDrawImage($hBackbuffer, $hBitStar[Mod($x + $y, 4)][1], BPos($x, 0), BPos($x, 1))
            EndIf
        Next
    EndIf

    $y = Mod($y + 1, 39)
    _AntiAlias($hBackbuffer)
    $gdibitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _WinAPI_SelectObject($dc, $gdibitmap)
    _WinAPI_UpdateLayeredWindow($hWnd, $ScreenDc, 0, $pSize, $dc, $pSource, 0, $pBlend, 2)

Until Not Sleep(250)

;Return x or y position for bitmap display
Func BPos($x, $xy)
    Local $StepW = Round((@DesktopWidth - 100) / 11, 0), $StepH = Round((@DesktopHeight - 220) / 8, 0)
    Switch $x
        Case 0 To 11
            If $xy = 0 Then
                Return 20 + ($x * $StepW);x
            Else
                Return 20;y
            EndIf
        Case 12 To 19
            If $xy = 0 Then
                Return 20 + (11 * $StepW);x
            Else
                Return 120 + ($StepH * ($x - 12));y
            EndIf
        Case 20 To 31
            If $xy = 0 Then
                Return 20 + (Abs($x - 31) * $StepW);x
            Else
                Return @DesktopHeight - 100;y
            EndIf
        Case 32 To 39
            If $xy = 0 Then
                Return 20;x
            Else
                Return 120 + ($StepH * Abs($x - 39));y
            EndIf
    EndSwitch
    Return
EndFunc  ;==>BPos

Func close()
    For $x = 0 To 4
        _GDIPlus_GraphicsDispose($hBitmap1[$x][2])
        _GDIPlus_BitmapDispose($hBitmap1[$x][1])
        _GDIPlus_GraphicsDispose($hBitmap1[$x][0])
    ;_WinAPI_DeleteDC($hBitmap1[$x][4])
    ;_WinAPI_DeleteObject($hBitmap1[$x][3])
        _GDIPlus_GraphicsDispose($hBitStar[$x][2])
        _GDIPlus_BitmapDispose($hBitStar[$x][1])
        _GDIPlus_GraphicsDispose($hBitStar[$x][0])
    ;_WinAPI_DeleteDC($hBitStar[$x][4])
    ;_WinAPI_DeleteObject($hBitStar[$x][3])
    Next
    _WinAPI_DeleteDC($dc)
    _WinAPI_ReleaseDC($hWnd, $ScreenDc)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
EndFunc  ;==>close

Func ToggleDisplay()
    $iChange = Mod($iChange + 1, 4)
EndFunc  ;==>ToggleDisplay

Func GraphicInit($iNum, $Col1)
    $n = 0
    For $x = 255 To 0 Step -8
        If $iNum = 4 Then
            $Pinsel = _GDIPlus_PenCreate($Col1, 2)
        Else
            $Pinsel = _GDIPlus_PenCreate("0x" & Hex($x, 2) & StringTrimLeft($Col1, 4), 2)
        EndIf
        _GDIPlus_GraphicsDrawEllipse($hBitmap1[$iNum][2], 34 - $n, 34 - $n, 1 + $n * 2, 1 + $n * 2, $Pinsel)
        _GDIPlus_PenDispose($Pinsel)
        $n += 1
    Next
    Return
EndFunc  ;==>GraphicInit

Func StarInit($iNum, $Col1)
    Local $hPath = GDIPlus_CreatePath()
    GDIPlus_AddPathLine2($hPath, $aPoints); Star Example
    Local $hBrushGrad = GDIPlus_CreatePathGradientFromPath($hPath)
    GDIPlus_SetLineGammaCorrection($hBrushGrad, True)
;=== Sets Path's center color ====
    GDIPlus_SetPathGradientCenterColor($hBrushGrad, $Col1)
    Local $aColors[10] = [0xFF00FFFF, 0xFF00FF00, 0xFF0000FF, 0xFFFFFFFF, 0xFF000000, _
            0xFF00FF00, 0xFF0000FF, 0xFFFFFFFF, 0xFF000000, 0xFF00FF00]
;local $aColors1[1] = $Col1
    $status = GDIPlus_SetPathGradientSurroundColorsWithCount($hBrushGrad, $aColors)
    $aArr = GDIPlus_GetPathGradientSurroundColorsWithCount($hBrushGrad)
    GDIPlus_ClosePathFigure($hPath)
    $hPen = _GDIPlus_PenCreate($Col1, 4)
    GDIPlus_DrawPath($hBitStar[$iNum][2], $hPen, $hPath)
    GDIPlus_FillPath($hBitStar[$iNum][2], $hBrushGrad, $hPath)

    _GDIPlus_BrushDispose($hBrushGrad)
    _GDIPlus_PenDispose($hPen)
    DllCall($ghGDIPDll, "int", "GdipDeletePath", "hwnd", $hPath)
    Return
EndFunc  ;==>StarInit

Func _AntiAlias($hGraphics)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc  ;==>_AntiAlias

; ===== Star related functions ========================
Func GDIPlus_AddPathLine2($hPath, $aPoints)
    Local $iI, $iCount, $pPoints, $tPoints, $aResult, $tmpError, $tmpExError
    $iCount = $aPoints[0][0]
    $tPoints = DllStructCreate("int[" & $iCount * 2 & "]")
    $pPoints = DllStructGetPtr($tPoints)
    For $iI = 1 To $iCount
        DllStructSetData($tPoints, 1, _WinAPI_FloatToInt($aPoints[$iI][0]), (($iI - 1) * 2) + 1)
        DllStructSetData($tPoints, 1, _WinAPI_FloatToInt($aPoints[$iI][1]), (($iI - 1) * 2) + 2)
    Next
    $aResult = DllCall($ghGDIPDll, "int", "GdipAddPathLine2", "hwnd", $hPath, "ptr", _
            $pPoints, "int", $iCount)
    $tmpError = @error
    $tmpExError = @extended
    _GDIPlus_BrushDefDispose()
    If $tmpError Then Return SetError($tmpError, $tmpExError, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc  ;==>GDIPlus_AddPathLine2

Func GDIPlus_ClosePathFigure($hPath)
    $aResult1 = DllCall($ghGDIPDll, "int", "GdipClosePathFigure", "hwnd", $hPath)
    Return
EndFunc  ;==>GDIPlus_ClosePathFigure

Func GDIPlus_CreatePath()
    Local $hPath, $res
    $hPath = DllCall($ghGDIPDll, "int", "GdipCreatePath", "int", 0, "int*", 0)
    Local $res = "GdipCreatePath  " & Hex($hPath[2]) & @CRLF
    Return $hPath[2]
EndFunc  ;==>GDIPlus_CreatePath

Func GDIPlus_CreatePathGradientFromPath($hPath)
    Local $hBrushGrad
    $hBrushGrad = DllCall($ghGDIPDll, "int", "GdipCreatePathGradientFromPath", "hwnd", $hPath, "int*", 0)
    Return $hBrushGrad[2]
EndFunc  ;==>GDIPlus_CreatePathGradientFromPath

Func GDIPlus_DrawPath($hGraphic, $hPen, $hPath)
    $aResult2 = DllCall($ghGDIPDll, "int", "GdipDrawPath", "hwnd", $hGraphic, "hwnd", $hPen, "hwnd", $hPath)
    $res = "GdipDrawPath" & @CRLF
    For $x = 0 To 3
        $res &= $x & "  " & $aResult2[$x] & @CRLF
    Next
    Return
EndFunc  ;==>GDIPlus_DrawPath

Func GDIPlus_FillPath($hGraphic, $hBrushGrad, $hPath)
    DllCall($ghGDIPDll, "int", "GdipFillPath", "hwnd", $hGraphic, "hwnd", $hBrushGrad, "hwnd", $hPath)
    Return
EndFunc  ;==>GDIPlus_FillPath

Func GDIPlus_SetPathGradientCenterColor($hBrush, $iARGB)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetPathGradientCenterColor", "hwnd", $hBrush, "int", $iARGB)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult;SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc  ;==>GDIPlus_SetPathGradientCenterColor

Func GDIPlus_SetPathGradientSurroundColorsWithCount($hBrush, $aArgb)
    Local $iI, $iCount, $aResult, $res, $x, $pArgb
    If IsArray($aArgb) Then
        $iCount = UBound($aArgb);_WinAPI_FloatToInt(UBound($aArgb));
        $tArgb = DllStructCreate("int[" & $iCount & "]")
        $pArgb = DllStructGetPtr($tArgb)
        For $iI = 0 To $iCount - 1
        ;DllStructSetData($tArgb, 1,dec('FF0000FF'),$iI + 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", "hwnd", $hBrush, _
            "int", $pArgb, "int*", $iCount)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult;SetError($aResult[0], 0, $aResult[2])
EndFunc  ;==>GDIPlus_SetPathGradientSurroundColorsWithCount

Func GDIPlus_GetPathGradientSurroundColorCount($hBrush)
    Local $iCount, $res, $x
    $iCount = DllCall($ghGDIPDll, "int", "GdipGetPathGradientSurroundColorCount", "hwnd", $hBrush, "int*", 0)
    $res = "GdipGetPathGradientSurroundColorCount" & @CRLF
    For $x = 0 To 2
        $res &= $x & "  " & $iCount[$x] & @CRLF
    Next
    Return $iCount[2]
EndFunc  ;==>GDIPlus_GetPathGradientSurroundColorCount

Func GDIPlus_GetPathGradientSurroundColorsWithCount($hBrush)
    Local $iI, $iCount, $aArgb, $tArgb, $pArgb, $aResult, $res, $iCount1
    $iCount1 = GDIPlus_GetPathGradientSurroundColorCount($hBrush)
    Local $aArgb[$iCount1 - 1]
    $iCount1 = UBound($aArgb);_WinAPI_FloatToInt(UBound($aArgb));
    $tArgb = DllStructCreate("int[" & $iCount & "]")
    $pArgb = DllStructGetPtr($tArgb)
    $aResult = DllCall($ghGDIPDll, "int", "GdipGetPathGradientSurroundColorsWithCount", "hwnd", $hBrush, "int*", $pArgb, "int*", $iCount)
    $res = "GdipGetPathGradientSurroundColorsWithCount" & @CRLF
    For $x = 0 To 3
        $res &= $x & "  " & $aResult[$x] & @CRLF
    Next
    For $iI = 1 To $iCount1
        $aArgb[$iI - 1] = DllStructGetData($tArgb, 1, "")
    Next
    $res = "GdipGetPathGradientSurroundColorsWithCount Array Return" & @CRLF
    For $x = 0 To $iCount1 - 1
        $res &= $x & "  " & $aArgb[$x] & @CRLF
    Next
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult;SetError($aResult[0], 0, $aResult[2])
EndFunc  ;==>GDIPlus_GetPathGradientSurroundColorsWithCount

Func GDIPlus_SetLineGammaCorrection($hBrush, $useGammaCorrection = True)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetLineGammaCorrection", "hwnd", $hBrush, "int", $useGammaCorrection)
    Return $aResult[0]
EndFunc  ;==>GDIPlus_SetLineGammaCorrection
;; =====> End of Star related functions ========================
;

Share this post


Link to post
Share on other sites
DaRam

Nice. You took the trouble to provide a clear explanation also which is appropriate for this forum.

Hmmm, too bad April 1st for this year is already past this would make a good prank for unsuspecting users :D

Do you have more/other border bitmaps creation codes that work well with this?

Share this post


Link to post
Share on other sites
UEZ

It looks kitschy but your code is excellent - I will learn a lot...

Thanks.

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×