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?