The Liberty Basic Newsletter - Issue #97 - June 2002
   (c) 2002, http://groups.yahoo.com/group/lbnews/
             All Rights Reserved
---------------------------------------------------------
 I believe in an open mind, but not so open that your 
 brains fall out. 

            - Arthur Hays Sulzberger
---------------------------------------------------------
In this issue:

SyntaxError: Some words from the editor
Tipcorner:   Dumping a file directly into a texteditor
Spotlight:   Three items that caught my fancy recently...
Article:     Serial Communication with LB - by Dean Jolly
Review:      David Drake reviews Image321.DLL
Noteworthy:  Translating Documentation 
Advanced:    Implementing an editor with Scintilla.dll
Submissions: Submit articles for publication
Attachments: List of included files.

---------------------------------------------------------
---------------------------------------------------------
SYNTAXERROR : Some words from the editor

(A new section that may appear every once and while)

This issue marks a new milestone in the evolution of the
Liberty Basic Newsletter.  This is the first of the many 
(I hope) of the jointly published newsletters featuring
newsletter team of Alyce Watson, Tom Nally and Brad Moore.

I am excited to be publishing this first issue, because 
of the really great articles that have been submitted.
The Liberty Basic community has been really generous, 
sharing ideas, solutions, and code.  I appreciate the 
people who have contributed to make this issue really 
special.    

Dean Jolly has written a fantastic article about serial 
communications, adding his extensive knowledge to the 
growing library of information on the subject.  David Drake
reviews the new Image321 DLL and a whole lot more.

Thanks for taking time to read the newsletter.  If you 
have found information in the newsletter helpful, or if
you have questions or comments, please let us know.  

Thank you - Brad Moore (June 2002 Editor)

---------------------------------------------------------
---------------------------------------------------------
TIPCORNER : Dumping a file directly into a texteditor

This month's tip is about loading text files directly
into a texteditor window.  The functionality was documented
in earlier versions of LB, but often missed.  The really
great thing is the timesavings that this little technique 
can save, in programming as well as execution times.

Here is how it works:
Open a window in your code which has a texteditor placed
on it.  Initially the texteditor will be blank.  filling 
it with text is a matter of three simple steps (and the 
first one can be skipped if you already know the name of
the file you plan to load).

First get the name of the file to be loaded into the 
texteditor.  Unless you already know the name of the file,
simply open a filedialog window and let the user pick a
file.  Here are the commands to do that part:

    fileName$ = ""
    FileDialog "Open text file", "*.txt", fileName$

Now we should have a valid filename from the operating 
system.  It is possible that the user pressed cancel, 
so we will test the string to insure it contains a value.
If it does we will open the file.  Here is the code:

    If fileName$ <> "" Then
      Open fileName$ For Input As #file

Continuing in the same IF-THEN block, we will simply 
"print" the contents of the file into the texteditor.
This is done by using the "!contents" text command.  The
help file says the following about the command:

print #handle, "!contents varname$";
print #handle, "!contents #handle";

This has two forms as described above.  The first form
causes the contents of the text window to be replaced 
with the contents of varname$, and the second form 
causes the contents of the text window to be replaced 
with the contents of the stream referenced by #handle.  
This second form is useful for reading large text files 
quickly into the window.

So, we should be able to load the entire file we just 
opened (as #file) into the texteditor with the following
command:

      #main.tedit, "!contents #file";

Don't forget to close the file after you are done with it,
and end the IF-THEN block.

      Close #file
    End If

So, that is how it is done.  There is a short demo program
that accompanies this newsletter called LBNR.BAS from
which this code snippet came from (it is included in a zip
file - LBNR.ZIP which is attached).  You can see the code
in action if you load and run the program in LB3.x or
higher.

---------------------------------------------------------
---------------------------------------------------------
SPOTLIGHT

We've got three exciting items in the SPOTLIGHT this month:

The first is the winners of the 2002 Liberty Basic 
Challenge Contest.  We were excited about the number of
people who put effort into creating and entering fine
quality programs into the contest.  It is a shame that all
of the contestants could not win, but that is the nature
of a contest.  All of us at LBNEWS want to thank everyone
who submitted a program, as well as those of you who took
the time to review the entries and vote.

Here is the announcement that Alyce Watson made regarding 
the contest and the winners on May 1st, 2002:


ANNOUNCING THE WINNERS!

The polls have closed for the 2002 Liberty BASIC 
Challenge. Thanks very much to everyone who 
participated, either to enter a program or to vote. 
There was tremendous variety in the programs
submitted to this contest. The voting was very
close in ALL categories. We have all gained
something very special from the participants who
shared their code and their ideas so generously. 
Thanks to all!


CONGRATULATIONS TO THE WINNERS!

Winner, Newbie Challenge:
Slot Machine - by Kenny Bruce

Winner, Oldbie Challenge:
RPN Calculator - by David Drake

Winner, Game Challenge:
Raining Cats and Dogs - by Mitchell Kotler

Winner, Open Category:
Polar Phun by - Tom Nally


All the submissions are available online at the 
YahooGroups site for LBNEWS - in the files section:

http://groups.yahoo.com/group/lbnews/files/

Also, the winners are being featured at the ABC Archives
website as Walt Decker points out in message 18233 on the 
LBNEWS site:

The winners are now featured on the ABC Specials page:

http://www.allbasiccode.com/downloads/specials/special.html

Walt Decker
ABC Archives Webmaster

(Thank you Walt and Alyce both for your hard work and effort
in seeing the contest through.  Thank you Carl and Alyce for
supplying prizes.)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

The second item in the Spotlight is an innovative idea that 
was recently discussed on the Liberty Basic Group.  Laz 
has written a pretty neat packer for packing files (bmp's, 
wav's, etc) into a single file, even concatenating it onto 
the LB run time itself.  Here is what he says: 

"...I found the best way to include files is to include them
to the end of an exe or some other file. Or to just put 
them all into a file by themselves. Then when you need them
just unpack them. The code to unpack the files is small. 
Of course the more files you add the larger the code 
becomes. I have included files to the runtime for LB and 
unpacked them."

His packer is still in beta testing, but it is available 
at the following address (watch for line wraps):

http://groups.yahoo.com/group/libertybasic/files/laz/include_file.bas

Read more about it in messages 5867 and 5874 on the web
at:

http://groups.yahoo.com/group/libertybasic/message/5867

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Finally in the spotlight this month is a little more on
awards.  It was a real pleasure to see that a program 
written in Liberty Basic has received wide public acclaim
and recognition.  I am of course talking about Eldron 
Gill's impressive, commercial quality application Birthday
Keeper.  Here is what Alyce Watson observed:

If you want to see a commercial program written in Liberty
BASIC that has won '5 star' awards from TWO ratings 
services, check out Birthday Keeper by Eldron Gill here: 

http://members.tripod.com/~eaglesoar/eagle.html

Way to go, Eldron!

- Alyce

Yes indeed Eldron - Way to go.  I certainly am inspired,
I hope you are too.

-Brad Moore 

---------------------------------------------------------
---------------------------------------------------------
ARTICLE : Serial Communication with Liberty Basic
by Dean Jolly 

[Ed: Dean points out that the material in this article is
not aimed at beginners who are just starting out using the
serial port.  I wanted to point out two other excellent 
resources if you fall into that category, use them as
primers to serial communications and they will make a 
great foundation on which to launch into the following 
article by Dean.

1) Serial Communications by Herman in Newsletter 49
2) Serial Primer by Neil Trimblay - available at the
   following URL - http://lbdev.5u.com/

Enjoy the article.]

Serial Communication with Liberty Basic

Abstract

Attempting to communicate with a serial device, other
than a modem,(such as an I/O board) using the standard 
LB2 commands gives at best poor or unreliable results. 
Far better results are obtained using LB3!
Under LB2, the most common problem being a delay 
between sending a command to the device and having the 
action performed ( such as toggling an output). This 
delay ranges from several hundred milliseconds to 
several seconds. An other and more equally serious 
problem is that reading the port sometimes freezes 
the system. It appears that these problems are caused 
by the interaction of LB2 and Windows. The solution to 
the problems is to call the communication functions in 
the USER DLL.


Communicating using the DLL with LB2
(after going through all of this I can guarantee you 
will want to do it with LB3 )

To communicate using the available functions requires 
several steps

1- create an instance of the needed DCB structure
2- open the User.DLL
3- build the DCB
4- open the comm port
5- read or write to the port
6- close the port when done
7- close the DLL

For those of you still using LB2, it looks like this:
NB You must do things in this order!
   
*1- create an instance of the DCB structure  
 ( very long structure )

    struct myDCB,_
            ID as char[1],_
            BaudRate as ushort,_
            ByteSize as char[1],_
            Parity as   char[1],_
            StopBits as char[1],_
            RlsTimeOut as ushort,_
            CtsTimeOut as ushort,_
            DsrTimeOut as ushort,_
                    fBinary as      ushort,_
                    fRtsDisable as  ushort,_
                    fParity as      ushort,_
                    fOutxCtsFlow as ushort,_
                    fOutxDsrFlow as ushort,_
                    fDummy       as ushort,_
                    fDtrDisable  as ushort,_
            fOutX           as ushort,_
            fInX            as ushort,_
            fPeChar         as ushort,_
            fNull           as ushort,_
            fChEvt          as ushort,_
            fDtrflow        as ushort,_
            fRtsflow        as ushort,_
            fDummy2         as ushort,_
                XonChar  as char[1],_
                XoffChar as char[1],_
                XonLim   as char[1],_
                XoffLim  as char[1],_
                PeChar   as char[1],_
                EofChar  as char[1],_
                EvtChar  as char[1],_
                TxDelay  as ushort
          ' end of structure

   

'*2- open dll
    open "user" for dll as #user
    
'*3- call OpenComm                      'opens port
        com$ = "COM1"+chr$(0)

        CallDll #user,"OpenComm",_
                    com$ as ptr,_
                    1024 as ushort,_     'output buffer size
                    128 as ushort,_      'input buffersize
                    idComDev as ushort   'this id is used everytime the
                                         'port is accessed
    
'*4- build DCB 
        buildCom$ = "COM1:9600,n,8,1"+chr$(0) 'required port settings

        CallDll #user,"BUILDCOMMDCB",_
                        buildCom$ as ptr,_
                        myDCB as struct,_    ' defined above
                        Bresult as ushort    ' if negative = error

    if Bresult < 0 then
        
        initport$="error" ' variable used to check for error
    else
        initport$ = "OK"
    end if
    myDCB.fNull.struct = 1                ' specifies that null char 
                                          'are to be discarded


'*5- set com state  must do this before using the port...
        CallDll #user,"SETCOMMSTATE",_
                        myDCB as struct,_
                        setResult as ushort  ' if negative = error
     if setResult < 0 then
       
        initport$ = "error"
     else
       initport$="OK"
    end if


'* >> serial port COM1 is now ready to communicate <<

 
After doing all of this, you still haven't 
really done anything with the port

here are the subroutines to write, read and flush the port

'*6a- Writting to the port is done this way :
 

'************************************
'* [write]                          *
'* sub #1 write to port             *
'* uses User.dll function WriteComm *
'* var                              *
'*    write.Length, write.String$   *
'*    returns write.result          *
'************************************
[write]
        write.Length = 0 ' reset this to 0

        write.String$ = "anything you want to send to the port"

        write.Length = len(write.String$) ' calc length

        CallDll #user,"WriteComm",_
            idComDev as ushort,_          ' obtained fromn opencomm
            write.String$ as ptr,_        ' string sent to port
            write.Length as ushort,_      ' number of bytes to send
            write.Result as ushort        ' number of bytes sent


        if write.Result <> write.Length then
           
            Notice "Error"+chr$(13)+"problems writting to port"
        end if

        write.String$ = ""                ' reset
    return


'6b -And Reading the port is done as follows:
'************************************
'* [read]                           *
'* sub #2 read port                 *
'* uses User.dll function readComm  *
'* var                              *
'* 	read.Buffer$		    *
'*	read.Bytes		    *
'*	read.Nb			    *
'*	read.Txt$		    *		     
'************************************
[read]

        read.Buffer$= space$(128) + chr$(0)  ' buffer for reading port
      	read.Bytes = 2 ' number of bytes to read 
      	

        read.Nb = 0                          ' number of bytes actually  
                                             ' read
        read.Txt$ = ""                       ' result of reading port

    ' loop until there is something in the buffer i.e read.Nb > 0
        while read.Nb = 0
             CallDll #user,"readComm",_
                    idComDev as ushort,_    'obtained from opencomm
                    read.Buffer$ as ptr,_   ' read buffer
                    read.Bytes as ushort,_  ' number of bytes to read
                    read.Nb as ushort       ' number of bytes read

               ' for d = 1 to 1000
               ' next d
               ' small delay; may (or may not) be necessary
        wend
        read.Txt$ = Trim$(read.Buffer$)      ' remove blanks,Chr$(13)&      
                                             ' Chr$(0)

   return

6c) flushing the port buffers
    Often used before reading the port 

'************************************
'* [flush]                          *
'* sub #3 flush port buffer         *
'* uses User.dll function readComm  *
'* var                              *
'*	flush.Q		     	    *	
'************************************

' flushes queues i.e serial port buffers
[flush]
            fnQueue = flush.Q                '0 = transmission
                                             '1 = receiving queue

            CallDll #user,"FlushComm",_
                    idComDev as ushort,_
                    fnQueue as ushort,_
                    flushResult as ushort   ' 0 if ok
             

        if flushResult <> 0 then
            Notice " Error" + chr$(13) + _
                   "problem flushing queue"+str$(flushQ)
         end if


Finally the port must be closed before exiting the program

'7-Finally closing the port 

   CallDll #user,"CloseComm",_
            idComDev as ushort,_
            result as void
  
   close #user	

	

Now lets look at things under LB3!

Carl has done us a favor, by building into LB3 
most of the work for the serial port.
As described in the new documentation, LB3 
uses Windows communication API.

With LB3 there are only 4 steps needed to use the serial port!

Before using the port you may want to change the size of the buffers.
This must be done before opening the port.
Just set Com variable to the size you want i.e Com = 8096 ( 8k)

1- Open port

	Open "COMn:baud,parity,data,stop,CS,Ds,PE,RS" for random as #com

	For I/O boards I have found that the following usually works:

	Open "COM1:9600,N,8,1,CS0,DS0,RS"

	i.e baud rate 9600, No parity, data length 8 bits, 1 stop bit
	    both the CTS and DSR should be set to zero 
            the default is 1000 millisecond time out, this often 
            causes the program to hang. With the io boards that 
            I use, I have found that only CS0 and DS0 work. 
	    and finally the request to send (RS) is disabled


2- Write to the port		
	
	nothing could simpler, just print to it !

	print #com,message$

3- Reading the port
	
	Only a few more lines of code are needed

	
    	while lof(#com) < NbofBytesToRead
		'do nothing
      wend
 	readport$ = input$(#com,lof(#com))	

4- Finally closing the port

	Close #com



In the lab that I work, I use IO boards from ONTRAK control 
systems.  The boards are called ADRs. They have 8 relay 
outputs, 4 contact or TTL inputs and an input that can 
count events.  The following is the bare bones program 
( no gui )that I use to test the boards

To help me track what's going on with the boards and/or 
com errors, every step concatenates the LOG$.

'Progarm ADR

Log$ = ""

open "com1:9600,n,8,1,cs0,ds0,rs" for random as #com
	Log$ = "Opening com1"+chr$(13)
oncomerror [error]

ADR$="2" 'board address from 0 to 9 change as needed

print " all relays being set"
for R = 0 to 7
   f$= setRelay$(ADR$,R) : print R;f$
    for t = 1 to 2000: next t
next R


'test read
print " reading port with interrupt request"
 s= setIE(ADR$)
 result$=readADR$(ADR$)

    print "board : ";left$(result$,1)
    print "input : ";mid$(result$,2)


print " resetting all relays"
 for R = 0 to 7
    r$ = resetRelay$(ADR$,R)
    print R;r$
    for t = 1 to 2000 : next t
  next R




print " event counter test "
print " a) clearing counter"
    c = clearCounter(ADR$)

print" b) setting counter to 5"
    sc = setCounter(ADR$,5)
print" c) please trigger 5 times"
print "     waiting for counter interrupt... "
     dat$ = readCounter$(ADR$)
    print" >>   counter toggled   <<"
    print"      board nb "; left$(dat$,1)
    print"      input nb "; mid$(dat$,2,1)

goto [quit]

[error]

    print "comm problem";ComError$	
	Log$ = Log$+ComError$+chr$(13)
	
    goto [quit]



[quit]

' save Log$ incase of bugs or problems

	Open "LogBook" for output as #lg
		print #lg,Log$
	close #lg

print " all done "
close #com
End

' sets i.e closes relay
function setRelay$(board$,relay)

    message$=board$+"SK"+str$(relay)+chr$(13)
    print #com,message$
    
    setRelay$ = "true" 
	Log$ = Log$+message$+chr$(13)	
    
 
end function

'resets opens relay
function resetRelay$(board$,relay)
    message$=board$+"RK"+str$(relay)+chr$(13)
    print #com,message$
    
    resetRelay$ = "true"	
    Log$ = Log$+message$+chr$(13)
end function

'sets interrupt
function setIE(board$)
 it$ = board$+"IE"+chr$(13)
 print #com,it$
    setIE=1
	Log$ = Log$+"interrupt enabled"+chr$(13)
end function

'reads io board

function readADR$(board$)

    while lof(#com) < 3 ' the ADR always sends back 3 digits
        wend
 readADR$ = input$(#com,lof(#com))
 Log$ = Log$+"read board"+chr$(13)	
end function

'clears 16bit counter

function clearCounter(board$)

    ct$ = board$+"CE"+chr$(13)
    print #com,ct$
 clearCounter = 1
 Log$=Log$+"counter cleared"+chr$(13)
end function

'sets counter to specified value

function setCounter(board$,count)
    ct$ = board$+"TL"+str$(count)+chr$(13)
    print #com,ct$
  setCounter = count
  Log$ = Log$ +"Counter set to : "+str$(count)+chr$(13)
end function

'reads counter
function readCounter$(board$)

    while lof(#com) < 3
        wend
 readCounter$ = input$(#com,lof(#com))
 Log$ =Log$+"read counter"

end function


[Ed: Because word wrap may have distorted the code above,
the code and the entire article are also available as an
attachment.  It is the file titled : SerialComInLB.txt]

---------------------------------------------------------
---------------------------------------------------------
REVIEW : Image321.DLL Reviewed by David Drake

Image321.dll is Picture-Perfect (Almost)

Alyce Watson has released a new 32-bit image manipulation
DLL for any 32-bit programming language.  [Ed: you can
get the DLL and documentation from Alyce's Restaurant,
URL - http://iquizme.0catch.com/lb/ - click on Tools for
Liberty Basic 3.]  The DLL incorporates functions for 
altering the color or appearance of images, scaling, 
rotation and mirroring, sprite tools, and more.  It's 
small size (36K, I believe) makes it light on the 
downloads.  Because Alyce wrote it with Liberty BASIC in 
mind, the DLL calls are simple enough for even the newer 
programmers among us.

Positive attributes:
* Image321 is relatively fast because it was written in 
  C++ and compiled.  Smaller images are altered instantly.  
  Very large images may take a few seconds.  Alyce 
  developed some nice algorithms to do the color and image 
  effects.
* It is comprehensive.  With Image321 you can do most of 
  the save basic editing functions as Paint Shop Pro.
* It is easy to use.  Since you manipulate the image in 
  memory, and designate it with the image's handle, you 
  can easily manage your images.  You can even manipulate 
  multiple images in memory.

Negative attributes:
* Image321 does not have built-in saving capability, which 
  means that, once an image is edited, you are limited to 
  the graphics saving capability of your programming 
  language.  In this case, Liberty BASIC's GETBMP and 
  BMPSAVE commands limit you to saving what can be 
  viewed on the computer screen and no more.  Very large 
  images that extend beyond the boundaries of the screen 
  cannot easily be written to disk.  No doubt some 
  intrepid programmer can find a work-around for this!

Image321.DLL includes the following functions (taken 
directly from the image321.bas demo program, with a few 
editor [David Drake] comments):

   * About - Opens an ABOUT box for the DLL
   * BitmapWidth(hBmp)
   * BitmapHeight(hBmp)
   * DrawBitmap(hBmp,hWnd,x,y)
   * DuoTone(hBmp,hWnd,nRed,nGreen,nBlue,x,y) -
         AND bitwise operator, with RGB specified, 
         each 0-255
   * Negative(hBmp, hWnd, x, y) -
         invert colors like photo negative
   * ChangeAll
         (hBmp,hWnd,xSource,ySource,nRed,nGreen,nBlue,x,y) -
         change all pixels the same color as pixel at 
         xSource,ySource
   * ColorSwap(hBmp,hWnd,nRed,nGreen,nBlue,x,y) - 
         0=make this color red,1=make this color green,
         1=make it blue so nRed=2 means make all red pixels 
         blue, etc.
   * FloodFillIt
         (hBmp,hWnd,xSource,ySource,nRed,nGreen,nBlue,x,y) -
         flood fill from xSource,ySource to be RGB specified
   * GrayScale(hBmp,hWnd,x,y)
   * Colorize(hBmp,hWnd,nRed,nGreen,nBlue,x,y) - 
         Creates pic in strong tones of color specified; 
         if nRed<>0 then use red in colorization, if 
         nRed=0 then don't use red in colorization, etc.
   * Hue(hBmp,hWnd,nRed,nGreen,nBlue,x,y) - 
         Creates pic in all colors, but hue of color 
         specified.  If nRed<>0 then use red in colorization, 
         if nRed=0 then don't use red in colorization, etc.
   * Tint(hBmp,hWnd,nRed,nGreen,nBlue,x,y) - Creates pic in 
         lighter tones of color specified. If nRed<>0 then 
         use red in colorization, if nRed=0 then don't use 
         red in colorization, etc.
   * Brightness(hBmp,hWnd,nBright,x,y) - 
         nBright=percent to brighten: 200 is twice as bright, 
         50 is half as bright.
   * Contrast(hBmp,hWnd,x,y) - 
         increases contrast between light and dark areas 
         (not user-definable)
   * Midtone(hBmp,hWnd,x,y) - 
         decreases contrast between light and dark areas 
         (not user-definable)
   * Soften(hBmp,hWnd,x,y)
   * Sharpen(hBmp,hWnd,x,y)
   * Pixelate(hBmp,hWnd,x,y)
   * Emboss(hBmp,hWnd,x,y)
   * BlendPictures(hBmp,hBmp2,hWnd,x,y) - 
         hBmp2 will be blended onto hBmp. If hBmp2 is 
         smaller than hBmp, it will be tiled. This is a 
         particularly cool effect (ed.)
   * Blur(hBmp,hWnd,x,y)
   * Rotate(hBmp,hWnd,angle,bgColor) - 
         use angle between 0 and 360, bgColor=0 for black, 
         bgColor=1 for white
   * RotateWidth(hBmp,hWnd,angle) -
         width needed to display rotated bmp
   * RotateHeight(hBmp,hWnd,angle) -
         height needed to display rotated bmp
   * ChangeSize(hBmp,hWnd,x,y,nWidth,nHeight) -
         display in pixel size indicated
   * FlipMirror(hBmp,hWnd,x,y,nMirror,nFlip) - 
         nMirror=1 will mirror, nMirror=0 will not mirror, 
         nFlip=1 will flip, nFlip=0 will not flip.  Can be 
         flipped and mirrored at same time
   * Scale(hBmp, hWnd, x, y, nScale) - 
         nScale is percentage: nScale=50 means half size, 
         200 means twice size
   * PartialBitmap(hBmp,hWnd,x,y,nWidth,nHeight) -
         displays part of bmp at x,y, width nWidth, height 
         nHeight
   * AddMask(hBmp,hWnd) -
         adds mask above sprite... sprite must have black 
         background
   * DrawSprite(hBmp,hWnd,x,y) -
         draws a sprite at x,y (sprite must have black 
         background, with proper mask above)
   * GetRed(color) - 
         gets red component of long color value
   * GetGreen(color) - 
         gets green component of long color value
   * GetBlue(color) - 
         gets blue component of long color value
   * MakeRGB(nRed,nGreen,nBlue) - 
         makes long colorref from red(0-255),green(0-255),
         blue(0-255)
   * GetPixelColor(hWnd,x,y)

Possible applications for the Image321.dll:

* Image editor (in the works)
* Game sprite/image manipulation
* Cool graphical effects built-in
* Alter images to where they are useless to an outside 
  person, but use the dll to restore the image's original 
  properties to use in your program (a kind of copy 
  protection or visual encryption)
* Image viewer that scales images to fit on screen or 
  zoom tightly into areas on the image


[Ed: A couple weeks after David graciously sent me this
review (which I confess I forced out of him - sorry 
David), he released Liberty BASIC Image321 Editor.  I
will let David tell you about it in his own words.] 

Hello all.

Warning: Shameless promotion of free Liberty BASIC 
program to follow.

If you are interested, I've just made available an image 
editing program written in, of course, LB. Using Alyce 
Watson's perfectly primo Image321.DLL and Ken Nishita's 
Nviewlib.DLL, the Image321 Editor will load many image 
formats, save as bitmap or jpg, rotate, scale, resize, 
crop, tint, hue, emboss, sharpen, soften, colorize, 
grayscale... And more.

Download the source code and dll's here:
http://www.foundrysearch.com
(Scroll to the bottom and look under "What's New")

One known issue: Saving as a JPG image makes an odd 
little strip on the right edge of the picture. If anyone 
can fix this, I'd sure appreciate it.

- David Drake

---------------------------------------------------------
---------------------------------------------------------
NOTEWORTHY : Translating Documentation

[Ed: I grabbed this little gem off the Liberty Basic 
Group during the month.  I thought it was interesting
and appropriate to our growing audience of people 
who do not speak English (and forms similar) as their
primary language.]


Hi,

As Liberty BASIC is growing in popularity people from all 
around the world would be trying to use it..

Since Liberty BASIC Docs are now available online...
If English isn't your main language and you can't fully 
comprehend the documentation then you can always use something 
like this:

[Ed: you are going to have to reassemble these links as they
are more than one line long - sorry]

---link

http://translate.copernic.com:8090/
gen_home.en.html?AlisTargetHost=localhost

---end link


All you do is give the above mentioned page a click.. Then type in 

--- link

www.libertybasicuniversity.com/lb3docs/index.html

--- end link


you can translate it into:

Spanish
French
German
Italian
Japanese
Portuguese
Simplified Chinese
Traditional Chinese


Here is a sample link.. for the Spanish translation :-)

---Link

http://translate.copernic.com:8090/?AlisUI=frames_ex/
gen_toolbar&AlisSourceLang=en&AlisTargetLang=es&AlisUILang=
en&AlisTargetURI=http%3A//www.libertybasicuniversity.com/
lb3docs/index.html

--- end link

Best of all this is free..

I don't know how good the translation is :-( as I can only 
read and write and speak English and American... :-) ( sorry 
had to put that in... Lol)

I'm Sure that there are other translation services out 
there.. If this one isn't to your liking

PS: Please watch out for line wraps

NOTE: As this service will translate ALL the English words 
it knows into the other language.. You'll still need to 
refer to the English version for Command Syntaxes, Reserved 
words, LB Specific commands, functions, variables


---------------------------------------------------------
---------------------------------------------------------
ADVANCED: Implementing an editor with Scintilla.dll

Mitchell sent me a really neat piece of work that he has 
poured many hours into.  He has adapted a DLL to Liberty
Basic that is useful for building programmers editors. 

Because the article is mostly annotated code, and most lines
would wrap if they were mailed as straight text, I have 
decided to offer the intro that Mitchell wrote and then 
include the four files that make up the package as a 
single zipped archive.  To read the rest of the article 
(the annotated code), unzip the archive and take a look
at scintilla.txt.  To run the program (and I highly 
recommend you do), open scintilla.bas in a LB3.01 (you
must have at least 3.01), open the bas file and run!

Here is what Mitchell had to say:

Here is the code for scintilla.  You should also download 
the full documentation from www.scintilla.org.  It will 
help you add to this program.

This works off the base of VB syntax coloring but I 
edited the C++ source for the VB syntax colorer to match 
LB, and re-compiled it.  I called the new dll 
SciLexerLB.dll, and it contains LB coloring in place of VB.  
There is also still a small bug in it where the default 
coloring becomes the keyword styling, only if there is no 
text after it.  So just put an extra carraige return at the 
end to fix it.

Thank you Mitchell.

---------------------------------------------------------
---------------------------------------------------------
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?

---------------------------------------------------------
---------------------------------------------------------
ATTACHMENTS

There are four attachments included with this newsletter:

1) LBNews_No97.txt -     a text version of the article
2) SerialComInLB.txt - a text version of the Serial
                       Communications Article by Dean Jolly
3) Scintilla.zip -     a zip file containing all the material
                       Mitchell submitted about scintilla.dll
4) LBNR.zip -          Liberty Basic Newsletter Reader Demo
                       (try reading the LBNews_No97.txt with it)

---------------------------------------------------------
---------------------------------------------------------
Comments, requests, submissions or corrections: 
Simply reply to this message, or contact a member of the team!

			The Team:
	Alyce Watson: alycewatson@charter.net
	Brad Moore: brad.moore@weyerhaeuser.com
	Tom Nally:  SteelWeaver52@aol.com
	Carl Gundel: carlg@libertybasic.com
	Bill Jennings: bbjen@bigfoot.com
---------------------------------------------------------
---------------------------------------------------------
