  
                                      
 L       BBBBBB        N   NNN  EEEE  WW          WW  SSSSSSSS
 L       BB  BB       NNN  NNN  EE  EE  WW      WW SSS  
 L       BBBBBB      NNNNN NNN  EEEE  WW  WWWW  WW SSSS
 L             NNNNNNNNNN  EE  WW WWWWWW WW SS
 L       BBBBBB    NNNNNNNNNNN  EE        WWWWWWWWWWWW   SSSSS
 L BB  BB   NNNN NNNNNN  EE  WWWWWW  WWWWW SSSSS
 LLLLLLL BBBBBB  NNNN   NNNNN  EEEEEEEE   WWWW    WWW SSSSSSSSS
                      
 ͻ
            The Liberty BASIC Newsletter - Issue #91 - July 2001                
               "Keeping you up to date with the LB community!"                  
                                                                                
                 (C)opyright 2001 The Liberty BASIC Community                   
            Published by Tegan Snyder and Andrew Sturges (a.k.a Bubba)           
                                                                                
            View the latest newsletters online at www.lbnews.cjb.net          
                                                                                
 ͼ 

		THIS ISSUE IS BEST VIED IN WORDPAD, FULLSCREEN, 
	     WITHOUT WORDWARP, AND WITH THE 'COURIER_NEW 10' FONT.
 
 In this Month's Issue
 ---------------------------------------------------------------------------------
 -Liberty BASIC News
 -Liberty BASIC 3.0 Progress
 -Programmers Spotlight on Alyce Watson
 -The 6 Steps of Game Design
 -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.