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:
Parameters:
|
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
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
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:
Parameters:
|
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:
Parameters:
|
👉 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.
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 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:
|
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.
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
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:
Parameters:
|
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:
Parameters:
|
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:
Parameters:
|
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:
|
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.
$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 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:
Parameters:
|
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
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:
Parameters:
|
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
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:
Parameters:
|
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
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:
Parameters:
|
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 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:
Parameters:
|
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:
Parameters:
|
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
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:
Parameters:
|
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:
Parameters:
|
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
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:
Parameters:
|
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
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:
Parameters:
|
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
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:
Parameters:
|
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
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:
|
$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
$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 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:
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. |
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 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:
|
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
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:
|
BCX_BLIT will blit an existing HBITMAP to an existing HDC.
Syntax:BCX_BLIT(hBmp AS HBITMAP, _ hndlDC AS HDC) Parameters:
|
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 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: |
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.
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 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:
|
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 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:
Parameters:
|
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 returns an HDC pointing to a bitmap.
Syntax:hDCFromhBmp = MAKEHDC(hBmp AS HBITMAP) Return Value:
Parameters:
|
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:
Parameters:
|
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
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:
|
'================================================================ ' 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
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
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