While old GDI is not much use with complex shapes or animation, it does simple things very economically. The following algo does either plain filed rectangles or alternately a filled rectangle with a different coloured border of use defined width. As normal an algo of this type must be called from within a WM_PAINT message something like the following snippet.
.case WM_PAINT
rcall BeginPaint,hWin,ptr$(ps)
invoke FilledRct,hWin,200,95,600,200,000000FFh,000000FFh,2
rcall EndPaint,hWin,ptr$(ps)
The algorithm.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
FilledRct proc hndl:QWORD,tx:QWORD,ty:QWORD,wd:QWORD,ht:QWORD,FillCol:QWORD,PenCol:QWORD,PenWid:QWORD
LOCAL hDC :QWORD
LOCAL hPen :QWORD
LOCAL hOld :QWORD
LOCAL hBrsh :QWORD
LOCAL oldbr :QWORD
LOCAL lbCol :LOGBRUSH
LOCAL rWid :QWORD
LOCAL rHgt :QWORD
mov rax, tx
add rax, wd
mov rWid, rax
mov rax, ty
add rax, ht
mov rHgt, rax
mov hDC, rvcall(GetDC,hndl)
mov hPen, rvcall(CreatePen,PS_SOLID,PenWid,PenCol)
mov hOld, rvcall(SelectObject,hDC,hPen)
mov lbCol.lbStyle, BS_SOLID
mov rax, FillCol
mov lbCol.lbColor, eax
mov lbCol.lbHatch, 0
mov hBrsh, rvcall(CreateBrushIndirect,ptr$(lbCol))
mov oldbr, rvcall(SelectObject,hDC,hBrsh)
invoke Rectangle,hDC,tx,ty,rWid,rHgt
rcall SelectObject,hDC,oldbr
rcall SelectObject,hDC,hOld
rcall DeleteObject,hBrsh
rcall DeleteObject,hPen
rcall ReleaseDC,hDC
ret
FilledRct endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Here is another that draws an elipse.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
ElipseFilled proc hndl:QWORD,x1:QWORD,x2:QWORD,y1:QWORD,y2:QWORD,FillCol:QWORD,PenCol:QWORD,PenWid:QWORD
LOCAL hDC :QWORD
LOCAL hPen :QWORD
LOCAL hOld :QWORD
LOCAL hBrsh :QWORD
LOCAL oldbr :QWORD
LOCAL lbCol :LOGBRUSH
mov hDC, rv(GetDC,hndl)
mov hPen, rv(CreatePen,PS_SOLID,PenWid,PenCol)
mov hOld, rv(SelectObject,hDC,hPen)
mrmd lbCol.lbStyle, BS_SOLID
mov rax, FillCol
mrmd lbCol.lbColor, eax
mov lbCol.lbHatch, 0
mov hBrsh, rv(CreateBrushIndirect,ADDR lbCol)
mov oldbr, rv(SelectObject,hDC,hBrsh)
invoke Ellipse,hDC,x1,x2,y1,y2
invoke SelectObject,hDC,oldbr
invoke SelectObject,hDC,hOld
invoke DeleteObject,hBrsh
invoke DeleteObject,hPen
invoke ReleaseDC,hDC
ret
ElipseFilled endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Rectangles are fine with Gdi, but for an ellipse I would definitely prefer Gdi+, see attached exe (the inner one is GdiPlus).
I agree but this is what GDI has to offer.