Paths and File Names
Observed online
Resources for the beginner
Graphics Drawing Rules
beginner's guide to API and DLL
Drawing IN MEMORY
Radiobuttons via API
NumbWord
Working with Comboboxes
It is not currently possible to draw on a hidden graphicbox, then transfer the image from the hidden graphicbox to a visible graphicbox. If it were possible, it would be achieved by using GETBMP on the hidden graphicbox to get a named Liberty BASIC bitmap, then using DRAWBMP on that named bitmap to draw it into the visible box. Since this will not work, the alternative is to use GDI functions to do the drawing in memory.
Drawing with the Graphics Device Interface (GDI) is a subject that would easily fill an entire book. This tutorial is NOT a tutorial on drawing with GDI. It presents a method to draw in memory, then place the image on the screen in Liberty BASIC. It doesn't attempt to explain the individual GDI drawing functions.
It is assumed that the reader understands the fundamentals of making Windows API calls. For more information on making API calls, and for using GDI functions, please examine one of the many Windows API reference books that are available in libraries and bookstores, or check the Microsoft Developers Network Library here:
http://msdn.microsoft.com/library
You may also check my website and electronic books:
http://iquizme.0catch.com/lb/
http://iquizme.0catch.com/lb/lbw3/master.html
http://iquizme.0catch.com/lb/using/index.html
THE DEVICE CONTEXT
GDI doesn't draw on a window, it draws on a device context (DC). A DC is an
interface used by GDI so that Windows can draw on any of the variety of hardware
that might be installed on a computer. Windows can also draw on a memory device
context, and that is what we'll use for this method.
MEMORY DRAWING - STEP BY STEP
Here is an outline of the steps we'll be using.
- create a window with a graphicbox
- put the pen DOWN in the graphicbox
- use GetBmp to get a Liberty BASIC bitmap from the graphicbox
- obtain the handle of the graphicbox with the hwnd() function
- obtain the handle of the Liberty BASIC bitmap with the hbmp() function
- get a DC for the graphicbox with GetDC
- create a memory DC with CreateCompatibleDC
- select the LB bitmap into the memory DC with SelectObject
- issue GDI drawing commands to the memory DC
- select the default bitmap back into the memory DC, freeing the LB bitmap
- use DRAWBMP to display the bitmap in the graphicbox - flushing if desired
- as many times as needed, select the bitmap into the memory
DC, draw on it with GDI functions, deselect it from the memory DC and display
with DRAWBMP
When the program ends:
- delete the created DC with DeleteDC
- release the graphicbox DC with ReleaseDC
- delete the LB bitmap with UNLOADBMP
MEMORY DRAWING - THE THEORY
Using the GETBMP command allows us to get a named, Liberty BASIC bitmap that
we can display with DRAWBMP or save with BMPSAVE. We can get a Windows handle
to this bitmap with the HBMP() function. Once we have a Windows handle, we
can select the bitmap into a memory device context and use GDI functions to
draw on it. After deselecting the LB bitmap out of the memory device context,
we can draw the altered bitmap in our graphicbox with DRAWBMP or we can save
it to disk with BMPSAVE.
USING GDI - THE DISADVANTAGES
The most obvious disadvantage of drawing with GDI rather than using Liberty
BASIC's own drawing commands is that the API drawing functions are more complicated,
and they require device contexts to be gotten, created, released and
destroyed. Using GDI also requires that pens, brushes and fonts be created,
selected into the device context, and
destroyed when they are no longer needed.
USING GDI - THE ADVANTAGES
Using GDI functions allows us to draw in memory, which presents many possibilities,
such as flicker-free animation,
and the ability to draw many objects before allowing the user to view them.
In other words, the drawings can be
presented as a finished picture, and the user doesn't see each step as it
is drawn. There is one other big advantage
to using GDI functions. There are many more graphics possibilities with GDI
functions than with Liberty BASIC
drawing commands. There are functions to floodfill, to create other objects
such as arcs and round rectangles, to
draw text that is filled with patterns, to draw with different RASTER OPERATIONS
(this is how sprites are done)
and on and on.
DRAWING IN MEMORY - A SIMPLE SAMPLE
The following code will run in Liberty BASIC 3.x. It is well commented.
nomainwin 'graphicbox size includes borders, 'so requires 202x202 graphicbox to 'display a drawing area 200x200 graphicbox #1.g, 10,10,202,202 open "Memory Drawing" for window_nf as #1 #1 "trapclose [quit]" #1.g "down" 'use getbmp to get an LB bitmap #1.g "getbmp mem 0 0 200 200" h=hwnd(#1.g) 'handle of graphicbox hMem=hbmp("mem")'handle of LB bitmap 'get a device context for graphicbox CallDLL #user32, "GetDC",_ h As long,_ 'handle of graphicbox hDC As long 'returns device context 'create a device context in memory 'that has the same attributes as the 'device context for the graphicbox CallDLL #gdi32,"CreateCompatibleDC",_ hDC As long,_ 'device context of graphicbox memDC As long 'returns memory device context 'select the LB bitmap into the 'memory device context CallDLL #gdi32,"SelectObject",_ memDC As long,_ 'handle of memory DC hMem As long,_ 'handle of LB bitmap oldObject As long 'returns handle of previous 'bitmap in DC 'draw some graphics with GDI functions: CallDLL #gdi32, "Rectangle",_ memDC As long,_ 'memory DC 10 As long,_ 'upper left x 10 As long,_ 'upper left y 60 As long,_ 'lower right x 80 As long,_ 'lower right y r As boolean 'next call requires this struct struct Point, x as long, y as long 'same as LB's PLACE command CallDLL #gdi32, "MoveToEx",_ memDC As long,_ 'memory DC 40 As long,_ 'x 20 As long,_ 'y Point As struct,_ 'returns previous x and y r As boolean 'same as LB's GOTO command CallDLL #gdi32, "LineTo",_ memDC As long,_ 'memory DC 140 As long,_ 'x 70 As long,_ 'y r As boolean 'fill a string variable t$="Memory Drawing" 'get length of variable ln=len(t$) 'draw the text CallDLL #gdi32, "TextOutA",_ memDC As long,_ 'memory DC 10 As long,_ 'x location 130 As long,_ 'y location t$ As ptr,_ 'string of text ln As long,_ 'length of string r As long 'you must deselect the bitmap from 'the memory DC each time you want to 'display it with DRAWBMP ' 'select the previous bitmap back 'into the memory DC to do this CallDLL #gdi32,"SelectObject",_ memDC As long,_ 'memory DC oldObject As long,_ 'original bmp in memDC hMem As long 'returns bmp to deselect 'now, simply draw it with DRAWBMP 'and flush #1.g "drawbmp mem 0 0; flush" wait [quit] 'be sure to unload the bmp unloadbmp "mem" 'release the DC for the graphicbox CallDLL#user32,"ReleaseDC",_ h As long,_ 'graphicbox handle hDC As long,_ 'DC handle result As long 'delete the memory DC from memory CallDLL #gdi32, "DeleteDC",_ memDC As long,_ 'memory DC handle r As boolean close #1:end