Line Drawing Graphics

STARTDRAW ... ENDDRAW procedure

Purpose:

STARTDRAW defines the beginning and ENDDRAW defines the end of a block of code, in which graphics drawing produces a persistent image, that is, an image which does not have to be repainted when it is moved behind other windows or when other windows are moved on top of the image.

Syntax:

hDestDC = STARTDRAW(Canvas AS HWND)
   'Graphics drawing functions are placed here
ENDDRAW(Canvas, hDestDC)

Return Value:

  • Data type: HDC
    hDestDC The handle of the device context in which the persistent image is drawn.

Parameters:

  • Data type: HWND
    Canvas The handle to a BCX_BITMAP.

Example 1:

GUI "PGUDB"
   
CONST IDC_BM1 = 101
   
'******************************************************************* 
GLOBAL Form AS HWND
GLOBAL Butt1 AS HWND
GLOBAL Canvas AS HWND
'******************************************************************* 
  
SUB FORMLOAD
  Form = BCX_FORM("Persistent Graphics Using Dynamic Bitmaps", 0, 0, 230, 165)
  Canvas = BCX_BITMAP(0, Form, IDC_BM1, 5, 5, 170, 135)
  Butt1 = BCX_BUTTON("Draw Stuff", Form, 1, 180, 5)
   
  CENTER(Form)
  SHOW(Form)
END SUB
   
BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_COMMAND
   
    SELECT CASE CBCTL
    CASE 1
      DIM RAW hDestDC AS HDC
      hDestDC = STARTDRAW(Canvas)
      BCX_FLOODFILL(0, 0, 0, RGB(RND * 255, RND * 255, RND * 255), RGB(RND * 255, RND * 255, RND * 255), TRUE, hDestDC)
      BCX_PSET(0, 2, 2, 0, hDestDC)
      BCX_LINE(0, 5, 5, 300, 250, RGB(RND * 255, RND * 255, RND * 255), hDestDC)
      BCX_LINETO(0, 300, 5, RGB(RND * 255, RND * 255, RND * 255), hDestDC)
      BCX_ARC(0, 90, 90, 130, 150, 95, 95, 130, 70, RGB(RND * 255, RND * 255, RND * 255), hDestDC)
      BCX_RECTANGLE(0, 40, 40, 100, 100, RGB(RND * 255, RND * 255, RND * 255), TRUE, hDestDC)
      BCX_ROUNDRECT(0, 120, 80, 100, 150, 20, 20, RGB(RND * 255, RND * 255, RND * 255), TRUE, hDestDC)
      BCX_ELLIPSE(0, 330, 10, 60, 100, RGB(RND * 255, RND * 255, RND * 255), TRUE, hDestDC)
      ENDDRAW(Canvas, hDestDC)
    END SELECT
   
  END SELECT
END EVENTS

Result:

This is an image produced by the above code.

Example 2:

The following code is a basic ray-tracing algorithm for rendering spheres in a 3D space onto a 2D screen. Each sphere's position and radius are defined in 3D space, and rays are cast from the camera to each pixel on the screen. The algorithm checks for intersections with spheres and calculates reflections, shadows, and shading for realistic effects.

GUI "Raytrace", PIXELS
OPTION BASE 1
CONST DEMOWIDTH = 512
CONST DEMOHEIGHT=  360

SUB FORMLOAD
  GLOBAL AS HWND Form1, Canvas
  Form1 = BCX_FORM("Raytrace in progress ... please wait", 0, 0, DEMOWIDTH, DEMOHEIGHT)
  Canvas = BCX_BITMAP(0, Form1, 0, 0, 0, DEMOWIDTH, DEMOHEIGHT)
  CENTER Form1
  SHOW Form1
  CALL Render
END SUB

BEGIN EVENTS
END EVENTS

SUB Render
  CONST spheres = 6
  ' Number of spheres in the scene 

  DIM AS SINGLE c[spheres, 3]
  ' Array to hold the center coordinates (x, y, z) of each sphere 

  DIM AS SINGLE r[spheres]
  ' Array to hold the radius of each sphere 

  DIM AS SINGLE q[spheres]
  ' Array to hold the square of the radius of each sphere (used for distance calculations) 

  DIM AS DWORD cl[4]
  ' Array to hold the color values for shading (RGB format) 

  ' Screen dimensions and variables for half-width, half-height, and scaling factor 
  DIM AS SINGLE scrw, scrh, w, h, s
  ' scrw, scrh: Screen width and height 
  ' w, h: Half of screen width and height, used for centering the rendering 
  ' s: Scaling factor for ray tracing steps (set to 0.0 initially) 

  ' Variables for the rendering loop and ray tracing calculations 
  DIM AS SINGLE x, y, z, dx, dy, dz, dd, sc, nx, ny, nz, nn, l, u, v
  ' x, y, z: Current ray position 
  ' dx, dy, dz: Direction of the ray from the camera to the screen 
  ' dd: Distance squared from the ray origin 
  ' sc: Dot product for determining the intersection distance 
  ' nx, ny, nz: Normal vector components at the point of intersection 
  ' nn: Length squared of the normal vector 
  ' l: Reflection factor used for calculating reflections 
  ' u, v: Temporary variables for distance calculations in shadows 

  DIM AS SINGLE px, py, pz, pp, bb, aa
  ' px, py, pz: Vector from ray origin to a sphere center 
  ' pp: Squared length of the above vector 
  ' bb: Projection length squared of the above vector on the ray 
  ' aa: Difference between the squared radii (used to determine if the ray intersects) 

  DIM AS INT n, ba
  ' n: Index of the sphere hit by the ray 
  ' ba: Base color index used for shading (1 to 3) 

  DIM AS DWORD ik
  ' ik: Color value used for plotting pixels 

  scrw = DEMOWIDTH
  ' Screen width; set to a constant or pre-defined variable 

  scrh = DEMOHEIGHT
  ' Screen height; set to a constant or pre-defined variable 

  ' Calculate half-width and half-height for screen center 
  w = scrw / 2
  ' Half-width of the screen 

  h = scrh / 2
  ' Half-height of the screen 

  s = 0.0
  ' Initialize scaling factor for ray tracing steps 

  ' Initialize color lookup table with different shades 
  cl[1] = RGB(0, 0, 0)
  ' Color for the base shade (black) 

  cl[2] = RGB(34, 24, 24)
  ' Dark color used for shadows or darker areas 

  cl[3] = RGB(65, 0, 0)
  ' Dark red color for spheres or reflections 

  cl[4] = RGB(0, 0, 0)
  ' Additional shade (same as the first) 

  ' Initialize sphere positions and properties (center coordinates and radius) 
  ' For each sphere: c[x, y, z] - Center coordinates; r - Radius; q - Radius squared 

  c[1, 1] = -0.3 : c[1, 2] = -0.8  : c[1, 3] = 3.0  : r[1] = 0.6  : q[1] = r[1] * r[1]
  c[2, 1] =  0.9 : c[2, 2] = -1.4  : c[2, 3] = 3.5  : r[2] = 0.35 : q[2] = r[2] * r[2]
  c[3, 1] =  0.7 : c[3, 2] = -0.45 : c[3, 3] = 2.5  : r[3] = 0.4  : q[3] = r[3] * r[3]
  c[4, 1] = -0.5 : c[4, 2] = -0.3  : c[4, 3] = 1.5  : r[4] = 0.15 : q[4] = r[4] * r[1]
  c[5, 1] =  1.0 : c[5, 2] = -0.2  : c[5, 3] = 1.5  : r[5] = 0.1  : q[5] = r[5] * r[5]
  c[6, 1] = -0.1 : c[6, 2] = -0.2  : c[6, 3] = 1.25 : r[6] = 0.2  : q[6] = r[6] * r[6]

  ' Setup for BCX persistent image (handle for drawing context) 
  DIM RAW hDestDC AS HDC
  ' hDestDC: Handle to the device context for drawing 

  hDestDC = STARTDRAW(Canvas)
  ' Begin drawing on the provided canvas 

  ' Main rendering loop - loops through each pixel on the screen 
  FOR INT i = 1 TO scrh
    ' Loop through each row of pixels 

    FOR INT j = 0 TO scrw - 1
      ' Loop through each column of pixels 

      ' Initialize ray origin and direction 
      x = 0.3 : y = -0.5 : z = 0
      ' Ray origin in space 

      ba = 3
      ' Base color index (default) 

      dx = j - w : dy = h - i : dz = (scrh / 480) * 640
      ' Direction from camera to the pixel on the screen 

      dd = dx * dx + dy * dy + dz * dz
      ' Squared distance from the ray origin to the current point 

      RayLoop:
      n = -(y >= 0  OR dy <= 0)
      IF n = 0 THEN s = -y / dy

      FOR INT k = 1 TO spheres
        ' Calculate distances and check for intersections 
        px = c[k, 1] - x
        py = c[k, 2] - y
        pz = c[k, 3] - z
        pp = px * px + py * py + pz * pz
        sc = px * dx + py * dy + pz * dz

        IF sc <= 0 THEN ITERATE

        bb = sc * sc / dd
        aa = q[k] - pp + bb
        IF aa <= 0 THEN ITERATE

        sc = (SQR(bb) - SQR(aa)) / SQR(dd)
        IF sc < s OR n < 0 THEN
          n = k
          s = sc
        END IF
      NEXT k

      IF n < 0 THEN
        BCX_PSET(0, j, scrh - i,  16 + (dy * dy / dd) * 240, hDestDC)
        ITERATE
      END IF

      ' Reflect rays and continue tracing 
      dx = dx * s
      dy = dy * s
      dz = dz * s
      dd = dd * s * s
      x += dx
      y += dy
      z += dz

      IF n <> 0 THEN
        nx = x - c[n, 1]
        ny = y - c[n, 2]
        nz = z - c[n, 3]
        nn = nx * nx + ny * ny + nz * nz
         l = 2 * (dx * nx + dy * ny + dz * nz) / nn
        dx = dx - nx * l
        dy = dy - ny * l
        dz = dz - nz * l
        GOTO RayLoop
      END IF

      ' Check for shadows and plot the pixels 
      FOR INT k = 1 TO spheres
        u = c[k, 1] - x
        v = c[k, 3] - z
        IF u * u + v * v <= q[k] THEN
          ba = 1
          EXIT FOR
        END IF
      NEXT k

      ' Determine plot color based on conditions 
      IF (x - INT(x) > 0.5) = (z - INT(z) > 0.5) THEN
        ik = cl[ba]
      ELSE
        ik = cl[ba + 1]
      END IF

      BCX_PSET(0, j, scrh - i, ik, hDestDC)
    NEXT j
  NEXT i
  ENDDRAW(Canvas, hDestDC)
  BCX_SET_TEXT(Form1, "Raytrace Completed")
END SUB

Result:

This is an image produced by the above code.

BCX_PRESET function

Purpose:

BCX_PRESET sets the starting position of the next drawing command to horizontal Xpos, vertical Ypos coordinates.

Syntax:

RetVal = BCX_PRESET(HndlWnd AS HWND, _
                    Xpos AS INTEGER, _
                    Ypos AS INTEGER  _
                  [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails.

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    Xpos Horizontal X-coordinate of the starting position of the next drawing command.
  • Data type: INTEGER
    Ypos Vertical Y-coordinate of the starting position of the next drawing command
  • Data type: HDC
    DrawHDC [OPTIONAL] A handle pointing to an open HDC. This is useful if a device context is to be written to many times. In this case, the programmer is responsible for closing the HDC at the appropriate time.
    👉 If drawing on an HDC, the HndlWnd parameter, above, must be set to 0.

BCX_PSET function

Purpose:

BCX_PSET sets the pixel located at X% (horizontal) Y% (vertical) to the color represented by the RGB color code in Pen.

Syntax:

 RetVal = BCX_PSET(HndlWnd AS HWND, _
                   Xpos AS INTEGER, _
                   Ypos AS INTEGER  _
                [, Pen AS COLORREF] _
                 [, DrawHDC AS HDC])

Return Value:

  • Data type: COLORREF
    RetVal Value to which the function sets the pixel. This value may differ from the color specified by Pen. That can happen when an exact match for the specified color cannot be found. If the function fails, the return value is -1.

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    Xpos Horizontal X-coordinate of the position.
  • Data type: INTEGER
    Ypos Vertical Y-coordinate of the position.
  • Data type: COLORREF
    Pen An RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case, the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Remarks:

👉 BCX_PENSIZE does not change the size of a pixel until BCX_PENSIZE is set to a value of 4 or greater. If BCX_PENSIZE < 4 then BCX_PSET will use the faster SetPixelV api function. If BCX_PENSIZE > 3 then it, instead, uses the LineTo api and the starting and ending coordinates are set equal which effectively creates a fat pixel. Neither SetPixel or SetPixelV allow for variable pen sizing, so this is a solution to that shortcoming.

Example:

GUI "BCXStarField"

MACRO StarCount  = 200
MACRO FactorX    = -1
MACRO FactorY    = 0
MACRO DirectionX = -1
MACRO DirectionY = 0

SUB FORMLOAD
  GLOBAL Form1 AS HWND
  GLOBAL Max_X
  GLOBAL Max_Y
  Form1 = BCX_FORM("BCX Star Field", 0, 0, 300, 250)
  BCX_SET_FORM_COLOR(Form1, 0)
  CENTER(Form1)
  SHOW(Form1)
END SUB

BEGIN EVENTS
  SELECT CASE CBMSG

  CASE WM_CREATE
    Max_X = 639
    Max_Y = 479
    CALL INIT_STARS
    EXIT FUNCTION

  CASE WM_SIZE
    Max_X = LOWORD(lParam)
    Max_Y = HIWORD(lParam)
    CALL INIT_STARS
    EXIT FUNCTION

  CASE WM_PAINT
    ProcessPlane( 1, StarCount * 0.333, 1)
    ProcessPlane( 71, StarCount * 0.666, 2)
    ProcessPlane(141, StarCount, 3)
    EXIT FUNCTION

  END SELECT
END EVENTS

SUB INIT_STARS
  DIM RAW I,Tmp
  GLOBAL  X [StarCount+1]
  GLOBAL  Y [StarCount+1]
  FOR I  = 0 TO StarCount
    Tmp  = RND * Max_X
    X[I] = Tmp
    Tmp  = RND * Max_Y
    Y[I] = Tmp
  NEXT
END SUB

SUB ProcessPlane (Start1, End1, Speed1)
  DIM LOCAL I, Tmp, Tmp1, Tmp2, T, Kol
  SLEEP(20)
  FOR I  = Start1 TO End1
    Tmp1 = X[I]
    Tmp2 = Y[I]
    T    = FactorX * Speed1
    Kol  = RND * QBCOLOR(0)
    BCX_PSET(Form1, Tmp1, Tmp2, Kol)
    Tmp  = X[I]
    INCR Tmp,T
    T    = FactorY * Speed1
    X[I] = Tmp
    Tmp  = Y[I]
    INCR Tmp,T
    Y[I] = Tmp
    Tmp = X[I]
    IF Tmp <= -1 THEN
      X[I] = Max_X
      Tmp   = RND * Max_Y
      Y[I] = Tmp
    END IF
    Tmp = X[I]
    IF Tmp >= Max_X + 1 THEN
      X[I] = 0
      Tmp   = RND * Max_Y
      Y[I] = Tmp
    END IF
    Tmp = Y[I]
    IF Tmp <= -1 THEN
      Y[I] = Max_Y
      Tmp   = RND * Max_X
      X[I] = Tmp
    END IF
    Tmp = Y[I]
    IF Tmp >= Max_Y THEN
      Y[I] = 0
      Tmp   = RND * Max_X
      X[I] = Tmp
    END IF
    Tmp1 = X[I]
    Tmp2 = Y[I]
    Kol  = RND * QBCOLOR(15)
    BCX_PSET(Form1, Tmp1, Tmp2, Kol)
  NEXT
END SUB

BCX_POLAR_PSET function

Purpose:

BCX_POLAR_PSET locates and sets a pixel at a point on an azimuthal radius.

Syntax:

BCX_POLAR_PSET(HndlWnd AS HWND, _
               OriginX AS LONG, _
               OriginY AS LONG, _
              Radius AS SINGLE, _
             Azimuth AS SINGLE, _
               Pen AS COLORREF  _
             [, DrawHDC AS HDC])

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: LONG
    OriginX Horizontal X-coordinate origin of the radius.
  • Data type: LONG
    OriginY Vertical Y-coordinate origin of the radius.
  • Data type: SINGLE
    Radius Distance from the origin to the set location of the pixel.
  • Data type: SINGLE
    Azimuth The direction of the radius in the positive range 0° to 360° decimal degrees.
  • Data type: COLORREF
    Pen Specifies an RGB color.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to device context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Remarks:

The purpose is to easily and intuitively place a pixel on an azimuthal radius that originates at the coordinates of a radius point and extends out from that location for some user-specified distance in a user-specified direction.

The direction chosen for this command is specified in decimal degrees, not radians, and use a common 360 degree circle. Zero degrees is at the top, 90 degrees is to the right, 180 degrees is at the bottom, and 270 degrees is to the left. Another way to think about those directions is: 12 o'clock, 3 o'clock, 6 o'clock, and 9 o'clock.

Example:

GUI "TGE", PIXELS

CONST MAXX = 600
CONST MAXY = 350

SUB FORMLOAD
  LOCAL Form1 AS HWND
  Form1 = BCX_FORM ("Timer / Graphics Example by MrBcx", 0, 0, MAXX, MAXY)
  BCX_SET_FORM_COLOR(Form1, QBCOLOR(0))
  MODSTYLE(Form1, 0, WS_MAXIMIZEBOX|WS_MINIMIZEBOX, FALSE)
  CENTER Form1
  SHOW   Form1
  '========================================================== 
  SetTimer(Form1, TimerID1,  50, (TIMERPROC) DotCircle_1)
  '========================================================== 
  SetTimer(Form1, TimerID2, 200, (TIMERPROC) DotCircle_2)
  '========================================================== 
  SetTimer(Form1, TimerID3, 200, (TIMERPROC) DotCircle_3)
  '========================================================== 
  SetTimer(Form1, TimerID4, 200, (TIMERPROC) DotCircle_4)
  '========================================================== 
  SetTimer(Form1, TimerID5,  50, (TIMERPROC) DotCircle_5)
  '========================================================== 
END SUB
 
BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_QUIT, WM_CLOSE, WM_DESTROY
    END
  END SELECT
END EVENTS
 
SUB DotCircle_1 (hWnd AS HWND, unt AS UINT, idEvent AS UINT, dwTime AS DWORD)
  '============================= 
  GLOBAL TimerID1 = 1001
  '============================= 
  BCX_PENSIZE = 4
  FOR INT i = 0 TO 360 STEP 10    ' draw a ring of colored pixels 
    BCX_POLAR_PSET (CBHWND, 100, 100, 50, i, QBCOLOR(RND2(12, 14)), 0)
  NEXT
  BCX_PRINTEX(CBHWND, 95, 85, "1", QBCOLOR(14), QBCOLOR(0), "Verdana", 25, 0)
END SUB
 
SUB DotCircle_2 (hWnd AS HWND, Unt AS UINT, idEvent AS UINT, dwTime AS DWORD)
  '============================= 
  GLOBAL TimerID2 = 1002
  '============================= 
  BCX_PENSIZE = 8
  FOR INT i = 0 TO 360 STEP 10    ' draw a ring of colored pixels 
    BCX_POLAR_PSET (CBHWND, 200, 200, 50, i, QBCOLOR(RND2(1, 15)), 0)
  NEXT
  BCX_PRINTEX(CBHWND, 195, 185, "2", QBCOLOR(14), QBCOLOR(0), "Verdana", 30, 0)
END SUB
 
SUB DotCircle_3 (hWnd AS HWND, Unt AS UINT, idEvent AS UINT, dwTime AS DWORD)
  '============================= 
  GLOBAL TimerID3 = 1003
  '============================= 
  BCX_PENSIZE = 8
  FOR INT i = 0 TO 360 STEP 10    ' draw a ring of colored pixels 
    BCX_POLAR_PSET (CBHWND, 300, 100, 50, i, QBCOLOR(RND2(1, 15)), 0)
  NEXT
  BCX_PRINTEX(CBHWND, 293, 85, "3", QBCOLOR(14), QBCOLOR(0), "Verdana", 35, 0)
END SUB
 
SUB DotCircle_4 (hWnd AS HWND, Unt AS UINT, idEvent AS UINT, dwTime AS DWORD)
  '============================= 
  GLOBAL TimerID4 = 1004
  '============================= 
  BCX_PENSIZE = 8
  FOR INT i = 0 TO 360 STEP 10    ' draw a ring of colored pixels 
    BCX_POLAR_PSET (CBHWND, 400, 200, 50, i, QBCOLOR(RND2(1, 15)), 0)
  NEXT
  BCX_PRINTEX(CBHWND, 390, 177, "4", QBCOLOR(14), QBCOLOR(0), "Verdana", 40, 0)
END SUB
 
SUB DotCircle_5 (hWnd AS HWND, Unt AS UINT, idEvent AS UINT, dwTime AS DWORD)
  '============================= 
  GLOBAL TimerID5 = 1005
  '============================= 
  BCX_PENSIZE = 4
  FOR INT i = 0 TO 360 STEP 10    ' draw a ring of colored pixels 
    BCX_POLAR_PSET (CBHWND, 500, 100, 50, i, QBCOLOR(RND2(12, 14)), 0)
  NEXT
  BCX_PRINTEX(CBHWND, 490, 73, "5", QBCOLOR(14), QBCOLOR(0), "Verdana", 50, 0)
END SUB

Result:

This is an image produced by the above code.

BCX_GETPIXEL function

Purpose:

BCX_GETPIXEL returns an integer representing the RGB color code of the pixel located at Xpos (horizontal) Ypos (vertical).

Syntax:

RetVal = BCX_GETPIXEL(HndlWnd AS HWND, _
                      Xpos AS INTEGER, _
                      Ypos AS INTEGER 
                    [, DrawHDC AS HDC])

Return Value:

  • Data type: COLORREF
    RetVal Value of the pixel located at Xpos (horizontal) Ypos (vertical).

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    Xpos Horizontal X-coordinate of the pixel.
  • Data type: INTEGER
    Ypos Vertical Y-coordinate of the pixel.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be read from many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

BCX_LINE function

Purpose:

BCX_LINE draws a line from coordinates StartX%, StartY% to EndX%, EndY%.

Syntax:

 RetVal = BCX_LINE(HndlWnd AS HWND, _
                 StartX AS INTEGER, _
                 StartY AS INTEGER, _
                   EndX AS INTEGER, _
                   EndY AS INTEGER  _
                [, Pen AS COLORREF] _
                 [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails.

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    StartX Horizontal X-coordinate start of line.
  • Data type: INTEGER
    StartY Horizontal Y-coordinate start of line.
  • Data type: INTEGER
    EndX Horizontal X-coordinate end of line.
  • Data type: INTEGER
    EndY Horizontal Y-coordinate end of line.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

BCX_LINETO function

Purpose:

BCX_LINETO draws a line from the last drawn position to EndX%, EndY%.

Syntax:

 RetVal = BCX_LINETO(HndlWnd AS HWND, _
                     EndX AS INTEGER, _
                     EndY AS INTEGER  _
                  [, Pen AS COLORREF] _
                   [, DrawHDC AS HDC])

Return Value:

  • RetVal INTEGER, nonzero if the function succeeds, zero if the function fails

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    EndX Horizontal X-coordinate end of line.
  • Data type: INTEGER
    EndY Horizontal Y-coordinate end of line.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

BCX_POLAR_LINE function

Purpose:

BCX_POLAR_LINE draws a line from an origin to a point on an azimuthal radius.

Syntax:

BCX_POLAR_LINE(HndlWnd AS HWND, _
               OriginX AS LONG, _
               OriginY AS LONG, _
              Radius AS SINGLE, _
             Azimuth AS SINGLE  _
            [, Pen AS COLORREF] _
             [, DrawHDC AS HDC])

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: LONG
    OriginX Horizontal X-coordinate origin of the radius.
  • Data type: LONG
    OriginY Vertical Y-coordinate origin of the radius.
  • Data type: SINGLE
    Radius Distance from the origin to the set location of the pixel.
  • Data type: SINGLE
    Azimuth The direction of the radius in the positive range 0° to 360° decimal degrees.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Remarks:

The purpose is to easily and intuitively draw a line that originates at the coordinates of a radius point and extends out from that location for some user-specified distance along a user-specified direction. The direction chosen for this command is specified in decimal degrees, not radians, and use a common 360 degree circle. Zero degrees is at the top, 90 degrees is to the right, 180 degrees is at the bottom, and 270 degrees is to the left. Another way to think about those directions is: 12 o'clock, 3 o'clock, 6 o'clock, and 9 o'clock.

Example:

$BCXVERSION "8.0.4"
GUI "PGE", PIXELS

CONST MAXX = 800
CONST MAXY = 800

SUB FORMLOAD
  GLOBAL Form1 AS HWND
  Form1 = BCX_FORM("Polar Graphics Example", 0, 0, MAXX, MAXY)
  BCX_SET_FORM_COLOR(Form1, QBCOLOR(0))
  MODSTYLE(Form1, 0, WS_MAXIMIZEBOX|WS_MINIMIZEBOX, FALSE)
  CENTER Form1
  SHOW Form1
  CALL Drawit
END SUB

BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_QUIT, WM_CLOSE, WM_DESTROY
    END
  END SELECT
END EVENTS
 
SUB Drawit
  FOR INT i = 0 TO 360 STEP 45 ' draw 8 spokes 
    BCX_POLAR_LINE(Form1, 400, 400, 100, i, QBCOLOR(9))
  NEXT
  BCX_PENSIZE = 4             ' fat pixels please 
  FOR INT i = 0 TO 360 STEP 10 ' draw a ring of colored pixels 
    BCX_POLAR_PSET(Form1, 400, 400, 120, i, QBCOLOR(RND2(9, 14)))
  NEXT
END SUB

BCX_ARC function

Purpose:

BCX_ARC draws an elliptical arc.

Syntax:

 RetVal = BCX_ARC(HndlWnd AS HWND, _
                  Left AS INTEGER, _
                   Top AS INTEGER, _
                 Right AS INTEGER, _
                Bottom AS INTEGER, _
                   BCX AS INTEGER, _
                   BCY AS INTEGER, _
                   ECX AS INTEGER, _
                   ECY AS INTEGER  _
               [, Pen AS COLORREF] _
                [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails.

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    Left Horizontal X-coordinate of the upper-left corner of the bounding rectangle.
  • Data type: INTEGER
    Top Vertical Y-coordinate of the upper-left corner of the bounding rectangle.
  • Data type: INTEGER
    Right Horizontal X-coordinate of the lower-right corner of the bounding rectangle.
  • Data type: INTEGER
    Bottom Vertical Y-coordinate of the lower-right corner of the bounding rectangle.
  • Data type: INTEGER
    BCX Horizontal X-coordinate of the starting point of the arc.
  • Data type: INTEGER
    BCY Vertical Y-coordinate of the starting point of the arc.
  • Data type: INTEGER
    ECX Horizontal X-coordinate of the ending point of the arc.
  • Data type: INTEGER
    ECY Vertical Y-coordinate of the ending point of the arc.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Example:

GUI "BCX_ARC"

SUB FORMLOAD
  GLOBAL Form1 AS HWND
  Form1 = BCX_FORM("BCX_ARC", 0, 0, 120, 125)
  BCX_SET_FORM_COLOR(Form1,QBCOLOR(14))
  CENTER(Form1)
  SHOW(Form1)
END SUB


BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_PAINT
    CALL DrawStuff
  END SELECT
END EVENTS

SUB DrawStuff
  BCX_PENSIZE = 7
  BCX_ARC(Form1,10,10,210,200,90,90,90,90,QBCOLOR(9))
  BCX_ARC(Form1,50,50,170,160,60,110,160,110,QBCOLOR(9)) ' Mouth 
  BCX_ARC(Form1,65,60,95,100,20,20,20,20,QBCOLOR(9))    ' Left eye 
  BCX_ARC(Form1,125,60,155,100,20,20,20,20,QBCOLOR(9)) ' Right Eye 
END SUB

Result:

This is an image produced by the above code.

BCX_PIE function

Purpose:

BCX_PIE draws a wedge within a circle.

Syntax:

 RetVal = BCX_PIE(HndlWnd AS HWND, _
                   Top AS INTEGER, _
                 Right AS INTEGER, _
                Bottom AS INTEGER, _
                   BCX AS INTEGER, _
                   BCY AS INTEGER, _
                   ECX AS INTEGER, _
                   ECY AS INTEGER  _
               [, Pen AS COLORREF] _
                [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails.

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    Left Horizontal X-coordinate of the upper-left corner of the bounding rectangle.
  • Data type: INTEGER
    Top Vertical Y-coordinate of the upper-left corner of the bounding rectangle.
  • Data type: INTEGER
    Right Horizontal X-coordinate of the lower-right corner of the bounding rectangle.
  • Data type: INTEGER
    Bottom Vertical Y-coordinate of the lower-right corner of the bounding rectangle.
  • Data type: INTEGER
    BCX Horizontal X-coordinate of the endpoint of the first radial.
  • Data type: INTEGER
    BCY Vertical Y-coordinate of the endpoint of the first radial.
  • Data type: INTEGER
    ECX Horizontal X-coordinate of the endpoint of the second radial.
  • Data type: INTEGER
    ECY Vertical Y-coordinate of the endpoint of the second radial.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Example:

GUI "BCX_PIE"
 
SUB FORMLOAD
  GLOBAL Form1 AS HWND
  Form1 = BCX_FORM("BCX_PIE", 0, 0, 115, 130)
  BCX_SET_FORM_COLOR(Form1,QBCOLOR(1))
  CENTER(Form1)
  SHOW(Form1)
END SUB
 
BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_PAINT
    CALL DrawStuff
  END SELECT
END EVENTS
 
SUB DrawStuff
  BCX_PIE(Form1, 25, 25, 190, 190, 200, 60, 200, 150, QBCOLOR(14), QBCOLOR(9))
END SUB

Result:

This is an image produced by the above code.

BCX_TRIANGLE function

Purpose:

BCX_TRIANGLE draws a wedge within a circle.

Syntax:

 RetVal = BCX_TRIANGLE(HndlWnd AS HWND, _
                     Vrtx1X AS INTEGER, _
                     Vrtx1Y AS INTEGER, _
                     Vrtx2X AS INTEGER, _
                     Vrtx2Y AS INTEGER, _
                     Vrtx3X AS INTEGER, _
                     Vrtx3Y AS INTEGER, _
                        Pen AS INTEGER, _
                  FillColor AS INTEGER  _
                 [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails.

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    Vrtx1X Horizontal X-coordinate of the first vertex of the triangle.
  • Data type: INTEGER
    Vrtx1Y Vertical Y-coordinate of the first vertex of the triangle.
  • Data type: INTEGER
    Vrtx2X Horizontal X-coordinate of the second vertex of the triangle.
  • Data type: INTEGER
    Vrtx2Y Vertical Y-coordinate of the second vertex of the triangle.
  • Data type: INTEGER
    Vrtx3X Horizontal X-coordinate of the third vertex of the triangle.
  • Data type: INTEGER
    Vrtx3Y Vertical Y-coordinate of the third vertex of the triangle.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: COLORREF
    FillColor Fill color.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Example:

GUI "Triangle", PIXELS

SUB FORMLOAD
  GLOBAL AS HWND Form1
  GLOBAL AS HWND Canvas
  Form1 = BCX_FORM ("Triangle", 0, 0, 300, 200)
  Canvas = BCX_BITMAP(0, Form1, 1000, 0, 0, 300, 200)
  CENTER Form1
  SHOW   Form1
  CALL Drawit
END SUB

BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_QUIT, WM_CLOSE, WM_DESTROY
    END
  END SELECT
END EVENTS

SUB Drawit
  DIM RAW hDestDC AS HDC
  hDestDC = STARTDRAW(Canvas)
  BCX_TRIANGLE(0, 50, 50, 250, 50, 150, 150, QBCOLOR(1), 1, hDestDC)
  ENDDRAW(Canvas, hDestDC)
END SUB

Result:

This is an image produced by the above code.

BCX_CIRCLE function

Purpose:

BCX_CIRCLE draws a circle.

Syntax:

 RetVal = BCX_CIRCLE(HndlWnd AS HWND, _
                      RPX AS INTEGER, _
                      RPY AS INTEGER, _
                   Radius AS INTEGER  _
                  [, Pen AS COLORREF] _
                  [, Fill AS INTEGER] _
                   [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails.

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    RPX Horizontal X-coordinate of the center of the circle.
  • Data type: INTEGER
    RPY Vertical Y-coordinate of the center of the circle.
  • Data type: INTEGER
    Radius Radius of the circle.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: INTEGER
    Fill [OPTIONAL] Zero (0) or one (1). The default is zero which will not fill the circle. A value of 1 will fill the circle with the color defined in the Pen parameter.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Example:

GUI "BCX_CIRCLE"
 
SUB FORMLOAD
  GLOBAL Form1 AS HWND
  Form1 = BCX_FORM("BCX_CIRCLE", 0, 0, 130, 115)
  BCX_SET_FORM_COLOR(Form1,QBCOLOR(1))
  CENTER(Form1)
  SHOW(Form1)
END SUB
 
BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_PAINT
    CALL DrawStuff
  END SELECT
END EVENTS
 
SUB DrawStuff
  BCX_CIRCLE(Form1,125,105,95,QBCOLOR(14),1)
  BCX_ARC(Form1,50,50,170,160,60,110,160,110,QBCOLOR(9)) ' Mouth 
  BCX_ARC(Form1,65,60,95,100,20,20,20,20,QBCOLOR(9))    ' Left eye 
  BCX_ARC(Form1,125,60,155,100,20,20,20,20,QBCOLOR(9)) ' Right Eye 
END SUB

BCX_RECTANGLE function

Purpose:

BCX_RECTANGLE draws a rectangle, optionally filling it.

Syntax:

 RetVal = BCX_RECTANGLE(HndlWnd AS HWND, _
                        Left AS INTEGER, _
                         Top AS INTEGER, _
                       Right AS INTEGER, _
                      Bottom AS INTEGER  _
                     [, Pen AS COLORREF] _
                     [, Fill AS INTEGER] _
                      [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails.

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    Left Horizontal X-coordinate of the upper-left corner of the bounding rectangle.
  • Data type: INTEGER
    Top Vertical Y-coordinate of the upper-left corner of the bounding rectangle.
  • Data type: INTEGER
    Right Horizontal X-coordinate of the lower-right corner of the bounding rectangle.
  • Data type: INTEGER
    Bottom Vertical Y-coordinate of the lower-right corner of the bounding rectangle.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: INTEGER
    Fill [OPTIONAL] Zero (0) or one (1). The default is zero which will not fill the rectangle. A value of 1 will fill the rectangle with the color defined in the Pen parameter.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

BCX_ROUNDRECT function

Purpose:

BCX_ROUNDRECT draws a rounded rectangle, optionally filling it.

Syntax:

 RetVal = BCX_ROUNDRECT(HndlWnd AS HWND, _
                        Left AS INTEGER, _
                         Top AS INTEGER, _
                       Right AS INTEGER, _
                      Bottom AS INTEGER, _
                       Width AS INTEGER, _
                      Height AS INTEGER  _
                     [, Pen AS COLORREF] _
                     [, Fill AS INTEGER] _
                      [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails.

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    Left Horizontal X-coordinate of the upper-left corner of the bounding rectangle.
  • Data type: INTEGER
    Top Vertical Y-coordinate of the upper-left corner of the bounding rectangle.
  • Data type: INTEGER
    Right Horizontal X-coordinate of the lower-right corner of the bounding rectangle.
  • Data type: INTEGER
    Bottom Vertical Y-coordinate of the lower-right corner of the bounding rectangle.
  • Data type: INTEGER
    Width width of ellipse used to draw the rounded corners.
  • Data type: INTEGER
    Height height of ellipse used to draw the rounded corners.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: INTEGER
    Fill Zero (0) or one (1), the default is zero which will not fill the ellipse. A value of 1 will fill the ellipse with the color defined in the Pen parameter.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Example:

GUI "BCX_RECTANGLE"
 
SUB FORMLOAD
  GLOBAL Form1 AS HWND
  Form1 = BCX_FORM("BCX_RECTANGLE", 0, 0, 140, 130)
  BCX_SET_FORM_COLOR(Form1, RGB(0,0,0))
  CENTER(Form1)
  SHOW(Form1)
END SUB
   
BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_PAINT
    CALL DrawStuff
 
  CASE WM_CLOSE
    DestroyWindow(Form1)
    EXIT FUNCTION
 
  END SELECT
END EVENTS
   
SUB DrawStuff
  BCX_PENSIZE = 10
  BCX_RECTANGLE(Form1,40,20,220,200,RGB(0x00,0x66,0x06),TRUE)
  BCX_ROUNDRECT(Form1,75,54,190,170,20,20,0xFFFFFF,FALSE)
  BCX_ROUNDRECT(Form1,82,62,190,170,20,20,0x999999,FALSE)
  BCX_ROUNDRECT(Form1,82,62,183,162,20,20,RGB(0xEF,0xE7,0xCF),TRUE)
END SUB

Result:

This is an image produced by the above code.

BCX_ELLIPSE function

Purpose:

BCX_ELLIPSE draws an ellipse.

Syntax:

 RetVal = BCX_ELLIPSE(HndlWnd AS HWND, _
                      Left AS INTEGER, _
                       Top AS INTEGER, _
                     Right AS INTEGER, _
                    Bottom AS INTEGER  _
                   [, Pen AS COLORREF] _
                   [, Fill AS INTEGER] _
                    [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails.

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    Left Horizontal X-coordinate of the upper-left corner of the bounding rectangle.
  • Data type: INTEGER
    Top Vertical Y-coordinate of the upper-left corner of the bounding rectangle.
  • Data type: INTEGER
    Right Horizontal X-coordinate of the lower-right corner of the bounding rectangle.
  • Data type: INTEGER
    Bottom Vertical Y-coordinate of the lower-right corner of the bounding rectangle.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: INTEGER
    Fill Zero (0) or one (1), the default is zero which will not fill the ellipse. A value of 1 will fill the ellipse with the color defined in the Pen parameter.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

BCX_POLYLINE function

Purpose:

BCX_POLYLINE function connects the points in the specified array to draw a series of line segments

Syntax:

 RetVal = BCX_POLYLINE(HndlWnd AS HWND, _
                      pPointX AS POINT, _
                  numPointX AS INTEGER  _
                    [, Pen AS COLORREF] _
                     [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    pPointX Pointer to an array of POINT structures that specify the startpoint and the endpoints of the line segments.
  • Data type: INTEGER
    numPointX Specifies the number of points in the array. This value must be greater than or equal to 2.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Example:

GUI "BCX_POLYLINE"
 
DIM pPoints[16] AS POINT
 
SUB FORMLOAD
  GLOBAL Form1 AS HWND
 
  Form1 = BCX_FORM("BCX_Polyline", 0, 0, 135, 110)
  BCX_SET_FORM_COLOR(Form1,QBCOLOR(0))
  CENTER(Form1)
  SHOW(Form1)
END SUB
 
BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_PAINT
    CALL DrawStuff
 
  CASE WM_CLOSE
    DestroyWindow(Form1)
    EXIT FUNCTION
 
  END SELECT
END EVENTS
 
SUB DrawStuff
  DIM RAW RetVal

  BCX_PENSIZE = 4

  pPoints[0].x  = 46: pPoints[0].y  = 83
  pPoints[1].x  = 86: pPoints[1].y  = 83
  pPoints[2].x  = 100: pPoints[2].y  = 94
  pPoints[3].x  = 93: pPoints[3].y  = 112
  pPoints[4].x  = 83: pPoints[4].y  = 116
  pPoints[5].x  = 35: pPoints[5].y  = 116
  pPoints[6].x  = 83: pPoints[6].y  = 116
  pPoints[7].x  = 90: pPoints[7].y  = 123
  pPoints[8].x  = 82: pPoints[8].y  = 135
  pPoints[9].x  = 70: pPoints[9].y  = 142
  pPoints[10].x = 26: pPoints[10].y = 142
  pPoints[11].x = 46: pPoints[11].y = 83
  pPoints[12].x = 51: pPoints[12].y = 83
  pPoints[13].x = 30: pPoints[13].y = 142
  pPoints[14].x = 33: pPoints[14].y = 142
  pPoints[15].x = 53: pPoints[15].y = 83
  RetVal = BCX_POLYLINE(Form1, pPoints, 16, QBCOLOR(12))

  pPoints[0].x  = 165: pPoints[0].y  = 95
  pPoints[1].x  = 151: pPoints[1].y  = 83
  pPoints[2].x  = 126: pPoints[2].y  = 83
  pPoints[3].x  = 103: pPoints[3].y  = 103
  pPoints[4].x  = 96: pPoints[4].y  = 125
  pPoints[5].x  = 111: pPoints[5].y  = 142
  pPoints[6].x  = 134: pPoints[6].y  = 142
  pPoints[7].x  = 156: pPoints[7].y  = 125
  RetVal = BCX_POLYLINE(Form1, pPoints, 8, QBCOLOR(9))

  pPoints[0].x  = 168: pPoints[0].y  = 83
  pPoints[1].x  = 202: pPoints[1].y  = 83
  pPoints[2].x  = 207: pPoints[2].y  = 100
  pPoints[3].x  = 230: pPoints[3].y  = 83
  pPoints[4].x  = 234: pPoints[4].y  = 85
  pPoints[5].x  = 209: pPoints[5].y  = 108
  pPoints[6].x  = 220: pPoints[6].y  = 142
  pPoints[7].x  = 184: pPoints[7].y  = 142
  pPoints[8].x  = 179: pPoints[8].y  = 120
  pPoints[9].x  = 153: pPoints[9].y  = 143
  pPoints[10].x = 150: pPoints[10].y = 139
  pPoints[11].x = 177: pPoints[11].y = 114
  pPoints[12].x = 168: pPoints[12].y = 83
  RetVal = BCX_POLYLINE(Form1, pPoints, 13, QBCOLOR(13))

END SUB

Result:

This is an image produced by the above code.

BCX_POLYGON function

Purpose:

BCX_POLYGON function draws a polygon consisting of two or more vertices connected by straight lines. The polygon is outlined by using the current pen and filled by using the current brush and polygon fill mode.

Syntax:

 RetVal = BCX_POLYGON(HndlWnd AS HWND, _
                      pVertX AS POINT, _
                  numVertX AS INTEGER  _
                   [, Pen AS COLORREF] _
                    [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails.

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    pVertX Array of POINT structures that specify the vertices of the polygon.
  • Data type: INTEGER
    numVertX Specifies the number of vertices in the array. This value must be greater than or equal to 2.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Example:

GUI "BCX_POLYGON"

DIM pVertX[10] AS POINT

SUB FORMLOAD
  GLOBAL Form1 AS HWND
  DIM i%
  DIM pi2#
  pi2# = 8.0 * ATN(1.0)
  FOR i = 0 TO 9
    pVertX[i].x = 125 + SIN(pi2# * i% / 10) * 55
    pVertX[i].y = 95 + COS(pi2# * i% / 10) * 55
  NEXT
  Form1 = BCX_FORM("BCX_POLYGON", 0, 0, 130, 110)
  BCX_SET_FORM_COLOR(Form1,QBCOLOR(31))
  CENTER(Form1)
  SHOW(Form1)
END SUB

BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_PAINT
    CALL DrawStuff

  CASE WM_CLOSE
    DestroyWindow(Form1)
    EXIT FUNCTION

  END SELECT
END EVENTS

SUB DrawStuff
  DIM RAW RetVal
  RetVal = BCX_POLYGON(Form1, pVertX, 10, QBCOLOR(4))
END SUB

Result:

This is an image produced by the above code.

BCX_POLYBEZIER function

Purpose:

BCX_POLYBEZIER function draws one or more Bézier curves.

Syntax:

 RetVal = BCX_POLYBEZIER(HndlWnd AS HWND, _
                        pPoints AS POINT, _
                    numPoints AS INTEGER  _
                      [, Pen AS COLORREF] _
                       [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    pPoints Array of POINT structures that contain the endpoints and control points of the curve(s).
  • Data type: INTEGER
    numPoints Specifies the number of points in the pPoints array. This value must be one more than three times the number of curves to be drawn, because each Bézier curve requires two control points and an endpoint, and the initial curve requires an additional starting point.
  • Data type: COLORREF
    Pen Specifies an RGB color. The default is 0, which is a black pen.
    👉 The Pen width, in pixels, can be set with the case insensitive BCX_PENSIZE GLOBAL variable.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Example:

GUI "BCX_POLYBEZIER"

DIM pPoints[10] AS POINT

SUB FORMLOAD
  GLOBAL Form1 AS HWND
  DIM i%
  DIM pi2#
  pi2# = 8.0 * ATN(1.0)
  FOR i = 0 TO 9
    pPoints[i].x = 155 + SIN(pi2# * i% / 10) * 10 * i%
    pPoints[i].y = 90 + COS(pi2# * i% / 10) * 10 * i%
  NEXT
  Form1 = BCX_FORM("BCX_POLYBEZIER", 0, 0, 140, 110)
  BCX_SET_FORM_COLOR(Form1,QBCOLOR(31))
  CENTER(Form1)
  SHOW(Form1)
END SUB

BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_PAINT
    CALL DrawStuff

  CASE WM_CLOSE
    DestroyWindow(Form1)
    EXIT FUNCTION
  END SELECT
END EVENTS


SUB DrawStuff
  DIM RAW RetVal
  RetVal = BCX_POLYBEZIER(Form1, pPoints, 10, QBCOLOR(4))
END SUB

Result:

This is an image produced by the above code.

BCX_FLOODFILL function

Purpose:

The BCX_FLOODFILL function fills an area with a specified color.

Syntax:

 RetVal = BCX_FLOODFILL(HndlWnd AS HWND, _
                       Xpos AS INTEGER, _
                       Ypos AS INTEGER, _
                   FTColor AS COLORREF  _
              [, FillColor AS COLORREF] _
                [, FillType AS INTEGER] _
                     [, DrawHDC AS HDC])

Return Value:

  • Data type: INTEGER
    RetVal Nonzero if the function succeeds, zero if the function fails.

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where the area color fill takes place.
    👉 The HndlWnd parameter must be set to 0 If printing to an HDC.
  • Data type: INTEGER
    Xpos Horizontal X-coordinate of the starting point for the area color fill.
  • Data type: INTEGER
    Ypos Vertical Y-coordinate of the starting point for the area color fill.
  • Data type: COLORREF
    FTColor
    • If the optional FillType parameter is not defined or defined as 0, the FTColor parameter specifies the RGB color value of the boundary of the fill area.
    • If the optional FillType parameter is defined as 1, the FTColor parameter specifies the RGB color value of the pixels to be changed in the fill area. The area will be filled as long as the color of an adjacent pixel is that specified by the color value of the FTColor parameter.
  • Data type: COLORREF
    FillColor Fill color.
  • Data type: INTEGER
    FillType Zero (0) or one (1).
    • 0 is the default value for this parameter. The area is filled until the boundary, specified by the color value of the FTColor parameter, is reached. For more detail see the documentation for the FLOODFILLBORDER value of the fuFillType parameter at the Microsoft Windows GDI ExtFloodFill function webpage
    • 1 is the optional value for this parameter. The area will be filled as long as the color of an adjacent pixel is that specified by the color value of the FTColor parameter. For more detail see the documentation for the FLOODFILLSURFACE value of the fuFillType parameter at the Microsoft Windows GDI ExtFloodFill function webpage
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Example:

GUI "BCX_FLOODFILL"
   
MACRO IDC_BM1 = 101
 
GLOBAL RetVal
GLOBAL Form1 AS HWND
GLOBAL Button1 AS HWND
GLOBAL Button2 AS HWND
GLOBAL Button3 AS HWND
GLOBAL Canvas AS HWND
   
SUB FORMLOAD
  DIM RAW hDestDC AS HDC
  Form1 = BCX_FORM("BCX_FLOODFILL", 0, 0, 200, 135)
  Canvas = BCX_BITMAP(0, Form1, IDC_BM1, 5, 5, 105, 105)
  Button1 = BCX_BUTTON("Fill Blue Center", Form1, 1, 115, 5, 75, 15)
  Button2 = BCX_BUTTON("Fill To Red Background", Form1, 2, 115, 20, 75, 15)
  Button3 = BCX_BUTTON("Restore Target", Form1, 3, 115, 35, 75, 15)
  hDestDC = STARTDRAW(Canvas)
  RetVal = BCX_RECTANGLE(Form1, 11, 11, 200, 200, QBCOLOR(12), 1, hDestDC)
  RetVal = BCX_CIRCLE(Form1, 110, 110, 60, QBCOLOR(14), 1, hDestDC)
  RetVal = BCX_CIRCLE(Form1, 110, 110, 40, QBCOLOR(9), 1, hDestDC)
  ENDDRAW (Canvas, hDestDC)
  CENTER(Form1)
  SHOW(Form1)
END SUB
   
BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_COMMAND
   
    SELECT CASE CBCTL
 
    CASE 1
      DIM RAW hDestDC AS HDC
      hDestDC = STARTDRAW(Canvas)
      '  To fill the blue center with black 
      RetVal = BCX_FLOODFILL(0, 110, 110, QBCOLOR(9), QBCOLOR(0), 1, hDestDC)
      ENDDRAW (Canvas, hDestDC)
 
    CASE 2
      DIM RAW hDestDC AS HDC
      hDestDC = STARTDRAW(Canvas)
      '  To fill to red background with black 
      RetVal = BCX_FLOODFILL(0, 110, 110, QBCOLOR(12), QBCOLOR(0), 0, hDestDC)
      ENDDRAW (Canvas, hDestDC)
 
    CASE 3
      DIM RAW hDestDC AS HDC
      hDestDC = STARTDRAW(Canvas)
      RetVal = BCX_RECTANGLE(0, 11, 11, 200, 200, QBCOLOR(12), 1, hDestDC)
      RetVal = BCX_CIRCLE(0, 110, 110, 60, QBCOLOR(14), 1, hDestDC)
      RetVal = BCX_CIRCLE(0, 110, 110, 40, QBCOLOR(9), 1, hDestDC)
      ENDDRAW (Canvas, hDestDC)
 
    END SELECT
 
  CASE WM_CLOSE
    DestroyWindow(Form1)
    EXIT FUNCTION
   
  END SELECT
END EVENTS

Result:

This is an image produced by the above code.

BCX_GRADIENT statement

Purpose:

BCX_GRADIENT statement fills an area with a specified color range.

Syntax:

BCX_GRADIENT(HndlWnd AS HWND, _
         TopColor AS COLORREF _
      BottomColor AS COLORREF _
         Direction AS INTEGER _
            [, DrawHDC AS HDC])

Parameters:

  • Data type: HWND
    HndlWnd Identifies the window where drawing takes place.
    👉 The HndlWnd parameter must be set to 0 If drawing to an HDC.
  • Data type: COLORREF
    TopColor Specifies an RGB color.
  • Data type: COLORREF
    BottomColor Specifies an RGB color.
  • Data type: COLORREF
    Direction parameter must be set to zero for drawing a Top-to-Bottom gradient or non-zero for drawing a Left-to-Right gradient.
  • Data type: HDC
    DrawHDC [OPTIONAL] The handle to Device Context pointing to an open HDC. This is useful if a device context is to be written to many times. In this case the programmer is responsible for closing the HDC at the appropriate time.
    👉 If printing to an HDC, the HndlWnd parameter, above, must be set to 0.

Example 1:

$BCXVERSION "8.2.4"
GUI "BCX_Gradient"
GLOBAL AS HWND Form, Canvas
                         
SUB FORMLOAD
  Form = BCX_FORM("BCX_GRADIENT Demo", 0, 0, 360, 250)
  MODSTYLE(Form, 0, WS_SIZEBOX|WS_MAXIMIZEBOX)
  Canvas = BCX_BITMAP(0, Form, 1, 10, 5, 340, 230)
  CENTER(Form)
  SHOW(Form)
  CALL Drawit
END SUB

BEGIN EVENTS
END EVENTS

SUB Drawit
  DIM RAW hDestDC AS HDC
  hDestDC = STARTDRAW(Canvas)
  '************************************************************* 
  BCX_GRADIENT (0,  RGB(255, 255, 255), RGB(0, 32, 0), 0, hDestDC)
  '************************************************************* 
  BCX_RECTANGLE(0, 40, 40, 100, 100, QBCOLOR(1), TRUE, hDestDC)
  BCX_ELLIPSE(0, 350, 100, 60, 200, QBCOLOR(3), TRUE, hDestDC)
  ENDDRAW(Canvas, hDestDC)
END SUB

Result:

This is an image produced by the above code.

Example 2:

$BCXVERSION "8.2.3"
GUI "BCX_GRADIENT Demo"

SUB FORMLOAD
  LOCAL AS HWND Form
  Form = BCX_FORM("BCX_GRADIENT Demo", 0, 0, 360, 250)
  MODSTYLE(Form, 0, WS_SIZEBOX | WS_MAXIMIZEBOX)
  CENTER(Form)
  SHOW(Form)
  SetTimer(Form, 1, 500, NULL)  ' Start a 1/2 second timer 
END SUB

BEGIN EVENTS
  STATIC i
  SELECT CASE CBMSG
    CASE WM_PAINT
    DIM AS PAINTSTRUCT ps
    DIM AS HDC hdc

    hdc = BeginPaint(CBHWND, &ps)
    IF i > 4 OR i = 0 THEN i = 1
    SELECT CASE i
      CASE 1
      BCX_GRADIENT(CBHWND, RGB(0, 0, 120), RGB(255, 255, 255), 0)
      CASE 2
      BCX_GRADIENT(CBHWND, RGB(120, 0, 0), RGB(255, 255, 255), 1)
      CASE 3
      BCX_GRADIENT(CBHWND, RGB(255, 255, 255), RGB(0, 120, 0), 0)
      CASE 4
      BCX_GRADIENT(CBHWND, RGB(255, 255, 255), RGB(120, 120, 0), 1)
    END SELECT
    EndPaint(CBHWND, &ps)

    CASE WM_TIMER    ' Force a re-paint of our window 
    INCR i
    InvalidateRect(CBHWND, NULL, 1)
    UpdateWindow(CBHWND)  ' Ensure WM_PAINT is processed immediately 
  END SELECT
END EVENTS

BCX_BUFFER_START ... BCX_BUFFER_STOP procedure

Purpose:

BCX_BUFFER_START ... BCX_BUFFER_STOP are used to easily create double-buffered graphics using the BCX point and line drawing commands. Double buffering is a great way to reduce or eliminate flickering and for speeding up the presentation of your line drawing statements. BCX_BUFFER_START and BCX_BUFFER_STOP are the boundary lines for the line drawing commands that you want buffered. BCX_BUFFER is a global HDC variable that points to the buffered HDC.

Syntax:

BCX_BUFFER_START(XPixels AS INTEGER, YPixels AS INTEGER) 'desired size (in pixels) of your buffer. 
' --- Your BCX drawing statements go here --- 
BCX_BUFFER_STOP(hForm) ' Transfers the buffered image to hForm. 

Parameters:

  • Data type: INTEGER
    XPixels Vertical size, in pixels, of the buffer.
  • Data type: INTEGER
    YPixels Horizontal size, in pixels, of the buffer.
  • Data type: INTEGER
    hForm is a HWND The handle of the surface on which the image is to be placed.

The line drawing to the buffer is done using the BCX system variable BCX_BUFFER as the argument in any of the BCX line drawing functions which offer the optional DrawHDC as the last parameter. In the Flower Wheel example below, circles are drawn and sent to BCX_BUFFER. Notice that the 1st argument is zero and the last is BCX_BUFFER.

Example Flower Wheel by BPLUS using extended QB64 commands.:

Flower Wheel by BPLUS using extended QB64 commands. BCX version by MrBcx August 18, 2023

$BCXVERSION "8.0.2"

GUI "Flower Wheel", PIXELS

CONST MAXX = 800   ' Experiment with sizes  
CONST MAXY = MAXX   ' keep it square  

SUB FORMLOAD
  GLOBAL AS HWND Form1
  Form1 = BCX_FORM("Flower Wheel", 0, 0, MAXX, MAXY)
  MODSTYLE(Form1, 0, WS_MAXIMIZEBOX | WS_MINIMIZEBOX, FALSE)
  CENTER Form1
  SHOW Form1
  CALL Drawit
END FUNCTION

BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_QUIT, WM_CLOSE, WM_DESTROY
    END
  END SELECT
END EVENTS

SUB Drawit
  DIM RAW Theta = 0 AS SINGLE
  DIM RAW x = MAXX/2 AS INTEGER
  DIM RAW y = MAXY/2 AS INTEGER
  DIM RAW z = MAXX/5 AS INTEGER
  BCX_PENSIZE = 3
  DO
    BCX_BUFFER_START(MAXX, MAXY)
    Theta = Theta + 0.0175 ' PI/180 = 0.0175 (approx)  
    AnimateFlowers(x, y, z, 0.25, 4, Theta)
    BCX_BUFFER_STOP(Form1)
  LOOP
 END SUB

SUB AnimateFlowers (x AS LONG, y AS LONG, r AS LONG, a AS SINGLE, n AS LONG, Theta AS SINGLE)
  '============================================================================================  
  '     This is a recursive SUB.  A recursive SUB/FUNCTION calls itself.  See below...  
  '============================================================================================  
  DIM RAW AS LONG xx, yy
  IF n > 0 THEN
    FOR SINGLE t = 0 TO Pi * 2 STEP 1.05      ' PI/3 = 1.05 (approx)  
      DOEVENTS
      xx = x + r * COS(t + Theta)
      yy = y + r * SIN(t + Theta)
      '=====================================================================================  
      BCX_CIRCLE(0, xx, yy, r,   RGB(255,   0, 0), 0, BCX_BUFFER)
      BCX_CIRCLE(0, xx, yy, r-4, RGB( 0, 255, 0), 0, BCX_BUFFER) ' add another color  
      '=====================================================================================  
      CALL AnimateFlowers(xx, yy, a*r, a, n-1, -Theta - n * 0.0175) ' 0.0175 = Pi/180  
      '=====================================================================================  
    NEXT
  END IF
END SUB

BCX_PENSIZE system variable

Purpose:

BCX_PENSIZE is a case insensitive GLOBAL variable that users can change to set the pen width, in pixels, of the following BCX graphics functions:

Syntax:

BCX_PENSIZE = Thick AS INTEGER

Parameters:

  • Data type: INTEGER
    Thick Pen width, in pixels. It is initialized to a value of one (1).

Example:

GUI "BCX_PENSIZE"
   
SUB FORMLOAD
  GLOBAL Form1 AS HWND
  Form1 = BCX_FORM("BCX_PENSIZE", 0, 0, 130, 125)
  BCX_SET_FORM_COLOR(Form1,QBCOLOR(1))
  CENTER(Form1)
  SHOW(Form1)
END SUB
   
BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_PAINT
    CALL DrawStuff
  END SELECT
END EVENTS
   
SUB DrawStuff
  BCX_PENSIZE = 5
  BCX_CIRCLE(Form1,125,105,95,QBCOLOR(14))
  BCX_PENSIZE = 10
  BCX_CIRCLE(Form1,125,105,75,QBCOLOR(12))
END SUB

Result:

This is an image produced by the above code.

BCX_PENSTYLE system variable

Purpose:

BCX_PENSTYLE is a case insensitive GLOBAL variable that users can change to set the pen style of the following BCX graphics functions:

Syntax:

BCX_PENSTYLE = Style AS INTEGER

Parameters:

  • Data type: INTEGER
    Style A pen style integer value from the list below. It has a default value of one (1).

BCX_BLIT function

Purpose:

BCX_BLIT will blit an existing HBITMAP to an existing HDC.

Syntax:

BCX_BLIT(hBmp AS HBITMAP, _
           hndlDC AS HDC)

Parameters:

  • Data type: HBITMAP
    hBmp an existing HBITMAP.
  • Data type: HDC
    hndlDC an existing HDC

Example:

Here is a snippet from a larger sample project:

DIM AS HBITMAP hBmpBackGrnd = BCX_LOADIMAGE("aquarium.jpg")

BCX_BUFFER_START(MAXX, MAXY)

BCX_BLIT(hBmpBackGrnd, BCX_BUFFER) ' fast enough to use for animations. 

BCX_BLIT_SPRITE function

Purpose:

BCX_BLIT_SPRITE will blit an existing HBITMAP, with an RGB transparency mask, to an existing HDC.

Syntax:

BCX_BLIT_SPRITE(hBmp AS HBITMAP, _
                Left AS INTEGER, _
                 Top AS INTEGER, _
            rgbMask AS COLORREF, _
                  hndlDC AS HDC)

Parameters:

  • Data type: HBITMAP
    hBmp an existing HBITMAP.
  • Data type: INTEGER
    Left distance in pixels from the left edge of the HDC
  • Data type: INTEGER
    Top distance in pixels from the top edge of the HDC
  • Data type: COLORREF
    rgbMask COLORREF value of the RGB transparency mask.
  • Data type: HDC
    hndlDC an existing HDC

Remarks:

Unlike BCX_BLIT which is intended to overwrite an entire HDC display buffer, BCX_BLIT_SPRITE is intended for smaller images that will be overlayed onto what is already in the HDC display buffer -- like placing actors at the front of a stage.
👉 You must specify an RGB mask but you are not obligated to use it. Just be sure to pick an RGB value that is not part of the sprite that you want displayed on the screen. I like using RGB(255,0,255), but you can choose any RGB value that you prefer.

Example:

Here is a snippet from a larger sample project:

FOR INTEGER j = 1 TO l[i]
  IF dx[i] < 0 THEN
    BCX_BLIT_SPRITE(Fish_1, x[i], y[i], RGB(255, 0, 255), BCX_BUFFER)
  ELSE
    BCX_BLIT_SPRITE(Fish_2, x[i], y[i], RGB(255, 0, 255), BCX_BUFFER)
  END IF
NEXT

BCX_BLIT_STRETCH function

Purpose:

BCX_BLIT_STRETCH will will stretch a bitmap that is smaller than the HDC to the maximum dimensions of the HDC.

Syntax:

BCX_BLIT_STRETCH(hBmp AS HBITMAP, _
                   hndlDC AS HDC)

Parameters:

  • Data type: HBITMAP
    hBmp an existing HBITMAP.
  • Data type: HDC
    hndlDC Handle of an existing device context.

Remarks:

The difference between BCX_BLIT and BCX_BLIT_STRETCH is that BCX_BLIT copies the bitmap to HDC, even if its dimensions are smaller than the HDC while BCX_BLIT_STRETCH will stretch a bitmap that is smaller than the HDC to the maximum dimensions of the HDC. Hence, the name and difference. Useful for switching from window to fullscreen and resizing screens.

MAKEBMP function

Purpose:

MAKEBMP function determines the size of the HDC bitmap and returns an HBITMAP to a copy of the original image data found in the HDC function argument. This function requires a valid HDC variable pointing to existing and active 32-bit bitmap data.

Syntax:

hBmpFromhDC = MAKEBMP(hndlDC AS HDC)

Return Value:

  • Data type: HBITMAP
    hBmpFromhDC Copy of image data found in the hndlDC argument.

Parameters:

  • Data type: HDC
    hndlDC An existing handle of a device context.

Example:

Here is a snippet from a larger sample project:

DIM Smile AS HBITMAP       ' Create a HBITMAP variable 

Smile = MAKEBMP(BCX_BUFFER) ' BCX_BUFFER is an HDC. Copy its bmp to Smile 

MAKEHDC function

Purpose:

MAKEHDC function returns an HDC pointing to a bitmap.

Syntax:

hDCFromhBmp = MAKEHDC(hBmp AS HBITMAP)

Return Value:

  • Data type: HDC
    hDCFromhBmp A handle pointing to a bitmap.

Parameters:

  • Data type: HBITMAP
    hBmp A handle to an existing bitmap.

NEWBMP function

Purpose:

NEWBMP creates a blank bitmap. The initial size of the bitmap is determined by the screen resolution that the app is running on. The size can grow or shrink depending upon subsequent manipulations.

Syntax:

hBmpNew = NEWBMP

Return Value:

  • Data type: HBITMAP
    hBmpNew A handle to a blank bitmap.

Parameters:

  • None

Example:

Here is a complete program showing MAKEBMP, MAKEHDC and NEWBMP usage.

$BCXVERSION "8.0.6"
GUI "Graphics Example", PIXELS
CONST MAXX = 810
CONST MAXY = 830

SUB FORMLOAD
    GLOBAL Form1 AS HWND
    Form1 = BCX_FORM ("Graphics Example",  0, 0, MAXX, MAXY)
    MODSTYLE(Form1, 0, WS_MAXIMIZEBOX|WS_MINIMIZEBOX, FALSE)
    '======================================================== 
    CALL ShowMeTheMagic        '<<<----   LOOK   ---<<< 
    '======================================================== 
END SUB

BEGIN EVENTS
    SELECT CASE CBMSG
        CASE WM_QUIT, WM_CLOSE, WM_DESTROY
        END
    END SELECT
END EVENTS

SUB ShowMeTheMagic
    DIM AS HBITMAP OurTileBitmap = NEWBMP                  ' Create a (currently) BLANK bitmap 
    BCX_BUFFER_START(200, 200)                            ' Create a 200 x 200 backbuffer bitmap 
    BCX_PENSIZE = 8                                       ' Use a fat pen for drawing 
    BCX_CIRCLE(0, 100, 100, 75, QBCOLOR(9), 0, BCX_BUFFER) ' Draw a circle off-screen 
    OurTileBitmap = MAKEBMP(BCX_BUFFER)                   ' Fill our bitmap with the CIRCLE bitmap 
    BCX_BUFFER_STOP(Form1)                                ' Our form is still invisible at this time 
    '======================================================================================= 
    '  This next bit demonstrates the technique of drawing on an -> EXISTING <- bitmap. 
    '  Various uses for this technique include adding filters, watermarks, and overlays 
    '  to -> EXISTING <- bitmaps, even those that we load from disk or embedded resources. 
    '======================================================================================= 
    DIM AS HDC hdcTemp = MAKEHDC(OurTileBitmap)           ' Points to our CIRCLE bitmap 

    IF hdcTemp <> NULL THEN                                ' If hdcTemp = NULL, we made BAD MAGIC. 
        BCX_PRINTEX(0, 40, 90, "It's Magic!", QBCOLOR(14), QBCOLOR(0), "Verdana", 26, hdcTemp)
    END IF

    BCX_TILE(Form1, OurTileBitmap)                        ' Give this 20-year old BCX command some work. 
    CENTER Form1                                           ' Now, just the usual GUI commands 
    SHOW Form1                                             ' And finally, THE BIG REVEAL !!! 
END SUB

DRAW statement

Purpose:

The DRAW statement draws a figure.

The GW-BASIC DRAW statement contains (17) subcommands.

The BCX DRAW statement contains (14) subcommands. These subcommands combine many of the capabilities of the other GW-BASIC graphics statements into an "object definition language" called Graphics Macro Language (GML). An object definition language is a language that defines a complete set of characteristics of a particular object. In this case, the characteristics are motion (up, down, left, right), color, and scale factor.

Syntax:

DRAW(GMLcommands AS STRING)

Parameters:

  • Data type: STRING
    GMLcommands A string composed of Graphics Macro Language commands.
  • Movement Commands

    Each of the following GML commands begins movement from the "current graphics position". This position is usually the coordinate of the last graphics point plotted with another GML command. The current position defaults to the TOP LEFT CORNER when a program is run.

    In the table below, the [OPTIONAL] [n] following the alphabetic GML movement command character is an integer specifying distance of movement. The default value is 1 if a value is not specified.

    GMLcommand Movement
    U[n] Moves Up n points
    D[n] Moves Down n points
    L[n] Moves Left n points
    R[n] Moves Right n points
    E[n] Moves Up to right diagonal n points
    F[n] Moves Down to right diagonal n points
    G[n] Moves Down to left diagonal n points
    H[n] Moves Up to left diagonal n points
    Mx,y Moves to point x,y. If x is preceded with a (+) plus or (-) minus sign the point is relative; otherwise the point is absolute.
    (Relative) If x is preceded by a plus ( + ) or minus ( - ) sign, x and y are added to the current graphics position and connected with the current position BY A LINE.
    (Absolute) Otherwise, a LINE IS DRAWN to point x, y from the current cursor position.
  • Prefix Commands

    The prefix commands in the table below may be prepended to the movement commands listed in the above table.

    GMLcommand Movement
    B Move, but do not plot points
    N Move and return to origin when move is completed.
    Cn Set the color, n is an integer in the range 1-31, representing a QBCOLOR.
    S[n] Set the scale factor. n is a floating point number used to multiply the distance of movement points.
    Pf,b Set the fill and boundary colors for a floodfill figure. f, the fill color, is an integer in the range 1-31 representing a QBCOLOR. b, the boundary color, is an integer in the range 1-31 representing a QBCOLOR.

    Example:

    DRAW ("S1 C1 B300,510 R50 U50 L50 D50 BR2 BU2 P2,0") ' Draw blue square and fill with green
    
    

Example 1:

'================================================================ 
' HINT:  Click the Windows Maximize button 
'================================================================ 

GUI "BCX Draw Command Demo", PIXELS

SUB FORMLOAD
    LOCAL Form1 AS CONTROL
    Form1 = BCX_FORM ("BCX Draw Command Demo 2", 0, 0, 1024, 768)
    DIM s$, c$, x$, y$
    FOR INT i = 1 TO 300
        BCX_PENSIZE = RND2(1, 5)                            ' Random Thickness 
        s$ = STR$(RND2(1, 5))                               ' Random Scale 
        c$ = STR$(RND2(1, 31))                              ' Random QBColor 
        x$ = STR$(RND2(10, GetSystemMetrics(SM_CXSCREEN)))  ' Random X ordinate 
        y$ = STR$(RND2(10, GetSystemMetrics(SM_CYSCREEN)))  ' Random Y ordinate 
        '      Dynamically build our DRAW string 
        DRAW "C" + c$ + "S" + s$ + "B" + x$ + "," + y$ + "NL5 NR5 NU5 ND5 NE5 NF5 NG5 NH5" ' An 8-point star 
    NEXT
    CENTER Form1
    SHOW Form1
END SUB

BEGIN EVENTS
END EVENTS

Example 2:

 GUI "BCX Draw Command Demo", PIXELS

 SUB FORMLOAD
   DIM Form1 AS CONTROL
   Form1 = BCX_FORM ("BCX Draw Command Demo", 0, 0, 1024, 384)
   MODSTYLE(Form1, 0, WS_MAXIMIZEBOX OR WS_MINIMIZEBOX, FALSE)
   BCX_SET_FORM_COLOR (Form1, RGB(0, 0, 0))
   BCX_PENSIZE = 4
   TextDraw("bcx basic to c++ translator", 70, 100, 4, 1)
   TextDraw("abcdefghijklmnopqrstuvwxyz" , 150, 150, 3, 2)
   BCX_PENSIZE = 1
   TextDraw(",.0123456789+-*/'"          , 250, 200, 4, 3)
   TextDraw("it's time to tinker ..."    , 500, 250, 3, 13)
   '========================================================  
   '      MrBcx Turbo<>Cogo NORTH ARROW created in 1992  
   '========================================================  
   DRAW ("S1C7B30,120U100F1D4F1D4F1D4F1D4F1D4F1D4F1D4")
   DRAW ("F1D4H8G8U4E1U4E1U4E1U4U4E1U4E1U4E1U4E2D70F5")
   DRAW ("D30H5F5U30H5G5D30E5G5U30E5U15H07D15U15F15U15")
   '========================================================  
   '     Several shapes demonstrating more DRAW verbs  
   '========================================================  
   DRAW ("B50,300S9C4R2U4L4D4R2")                         ' Square  
   DRAW ("B150,300S9C4R3H4G4R5")                          ' Triangle  
   DRAW ("B230,280S9C4L2R4L2U2D4")                        ' Cross  
   DRAW ("S1C1B300,310R50U50L50D50BR2BU2P2,0")            ' Blue square, filled green  
   DRAW ("C9S.4B400,285NL50NR50NU50ND50NE50NF50NG50NH50") ' Light Blue Star  
   CENTER Form1
   SHOW Form1
 END SUB

 BEGIN EVENTS
 END EVENTS

 SUB TextDraw (Txt$, X, Y, Scale, tColor)
   DIM Tmp1$, Tmp2$, sDraw$

   sDraw$ = "S" + STR$(Scale) + "C" + STR$(tColor) + "B" + STR$(X) + "," + STR$(Y)
   DRAW (sDraw$)

   Tmp1$ = UCASE$(Txt$)

   FOR INT A = 1 TO LEN(Tmp1$)
     Tmp2$ = MID$(Tmp1$, A%, 1)
     SELECT CASE Tmp2$

     CASE "A"
       sDraw$ = sDraw$ + "U6R6D6BU3L6BD3BR9"

     CASE "B"
       sDraw$ = sDraw$ + "U6R4D3L4R6D3L6BR9"

     CASE "C"
       sDraw$ = sDraw$ + "U6R6BL6BD6R6BR3"

     CASE "D"
       sDraw$ = sDraw$ + "U6R6D6L6BR9"

     CASE "E"
       sDraw$ = sDraw$ + "U6R6BL6BD3R6BL6BD3R6BR3"

     CASE "F"
       sDraw$ = sDraw$ + "U6R6BL6BD3R3BD3BR6"

     CASE "G"
       sDraw$ = sDraw$ + "U6R6BL6BD6R6U3L3BR6BD3BR2"

     CASE "H"
       sDraw$ = sDraw$ + "U6BD3R6U3BD3D3BR3"

     CASE "I"
       sDraw$ = sDraw$ + "BR2U6BD6BR4"

     CASE "J"
       sDraw$ = sDraw$ + "U3BD3R6U6BD6BR3"

     CASE "K"
       sDraw$ = sDraw$ + "U6D3R2NE3F4BR3BU1"

     CASE "L"
       sDraw$ = sDraw$ + "U6BD6R6BR3"

     CASE "M"
       sDraw$ = sDraw$ + "U6F3E3D6BR3"

     CASE "N"
       sDraw$ = sDraw$ + "U6F6U6BD6BR4"

     CASE "O"
       sDraw$ = sDraw$ + "U6R6D6L6BR9"

     CASE "P"
       sDraw$ = sDraw$ + "U6R6D3L6BD3BR9"

     CASE "Q"
       sDraw$ = sDraw$ + "U6R6D6L6BR4NH2F2BU2BR3"

     CASE "R"
       sDraw$ = sDraw$ + "U6R6D3L6BR3F3BR3"

     CASE "S"
       sDraw$ = sDraw$ + "R6U3L6U3R6BD6BR3"

     CASE "T"
       sDraw$ = sDraw$ + "BR2U6L3BR3R3BD6BR3"

     CASE "U"
       sDraw$ = sDraw$ + "U6BD6R6U6BD9BR3"

     CASE "V"
       sDraw$ = sDraw$ + "BU3BR2H2NU4F2R1E2U4BD6BR3"

     CASE "W"
       sDraw$ = sDraw$ + "U6BD6E2R3F2U6BD6BR3"

     CASE "X"
       sDraw$ = sDraw$ + "NE6BR6NH6BR5"

     CASE "Y"
       sDraw$ = sDraw$ + "BR1U3NH3NE3BD3BR5"

     CASE "Z"
       sDraw$ = sDraw$ + "R6BL6E6L6BD6BR9"

     CASE "0"
       sDraw$ = sDraw$ + "U6R6D6L6BR9"

     CASE "1"
       sDraw$ = sDraw$ + "BR1U6BD6BR4"

     CASE "2"
       sDraw$ = sDraw$ + "R6L6U3R6U3L6BD6BR9"

     CASE "3"
       sDraw$ = sDraw$ + "R6U3L6BR6U3L6BR9BD6"

     CASE "4"
       sDraw$ = sDraw$ + "BR6U6BD3L6U3BD3BR6BD3BR3"

     CASE "5"
       sDraw$ = sDraw$ + "R6U3L6U3R6BR3BD6"

     CASE "6"
       sDraw$ = sDraw$ + "U6R6L6D6R6U3L6R6D3BR3"

     CASE "7"
       sDraw$ = sDraw$ + "BR6U6L6R6D6BR3"

     CASE "8"
       sDraw$ = sDraw$ + "U6R6D3L6R6D3L6BR9"

     CASE "9"
       sDraw$ = sDraw$ + "BR6U6L6D3R6BD3BR3"

     CASE SPC$
       sDraw$ = sDraw$ + "BR5"

     CASE ","
       sDraw$ = sDraw$ + "G1E1U1BD1BR3"

     CASE "."
       sDraw$ = sDraw$ + "R1BR3"

     CASE "'"
       sDraw$ = sDraw$ + "BR1 BU6E2BG2BD7BR4"

     CASE ":"
       sDraw$ = sDraw$ + "BR1U1BU3U1BR2BD5"

     CASE ";"
       sDraw$ = sDraw$ + "BR1G1E1U1BU4U1BR3BD6"

     CASE "+"
       sDraw$ = sDraw$ + "BR4U4BD2L2R4BR2BD2"

     CASE "-"
       sDraw$ = sDraw$ + "BU3R5BD3BR4"

     CASE "*"
       sDraw$ = sDraw$ + "BR2BU3H2F4H2E2G4E2L3R6BD2BR3 "

     CASE "/"
       sDraw$ = sDraw$ + "BR1E5BD5BR4"
     END SELECT
   NEXT
   DRAW (sDraw$)
 END SUB

Result:

This is an image produced by the above code.

Example 3:

GUI "StrokeFonts", PIXELS

SUB FORMLOAD
  DIM Form1 AS CONTROL
  Form1 = BCX_FORM("Stroke Me!", 0, 0, 1000, 350)

  BCX_PENSIZE = 4
  TextDraw("Font definitions by Veit Wahlich, Markus Stehr, and MrBcx", 50, 50, 2, 6)

  BCX_PENSIZE = 3
  TextDraw("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 50, 100, 2, 2)
  TextDraw("abcdefghijklmnopqrstuvwxyz", 50, 150, 2, 3)

  BCX_PENSIZE = 2
  TextDraw("0.123,456,789.,+-*/=\:;[]()^",   50, 200, 2, 4)

  BCX_PENSIZE = 1
  TextDraw(".,+-*/=\[]()^:;9.876,543,210",   50, 250, 2, 9)

  BCX_PENSIZE = 2
  TextDraw("ABC $$$ ABC", 50, 300, 2, 4)

  CENTER Form1
  SHOW Form1
END SUB

BEGIN EVENTS
END EVENTS

SUB TextDraw(Txt$, X, Y, Scale, tColor)
  '******************************************************** 
  ' Original DRAW strings by Veit Wahlich and Markus Stehr 
  '******************************************************** 
  DIM Tmp1$, Tmp2$
  DIM Length
  DIM sDraw$

  sDraw$ = "S" + STR$(Scale) + "C" + STR$(tColor) + "B" + STR$(X) + "," + STR$(Y)
  DRAW (sDraw$)

  Tmp1$ =  Txt$
  Length = LEN(Tmp1$)

  FOR INT i = 1 TO Length
    Tmp2$ = MID$(Tmp1$, i, 1)
    SELECT CASE Tmp2$
    CASE "A" : sDraw$ = sDraw$ + "U6E6D12BU4L6BD4BR9"
    CASE "B" : sDraw$ = sDraw$ + "U12R4F2D2G2L4BR4F2D2G2L4BR9"
    CASE "C" : sDraw$ = sDraw$ + "BR6L4H2U8E2R4BD12BR3"
    CASE "D" : sDraw$ = sDraw$ + "U12R4F2D8G2L4BR9"
    CASE "E" : sDraw$ = sDraw$ + "U12R4BL4BD6R5BL5BD6R6BR3"
    CASE "F" : sDraw$ = sDraw$ + "U12R6BL6BD6R4BL4BD6BR9"
    CASE "G" : sDraw$ = sDraw$ + "BR4BU5R2D3G2L2H2U8E2R2F2BD10BR3"
    CASE "H" : sDraw$ = sDraw$ + "U12BD6R6BU6D12BR3"
    CASE "I" : sDraw$ = sDraw$ + "U12BD12BR3"
    CASE "J" : sDraw$ = sDraw$ + "BU1F1R2E1U11BD12BR3"
    CASE "K" : sDraw$ = sDraw$ + "U12BD6E6BG6F6BR3"
    CASE "L" : sDraw$ = sDraw$ + "U12BD12R6BR3"
    CASE "M" : sDraw$ = sDraw$ + "U12F4E4D12BR3"
    CASE "N" : sDraw$ = sDraw$ + "U12F6BU6D12BR3"
    CASE "O" : sDraw$ = sDraw$ + "BR2H2U8E2R2F2D8G2L2BR7"
    CASE "P" : sDraw$ = sDraw$ + "U12R4F2D2G2L4BD6BR9"
    CASE "Q" : sDraw$ = sDraw$ + "BR2H2U8E2R2F2D8G2L2BR2BU1F2BU1BR3"
    CASE "R" : sDraw$ = sDraw$ + "U12R4F2D2G2L4BR3F3D3BR3"
    CASE "S" : sDraw$ = sDraw$ + "R5E1U4H1L4H1U4E1R5BD12BR3"
    CASE "T" : sDraw$ = sDraw$ + "BU12R6BL3D12BR6"
    CASE "U" : sDraw$ = sDraw$ + "BU12D10F2R2E2U10BD12BR3"
    CASE "V" : sDraw$ = sDraw$ + "BU12D12E6U6BD12BR3"
    CASE "W" : sDraw$ = sDraw$ + "BU12D12E4F4U12BD12BR3"
    CASE "X" : sDraw$ = sDraw$ + "U3E6U3BL6D3F6D3BR3"
    CASE "Y" : sDraw$ = sDraw$ + "R6U6U6BL6D6R6BD6BR3"
    CASE "Z" : sDraw$ = sDraw$ + "BU12R6D3G6D3R6BR3"
      '*************************************************************** 
    CASE "a" : sDraw$ = sDraw$ + "BR2H2U2E2R2F2BU2D6BU2G2L2BR7"
    CASE "b" : sDraw$ = sDraw$ + "U12BD8E2R2F2D2G2L4BR9"
    CASE "c" : sDraw$ = sDraw$ + "BR6BU1G1L3H2U2E2R3F1BD5BR3"
    CASE "d" : sDraw$ = sDraw$ + "BR6L4H2U2E2R3F2BU8D12BR3"
    CASE "e" : sDraw$ = sDraw$ + "BR6L4H2U2E2R3F1D1G1L4BD3BR9"
    CASE "f" : sDraw$ = sDraw$ + "BD2U12E2R1BD7L3BD5BR6"
    CASE "g" : sDraw$ = sDraw$ + "BR6BU1G1L3H2U2E2R4F1D8G1L4BU4BR8"
    CASE "h" : sDraw$ = sDraw$ + "U12BD8E2R2F2D4BR3"
    CASE "i" : sDraw$ = sDraw$ + "U6BU3U1BD10BR3"
    CASE "j" : sDraw$ = sDraw$ + "BD4R1E2U8BU3U1BD10BR3"
    CASE "k" : sDraw$ = sDraw$ + "U12BD9R2E3BG3F3BR3"
    CASE "l" : sDraw$ = sDraw$ + "BU12D11F1R2BR3"
    CASE "m" : sDraw$ = sDraw$ + "U6R3F1D5BU5E1R2F1D5BR3"
    CASE "n" : sDraw$ = sDraw$ + "U6R4F1D5BR3"
    CASE "o" : sDraw$ = sDraw$ + "BR2H2U2E2R2F2D2G2L2BR7"
    CASE "p" : sDraw$ = sDraw$ + "BU5D9BU6F2R2E2U2H2L2G2BD5BU1BR9"
    CASE "q" : sDraw$ = sDraw$ + "BR5BU1G1L2H2U2E2R2F2D8BU4BR3"
    CASE "r" : sDraw$ = sDraw$ + "U6BD2E2R1BD6BR3"
    CASE "s" : sDraw$ = sDraw$ + "R5E1U1H1L4H1U1E1R5BD6BR3"
    CASE "t" : sDraw$ = sDraw$ + "BU12D4R3BL3D7F1R2BR3"
    CASE "u" : sDraw$ = sDraw$ + "BU6D5F1R4U6BD6BR3"
    CASE "v" : sDraw$ = sDraw$ + "BU6D6E6BD6BR3"
    CASE "w" : sDraw$ = sDraw$ + "BU6D6E3F3U6BD6BR3"
    CASE "x" : sDraw$ = sDraw$ + "BU6F6BU6G6BR9"
    CASE "y" : sDraw$ = sDraw$ + "BU6D4F2R2E2BU4D10L4BU4BR7"
    CASE "z" : sDraw$ = sDraw$ + "BU6R6G6R6BR3"
      '*************************************************************** 
    CASE "0" : sDraw$ = sDraw$ + "U12R6D12L6BR9"
    CASE "1" : sDraw$ = sDraw$ + "U12BD12BR3"
    CASE "2" : sDraw$ = sDraw$ + "BR6L6U6R6U6L6BD12BR9"
    CASE "3" : sDraw$ = sDraw$ + "R6U12L6BD6R6BD6BR3"
    CASE "4" : sDraw$ = sDraw$ + "BR6U12BL6D6R6BD6BR3"
    CASE "5" : sDraw$ = sDraw$ + "R6U6L6U6R6BD12BR3"
    CASE "6" : sDraw$ = sDraw$ + "R6U6L6BD6U12R6BD12BR3"
    CASE "7" : sDraw$ = sDraw$ + "BU12R6D12BR3"
    CASE "8" : sDraw$ = sDraw$ + "R6U6L6BD6U12R6D6BD6BR3"
    CASE "9" : sDraw$ = sDraw$ + "R6U6L6U6R6D6BD6BR3"
      '*************************************************************** 
    CASE "[" : sDraw$ = sDraw$ + "BU2BR3L3U12R3BR3BD14"
    CASE "]" : sDraw$ = sDraw$ + "BU2R3U12L3BR6BD14"
    CASE "(" : sDraw$ = sDraw$ + "BU2BR3H3U6E3BR3BD14"
    CASE ")" : sDraw$ = sDraw$ + "BU2E3U6H3BR6BD8"
    CASE " " : sDraw$ = sDraw$ + "BR9"
    CASE "," : sDraw$ = sDraw$ + "BR2G1E1U1BD1BR3"
    CASE "." : sDraw$ = sDraw$ + "BU1R1BR3BD1"
    CASE "'" : sDraw$ = sDraw$ + "BR1BU7E2BG2BD7BR4"
    CASE ":" : sDraw$ = sDraw$ + "BR2U1BU3U1BR4BD7"
    CASE ";" : sDraw$ = sDraw$ + "BU2BR2G1E1U1BU4U1BR4BD10"
    CASE "+" : sDraw$ = sDraw$ + "BU5R4U4D8U4R4BD4BR4"
    CASE "-" : sDraw$ = sDraw$ + "BU4R5BD4BR4"
    CASE "*" : sDraw$ = sDraw$ + "BU1BR2BU3H2F4H2E2G4E2L3R6BD4BR3"
    CASE "^" : sDraw$ = sDraw$ + "BU6BR1E5F5BD7BR4"
    CASE "/" : sDraw$ = sDraw$ + "BR2BU1E11BD12BR4"
    CASE "\" : sDraw$ = sDraw$ + "BU11BR1F10BD1BR3"
    CASE "=" : sDraw$ = sDraw$ + "BR1BU8R8BL8BD3R8BR4BD5"
    CASE "$": sDraw$ = sDraw$ + "R5E1U4H1L4H1U4E1R5BD13BL3u14BD13BR6"
    END SELECT
  NEXT
  DRAW (sDraw$)
END SUB

Result:

This is an image produced by the above code.