' '=================================================================================== ' The Canvas module ' Written by Marco Kurvers, Holland ' Purpose: replaces the commands, properties and functions as well as Canvas methods ' Usage: ' - If you already have the globals False and True, for example via another ' module, you can simply delete them from the Init sub in the Canvas module. ' - You can also just use a 0 or a 1 instead of the False and True. ' - Call Canvas.Init with the window handle and a hWnd pointer as the arguments ' after the OPEN command. ' - The Canvas also works on the GRAPHICBOX. Please provide the window and the name ' of the GRAPHICBOX. ' - Don't call some functions, for example the GetHandle$ function, see comment there. ' These functions are private functions. ' Only the Canvas methods uses the feature. ' Example with a graphics window: ' call Canvas.Init "#", hwnd(#) ' Example with a graphicbox control: ' call Canvas.Init "#.", hwnd(#.) ' Example with windowhandle #g: ' call Canvas.Init "#g", hwnd(#g) ' Example with graphicbox control gbox: ' call Canvas.Init "#w.gbox", hwnd(#w.gbox) 'This new version has a False and a True in the Init. sub Canvas.Init handle$, hWnd global False, True False = 0 True = 1 'Canvas structure to hold values for the methods struct Canvas,_ handle$ as ptr,_ hWnd as long,_ PI as double,_ RD as double,_ Paper.normal as ushort,_ Paper.vga as ushort,_ Paper.svga as ushort,_ Paper.xga as ushort,_ Pen.size as ulong,_ Pen.color$ as ptr,_ Pen.backcolor$ as ptr,_ RGB.red as word,_ RGB.green as word,_ RGB.blue as word,_ RGB.string$ as ptr,_ RGB.pColor as long,_ RGB.fillColor as long Canvas.handle$.struct = handle$ Canvas.hWnd.struct = hWnd Canvas.PI.struct = atn(1) * 4 Canvas.RD.struct = Canvas.PI.struct / 180 Canvas.Paper.normal.struct = 0 Canvas.Paper.vga.struct = 1 Canvas.Paper.svga.struct = 2 Canvas.Paper.xga.struct = 3 Canvas.Pen.size.struct = 1 Canvas.Pen.color$.struct = "black" Canvas.Pen.backcolor$.struct = "black" end sub 'private in the Canvas: don't call this function function Canvas.GetHandle$() Canvas.GetHandle$ = winstring(Canvas.handle$.struct) end function 'private in the Canvas: don't call this function function Canvas.GetHWnd() Canvas.GetHWnd = Canvas.hWnd.struct end function 'call this sub to get the x and y position in a string 'the string Q$ must be are a legal position list sub Canvas.GetCoord Q$, byref nx, byref ny n$ = word$(Q$, 1, ";") nx = val(word$(n$, 1, ",")) ny = val(word$(n$, 2, ",")) end sub 'call this function to remove the first position in a string 'the string Q$ must be are a legal position list function Canvas.PopCoord$(Q$) p = instr(Q$, ";", 1) Canvas.PopCoord$ = trim$(mid$(Q$, p + 1)) end function 'set the position of a window that must be created sub Canvas.WindowPos x, y UpperLeftX = x UpperLeftY = y end sub 'set the width size and the height size of a window that must be created sub Canvas.WindowSize w, h WindowWidth = w WindowHeight = h end sub 'this sub moves a window to a new position with a new size sub Canvas.MoveParent x, y, w, h hWnd = Canvas.GetHWnd() calldll #user32, "MoveWindow",_ hWnd as ulong,_ x as long,_ y as long,_ w as long,_ h as long,_ 1 as boolean,_ r as boolean end sub 'clears the clientview of a graphic window or a graphicbox sub Canvas.Cls handle$ = Canvas.GetHandle$() #handle$ "cls" end sub 'sets the pen size and color sub Canvas.SetPen size, color$ handle$ = Canvas.GetHandle$() #handle$ "size "; size #handle$ "color "; color$ Canvas.Pen.size.struct = size Canvas.Pen.color$.struct = color$ end sub 'this sub returns the pen size and color sub Canvas.GetPen byref size, byref color$ size = Canvas.Pen.size.struct color$ = winstring(Canvas.Pen.color$.struct) end sub 'this sub saves the RGB values in the RGB structure sub Canvas.SetRGB r, g, b Canvas.RGB.red.struct = r Canvas.RGB.green.struct = g Canvas.RGB.blue.struct = b Canvas.RGB.string$.struct = r; " "; g; " "; b end sub 'this function loads the RGB from the RGB structure function Canvas.GetRGB$() Canvas.GetRGB$ = winstring(Canvas.RGB.string$.struct) end function 'sets the pen down sub Canvas.Down handle$ = Canvas.GetHandle$() #handle$ "down" end sub 'sets the pen up sub Canvas.Up handle$ = Canvas.GetHandle$() #handle$ "up" end sub 'sets the pen down on a new place sub Canvas.SetPenDown x, y call Canvas.Down call Canvas.Place x, y end sub 'sets a new rule sub Canvas.Rule ruleConst handle$ = Canvas.GetHandle$() #handle$ "rule "; ruleConst end sub 'sets the pen on the home center point in the clientview sub Canvas.Center handle$ = Canvas.GetHandle$() #handle$ "home" end sub 'sets the pen on the topleft point in the clientview sub Canvas.Home call Canvas.Place 0, 0 end sub 'moves the pen to a new position sub Canvas.Goto x, y call Canvas.Up handle$ = Canvas.GetHandle$() #handle$ "goto "; x; " "; y end sub 'turns the pen to the north: default command sub Canvas.North handle$ = Canvas.GetHandle$() #handle$ "north" end sub 'turns the pen to the south sub Canvas.South handle$ = Canvas.GetHandle$() #handle$ "north" call Canvas.Turn 180 end sub 'turns the pen to the west sub Canvas.West handle$ = Canvas.GetHandle$() #handle$ "north" call Canvas.Turn 270 end sub 'turns the pen to the east sub Canvas.East handle$ = Canvas.GetHandle$() #handle$ "north" call Canvas.Turn 90 end sub 'turns the pen to the given direction sub Canvas.Turn direction handle$ = Canvas.GetHandle$() #handle$ "turn "; direction end sub 'this sub draws a line from the current position to a given distance sub Canvas.Go distance handle$ = Canvas.GetHandle$() #handle$ "go "; distance end sub 'this sub makes it possible to give more drawing commands in a string sub Canvas.Turtle component$ handle$ = Canvas.GetHandle$() #handle$ component$ end sub 'this sub prints the drawing to a given print size sub Canvas.Print size handle$ = Canvas.GetHandle$() select case size case Canvas.Paper.normal.struct #handle$ "print" case Canvas.Paper.vga.struct #handle$ "print vga" case Canvas.Paper.svga.struct #handle$ "print svga" case Canvas.Paper.xga.struct #handle$ "print xga" end select end sub 'sets the pixel size: the size works always from the center sub Canvas.Size size handle$ = Canvas.GetHandle$() #handle$ "size "; size end sub 'places the pen on an another position sub Canvas.Place x, y handle$ = Canvas.GetHandle$() #handle$ "place "; x; " "; y end sub 'returns the length of a given string in pixels function Canvas.TextWidth(string$) handle$ = Canvas.GetHandle$() #handle$ "stringwidth? string$ width" Canvas.TextWidth = width end function 'this sub renders a given string on the clientview of a graphics window or a graphicbox sub Canvas.SetText string$ handle$ = Canvas.GetHandle$() #handle$ "|"; string$ end sub 'sets the backcolor and saves it in the Pen structure sub Canvas.BackColor color$ handle$ = Canvas.GetHandle$() #handle$ "backcolor "; color$ Canvas.Pen.backcolor$.struct = color$ end sub 'returns the saved backcolor from the Pen structure 'when there is no backcolor, the default backcolor is black function Canvas.BackColor$() backColor$ = winstring(Canvas.Pen.backcolor$.struct) if trim$(backColor$) = "" then backColor$ = "black" Canvas.Pen.backcolor$.struct = backColor$ end if Canvas.BackColor$ = backColor$ end function 'sets the forecolor and saves it in the Pen structure sub Canvas.Color color$ handle$ = Canvas.GetHandle$() #handle$ "color "; color$ Canvas.Pen.color$.struct = color$ end sub 'returns the saved forecolor from the Pen structure 'when there is no forecolor, the default forecolor is black function Canvas.Color$() color$ = winstring(Canvas.Pen.color$.struct) if trim$(color$) = "" then color$ = "black" Canvas.Pen.color$.struct = color$ end if Canvas.Color$ = color$ end function 'saves the color code in the RGB structure for using in API functions sub Canvas.SetPColor pColor Canvas.RGB.pColor.struct = pColor end sub 'returns the saved API color code from the RGB structure function Canvas.GetPColor() Canvas.GetPColor = Canvas.RGB.pColor.struct end function 'saves the fillColor code in the RGB structure for using in API functions sub Canvas.SetFillColor fillColor Canvas.RGB.fillColor.struct = fillColor end sub 'returns the saved API fillcolor code from the RGB structure function Canvas.GetFillColor() Canvas.GetFillColor = Canvas.RGB.fillColor.struct end function 'sets a pixel on the given position sub Canvas.Point x, y handle$ = Canvas.GetHandle$() #handle$ "set "; x; " "; y end sub 'draws a line from the current position to the x2 and y2 position sub Canvas.LineTo x2, y2 handle$ = Canvas.GetHandle$() call Canvas.GetPos x1, y1 #handle$ "line "; x1; " "; y1; " "; x2; " "; y2 end sub 'draws a line sub Canvas.Line x1, y1, x2, y2 handle$ = Canvas.GetHandle$() #handle$ "line "; x1; " "; y1; " "; x2; " "; y2 end sub 'draws a box shape filled or not filled sub Canvas.Box x1, y1, x2, y2, filled call Canvas.Place x1, y1 handle$ = Canvas.GetHandle$() if filled then #handle$ "boxfilled "; x2; " "; y2 else #handle$ "box "; x2; " "; y2 end if end sub 'draws a rectangle with the box shape command, but now with the given width and height and filled or not filled sub Canvas.Rectangle x, y, w, h, filled call Canvas.Place x, y handle$ = Canvas.GetHandle$() if filled then #handle$ "boxfilled "; x + w; " "; y + h else #handle$ "box "; x + w; " "; y + h end if end sub 'draws a circle shape filled or not filled sub Canvas.Circle x, y, r, filled call Canvas.Place x, y handle$ = Canvas.GetHandle$() if filled then #handle$ "circlefilled "; r else #handle$ "circle "; r end if end sub 'draws an ellipse shape filled or not filled sub Canvas.Ellipse x, y, w, h, filled call Canvas.Place x, y handle$ = Canvas.GetHandle$() if filled then #handle$ "ellipsefilled "; w; " "; h else #handle$ "ellipse "; w; " "; h end if end sub 'sets a horizontal scrollbar on or off and sets the min and max values for scrolling the clientview sub Canvas.HScrollBar visible, min, max, withMinMax handle$ = Canvas.GetHandle$() if visible then if withMinMax then #handle$ "horizscrollbar on "; min; " "; max else #handle$ "horizscrollbar on" end if else #handle$ "horizscrollbar off" end if end sub 'sets a vertical scrollbar on or off and sets the min and max values for scrolling the clientview sub Canvas.VScrollBar visible, min, max, withMinMax handle$ = Canvas.GetHandle$() if visible then if withMinMax then #handle$ "vertscrollbar on "; min; " "; max else #handle$ "vertscrollbar on" end if else #handle$ "vertscrollbar off" end if end sub 'this sub retrieves the current position sub Canvas.GetPos byref x, byref y handle$ = Canvas.GetHandle$() #handle$ "posxy x y" end sub 'this function returns the Device Context for API drawing functions function Canvas.GetDC() hWnd = Canvas.GetHWnd() on error goto [error] calldll #user32, "GetDC",_ hWnd as long,_ hDC as long Canvas.GetDC = hDC exit function [error] Canvas.GetDC = -1 end function 'this function returns the pixel color with the given position 'don't forget to return the Device Context first, before you use this function function Canvas.GetPixel(hDC, x, y) on error goto [error] calldll #gdi32, "GetPixel",_ hDC as long,_ x as long,_ y as long,_ pColor as long Canvas.GetPixel = pColor exit function [error] Canvas.GetPixel = -1 end function 'this sub sets a pixel with the given position and color 'don't forget to return the Device Context first, before you use this sub sub Canvas.SetPixel hDC, x, y, pColor on error goto [error] calldll #gdi32, "SetPixel",_ hDC as long,_ x as long,_ y as long,_ pColor as long,_ r as long exit sub [error] end sub 'this sub disposes the Device Context 'you must always release the DC if you don't use the API methods anymore sub Canvas.ReleaseDC hDC on error goto [error] hWnd = Canvas.GetHWnd() calldll #user32, "ReleaseDC",_ hWnd as long,_ hDC as long,_ r as long exit sub [error] end sub 'this sub draws the standard Pie from the pie command with the rounding problem sub Canvas.Pie x, y, w, h, angle1, length, filled handle$ = Canvas.GetHandle$() call Canvas.Place x, y if filled then #handle$ "piefilled "; w; " "; h; " "; angle1; " "; length else #handle$ "pie "; w; " "; h; " "; angle1; " "; length end if end sub 'this sub draws a Pie with the calculated lines without the rounding problem 'to fill this shape, use the FloodFill commands (via stack, queue or API) sub Canvas.PieAngle size, x, y, width, height, start, ending call Canvas.Size size if ending < 0 then angle = 360 else angle = 0 for i = start to angle + ending w1 = i * Canvas.RD.struct if i = start then x1 = int(x + width * cos(w1)) y1 = int(y - height * sin(w1)) call Canvas.Line x, y, x1, y1 else x2 = int(x + width * cos(w1)) y2 = int(y - height * sin(w1)) call Canvas.Line x1, y1, x2, y2 x1 = x2 y1 = y2 end if next i call Canvas.LineTo x, y end sub 'this sub draws an arc with a given radius sub Canvas.Arc size, x, y, width, height, start, ending call Canvas.Size size if ending < 0 then angle = 360 else angle = 0 for w = start to angle + ending w1 = w * Canvas.RD.struct if w = start then x1 = int(x + width * cos(w1)) y1 = int(y - height * sin(w1)) else x2 = int(x + width * cos(w1)) y2 = int(y - height * sin(w1)) call Canvas.Line x1, y1, x2, y2 x1 = x2 y1 = y2 end if next end sub 'this FloodFill uses the recursive stack technique to fill a shape sub Canvas.FloodFill hDC, x, y, target, replacement color = Canvas.GetPixel(hDC, x, y) if color <> target then exit sub end if if color <> replacement then call Canvas.SetPixel hDC, x, y, replacement call Canvas.FloodFill hDC, x, y + 1, target, replacement call Canvas.FloodFill hDC, x, y - 1, target, replacement call Canvas.FloodFill hDC, x - 1, y, target, replacement call Canvas.FloodFill hDC, x + 1, y, target, replacement end if end sub 'this FloodFill uses the queue technique with a list as a string sub Canvas.FloodFillQueue hDC, x, y, target, replacement '1. Set Q to the empty queue or stack. '2. Add node to the end of Q. Q$ = x; ","; y; ";" nx = 0 ny = 0 '3. While Q is not empty: while len(Q$) > 0 scan '4. Set n equal to the first element of Q. call Canvas.GetCoord Q$, nx, ny '5. Remove first element from Q. Q$ = Canvas.PopCoord$(Q$) '6. If n is Inside: ' Set the n ' Add the node to the west of n to the end of Q. ' Add the node to the east of n to the end of Q. ' Add the node to the north of n to the end of Q. ' Add the node to the south of n to the end of Q. if Canvas.GetPixel(hDC, nx, ny) = target then call Canvas.SetPixel hDC, nx, ny, replacement Q$ = Q$; (nx - 1); ","; ny; ";" Q$ = Q$; (nx + 1); ","; ny; ";" Q$ = Q$; nx; ","; (ny - 1); ";" Q$ = Q$; nx; ","; (ny + 1); ";" end if '7. Continue looping until Q is exhausted. wend '8. Return. end sub 'this FloodFill uses the API function 'use the filltype constants for how to fill the shape sub Canvas.FloodFillAPI hDC, x, y, fillcolor, filltype calldll #gdi32, "ExtFloodFill", _ x as long, _ y as long, _ fillcolor as long, _ filltype as ulong, _ r as long end sub 'this sub draws a Polygon shape with the queue technique sub Canvas.PolyShape size, x, y, Q$, color$ call Canvas.SetPen size, color$ call Canvas.Place x, y nx = 0 ny = 0 while len(Q$) > 0 call Canvas.GetCoord Q$, nx, ny Q$ = Canvas.PopCoord$(Q$) call Canvas.LineTo nx, ny wend call Canvas.LineTo x, y end sub 'this sub draws lines from the current position continue to the next position with the queue string sub Canvas.ContinueLine Q$, size, color$ call Canvas.SetPen size, color$ nx = 0 ny = 0 while len(Q$) > 0 call Canvas.GetCoord Q$, nx, ny Q$ = Canvas.PopCoord$(Q$) call Canvas.LineTo nx, ny wend end sub 'places an image by the given position sub Canvas.DrawBmp bmpName$, x, y handle$ = Canvas.GetHandle$() #handle$ "drawbmp "; bmpName$; " "; x; " "; y end sub 'sets the bitmap image picked from the clientview by a given position, width and height sub Canvas.SetBmp bmpName$, x, y, w, h handle$ = Canvas.GetHandle$() #handle$ "getbmp "; bmpName$; " "; x; " "; y; " "; w; " "; h end sub