D2Circle and D2PCircle commands

Requires: Direct2D.lg32

Purpose

D2Circle draws a circle in the render target's drawing area, while D2PCircle draws a filled circle in the render target's drawing area.

Syntax

D2Circle x!, y!, r![, w1%][, w2%][, Figure%] [,D2Brush]
D2PCircle x!, y!, r![, w1%][, w2%][, Figure%] [,D2Brush]

x!, y!, r!: float expression
w1%, w2%, Figure%: integer expression
D2Brush: Object expression

Description

D2Circle draws the outline of a circle with position x,y and radius r in device-independent pixels. By default, the outline is drawn using a solid color brush created from the current foreground color D2ForeColor. If the application passes a D2Brush object, the stroke (line) is painted with that brush. Use D2DefLine to set the line style and width. By using the start (w1) and end (w2) angles, you can draw just an arc (default), a closed arc, or a pie, rather than the full circle - the angles w1 and w2 are given in whole degree steps with any arc being drawn in an anti-clockwise direction. Figure% can have the following values:

D2PCircle draws the interior of a circle with position x,y and radius r in device-independent pixels. By default, the interior is painted using the brush set with D2DefFill. If the application specified a brush object with the D2PCircle command, the interior is painted with that brush. The outline of the circle is painted using the current foreground color. To prevent the painting of the outline set line-width to zero using D2DefLine , 0. By using the start (w1) and end (w2) angles, you can draw just an arc (default) or a closed arc, rather than the full circle - the angles w1 and w2 are given in whole degree steps with any arc being drawn in an anti-clockwise direction. Figure% can have the following values:

Example

'

' Samples\Direct2D\D2PCircles.g32 (dpi-aware)

' - Animation with circles

' - Uses high-resolution timer

'

$Library "direct2d"

$Library "gfawinx"

DpiAwareness()

OpenW 1, 0, 0, 600, 500, ~15    ' size as if on 96 dpi screen

FormScaleForDpi(Me)

' Direct2D stuff

Global RT1 As Object, RTWidth As Float, RTHeight As Float

Set RT1 = D2GetRT()

D2GetSizeRT RT1, RTWidth, RTHeight

' D2Bitmap a device dependent resource

Global bmpBulldog As Object, bmpW As Float, bmpH As Float

Set bmpBulldog = D2Bitmap(":Bulldog")

D2BitmapSize bmpBulldog, bmpW, bmpH

' Create a high-resolution timer with 10 msec interval

' (The minimal interval of an Ocx Timer is 15.625 ms => 64 fps)

Global Object tmrQ

Set tmrQ = TimerQ(Me, 1, 10' from gfawinx.lg32

' Show FPS each second

Global fps As Long, fpsShow As Long

Ocx Timer tmrfps

tmrfps.Interval = 1000          ' 1 sec

tmrfps.Enabled = True

Global Float ang, x, y, x2, y2, x3, y3, x4, y4

Do

Sleep

Until Me Is Nothing

 

Sub tmrfps_Timer    ' after 1 sec

fpsShow = fps

fps = 0

EndSub

 

Sub Win_1_Message(hWnd%, Mess%, wParam%, lParam%)

Const frq As Float = 1.0!

Const frq2 As Float = 4.0!

Const frq3 As Float = 6.0!

Const outeroffset As Float = 13.0!

Const outerfrq As Float = 6.0!

If Mess% == WM_TIMER && wParam% == ' 10 msec timer

fps++ ' increment frame per seconds

' Show some animation

x = 266 + (180 + outeroffset * Sin(outerfrq * ang)) * Cos(ang)

y = 266 + (180 + outeroffset * Sin(outerfrq * ang)) * Sin(ang)

x2 = x + 40 * Cos(ang * frq)

y2 = y + 40 * Sin(ang * frq)

x3 = x2 + 20 * Cos(ang * frq2)

y3 = y2 + 20 * Sin(ang * frq2)

x4 = x3 + 10 * Cos(ang * frq3)

y4 = y3 + 10 * Sin(ang * frq3)

ang = ang + 0.01

Win_1_Paint

EndIf

End Sub

 

Sub Win_1_Paint

D2BeginDraw RT1

D2Put 0, 0, bmpBulldog, RTWidth , RTHeight ' shrink to fit

D2DefFill ARGB(0, 0, 0, 0)

D2PCircle x, y , 40

D2DefFill ARGB(128, 255, 0, 0)

D2PCircle x2, y2 , 20

D2DefFill ARGB(128, 0, 0, 255)

D2PCircle x3, y3 , 10

D2DefFill ARGB(128, 255, 255, 255)

D2PCircle x4, y4, 4

D2Text 0, 0, "Fps: " + Dec(fpsShow)

D2EndDraw

EndSub

 

Sub Win_1_ReSize

D2ResizeRT RT1, _X, _Y

D2GetSizeRT RT1, RTWidth, RTHeight

 

Sub Win_1_MessageProc(hWnd%, Mess%, wParam%, lParam%, retval%, ValidRet?)

Local Int dpi

If Mess% == WM_DPICHANGED

If FormScaleForDpi(Me, wParam%, lParam%' scale (resize) form and it's Ocx-es

' Here: Update other Dpi dependent resources (toolbar, bitmaps, Direct2D)

dpi = LoWord(wParam%)             ' new Dpi for form

D2SetDpiRT RT1, dpi            ' update D2 rendertarget's dpi

EndIf

retval% = 0 : ValidRet? = True    ' tell OS we handled it

EndIf

EndSub

 

Function FormScaleForDpi(ByVal frm As Form, Optional newdpi As Int, Optional lParam As Int) As Bool

Local i As Int, c As Control, rc As RECT, prevDpi As Int, newrc As Pointer To RECT, _

tb As Tab, w As Int, h As Int

With frm

' Set initial newdpi for the form and the scale factors for a LoadForm

If .WhatsThisHelpID == 0

If Exist(":{" + .Name)                    ' a Form-Editor form

.WhatsThisHelpID = WinDpi(0)            ' initial dpi is system newdpi

.ScaleWidth = .ScaleWidth * 96 / .WhatsThisHelpID   ' set initial scale factors

.ScaleHeight = .ScaleHeight * 96 / .WhatsThisHelpID

Else                                      ' created by OpenW or Form command

.WhatsThisHelpID = 96                   ' coord space is 96

EndIf

EndIf

prevDpi = .WhatsThisHelpID

newdpi = LoWord(newdpi)

If newdpi == 0 Then newdpi = WinDpi(.hWnd)

Exit Func If newdpi == prevDpi              ' don't continue if equal

' Size the form, except if it is a child window

If !(GetWindowLong(.hWnd, GWL_STYLE) %& WS_CHILD)

If lParam                                 ' size to the OS suggested size

Pointer newrc = lParam                  ' ptr to RECT in lParam

SizeW .hWnd, newrc.Right - newrc.Left, newrc.Bottom - newrc.Top

Else                                      ' scale based on the current client size

GetClientSize .hWnd, w, h               ' can't use _X _Y, they are for ME only

AdjustW .hWnd, Scale(w, newdpi, prevDpi), Scale(h, newdpi, prevDpi)

EndIf

EndIf

.FontSize = .FontSize * newdpi / prevDpi

.ScaleWidth = .ScaleWidth * prevDpi / newdpi

.ScaleHeight = .ScaleHeight * prevDpi / newdpi

' Scale position and size of the Ocx windowed controls

For Each c In frm.Controls

If !(TypeOf(c) Is ImageList || TypeOf(c) Is Timer || _

TypeOf(c) Is CommDlg || TypeOf(c) Is TrayIcon' not the windowless OCX-es

' First set fontsize, but not all OCX-es have a Font property

If !(TypeOf(c) Is ProgressBar || TypeOf(c) Is Slider || TypeOf(c) Is Image || TypeOf(c) Is RichEdit)

c.fontsize = c.fontsize * newdpi / prevDpi

ElseIf TypeOf(c) Is RichEdit            ' Requires LoadRichEdit50W!

SendMessage c.hwnd, WM_DPICHANGED, MakeLong(newdpi, newdpi), 0

EndIf

' Set new position and size for OCX-controls

GetWinPos(c.hwnd, rc)                   ' relative to parent

~SetWindowPos(c.hwnd, 0, _

Scale(rc.Left, newdpi, prevDpi), Scale(rc.Top, newdpi, prevDpi), _

Scale(rc.Right - rc.Left, newdpi, prevDpi), _

Scale(rc.Bottom - rc.Top, newdpi, prevDpi),  SWP_NOZORDER) ' new pos and size

If TypeOf(c) Is Form                    ' Scale OCX-es of a child Form Ocx

c.WhatsThisHelpID = prevDpi

~FormScaleForDpi(c, newdpi)

ElseIf TypeOf(c) Is TabStrip            ' Scale TabStrip's attached forms

For Each tb In c.Tabs

If TypeOf(tb.Ocx) Is Form

tb.Ocx.WhatsThisHelpID = prevDpi

~FormScaleForDpi(tb.Ocx, newdpi)

EndIf

Next

EndIf

EndIf

Next

.WhatsThisHelpID = newdpi     ' store new newdpi

EndWith

FormScaleForDpi = True

EndFunc

NOTE: The above example will not run as it relies on an embedded file which is not present in the syntax. The programme with full resources can be found in GFABASIC/Samples/Direct2D/D2PCircles.g32.

Remarks

Requires an active render target, either set with D2BeginDraw or D2SetRT.

All drawing commands must be placed between D2BeginDraw and D2EndDraw.

D2Circle invokes the ID2D1RenderTarget::DrawEllipse method and D2PCircle invokes the ID2D1RenderTarget::FillEllipse method.

The arc and pie figures are implemented using a temporary path geometry. More info can be found in the D2Sink_AddArc topic.

See Also

D2PBox, D2Box, D2PRBox, D2RBox, D2Line, D2Ellipse, D2PEllipse, D2SetRT, D2DefFill, D2DefLine, D2Brush, D2BeginDraw, D2EndDraw, D2Sink_AddArc.

{Created by James Gaite; Last updated: 03/03/2022 by James Gaite}