To use _WinAPI_BitmapDisplayTransparentInGUI() you must create a complete frame within the function.
Example:
; https://www.autoitscript.com/forum/topic/213118-_circularprogress/
;----------------------------------------------------------------------------------------
; Title...........: _CircularProgress.au3
; Description.....: Creates a customizable circular progress bar using GDI+ graphics.
; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.5
; Note............: Testet in Win10 22H2 Date:08/09/2025
; Based on post ..: https://www.autoitscript.com/forum/topic/213113-simple-circular-progressbar-with-smooth-edges-gradient-color/#findComment-1545755
;----------------------------------------------------------------------------------------
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WinAPISysWin.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>
#include <WinAPIConstants.au3>
#include <Array.au3>
_GDIPlus_Startup()
Global $hGUI
_Example() ; as demo
_GDIPlus_Shutdown()
Func _Example()
$hGUI = GUICreate("RingProgressBar", 300, 300, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))
GUISetState(@SW_SHOW)
Local $aList[2000]
Local $iCnt = UBound($aList)
ConsoleWrite("$iCnt=" & $iCnt & @CRLF)
Local $nProgress
For $i = 1 To UBound($aList)
$nProgress = Int($i / $iCnt * 100)
ConsoleWrite($i & ") $nProgress=" & $nProgress & @CRLF)
_CircularProgress($nProgress)
Next
Sleep(200) ; Give it some time to see the 100%.
EndFunc ;==>_Example
; #FUNCTION# ====================================================================================================================
; Name...........: _CircularProgress
; Description....: Creates a customizable circular progress bar using GDI+ graphics.
; Syntax.........: _CircularProgress($iPercent [, $iLeft = -1 [, $iTop = -1 [, $iSize = 300 [, $iThickness = 30 [, $TextCol = 0xFFFFFF [, $StartCol = 0xFF0000, $EndCol = 0xFFFF00]]]]]])
; Parameters.....: $iPercent - The percentage complete for the progress bar (0 to 100).
; $iLeft - [optional] X-coordinate of the top-left corner. (Default is -1 for center)
; $iTop - [optional] Y-coordinate of the top-left corner. (Default is -1 for center)
; $iSize - [optional] width and height of the circular progress bar. (Default is 300)
; $iThickness - [optional] Thickness of the progress arc. (Default is 30)
; $TextCol - [optional] Color of the text within the progress bar. (Default is White)
; $StartCol - [optional] Start color of the progress arc gradient. (Default is Yellow)
; $EndCol - [optional] End color of the progress arc gradient. (Default is Red)
; Return values .: Success: create the progress bar GUI
; Author ........: ioa747
; Modified ......: 08/09/2025 - v0.5
; Remarks .......: Cleanup is handled automatically by passing an $iPercent > 100.
; Avoid using 0x050505 Color for $TextCol, $StartCol, or $EndCol, as it is used as a transparency color for the background.
; Related .......: _GDIPlus_Startup, _GDIPlus_GraphicsCreateFromHWND, etc.
; Link ..........: https://www.autoitscript.com/forum/topic/213113-simple-circular-progressbar-with-smooth-edges-gradient-color/#findComment-1545755
; Example .......: _CircularProgress(50, -1, -1, 300, 20, 0x00FF00, 0xFF00FF, 0xFFFFFF)
; ===============================================================================================================================
Func _CircularProgress($iPercent, $iSize = 300, $iThickness = 30, $TextCol = 0xFF404040, $StartCol = 0xFFFFFF00, $EndCol = 0xFFFF0000)
Local $hBmp, $hBmpGraphics, $inSize, $iRadius, $iX, $iY
$inSize = $iSize
$iRadius = ($inSize - 4) / 2
$iX = $inSize / 2
$iY = $iX
; Create an off-screen bitmap for double-buffering
$hBmp = _GDIPlus_BitmapCreateFromScan0($inSize, $inSize)
$hBmpGraphics = _GDIPlus_ImageGetGraphicsContext($hBmp)
_GDIPlus_GraphicsSetSmoothingMode($hBmpGraphics, 4)
_GDIPlus_GraphicsSetTextRenderingHint($hBmpGraphics, 4)
; Draw progress arc as pie
Local $angle = ($iPercent / 100) * 360
Local $hBrushProg = _GDIPlus_LineBrushCreate($iX - $iRadius, $iY, $iX + $iRadius, $iY, $EndCol, $StartCol, 1)
Local $hPen = _GDIPlus_PenCreate2($hBrushProg, $iThickness)
_GDIPlus_GraphicsDrawArc($hBmpGraphics, $iX - $iRadius + $iThickness / 2, $iY - $iRadius + $iThickness / 2, $iRadius * 2 - $iThickness, $iRadius * 2 - $iThickness, -90, $angle, $hPen)
_GDIPlus_BrushDispose($hBrushProg)
_GDIPlus_PenDispose($hPen)
Local $hFontFamily = _GDIPlus_FontFamilyCreate("Times New Roman")
Local $iFontSize = $iRadius * 0.3
Local $hFont = _GDIPlus_FontCreate($hFontFamily, $iFontSize, 1)
Local $hFormat = _GDIPlus_StringFormatCreate()
_GDIPlus_StringFormatSetAlign($hFormat, 2)
_GDIPlus_StringFormatSetLineAlign($hFormat, 2)
Local $hBrushText = _GDIPlus_BrushCreateSolid($TextCol)
; Draw percentage text
Local $rect = _GDIPlus_RectFCreate(($inSize - ($iFontSize * 4)) / 2, ($inSize - ($iFontSize * 2)) / 2, $iFontSize * 4, $iFontSize * 2)
_GDIPlus_GraphicsDrawStringEx($hBmpGraphics, $iPercent & "%", $hFont, $rect, $hFormat, $hBrushText)
_GDIPlus_FontFamilyDispose($hFontFamily)
_GDIPlus_FontDispose($hFont)
_GDIPlus_StringFormatDispose($hFormat)
_GDIPlus_BrushDispose($hBrushText)
Local $hHBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp)
_WinAPI_BitmapDisplayTransparentInGUI($hHBmp, $hGUI)
_GDIPlus_BitmapDispose($hBmp)
_GDIPlus_GraphicsDispose($hBmpGraphics)
EndFunc ;==>_CircularProgress
Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $iFlags = $ULW_ALPHA, $bReleaseGDI = True, $tDest = Null, $iBGR = 0)
If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
Local $tDim = DllStructCreate($tagBITMAP)
If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
$tSize.X = $tDim.bmWidth
$tSize.Y = $tDim.bmHeight
$tBlend.Alpha = $iOpacity
$tBlend.Format = 1
_WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, $tDest, $tSize, $hMemDC, $tSource, $iBGR, $tBlend, $iFlags)
_WinAPI_ReleaseDC(0, $hScrDC)
_WinAPI_SelectObject($hMemDC, $hOld)
_WinAPI_DeleteDC($hMemDC)
If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
Return True
EndFunc ;==>_WinAPI_BitmapDisplayTransparentInGUI
If you have static variable, such as bitmap, brushes, etc., you can put out these parts off the _CircularProgress() function.