The Liberty Basic Newsletter - Issue #85
© 1-January-2001 Cameron Arnott
All Rights Reserved

In this issue:

Attachments:

Proposed For Future Issues:

  • LIberty BASIC Tutorials - Learn LB with me!!!
  • Open source Game Development for Beginners
  • More on the Evolution of Liberty BASIC
  • More Interesting Snippets from the LBNews Mailing list
  • More Spotlights on Fellow Liberty BASIC programmers

Letter from the editor

Back to the Top

Well, another year gone and not forgotten, as much as some of us may wish to forget it.  Its been recorded in the newsletters and the mailing list for posterity.  Now we are really into the next millennium.  Entries for the "2001, A Liberty BASIC Odyssey" contest are starting to come in.  Are you working on yours and have you thought about nominating anyone or their web site?

I'd Like to thank all of you who have contributed to the past, present and future newsletters success.  Lots of people of varying degrees of expertise have contributed by submitting articles, questions, answers, suggestions, and their thoughts on subjects.  We are all learning and none of us know it all.  It takes all kinds of people to build a community such as ours.  I for one have learned a lot while publishing this newsletter every month.  Thank you ALL.

This is the first Issue on the new Liberty Basic Newsletters web site.  Yes we are now open for all Liberty BASIC previewers and programmers.  I hope you all enjoy reading and learning from the contents of the newsletter.

There have been heaps of messages and snippets of code this month, the most since starting this column.  There is a good selection of them in this newsletter.  Don't forget to get all the others that there simply wasn't space for in the newsletter.  You can sign up for the LBNews mailing list at <http://www.egroups.com/subscribe/lbnews>

I'll bet you're all eager to get into reading the interesting articles submitted this month.  I always try to put a balance of different levels of expertise in each issue so that there is something for everyone.  Just remember that the newsletters are always a great starting point for solutions when you are trying to figure out "How do i do that?".

Happy Programming,
Cameron Arnott

Spotlight on Kevin Agorastos

Back to the Top

This month's spotlight is on Kevin Agorastos.  We all know him as Sid^.  He is 25 years old. Kevin’s email address is mailto:kevina@orbitworld.net.

Kevin started out with GW-Basic in DOS about 10 years ago.  From there he went onto QBasic and a little known QBasic clone called FirstBasic.  Now Kevin mainly uses Liberty BASIC.  He has been using Liberty BASIC for 1 to 1-1/2 years.  Kevin rates his sill level in using Liberty BASIC as an intermediate.  ?He took up programming in Liberty BASIC to be able to program in the Windows environment.  Kevin rates Liberty BASIC as Excellent and getting better.

His other interests include reading and physical fitness

I asked Kevin to say a few words about himself to the group; this is what he said:

"I'm a very creative person; I've always liked to create things.  That very reason is why programming first appealed to me.  Programming is not only a hobby but a creative outlet for me.”


Liberty BASIC Evolution : (Part 1)
A Retrospective Look at the Development of
Liberty BASIC v2.0 :
Copyright 2000, Carl Gundel

Back to the Top

With the introduction of version 2.0 of Liberty BASIC, the language has a broader appeal.  User functions and subprograms with scoped variables make Liberty BASIC a real structured language, and even more suitable for real work and for teaching good programming.  Many improvements have been made to the compiler so that it generates much more helpful compile-time error messages.  The new graphical sprites appeal to people who like to write games.  Many all-round improvements have been made to fonts, colors, printing and more!

A Balancing Act

Software design and development is always an exercise in compromise.  It was a challenge to decide what to put into Liberty BASIC v2.0, and what to leave out.  I didn't manage to include some of the things I really wanted, including code libraries (like DLL's, but Liberty BASIC specific), support for operating system callbacks, a really powerful debugger, some hooks into the IDE to make it possible to extend it directly by writing code in BASIC.  I could go on.

Let's move on to what we did manage to include.  There's some really cool stuff in v2.0!

Functions and subprograms

In my own mind, another major release of Liberty BASIC without some sort of support for functions and subprograms with locally scoped variables would have been a mistake.  This is the cornerstone of the new release.  Not surprisingly, it was the hardest part to deliver.  It necessitated heavy rework throughout.  What made this especially hard to deliver was that Liberty BASIC just wasn't designed to accommodate this kind of functionality.

First I worked on the functions.  This was sometimes brain splitting work.  I also had to deal with the fact that changing the underlying model to have a context stack would slow down Liberty BASIC considerably.  I had to pull out all the stops to speed everything else up in order to compensate.  It might have been okay for Liberty BASIC to become slower, but only slightly.  In addition, the debugger really needed to be rewritten in order to work with the new model.

Once the functions worked, the subprograms came essentially for free.  They have a slightly different syntax, but they borrow most of their functionality from the functions implementation.

Now that we have a framework for doing this sort of thing, more interesting functionality should be easier to deliver.  I imagine things like:

  • Sharable libraries (sort of like DLL's, but for Liberty BASIC)
  • Incremental compilation
  • A more powerful debugger
  • Hooks in the IDE so you can extend it by writing BASIC code
  • Other cool stuff I don't dare mention
  • Improving the compiler

    I've learned a lot about writing a compiler in the last nine years.  Liberty BASIC has been hampered by its legacy code.  Users have had to deal with cryptic compiler error messages, and Liberty BASIC v2.0 improves this situation.

    One early design mistake I made was to not typecheck numeric and string variables and values. This offered a slight performance improvement, or so I thought.  The user had to live with weird error messages and in some cases odd runtime bugs.  Some users were using undocumented features, like being able to use the len() function with numbers.  This sort of thing was possible to do because Liberty BASIC was not distinguishing between numbers and strings.  Some substitutions of this kind didn't produce friendly results but instead would blow up at runtime, or worse yet they malfunctioned quietly.  Eventually I figured out how to fix all this at compile time without affecting runtime performance, and this fix went into LB2.

    Other design improvements affect the friendliness of the compiler, and actually make it smaller and simpler.

    Graphical Sprites

    Sprites are a surprise feature of LB2.  I did not plan to include sprites as a feature, even though I really wanted to.  People were asking for them, but I just didn't see how I would be able to include them.  Alyce Watson had written a great sprite DLL, and one day I was just hit by this spirit of inspiration.  I figured it wouldn't be that hard to add sprites if I leveraged Alyce's DLL, so I contacted her to get her okay.  She very graciously offered to let me use her library.  It didn't take very long to make this work.  The higher level sprite functionality I layered on top taxed my gray matter and took most of the time I spent on it.

    Once this feature was made part of a test release we soon discovered that Windows NT doesn't like the way that certain 16-bit DLL's are called.  Several people offered to try some different things to make the library work under NT, but no luck.  The cold realization came to me that I would have to re-implement the entire sprite library inside of Liberty BASIC.  This was really harder than it should have been, but after a few nights of very hard work it came together.  The result is a fun and useful animation mechanism.  I can't thank Alyce enough for her generosity and assistance!

    Fonts

    I wanted to make fonts more capable and more consistent in their application in Liberty BASIC.  To do this, I changed the font specification code so that all TrueType fonts could be specified by their point size, by pixel dimensions (as in earlier versions), and in italic, strike out, and underline forms.  I also added a font dialog so that the programmer could ask the user for a font specification.  Also, it is now possible to set the font for all the controls in a window in one command.

    Color

    Liberty BASIC now allows RGB colors to be specified for most graphics operations, and it is possible to set the color for the foreground and background of windows and dialog boxes.

    Printing

    Printing has been improved both in the IDE and from inside of running programs.  The Liberty BASIC editor now lets you choose a font for printing, and word wrapping is properly supported.  In the programming side, you can open a printer dialog so the user can choose a printer.  You can also get the printers name and some other information when the user chooses a printer.

    Timer

    One feature that Liberty BASIC users have been wanting for a long time is a timer mechanism so that they can create programs which perform some action periodically, but without consuming processor cycles while waiting idly to perform the action again.  The timer command lets the programmer do this easily, whether for setting a rate for game animation, or for controlling processes which have longer periods, like clocks, reminder mechanisms, or utilities for testing network resources to see if they are still up.

    The IDE (Integrated Development Environment)

    Liberty BASIC has always been approachable because of its simplicity of interface.  On the other hand, it is arguably plain.  It is important to make a good first impression, and most people are used to bells and whistles.  I've gone to some length to improve the user experience.

    Just a glance at the new IDE promises a better product.  There is a colorful toolbar, a status pane on the bottom of the window, and a syntax coloring text editor!  The editor itself has been tweaked in a dozen user friendly ways.  There is even a new built-in icon editor!

    The first time you start Liberty BASIC v2.0 it loads a welcome for you to read, giving the new user helpful direction.  The Help menu includes items which will launch your web browser straight to our ordering, news and links pages.  The help file is more comprehensive than ever!

    Community

    One important aspect of Liberty BASIC v2.0 is the user community.  I have benefitted greatly from the enthusiastic and generous people, both young and old who provided inspiration, assistance, and testing.  The Internet provided an affordable, speed of light conduit which made it possible for people who live literally all over the world to participate in the development of Liberty BASIC.  In addition to the various commercial services there have been and are web servers hosted by individuals on their own hardware.  There are dozens of Liberty BASIC related web sites, and there are more than a few individuals who have written instructional materials and software for use with Liberty BASIC.  I owe all of you a debt of gratitude!

    The Future

    First, the near future.  The next release of Liberty BASIC will be primarily a port of the 2.0 work into a 32-bit base and it will be called Liberty BASIC v3.0.  This will permit a great speed increase (at least 3x), make 32-bit API and DLL calls available, provide long filename support, and take advantage of the 32-bit common dialogs.  It may be possible to support OCX functionality in some fashion in this release, but I will need to research this first to see what is involved.

    I also hope to add:

    • Debugger refinements
    • TCP/IP support
    • Operations on bitmaps in memory (like with graphics windows)
    • Support for callbacks
    • Add more GUI controls

    Further down the line, I would like to create a real world-class development environment.  Coming from the Smalltalk culture, I have high standards for what the user experience should be.  I hope to create a version of BASIC which provides the same sort of highly productive software construction environment as Smalltalk does.  If this sounds very abstract, that's because I haven't quite figured it all out yet.  ;-)


    Newbie's guide to IRC by Kevin Agorastos

    Back to the Top

    Contents:

    • What is IRC?
    • Where can I get mIRC?
    • How do I set-up mIRC?
    • How do I use mIRC?
    • Miscellaneous

    What is IRC?

    IRC stands for "Internet Relay Chat."  This basically means that you can chat with others in real-time.  IRC is one of the most popular ways which people use to chat all over the world.  Before you get started you will need an IRC Client, such as mIRC.

    Where can I get mIRC?

    mIRC is an IRC client used to connect to various chat servers.  There are many IRC client’s available, mIRC being a very popular one.  Use<http://www.mirc.com> to download mIRC, which is a little over 1 meg in size.  If you want to try IRC out without downloading anything, go to <http://lbn.cjb.net/index.htm> and select chat from the menu.  This Java client will connect to #LibertyBasic on DALnet, a major IRC server.  I would suggest, however, when you have time, download mIRC.  It's much more powerful and faster than its Java counterpart.

    How do I set-up mIRC?

    Assuming you have already installed mIRC, you will need to set it up.  Upon opening mIRC for the first time, the mIRC Options should pop-up.  Firstly you must enter your full name and e-mail address in the fields provided.  It is not necessary to enter your actual name or e-mail address, but you must enter something.  Next you must enter a nickname and an alternate nickname to use.  You may find out that your nickname is already used by someone else.  That’s okay, I will tell you how to change it later.  The last thing to be done is to select the IRC server to use.  There are many to choose from in the pull down menu.  I would suggest using the random US or EU Dalnet server.  As mentioned earlier, DALnet is one of the biggest and popular IRC servers out there.  You’re all ready to go.  Press the "Connect to IRC Server" button, and you're on your way.

    How do I use mIRC?

    There are many commands used in mIRC, so many that I would have to write a separate article to list them all.  I will be going over the most commonly used commands to get around with.  The syntax for commands are /(Command) {perimeter}

    If and when you do register a nickname on DALnet, its a good idea to set it up so you don’t manually have to identify yourself every time at start-up.  Press ALT+O and go to IRC\Perform options.  Make sure there is a check next to "On connect, perform these commands."

    Now type in /msg NickServ@services.dal.net IDENTIFY <your nickname password> and press "OK."

    You're ready to go!

    If you want to look through all the channels or search for specific ones, press ALT+L.  The first time using this you'll have to press the "Get List" button to get all the channels.

    This may take a few minutes, but you should only have to do it once.  After the list is completed, you can either browse through the list or search for a word, by entering a word below the "Match text" field and pressing "Apply."

    Miscellaneous:

    For additional help on mIRC, visit #mIRC, #DALnet, and #irchelp channels.  Also visit <http://www.irchelp.org/>.

    mIRC is capable of producing programs called scripts.  This is advanced, but if your interested, join #Scripting or go to <http://www.xcalibre.net/scripting.htm> to learn more.

    Visit us on the official Liberty Basic channel, #Liberty BASIC on irc.DAL.net.  See you there!


    Interesting messages posted in LBNews in December:

    Back to the Top
    From: Mark Parkinson [mark@bodmin-comm-coll.demon.co.uk]
    Sent: Wednesday, 6 December 2000 10:04 AM
    To: lbnews@egroups.com
    Subject: [lbnews] a use for the LET command

    Syntax colouring makes tidying up word wrapped programs from emails much easier. If you use 'let' then all proper lines would start in blue (except lines starting with ' - and these you can make blue by using rem). Wrap arounds are then easily spotted because they're not blue. Mark Parkinson Bodmin Cornwall

    From: Gary Capps [mourndove@wwgap.net]
    Sent: Sunday, 17 December 2000 8:04 AM
    To: lbnews@egroups.com
    Subject: [lbnews] Encryption

    Hey Everybody, Found a few typo mistakes in the code for the encryption tools. The textboxes were reading wrong and the No1 and No2 variables were crossed in the code generator section. Works pretty good now. Neat stuff Tim. See ya, Gary ' This program '1. will generate a nag screen '2. will limit the program use to your choice of days '3. will kill the program after the grace period '4. cannot be bypassed by re-installing the program (slick) '5. comes with the complimentary liberty basic file ' Code4.bas to generate the registration numbers 'from whatever name is entered for registration. ' Credits ' (couldn't have done it without their ideas and input) ' Carl Gundel ' Ian Davies ' Alyce Watson ' and I'm sure Brosco did something too, ' so raise your hand Brosco! ' Announcement ' This code is hereby released to public domain. ' (Mainly for Carl Gundel's followers) ' This program may be distributed on the condition that it is ' distributed in full and unchanged (including the above credits ' and all comments). No fee shall be charged for any such ' distribution with the exception of reasonable shipping and media ' charges. In addition, the code in this program may be ' incorporated into your own programs and the resulting programs ' may be distributed without payment of royalties. ' Discussion ' This code will generate encrypted registration numbers based on ' the name of the user entered for the program registration. ' It will give the user a predetermined number of trial days ' before rendering the program useless. Uninstalling the program ' and re_installing will frustrate any thievery because of a file ' hidden somewhere ' (of your choosing), somewhere on their computer... ' stashed away from any typical user. If the program is installed ' again, it will still know that it is on day x, or that it is ' past the last day. Cracking the code for this encryption would ' be extremely difficult, but not beyond possibility. I'm sure ' there is some geek out there somewhere who has nothing better to ' do, but it would simply not be worth the effort. Registration ' is by far the easiest solution to this code! ' CUSTOMISING THE CODE FOR YOURSELF ' A. ' You will need to create a registration file called Register.txt ' which is a registration form. ' See example at end of this file. In lieu of this, you could ' modify the [register] routine to send them to a website and ' register by credit card. (or give them a choice). 'B. ' You must customize the encryption code by changing the following ' data. This will ensure that files and code generated will be ' uniquely yours and be different from anyone else who might use ' this program. 'Change this name of your dummy file to store registration data dummyfile$ = "\kidney.sys" 'A file ending with an extension such as dll, sys, obx, is best 'so the user won't suspect it contains anything they may be able 'to mess with. (be sure to put the "\" on the front). ' Be careful not to name it the same name as an existing file, ' or disaster could result! 'C. 'Change this to whatever you want to make your numbers unique constant1 = 8752 'Change this to whatever you want to make your numbers unique constant2 = 3576 'Change this to whatever you want to make your numbers unique Ca = 2 'Change this to whatever you want to make your numbers unique Cb = 9 TimeLimit = 10 'Ten day trial (these are unconcecutive days) ' A note on Ca, Cb, Constant1, and Constant2 ' No matter what kind of equation you use, it is ' recommended that you use only slight differences between ' Ca and Cb, Constant1 and Constant2. That way, ' both numbers will be similar in magnitude and ' have approximately the same number of characters. ' It just looks better that way... ' Begin code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ' First find the system directory ' This call gets the system directory ' You could also use the "GetWindowsDirectory" call ' and put the file in the windows directory ' lpBuffer$=space$(256)+chr$(0) nSize=len(lpBuffer$)_1 open "kernel" for dll as #kernel calldll #kernel, "GetSystemDirectory", _ lpBuffer$ as ptr, _ nSize as word, _ result as word close #kernel SystemPath$ = trim$(lpBuffer$) 'Or you might want to use trim$(lpBuffer$)+"32" 'to put the file in Windows/System32 open SystemPath$+dummyfile$ for append as #Registerfile ' This creates the file if it is not present close #Registerfile open SystemPath$+dummyfile$ for input as #Registerfile if eof(#Registerfile) = -1 then [endregister] ' If first run then skip to [ ] ' Otherwise, input the previous information line input #Registerfile,name$ ' If the file already exists, then input #Registerfile,Regza 'Retrieve the three lines of information input #Registerfile,Regzb RegistrationNo1 = Regza ' registration numbers RegistrationNo2 = Regzb howmany = RegistrationNo1 ' use registration #1 for use to increment ' the usage counter as long as the user ' is not registered. gosub [encryption] ' generate two unique numbers from name$ ' Compare the calculated numbers to the numbers in the file ' If they match, then the user has registered if No1 = RegistrationNo1 AND No2 = RegistrationNo2 then_ close #Registerfile if No1 = RegistrationNo1 AND No2 = RegistrationNo2 then_ [ThisGuyHasRegistered] ' If the user is not registered, then execution of the program ' will continue with the next steps, which will increment ' the number of days of program trial usage. ' This part changes the day by one even if the system clock ' is reset or screws up. It does not matter what day it is... ' only that they are different. if name$ <> date$() then howmany = howmany + 312 dummy = dummy + 3 [endregister] ' this is where the program goes to if it is close #Registerfile ' 1. the first execution of the program, or name$ = date$() ' 2. incrementing the number of uses open SystemPath$+dummyfile$ for output as #Registerfile ' open the dummy dll file print #Registerfile, name$ ' print the date (which is called "name") print #Registerfile, howmany ' print how many days the program has been used ' (disguised by a factor) print #Registerfile, dummy*3.1^2 ' just a dummy number to take up space close #Registerfile ' close the file ' open a notice for the non registered user notice "THIS IS MY PROGRAM!"+ chr$(13) + chr$(13) +_ "It will quit working if you don't resister" + chr$(13) +_ "You may use this program for a period of" + chr$(13)_ + "10 unconcecutive days free of charge for evaluation." +_ chr$(13)_ + chr$(13) + "If after that time you like the program "_ + chr$(13) + "please register it."+ chr$(13) + chr$(13)_ + "For Registration Information please see the" + chr$(13)_ + "enclosed file named 'Register.txt' or" + chr$(13)_ + "select the Help menu in the Tool Box." + chr$(13)_ + chr$(13) + "You are on day " ; int(howmany/312)+1 ; _ " of your 10 day evaluation period" + chr$(13) + chr$(13) +_ "The Registered version does not display this notice." if (howmany/312)+1 > TimeLimit then [kissoff] ' This causes a complete bypass of the program ' for users who have used up the grace period. [ThisGuyHasRegistered] ' This is where the program skips to if the user has registered. 'vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 'vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 'vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 'vvvvvvvv *****Your Program goes below here**** vvvvvvvvvvvvvvvvvv [YourProgram] nomainwin ' open no main window UpperLeftX = INT((DisplayWidth_400)/2) UpperLeftY = INT((DisplayHeight_150)/2) WindowWidth = 400 WindowHeight = 150 if ProgramFlag >0 then close #1 ' in case it's already open ProgramFlag =1 menu #1, &File, &quit, [quit] menu #1, &Help, &Order, [Order], &Register, [Register] graphicbox #1.g, 0,0,400,150 open "My Program v 1.0" for graphics_nsb_nf as #1 cursor hourglass print #1.g, "down" for i = 0 to 100 'draw gradient print #1.g, "color ";i*2+50;" ";i*2 +50;" 950" print #1.g, "line 0 ";i;" 400 ";i next i cursor normal print #1.g, "up" print #1.g, "flush" print #1, "trapclose [quit]" [inputLoop] ' stop and wait for buttons to be pressed scan goto [inputLoop] [quit] if RegisterFlag > 0 then close #Register if ProgramFlag >0 then close #1 end '^^^^^^^^^^^^^^^^^^^ Your Program goes above here^^^^^^^^^^^^^^^^^ '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [Register] ' This routine first checks to see if the user is registered. ' If the user is registered, they are thanked and kicked out ' of the registration process. ' If they aren't registered, then, registering info is allowed to ' be input. open SystemPath$+dummyfile$ for input as #Registerfile line input #Registerfile,name$ ' Retrieve the first line of information input #Registerfile,Regza ' Retrieve the second line of info input #Registerfile,Regzb ' Retrieve the third line of info RegistrationNo1 = Regza ' These are supposed to be the registration no.'s. RegistrationNo2 = Regzb close #Registerfile ' check the entered data and see if they have already registered. gosub [encryption] ' generate two unique numbers from name$ ' Compare the calculated numbers to the numbers in the file. ' If they match, then the user has registered. if No1 = RegistrationNo1 AND No2 = RegistrationNo2 then_ notice "Thank You!"+chr$(13)+"You Have Already Registered!" if No1 = RegistrationNo1 AND No2 = RegistrationNo2 then goto_ [inputLoop] ' If the user hasn't registered, the following steps will ' open a window to allow registration. if RegisterFlag > 0 then close #Register ' (in case the register window is already open) RegisterFlag = 1 WindowWidth = 245 WindowHeight = 342 nomainwin menu #Register, &Click_Here_To_Order,&Order, [Order] textbox #Register.textbox3, 14, 216, 200, 25 textbox #Register.textbox2, 14, 151, 200, 25 textbox #Register.textbox1, 14, 91, 200, 25 statictext #Register.statictext4,_ "Registration Name", 14, 71, 144, 20 statictext #Register.statictext5,_ "Registration Number 1", 14, 131, 152, 20 statictext #Register.statictext6,_ "Registration Number 2", 14, 196, 176, 20 statictext #Register.statictext7,_ "Please Enter Your Registration", 14, 6,240, 20 statictext #Register.statictext8,_ "Codes Exactly as They Appear", 14, 21,224, 20 statictext #Register.statictext9,_ "On Your Registration Notice.", 14, 36,224, 20 button #Register.button10, "Accept",_ [AcceptRegistration], UL, 14, 256, 90, 25 button #Register.button11, "Cancel",_ [CancelRegistration], UL, 110, 256,104, 25 open "Registration Entry" for graphics_nsb as #Register print #Register, "fill white; flush" goto [inputLoop] [AcceptRegistration] 'Perform action for the button named 'button10' print #Register.textbox3, "!contents?" input #Register.textbox3, RegistrationNo2 print #Register.textbox2, "!contents?" input #Register.textbox2, RegistrationNo1 print #Register.textbox1,"!contents?" input #Register.textbox1, name$ gosub [encryption] ' generate two unique numbers from name$ if No1 <> RegistrationNo1 OR No2 <> RegistrationNo2 then_ notice "Invalid ID or Reg Number"+chr$(13)+"Try again" if No1 <> RegistrationNo1 OR No2 <> RegistrationNo2 then_ [inputLoop] 'If name and numbers are correct, then put the 'info into the dummy file for future reference 'and close the #Registerfile file. open SystemPath$+dummyfile$ for output as #Registerfile print #Registerfile,name$ print #Registerfile,RegistrationNo1 print #Registerfile,RegistrationNo2 close #Registerfile notice "Registration Successful" +chr$(13)+_ "Thank You For Registering!" close #Register RegisterFlag = 0 goto [inputLoop] [CancelRegistration] 'Perform action for the button named 'button11' close #Register RegisterFlag = 0 goto [inputLoop] '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [kissoff] WindowWidth = 240 WindowHeight = 105 nomainwin button #Trial.button1, "Order", [Order], UL, 6, 41, 72, 25 button #Trial.Trial2, "Register", [Register], UL, 78, 41, 72, 25 button #Trial.Trial3, "Cancel", [CancelClick], UL, 150, 41, 72, 25 statictext #Trial.statictext4, "Your Trial Period Has Expired",_ 14, 11,216, 20 open "End of Trial" for graphics_nsb as #Trial print #Trial, "fill white; flush" goto [inputLoop] [Order] pathname$ = MID$( DefaultDir$ , 1 , LEN( DefaultDir$ ) ) registerInfo$ = "notepad.exe " + pathname$ + "\register.txt" RUN registerInfo$ goto [inputLoop] [CancelClick] close #Trial if RegisterFlag > 0 then close #Register end goto [inputLoop] [encryption] ' *** Begin encryption code. ' *** The following lines use ' *** the persons name to generate ' *** two unique registration numbers CodeSum = 0 for index = 1 to len(name$) CodeSum = CodeSum + asc(mid$(name$,index,1)) 'Sum all the ascii number values in the name next index No1 = int(CodeSum*Ca + constant1) 'Generate two unique numbers from the sum No2 = int(CodeSum*Cb + constant2) 'using linear equations. return 'More complex equations can be used such as shown below '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ '3rd degree Polynomial Fit: y=a+bx+cx^2+dx^3... ' No1 =int(Ca+Ca*CodeSum + Ca*CodeSum^2+Ca*CodeSum^3) ' No2 =int(Cb+Cb*CodeSum + Cb*CodeSum^2+Cb*CodeSum^3) 'Sinusoidal Fit: y=a+b*cos(cx+d) ' No1 =int(Ca+Ca*cos(Ca*CodeSum+Ca)) ' No2 =int(Cb+Cb*cos(Cb*CodeSum+Cb)) 'Heat Capacity Model: y=a+bx+c/x^2 ' No1 =int(Ca+Ca*CodeSum+Ca/CodeSum^2) ' No2 =int(Cb+Cb*CodeSum+Cb/CodeSum^2) '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ '***************************************************************** '***************************************************************** '***************************************************************** '***************************************************************** '***************************************************************** ' This starts the Code generator progam which is separate from ' above... ' Copy this, and make a separate program to generate key codes for ' your registered users... '~ Code Generator (seperate program) ' Generates Registration Numbers constant1 = 8752 'This has to match whatever is in your main program constant2 = 3576 'This has to match whatever is in your main program Ca = 2 'This has to match whatever is in your main program Cb = 9 'This has to match whatever is in your main program sum = 0 input "Name "; name$ 'read the string CodeSum = 0 for index = 1 to len(name$) CodeSum = CodeSum + asc(mid$(name$,index,1)) 'Sum all the ascii number values in the name next index No2 = int(CodeSum*Cb + constant2) 'Generate two unique numbers from the sum No1 = int(CodeSum*Ca + constant1) 'using simple linear equations. More complex 'equations can be used such as 'int((sine(CodeSum)*Ca)) and int((cos(CodeSum)*Cb)), etc Print "" Print "" Print "" Print "" Print "Dear "+name$+"," Print "" Print " Thank you for your interest in my" Print " silly program!" Print "" Print " To enter your registration numbers " Print " and unlock your shareware software, " Print " enter the following information " Print " into the 'Help/Registration' window " Print " just as it appears below." Print "" Print " Please note entries are case sensitive!" Print "" Print "" print " Registration Name "; name$ print " Registration Number 1 " ;No1 print " Registration Number 2 " ;No2 Print "" Print "" Print "Thank you for registering My Program!" Print "" Print "" Print "Sincerely," Print "" Print "" Print "" Print "" Print "My Name" [loop] scan goto [loop] close #main end '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ' ' Here is an example of the register file you need for the ' "register function as used in the example program above... ' '_________________________________________________________________ 'Registration _ For My Program '_________________________________________________________________ ' ' ' My Program Registration ' ' Send your check or money order for $_____ along with your ' e_mail address to ' ' Me ' My Address, Street, Po, etc. ' City, State Zip ' ' Make checks payable to Me ' ' After reciept of your registration fee, You will recieve ' registration passwords by e-mail to unlock the program. ' Once the program is unlocked, all versions from then on ' that you download from the website will also be unlocked. ' Check back often for updates at ' ' Thank you for registering

    For your convenience a copy of register.bas has been attached to this newsletter.


    From: carlcourt@aol.com
    Sent: Thursday, 14 December 2000 2:06 PM
    To: lbnews@egroups.com
    Subject: Re: [lbnews] Double click
    In a message dated 12/13/00 10:33:13 PM Eastern Standard Time, mourndove@wwgap.net writes: << Does anyone know how to trap a single click and a double click seperately? >> Gary, Here's a way to differentiate between a single or double click. I've applied this example to a listbox, but you could use it other ways. CarlC '''''''''''''''''''''''''''''' Start Code nomainwin interval=250 'milliseconds UpperLeftX = int((DisplayWidth-500)/2) UpperLeftY = int((DisplayHeight-400)/2) WindowWidth = 100 WindowHeight = 100 array$(1)="Moe" array$(2)="Larry" array$(3)="Curly" LISTBOX #w.lb, array$(, [click], 1,1,50,50 open "click" for graphics_nsb_nf as #w print #w.lb, "singleClickSelect" [loop] input a$ [click] if time$("ms")-mil<interval then notice "You Double Clicked" mil=time$("ms") print mil goto [loop] ''''''''''''''''' End Code

    From: Jay Shrimplin [jshrimp@earthling.net]
    Sent: Saturday, 2 December 2000 3:43 AM
    To: lbnews@egroups.com
    Subject: [lbnews] Shadow Box and Outline Box subroutines
    The boss wants a quick program and you don't have time to spruce it up graphically. Just use these three routines to make your code look nice and a little bit more professional without doing a whole lot of graphic programming. Shadow Box contains 2 subroutines that will let you add the raised and lowered shadow boxes and outlines easily. Also threw in a 3rd routine to make a box grow effect. The program included demonstrates how to use these routines and shows different combinations of shadow boxes and outlines that make the screen look so much better than just a plain flat screen output Hey, I even got it to compile in the unregistered version limitations.                                 Jay Shrimplin

    For your convenience a copy of sbox.bas has been attached to this newsletter.



    From: Doyle Whisenant [mechanic@sonet.net]
    Sent: Sunday, 10 December 2000 11:02 AM
    To: lbnews@egroups.com
    Subject: Re: [lbnews] Re:Switch resolutions
    Attachment: screenres.zip

    White Eagle Software wrote:
    >
    >http://www.vb-world.net/graphics/screenres/
    > Attached you will find a file with some functions to determine the screen resolution and some other device variables. Note that to actually change the screen resolution/color depth on the "fly" you would have to "thunk" a couple of 32 bit calls. I'm not up to that challenge just yet, maybe later. Anyways, enjoy! :) --
    Doyle Whisenant
    mechanic@sonet.net
    http://mechanic.webjump.com

    From: A. Watson [alycewatson@bigfoot.com]
    Sent: Thursday, 21 December 2000 9:59 AM
    To: lbnews@egroups.com
    Subject: Re: [lbnews] scroll bars
    At 05:53 PM 12/20/00 -0600, you wrote: >At 03:44 PM 12/20/00 -0500, you wrote: >>Hi Carl, >> >>Is there any way that you could fix the graphic box scrolling >> problem? > >There is no problem. It works just fine. All you need to do is > add a "fill" command. FWIW, you are not 'creating' a scroll bar, just causing it to appear. It must be a part of the graphicbox already, in LB. Also, why not take advantage of LB's function and sub capabilities, as in the following. Anyway, thanks for sharing. Great stuff! 'Example to show how to add scroll bars easily to a graphics box 'by Bubba (andrew@britcoms.com) WindowWidth = 600 WindowHeight = 400 nomainwin UpperLeftX = 100 UpperLeftY = 100 loadbmp "pic","VWSIGNON.bmp" open "user" for dll as #user graphicbox #main.graph, 10, 10, 570, 350 open "Graphics box scrollbars" for window as #main print #main.graph, "trapclose [exit]" print #main, "resizehandler [resize]" print #main.graph, "down; fill blue;backcolor blue" print #main.graph, "drawbmp pic 10 60" print #main.graph, "down; place 10 10" print #main.graph, "| Text" print #main.graph, "flush" h = hwnd(#main.graph) call ShowScrollBar h, 1 call ShowScrollBar h, 0 [wait] input st$ goto [wait] [resize] 'Need this to redraw the scrollbar call ShowScrollBar h, 1 call ShowScrollBar h, 0 print #main.graph, "redraw" goto [wait] [exit] close #main close #user end sub ShowScrollBar hW, index calldll #user,"ShowScrollBar", _ hW as word, _ index as short, _ 1 as short, _ result as void end sub

    From: A. Watson [alycewatson@bigfoot.com]
    Sent: Monday, 25 December 2000 1:07 AM
    To: lbnews@egroups.com
    Subject: Re: [lbnews] Graphicsbox frame color
    At 06:29 PM 12/23/00 -0600, you wrote: >Thanks Alyce >I tried the dll but the border still appears, until it is covered >up or the window is minimized then restored. Any suggestions? Alright. I've fiddled around with it, trying to recreate your problem. I've discovered that the frame sometimes shows until after the window is minimized or covered if certain BackgroundColor$'s are used. Consider what this means. It means that the window and graphicbox without border DO display properly after a repaint. There are several ways to force a repaint via api, but the easiest way to force a repaint is by sending a "refresh" command to the window - note that it is of type-window. Graphics windows do not understand a refresh command. To do this via api, the easist call to make is to SendMessage with _WM_PAINT as the message, and the window handle as the handle param. Code follows. nomainwin BackgroundColor$="green" graphicbox #1.g, 10,10,100,100 open "test" for window as #1 print #1.g, "trapclose [quit]" open "user" for dll as #user h=hwnd(#1.g) hWin=hwnd(#1) Index = _GWL_STYLE or 0 calldll #user, "GetWindowLong", _ h as word, _ Index as word, _ oldStyle as long dwStyle = oldStyle xor _WS_BORDER calldll #user, "SetWindowLong", _ h as word, _ Index as word, _ dwStyle as long, _ result as long print #1.g, "down;fill cyan;flush" 'print #1, "refresh" calldll #user, "SendMessage", _ hWin as ushort, _ _WM_PAINT as ushort, _ 0 as ushort, _ 0 as ulong, _ result as ulong close #user wait [quit] close #1:end

    From: Drake, David [ddrake@acipco.com]
    Sent: Tuesday, 26 December 2000 5:14 PM
    To: 'lbnews@egroups.com'
    Subject: [lbnews] Animated file copy window demo
    I've uploaded a demo of a simulation of the Windows9x "copying files" animated window (you know, the one with the sheet of paper flying from one folder to another?). This demo is badly bloated because I've not taken the time to optimize the sprites. It LOOKS good, though. Download at:
    http://www.egroups.com/files/lbnews/filexfr.zip

    ----- Message Sniped As coniatned Unrelated material

    -David Drake

    For your convience a copy of filexfer.zip has been attached to this newsletter.


    From: Dennis McK [dlm81854@accs.net]
    Sent: Saturday, 30 December 2000 4:02 PM
    To: lbnews@egroups.com
    Subject: [lbnews] Better Tabbing in window-type windows
    Been having some fun with this. Tabbing now works from any control. Added auto dropdown for combobox. Also discovered quirk with combobox hwnds. Again, all info came from posts and newsletters. Dennis '------------- NoMainWin Dim cbo1$(9) cbo1$(1) = "a" cbo1$(2) = "b" cbo1$(3) = "c" cbo1$(4) = "d" cbo1$(5) = "e" cbo1$(6) = "f" cbo1$(7) = "g" cbo1$(8) = "h" cbo1$(9) = "i" Dim lst1$(9) lst1$(1) = "1" lst1$(2) = "2" lst1$(3) = "3" lst1$(4) = "4" lst1$(5) = "5" lst1$(6) = "6" lst1$(7) = "7" lst1$(8) = "8" lst1$(9) = "9" buffer$ = space$(256) + chr$(0) WindowWidth = 586 WindowHeight = 400 UpperLeftX = Int((DisplayWidth - WindowWidth) / 2) UpperLeftY = Int((DisplayHeight - WindowHeight) / 2) button #form1.Button1, "Button 1", [form1.Button1.Click], UL,_ 18,18, 102, 30 button #form1.Button2, "Button 2", [form1.Button2.Click], UL,_ 132, 18, 114, 30 textbox #form1.TextBox1, 18, 60, 228, 30 textbox #form1.TextBox2, 18, 96, 228, 30 checkbox #form1.CheckBox1, "CheckBox 1",_ [form1.CheckBox1.Set],_ [form1.CheckBox1.Reset], 18, 132, 180, 30 checkbox #form1.CheckBox2, "CheckBox 2",_ [form1.CheckBox2.Set],_ [form1.CheckBox2.Reset], 18, 162, 180, 30 radiobutton #form1.RadioButton1, "RadioButton 1",_ [form1.RadioButton1.Set], [form1.RadioButton1.Reset], 18, 192,_ 180, 30 radiobutton #form1.RadioButton2, "RadioButton 2",_ [form1.RadioButton2.Set], [form1.RadioButton2.Reset], 18, 222,_ 186, 30 combobox #form1.ComboBox1, cbo1$(, [form1.ComboBox1.Click],_ 216,132, 144, 144 listbox #form1.ListBox1, lst1$(,_ [form1.ListBox1.DoubleClick],372, 132, 138, 114 Open "Tab Test" for Window as #form1 Print #form1, "trapclose [Quit]" Print #form1.TextBox1, "!font MS_Sans_Serif 10" Print #form1.TextBox2, "!font MS_Sans_Serif 10" Print #form1.RadioButton1, "font MS_Sans_Serif 10" Print #form1.RadioButton2, "font MS_Sans_Serif 10" Print #form1.CheckBox1, "font MS_Sans_Serif 10" Print #form1.CheckBox2, "font MS_Sans_Serif 10" Print #form1.ListBox1, "font MS_Sans_Serif 10" Print #form1.ComboBox1, "font MS_Sans_Serif 10" Print #form1.Button1, "!font MS_Sans_Serif 10" Print #form1.Button2, "!font MS_Sans_Serif 10" Open "user.dll" for dll as #user Dim TabStop(10) TabStop(1) = hwnd(#form1.Button1) TabStop(2) = hwnd(#form1.Button2) TabStop(3) = hwnd(#form1.TextBox1) TabStop(4) = hwnd(#form1.TextBox2) TabStop(5) = hwnd(#form1.CheckBox1) TabStop(6) = hwnd(#form1.CheckBox2) TabStop(7) = hwnd(#form1.RadioButton1) TabStop(8) = hwnd(#form1.RadioButton2) 'Here's a work around. 'Comboboxes return a different handle with Getfocus API. print #form1.ComboBox1, "setfocus" calldll #user, "GetFocus" , AlternateCbo1Hwnd AS short TabStop(9) = AlternateCbo1Hwnd TabStop(10) = hwnd(#form1.ListBox1) cbo1Hwnd = hwnd(#form1.ComboBox1) 'still need for other calls 'set to first button CurH = hwnd(#form1.Button1) Call TabNext, CurH [Main.Loop] 'position in the buffer$ is the ascii code + 1 ' (thanks Bill J.) calldll #user, "GetKeyboardState", buffer$ as ptr,_ result as void For Ascii = 33 to 127 Chk$ = mid$(buffer$,Ascii,1) If asc(Chk$) > 127 Then Goto [CheckCombo] End If Next Ascii tab$ = mid$(buffer$,10,1) If asc(tab$) > 127 Then GoTo [ScanKey] End If scan Goto [Main.Loop] [CheckCombo] calldll #user, "GetFocus" , result AS short If result = AlternateCbo1Hwnd Then print #form1.ComboBox1, "contents? cboTxt$" If cboTxt$ <> "" Then calldll #user, "SendMessage", cbo1Hwnd as word,_ _CB_SHOWDROPDOWN as word, 1 as word, 0 as long,_ result as long End If End If Goto [Main.Loop] [ScanKey] [Rescan] 'wait for the key to be released calldll #user, "GetKeyboardState", buffer$ as ptr,_ result as void tab2$ = mid$(buffer$,10,1) If tab2$ = tab$ Then GoTo [Rescan] GoTo [Tab] GoTo [Main.Loop] [Tab] calldll #user, "GetFocus" , result AS short For j = 1 to 10 If TabStop(j) = result Then x = j + 1: If x = 11 Then x = 1 CurH = TabStop(x) j = 10 End If Next j Call TabNext, CurH CurFocus = CurH GoTo [Main.Loop] Sub TabNext Index calldll #user, "SetFocus",_ Index as word,_ result as short End Sub [Quit] close #user close #form1 : End '----------- empty branches ------------ [form1.Button1.Click] GoTo [Main.Loop] [form1.Button2.Click] GoTo [Main.Loop] [form1.CheckBox1.Reset] GoTo [Main.Loop] [form1.CheckBox1.Set] GoTo [Main.Loop] [form1.CheckBox2.Reset] GoTo [Main.Loop] [form1.CheckBox2.Set] GoTo [Main.Loop] [form1.ComboBox1.Click] GoTo [Main.Loop] [form1.ListBox1.DoubleClick] GoTo [Main.Loop] [form1.RadioButton1.Reset] GoTo [Main.Loop] [form1.RadioButton1.Set] GoTo [Main.Loop] [form1.RadioButton2.Reset] GoTo [Main.Loop] [form1.RadioButton2.Set] GoTo [Main.Loop]