The Liberty Basic Newsletter - Issue #91 - JUL 2001

© 2003, http://groups.yahoo.com/group/lbnews/

All Rights Reserved

Individual authors retain copyrights to their works.

"Keeping you up to date with the LB community!"

In this issue:

Liberty BASIC News
Liberty BASIC 3.0 Progress
Programmers Spotlight on Alyce Watson
The 6 Steps of Game Design

Liberty BASIC Mouse Commands by Ben Jimnez
Changing the background color of a bmpbutton
Code Snippits
LB Websites

 


 

For Next Month's Issue

-New to LB
-Liberty BASIC 3.0 Progress
-Custom-made Common Controls in Liberty BASIC, by Bubba
-Command Parsing for a Scripting Language, by Bubba



 

Liberty BASIC News

-ATTENTION! If you are new to the Liberty BASIC community, or new to Liberty BASIC programming in general, then we want to hear about it! Starting next month, the newsletter will have a new section called "New To LB". It will feature a short bio of each new programmer that has joined the community durring the month, including what got them into LB programming, and why they like it to use it. Stay tuned! -Well, the 2001, A Liberty BASIC Odyssey contest is almost over. Entry deadlines have been extended to allow more people to enter the contest. The final deadline might be by the end of this month, but could be extended even further if needed.



 

Liberty BASIC 3.0 Alpha Progress

A great deal of progress is being made by the current testers of the latest alpha version of Liberty BASIC. Everything is going good and when bugs are reported Carl gets to fixing them. When LB 3.0 is offically released expect some 32 bit calls already translatted because of the fine work of the beta testers.


 


Programmers Spotlight on Alyce Watson

[Alyce Watson.] I had no programming experience at all prior to learning Liberty BASIC. I worked my way through the six week course of tutorials that come with LB. Then I tried modifying the sample programs. After that, it was time to try to write my own first program. That blank screen is very intimidating! I had recently watched my son, Thomas, write a hangman game in QBasic, so I thought I'd try that. He had to help me A LOT! He still likes to remind me how lost I was in the beginning whenever I tried to use an array. He was the best teacher and helper anyone could have.

After that first program, I felt a little more comfortable and started trying more and more things. It took me several months to get the nerve to try anything with API calls. Back then, in 1997, there were very few online resources for LB. The two biggest helps were the Liberty BASIC Programmer's Journal by Ryan Jeffords, and Carl Gundel's email list. I was far too shy to write to the list for a long time, but I learned a lot from reading the messages. Ryan was very encouraging also. Did I mention that back then I was 45 years old? See, you CAN teach an old dog new tricks! It took a character named Brosco to pull me out of my shell. By the time he joined, when I'd been involved in LB for nearly a year, I had gathered up the courage to place some code online on my son's website, and I also occassionally wrote messages to the email list. Brosco was a retired career programmer, and he thought I showed some potential, but that I needed a bit of guidance. (Does the term "spaghetti code" sound familiar?) Brosco wrote to me quite patiently over a period of several months, and he finally brought me out of my shell. My website, Alyce's Restaurant, was done because he pestered me to do it. He also started Side by Side Software, a site for the projects we did together. He also started the newsletter with my help in April, 1998. I will soon celebrate the start of my second "half century". It is a testimonial to Carl Gundel, Liberty BASIC and to the generous and friendly online community that a middle-aged person who knew nothing at all about programming, could learn so much and have so much fun!

 


 

The 6 Steps of Game Design by Tegan Snyder

If you are trying to start designing a game in Liberty BASIC you may find your-self running into little problems every now and then, but when you have achieved success the feeling is great. I will go in detail on all subjects about LB Game
Programming.
Step 1 - Design a brief outline or sketch up for your game. This will help you relate to your material when you need ideas.

Step 2 - Workup Graphics for Game Use a freeware graphics program such as Paint Shop Pro, or try out any of the trial products Macromedia has to to offer. Start of by Designing a logo for your game and then make buttons for specific areas. Once finished draw sprites out, or if your not a artist you can use royalty free sprites from lboutpost.com

Step 3 - Decide Window Type Is your game going to be full screen, full screen window popup, or a specific window size.

Step 4 - Start the Coding. Begin coding your game. After you make changes make sure you run it to make sure everything works. If you need to test certain parts you can always make a new .bas file and try it out.

Step 5 - Testing Game. When your game is done you will need to make sure all parts work. You alone may not be able to test your game to full extent. Believe me once you get a few testers they can find problems you never had seen.

Step 6 - Freeware/Non-Freeware The final choice is based on your decision. It also should depend on how much time you put into the game and its graphics. Freeware is always a good idea if you have recieved a lot of help from the community, but If hours of time were spent and the game has the possibility to make some money what the heck.

 


 

Liberty BASIC Mouse Commands by Ben Jimnez

Most Liberty BASIC windows support the mouse commands, but in most cases you will find you'll want to use the mouse commands when using the ever popular graphic window. When using the mouse commands with a graphic window you don't have to be programming a game, just any type of program where mouse support is needed.

The examples displayed in this write up will not be about any paticular type of program, but will just be examples of how to use the mouse commands in different situations. The avaliable mouse commands are listed below. Notice that
Liberty BASIC provides a command for almost every possible click you can make with your mouse (theres even one for no click!), these commands are more then enough to help you with any mouse support you may need. There is even a character command that can be used to capture any keys pressed on the keyboard. Make sure your window has the focus when using this command or you will not get the results you expect.

Liberty BASIC Mouse Commands

leftButtonDown- the left mouse button is now down
leftButtonUp - the left mouse button has been released
leftButtonMove- the mouse moved while the left button is down
leftButtonDouble- the left button has been double-clicked
rightButtonDown- the right mouse button is now down
rightButtonUp- the right mouse button has been released
rightButtonMove- the mouse moved while the right button is down
rightButtonDouble- the right button has been double-clicked
mouseMove- the mouse moved when no button was down
characterInput- a key was pressed while the graphics window has
input focus (see the setfocus command, above)

 

Now first understand that when you talk about using mouse commands in your program with other Liberty BASIC users the proper way to describe using the mouse is to say mouse event, so from here on we call them mouse events. Here is a common event used in a program.

 

PRINT #MAIN,"when leftButtonDown [branch.name]";

When you use this command you are telling Liberty BASIC that when the user clicks the left mouse button, and when that button is in the down position, go to the branch label shown in the brackets.What happens once your program executes the branch is up to you, you could have it display a notice window, draw something, check if your mouse is over a certain x y location, change the background color of your window or anything else you want to do. There are no restrictions on you when your branch in executed. Here is an example showing the use of the command above.

 

nomainwin
open "Mouse Test" for graphics as #test
       PRINT #test,"when leftButtonDown [where.am.i]"; 
[main.loop]
       wait
[where.am.i]
       notice "Current MouseX is ";MouseX;" and current MouseY is        ";MouseY
       goto [main.loop]


In this example we used the mouse event leftButtonDown, and we said when the left mouse button is pressed and in the down position go to branch label [where.am.i]. This event will be triggered every time you press the left mouse button. How would you stop this event from happening? Good question. the proper way to end a mouse event is to call the event with no branch label inserted into the command, like this

 

PRINT #test,"when leftButtonDown";

 

This tells Liberty BASIC to do nothing when this event happens, so in simple terms you are turning off support for this mouse event, but this is ok because you can always turn it back on! You may have noticed that I used two other commands in my program that gave us the X Y location of your mouse. The commands MouseX and MouseY are commands that are only usable with your mouse events. They simply give you the ability to know where the mouse
is when an event is executed.

       MouseX----------------H Is the Horizontal position of the mouse
       MouseY
       |
       |
       |
       |
       V Is the Vertical position

 

You can use the MouseX and MouseY commands to aid you in locating the current position of the mouse pointer. In our next example we will draw a box in a graphic window and use the mouseMove command to determine if the mouse pointer has moved over the box.

 

nomainwin
       'Open our window
       Open "Mouse test 2" for graphics_nsb as #test
       'place pen at starting position of box
       print #test,"place 100 100;down";
       'draw our box
       print #test,"backcolor white;boxfilled 200 200;flush";
       'send mouse event command
       print #test,"when mouseMove [mouse.move]"
       [main.loop]
wait
[mouse.move]
       if MouseX >=100 and MouseX <=200 and MouseY >=100 and MouseY <=200        then
       print #test,"backcolor red;boxfilled 200 200;flush"
       else
       print #test,"backcolor white;boxfilled 200 200;flush"
       end if
goto [main.loop]


In the above example we've added a line that makes it easy to determine if your mouse is over a certain area of your graphic window.

 

penX boxX penY boxY
       if MouseX >=100 and MouseX <=200 and MouseY >=100 and MouseY <=200        then

 

 

100x100---------------------- 100x100 is the current pen postion
       |                    | 100 accross X by 100 down Y
       |                    |
       |                    |
       |                    |
       |                    |
       |                    |
       |                    | 
       |                    |
       |                    |
       |                    |
       ----------------------200x200 is the current box bottom right corner
                                     200 accross X by 200 down Y

 

By using <>= and the AND comand we can determine if our mouse is anywhere within the 10,000 point pixel range that our box covers. When you think of how many points in our box are being checked it's a wonder that it's
done so fast!

 

Now let's break down our new line,

 

IF MouseX >=100 and <=200 and MouseY >=100 and MouseY <=200 then

 

Liberty BASIC checks to see if the MouseX is at a position greater then the upper left corner of our box (100), and is less then the upper right corner of our box (200). At the same time Liberty BASIC checks to see if MouseY is at a postion lower then the upper left corner of our box (100) and less then the lower corner of our box (200). If all are true then the THEN part of our line is executed. This is the simplest way to track your mouse, as you learn to use the mouse commands and Liberty BASIC you may require more advanced mouse tracking techniques. Our last example is an example of how to compare your MouseX and MouseY to more then one objects XY positon using arrays. As you might already know, arrays are used to store data in memory for quick access by your program. Below is an example of how to determine which box our mouse is over by searching through our arrays and comparing the current MouseX and MouseY to the positions of each box.

 

nomainwin
'dim arrays
       dim xPlc(3)
       dim yPlc(3)
       dim xLoc(3)
       dim yLoc(3)
'set width and height of our boxes
       width=100
       height=100
'fill array
       'box 1
       xPlc(1)=100:yPlc(1)=120:xLoc(1)=200:yLoc(1)=220
       'box 2
       xPlc(2)=10:yPlc(2)=10:xLoc(2)=110:yLoc(2)=110
       'box 3
       xPlc(3)=190:yPlc(3)=10:xLoc(3)=290:yLoc(3)=110
'Open our window
       Open "Mouse test 2" for graphics_nsb as #test
'send mouse event command
       print #test,"when mouseMove [mouse.move]"
       print #test,"down"
[main.loop]
       print #test,"place 10 300;\ ";
       print #test,"place 10 300;backcolor white;\";MouseX;"x";MouseY
       wait
[mouse.move]
       for x=1 to 3
       if MouseX >=xPlc(x) and MouseX <=xLoc(x) and MouseY >=yPlc(x) and        MouseY<=yLoc(x) then
       print #test,"backcolor red;place ";xPlc(x);" ";yPlc(x);";boxfilled        ";xLoc(x);" ";yLoc(x);";flush"
       else
       print #test,"backcolor white;place ";xPlc(x);" ";yPlc(x);";boxfilled        ";xLoc(x);" ";yLoc(x);";flush"
       end if
       next x
goto [main.loop]




Changing the Background of a BmpButton by Alyce Watson

A bmpbutton with a lightgray background looks odd when a different color scheme is in use on a computer... like Maple, Brick Desert or Eggplant. This method allows the button to look "right" on any system. Try setting your desktop color scheme to an alternate one and run a program with a gray bmpbutton. Then run this program and see the difference. Most of the bitmaps in Liberty BASIC's bmp folder have the standard lightgray background color. The API calls needed to evaluate the colors require color values as "long" types. To create a "long" color value, we must multiply the blue value by 256^2, which is 256*256, or 65536. The green value must be multiplied by 256. The red value is used as is. Each of the color values, red, green and blue, must be in the range of 0-255. 0 means an absense of the color, while 255 indicates a total saturation or the color. 0 0 0 is the RGB for black, while 256 256 256 is the RGB for white. Pure red is 255 0 0. Pure blue is 0 0 255 and so on. Determine a long color value with this equation:

 

 longColor = (blue*256*256) + (green*256) + red

 

The lightgray color that forms the background of most bmpbutton images is RGB 192 192 192. To discover the long value for this RGB combination, do the math as above:

 

gray = (192*256*256) + (192*256) + 192 

 

Now we know which color to change when we encounter it in the image. Next we need to know the color to change it TO. We can do this with an API call to get the user's desktop color scheme value for "buttonface". We'll set up a function to "wrap" the API call. We'll use the index of the color to query as an input parameter, and we'll return the color value of the index. The function to call is GetSysColor, which is part of "user.dll".

 

Function GetSysColor(nIndex)
       open "user" for dll as #u
       calldll #u, "GetSysColor",_
       nIndex as word,_
       sysColor as long
       close #u
       GetSysColor=sysColor
       End Function

The index for the buttonface color is 15. We can discover this value by checking in the win32api.txt file. We needn't know the actual value, though. Liberty BASIC will evaluate most of the Windows constants for us. To use a Windows constant, we place an underscore character in front of it. The LB version of the constant for the buttonface color is: _COLOR_BTNFACE Here is how we call our function. After this call, the value of the system buttonface color is in the variable called "new":

 

new=GetSysColor(_COLOR_BTNFACE) 

 

Let's first set up a window to contain our bmpbutton. We'll include a bmpbutton (duh!) and a statictext to give the user messages. The first message is "PLEASE WAIT!!!" because we'll need to do some memory manipulations before the new bmpbutton image is ready to show. We'll also make the cursor into an hourglass as an additional warning to the user:

 

 WindowWidth=200:WindowHeight=150
       statictext#1.s, "PLEASE WAIT!!!",10,10,200,30
       bmpbutton #1.b, "bmp\copy.bmp",[huh],UL,10,50
       open "BmpButton Change" for window_nf as #1
       print #1, "trapclose [quit]"
CURSOR HOURGLASS

 

We used the "copy.bmp" in the LB bmp folder for this demo. In addition to using it in the bmpbutton command, we'll load it with "loadbmp" and give it the name "copy". 'bmp to change:

 

loadbmp "copy","bmp\copy.bmp"

 

We'll want the handle of this bmp so that we can manipulate it with API calls. Note that the manipulations only alter
the image in memory, NOT the disk file of the image. To get the handle, use the HBMP() function:

 

hCopy=hbmp("copy")

 

We could open our bitmap in MS Paint and get the width and height. We need to know these dimensions to maniplate the bitmap colors. We can also get the width and height from within the program. We use the structure for a BITMAP, which is as follows:

 

 struct BITMAP,_ '14 bytes
       bmType as short,_
       bmWidth As short,_
       bmHeight As short,_
       bmWidthBytes As short,_
       bmPlanes as short,_
       bmBitsPixel as short,_
       bmBits as short
 

With the bitmap handle as a parameter, we use the GDI function to GetObject to fill the BITMAP structure:

 

 open "gdi" for dll as #g
       calldll #g, "GetObject", hBitmap as word,_
       14 as short,BITMAP as struct,_
       results as short
       close #g

 

After making the call to GetObject, the width of the bitmap will be contained in the BITMAP struct member "bmWidth", which we retrieve like this:

 

width=BITMAP.bmWidth.struct

 

Again, we'll use an LB function to "wrap" the API calls. We'll set up a function to get the width and a separate function to get the height. Here are the two functions, which require the handle of the bitmap as an input parameter, and return the dimension:

 

Function WidthBitmap(hBmp)
       open "gdi" for dll as #g
       calldll #g, "GetObject", hBmp as word,_
       14 as short,BITMAP as struct,_
       results as short
       WidthBitmap=BITMAP.bmWidth.struct
       close #g
       End Function
Function HeightBitmap(hBmp)
       open "gdi" for dll as #g
       calldll #g, "GetObject", hBmp as word,_
       14 as short,BITMAP as struct,_
       results as short
       HeightBitmap=BITMAP.bmHeight.struct
       close #g
       End Function

To call our functions and place the width into the variable "bw" and the height into the variable "bh":

 

bw=WidthBitmap(hCopy)
       bh=HeightBitmap(hCopy)

 

Everything up until now has been pretty straight-forward. Now it gets a little more complicated, BUT NOT TOO HARD, so read on. We'll need to create a memory device context to manipulate the bitmap. A device context is a bit of information that Windows maintains about your hardware (printer, display monitor). You give instructions to the device context, and Windows takes care of sending the instructions to your hardware. This is the heart of the Graphics Device Interface, or GDI. Without this interface, the program would have to know how to communicate with each individual monitor type, and that could get complicated very quickly! Before we create a memory device context, we must GetDC, or get a device context for our window. This is extremely easy. Here is an LB function that wraps the GetDC function. It takes in the window handle as a parameter, and returns a device context for the window:

 

function GetDC(hWnd)
       open "user" for dll as #u
       calldll #u, "GetDC",hWnd as word,hDC as short
       close #u
       GetDC=hDC
       end function

 

When we no longer need the device context, we must release it from memory with a call to ReleaseDC. Here is the LB sub that wraps the ReleaseDC function. (It doesn't require a return value, so we've made it a sub, not a function.) It requires input parameters of the window handle, and DC handle:

 

sub ReleaseDC hWnd, hDC
       open "user" for dll as #u
       calldll#u,"ReleaseDC",hWnd as word,_
       hDC as word,result as ushort
       close #u
       end sub

To call our function and get the DC of the window, we first obtain the window handle with LB's HWND() function:

 

h=hwnd(#1)

 

We then call our GetDC function, placing our window DC into the var "hDC":

 

hDC=GetDC(h)

 

After we've finished with it, we will call our ReleaseDC sub:

 

call ReleaseDC h,hDC

 

Now we can create a compatible DC for memory manipulations. This is another really easy function. It requires an input parameter of the window DC, and returns the handle of the memory DC:

 

function CreateCompatibleDC(hDC)
       open "gdi" for dll as #g
       calldll #g,"CreateCompatibleDC", hDC as word,_
       hDCmemory as word
       close #g
       CreateCompatibleDC=hDCmemory
       end function

 

When we no longer need the memory DC, we delete it with a call to DeleteDC. Here is the LB sub which wraps the DeleteDC function. It requires a single input parameter, which is the handle of the memory DC.

 

sub DeleteDC hDC
       open "gdi" for dll as #g
       calldll #g, "DeleteDC",hDC as word, r as void
       close #g
       end sub
 

To call our function to create a memory DC, and place the DC handle into the varialbe "hMem":

 

hMem=CreateCompatibleDC(hDC)

 

When it is no longer needed, we call our DeleteDC sub like this:

 

call DeleteDC hMem

 

DON'T GIVE UP NOW... WE'RE ALMOST DONE! To manipulate our bitmap, we first select it into our memory DC with SelectObject. Once the bitmap is selected into the memory DC, the instructions we send to the DC will be carried out on the bitmap. Here is our LB function wrapper for SelectObject, which requires input parameters of the memory DC handle, and the handle of the bitmap:

 

function SelectObject(hDC,hObject)
       open "gdi" for dll as #g
       calldll #g,"SelectObject",hDC as word,_
       hObject as word,result as word
       close #g
       SelectObject=result
       'returns previously selected object
       end function

 

To call our function, we do this. Note that we don't need to use the return from the function:

 

ret=SelectObject(hMem,hCopy)

 

The actual routine to change the background color is easy to understand. We'll evaluate each pixel in turn. If the pixel is the lightgray color in our variable called "gray", then we'll change it to the system buttonface color which is in our variable called "new". This requires two API calls. One is to GetPixel, which retrieves the color of the pixel. The other is to SetPixel, which sets the color of a pixel to be the color specified. Here is the LB function wrapper for GetPixel. It requires input parameters of the DC handle, and the x,y location of the pixel to query. It returns the long color value of the specified pixel:

 

function GetPixel(hDC,x,y)
       open "gdi" for dll as #g
       calldll #g, "GetPixel", hDC AS short,_
       x AS short,y AS short, RESULT AS long
       Close #g
       GetPixel=RESULT
       end function

 

We call our function like this, placing the value into a var called "col":

 

col=GetPixel(hMem,i,j)

 

We've created a sub to set the color of a pixel. It requires input parameters of the DC, the x,y location and the desired long color value:

 

sub SetPixel hDC,x,y,color
       open "gdi" for dll as #g
       calldll#g,"SetPixel",hDC as word,_
       x as short,y as short,color as long,_
       result as long
       close #g
       end sub

 

We'll call it like this:

 

call SetPixel hMem,i,j,new

 

The actual routine that changes the background color follows. It consists of a nested loop. The outer loop goes through the x values from 0 to (bitmap width - 1). Since we start the evaluation at 0, the last pixel is actually the width of the bitmap minus 1. The inner loop does the same thing for the y values, so we'll have accessed each x,y combination of pixel locations when we are done.

 

for i = 0 to bw-1
       for j = 0 to bh-1
       'code here
       next j
       next i

 

The method we use gets the color of a pixel. If the color is equal to the lightgray color, then we call SetPixel to change it
to the system buttonface color. If it is not the lightgray color, then we leave it alone and move on to the next pixel:

 

 col=GetPixel(hMem,i,j)
       if col=gray then
       call SetPixel hMem,i,j,new
       end if

 

The entire routine that changes the background color:

 

for i = 0 to bw-1
       for j = 0 to bh-1
       col=GetPixel(hMem,i,j)
       if col=gray then
       call SetPixel hMem,i,j,new
       end if
       next j
       next i


WHEW! We're done with the hard part. Let's give the user a message that he can now click the button to see the background color change, and let's also change the cursor back to its normal appearance.

 

print #1.s, "Click button to change."
       CURSOR NORMAL
       wait

 

Believe it or not, when we use Liberty BASIC commands to draw the bitmap that we have named "copy" it will now be
the one we changed with API calls. If we draw it in a graphicbox, like this, it will be the changed version:

 

print #win.graphicbox, "drawbmp copy 10 10"

 

We're not drawing it with DRAWBMP, though. We're using the bitmap buttons "Bitmap" command to change the image on a bmpbutton to be the loaded bmp that is referenced. In this case, our loaded bmp is called "copy".

 

print #1.b, "bitmap copy"

 

When the user clicks the button, the button will change appearance to match the system colors. Note that you won't notice any change at all if your system is set up with the standard Windows desktop color scheme, so you might want to change your color scheme to see this work.

 

When we close the program, we need to unload the bitmap, close the window, and issue the END command:

 

unloadbmp("copy")
       close #1:end

 

What follows is the complete source code for the program. Run it from your Liberty BASIC root directory, so that it knows where to find "bmp\copy.bmp" (look below in the Code Snippits section)

 


Code Snippits

(bbtncol.bas) - by Alyce Watson - alycewatson@charter.net
Code to changed the background color of a BmpButton to a system color

 

nomainwin
       gray=(192*256*256)+(192*256)+192 'default lightgray bg color
       new=GetSysColor(_COLOR_BTNFACE) 'system buttonface color
 struct BITMAP,_ '14 bytes
       bmType as short,_
       bmWidth As short,_
       bmHeight As short,_
       bmWidthBytes As short,_
       bmPlanes as short,_
       bmBitsPixel as short,_
       bmBits as short
WindowWidth=200:WindowHeight=150
statictext#1.s, "PLEASE WAIT!!!",10,10,200,30
       bmpbutton #1.b, "bmp\copy.bmp",[huh],UL,10,50
       open "BmpButton Change" for window_nf as #1
       print #1, "trapclose [quit]"
CURSOR HOURGLASS
'bmp to change:
       loadbmp "copy","bmp\copy.bmp"
       hCopy=hbmp("copy")
       bw=WidthBitmap(hCopy)
       bh=HeightBitmap(hCopy)
'get DC of window:
       h=hwnd(#1)
       hDC=GetDC(h)
'create compatibleDC for memory manipulations
       hMem=CreateCompatibleDC(hDC)
'select bmp into memdc
       ret=SelectObject(hMem,hCopy)
'change background color:
       for i = 0 to bw-1
       for j = 0 to bh-1
       col=GetPixel(hMem,i,j)
       if col=gray then
       call SetPixel hMem,i,j,new
       end if
       next j
       next i
call ReleaseDC h,hDC
       call DeleteDC hMem
print #1.s, "Click button to change."
CURSOR NORMAL
       wait
[huh]
       print #1.b, "bitmap copy"
       wait
[quit]
       unloadbmp("copy")
       close #1:end
'****functions:
function GetPixel(hDC,x,y)
       open "gdi" for dll as #g
       calldll #g, "GetPixel", hDC AS short,_
       x AS short,y AS short, RESULT AS long
       Close #g
       GetPixel=RESULT
       end function
sub SetPixel hDC,x,y,color
       open "gdi" for dll as #g
       calldll#g,"SetPixel",hDC as word,_
       x as short,y as short,color as long,_
       result as long
       close #g
       end sub
function GetDC(hWnd)
       open "user" for dll as #u
       calldll #u, "GetDC",hWnd as word,hDC as short
       close #u
       GetDC=hDC
       end function
sub ReleaseDC hWnd, hDC
       open "user" for dll as #u
       calldll#u,"ReleaseDC",hWnd as word,_
       hDC as word,result as ushort
       close #u
       end sub
function SelectObject(hDC,hObject)
       open "gdi" for dll as #g
       calldll #g,"SelectObject",hDC as word,_
       hObject as word,result as word
       close #g
       SelectObject=result
       'returns previously selected object
       end function
function CreateCompatibleDC(hDC)
       open "gdi" for dll as #g
       calldll #g,"CreateCompatibleDC", hDC as word,_
       hDCmemory as word
       close #g
       CreateCompatibleDC=hDCmemory
       end function
sub DeleteDC hDC
       open "gdi" for dll as #g
       calldll #g, "DeleteDC",hDC as word, r as void
       close #g
       end sub
Function GetSysColor(nIndex)
       open "user" for dll as #u
       calldll #u, "GetSysColor",_
       nIndex as word,_
       sysColor as long
       close #u
       GetSysColor=sysColor
       End Function
Function WidthBitmap(hBmp)
       open "gdi" for dll as #g
       calldll #g, "GetObject", hBmp as word,_
       14 as short,BITMAP as struct,_
       results as short
       WidthBitmap=BITMAP.bmWidth.struct
       close #g
       End Function
Function HeightBitmap(hBmp)
       open "gdi" for dll as #g
       calldll #g, "GetObject", hBmp as word,_
       14 as short,BITMAP as struct,_
       results as short
       HeightBitmap=BITMAP.bmHeight.struct
       close #g
       End Function


 
      


(movewin.bas) - by Alyce Watson, modified by Bubba
Code to create a custom titlebar that moves a window that doesn't have the standard Windows titlebar

 

[start]
       WindowWidth = 450
       WindowHeight = 520
       nomainwin
       UpperLeftX = 170
       UpperLeftY = 20
       BackgroundColor$ = "darkblue"
       titleText$ = "Custom Titlebar Example"
open "user" for dll as #user
       graphicbox #help.titlebar, 2, 2, 446, 20
       bmpbutton #help.exit, "exit.bmp", [exit], UR, 5, 4
       bmpbutton #help.minimize, "minimize.bmp", [minimize], UL, 5, 4
       graphicbox #help.view, 2, 90, 446, 428
       open titleText$ for window_popup as #help
       print #help, "trapclose [exit]"
       print #help.titlebar, "when leftButtonDown [start.move]"
       hHelp = hwnd(#help)
       gosub [redraw.titlebar]
[wait]
       wait
       goto [wait]
[minimize]
       calldll #user, "CloseWindow", hHelp as word, re as void
       goto [wait]
[start.move]
       print #help.titlebar, "when leftButtonMove [move]"
       print #help.titlebar, "when leftButtonUp [stop.move]"
       offsetX = MouseX
       offsetY = MouseY
       goto [wait]
[move]
       X = CursorPosX()
       Y = CursorPosY()
       if X - offsetX < 0 then origX = 0 else origX = X - offsetX
       if Y - offsetY < 0 then origY = 0 else origY = Y - offsetY
       call MoveWindow hHelp, origX, origY, 450, 520
       goto [wait]
[stop.move]
       print #help.titlebar, "when leftButtonMove [wait]"
       print #help.titlebar, "when leftButtonUp [wait]"
       goto [wait]
[exit]
       close #user
       close #help
       end
[redraw.titlebar]
       print #help.titlebar, "fill 114 211 252; flush; font ms_sans_serif        8 bold"
       print #help.titlebar, "backcolor 114 211 252; down; size 2"
       print #help.titlebar, "color white; line 0 0 450 0; line 0 0 0 20"
       print #help.titlebar, "color black; line 0 18 450 18; line 445 18 445        0"
       print #help.titlebar, "stringwidth? titleText$ lenTitle"
       if lenTitle<=446 then print #help.titlebar, "color black; place        ";abs(446-lenTitle)/2;" 13"
       if lenTitle>446 then print #help.titlebar, "color black; place ";abs(lenTitle-446)/2;"        13"
       print #help.titlebar, "|"; titleText$
       if lenTitle<=446 then
       print #help.titlebar, "size 1; line 2 4 ";abs(446-lenTitle)/2-2;"        4; line ";abs(446-lenTitle)/2+lenTitle+2;" 4 442 4"
       print #help.titlebar, "line 2 7 ";abs(446-lenTitle)/2-2;"        7; line ";abs(446-lenTitle)/2+lenTitle+2;" 7 442 7"
       print #help.titlebar, "line 2 10 ";abs(446-lenTitle)/2-2;"        10; line ";abs(446-lenTitle)/2+lenTitle+2;" 10 442 10"
       print #help.titlebar, "line 2 13 ";abs(446-lenTitle)/2-2;"        13; line ";abs(446-lenTitle)/2+lenTitle+2;" 13 442 13"
       end if
       print #help.titlebar, "flush"
       return
sub MoveWindow hWin, left, top, width, height
       if left<0 then left=0
       if top<0 then top=0
       calldll #user, "MoveWindow", hWin as short, left as short, top        as short, _
       width as short, height as short, 1 as short, _
       ret as short
       end sub
function CursorPosX()
       struct point, x as short, y as short
       calldll #user, "GetCursorPos", point as struct, ret as void
       CursorPosX = point.x.struct
       end function
function CursorPosY()
       struct point, x as short, y as short
       calldll #user, "GetCursorPos", point as struct, ret as void
       CursorPosY = point.y.struct
       end function




LB Websites

Liberty BASIC Outpost is back with new content and will soon be having new files. There is a Snippet Resource Center http://www.freecfm.com/t/tblb2/ be sure to share code snippets there.



Thank you for reading this months issue of the newsletter. I hope Andrew and I can bring a new issue to you for as long as we can. If you have any questions or if anything needs to be revised please email us at teg@tegdesign.com or andrew@britcoms.com and we will get back to you.


SUBMISSIONS

The Liberty BASIC Newsletter encourages all LB programmers to submit articles for publication. Everyone has something valuable to say, from beginners to veteran LBers. Consider sharing a code routine, with explanation. Perhaps you can review a favorite LB website, or program, or coding tool? Why not submit a list of questions that have been nagging at you? How about sharing your favorite algorithm?