---------------------------------------------------------
The Liberty Basic Newsletter - Issue #94 - MAR 2002
    2002, http://groups.yahoo.com/group/lbnews/
             All Rights Reserved
---------------------------------------------------------
"Never let the fear of striking out get in your way."
	- Babe Ruth
---------------------------------------------------------
In this issue:
	Contest Reminder
	Using Color Statements to Color Controls
	Updating the Open Source Editor - Colored Textboxes
	Tip Corner - INPUTTO$
	Spotlight - Development4Life.net
	Why Development4Life? by John Magne Spilling
	Writing to the console from Liberty BASIC
		- sample program by Brent Thorn
		- API documentation from MS
	Submissions
	Volunteer to Publish the LB Newsletter!

---------------------------------------------------------
---------------------------------------------------------
CONTEST REMINDER

	2002 Liberty BASIC Challenge
		***********

Win a registration for Liberty BASIC 3!
Have YOUR program featured on the official
Liberty BASIC homepage!

		***********

Contest Website:

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

		***********

Starting Date:  February 16, 2002
Ending Date:    March 31,    2002
Polls Open:     April 1,     2002
Polls Close:    May 1,       2002

RULES:
This contest will last for six weeks.  
There are four categories:

1. Newbie - pick from two challenges
2. Oldbie - pick from two challenges
3. Game   - sprite arcade game
            pick from two challenges
4. Open   - anything goes!


Contestants must follow the rules provided for the 
category they wish to enter.  All code must be submitted 
in the form of source code.  Include TKNs also so that
unregistered users may try the program.

Entries must be uploaded to the files area of lbnews in
the folder called 2002 Liberty BASIC Challenge.  The files 
area will be closed on April 1, so all entries must be 
uploaded by March 31:

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

At the top of the code, include your name, your email address, 
and the category for the program entry.  Also include the 
version of Liberty BASIC needed to run the program.

Polls will open on April 1, and remain open until May 1.  
During that time, vote here:

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


PRIZES:
Each participant will receive his choice of a registration 
of LB Workshop or Game Workshop.  Write to Alyce Watson
mailto:alycewatson@charter.net after you have uploaded
your entry and specify whether you would like a registration
to LB Workshop or Game Workshop.

Winning programs will be featured on the official Liberty BASIC 
website, and the authors will receive a FREE registration for 
Liberty BASIC 3!

See the complete contest guidelines in the files area of
our lbnews website, in the "2002 Liberty BASIC Challenge"
folder:

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

---------------------------------------------------------
---------------------------------------------------------
USING COLOR STATEMENTS TO COLOR CONTROLS

Windows and controls can be colored by using color statements.
The possible color statements are:

	TextboxColor$
	TexteditorColor$
	ListboxColor$
	ComboboxColor$
	ForegroundColor$
	BackgroundColor$

If no color statements are used, then default colors will
appear on windows and controls.  Color statements require
named Liberty BASIC colors.  Case doesn't matter in the color
names, but it DOES matter in the variable names.  TextboxColor$
is correct.  TEXTBOXCOLOR$ is incorrect and will not be 
recognized as a command by Liberty BASIC. If Liberty BASIC 
doesn't recognize the color name in the color statement,
then it will use the default value for that color.

  Usage:
	TextboxColor$      = "Red"
	TexteditorColor$   = "blue"
	ListboxColor$      = "buttonface"
	ComboboxColor$     = "GREEN"
	ForegroundColor$   = "YelLow"
	BackgroundColor$   = "uh oh"

The BackgroundColor$ in the example above will be the default
color, because Liberty BASIC doesn't recognize "uh oh" as a
named color.  Note that the color names are not case-sensitive,
but the variable names, like TextboxColor$, as variables,
must be in the correct case.

  Named colors:
	red
	darkred
	blue
	darkblue
	green
	darkgreen
	pink
	darkpink
	cyan
	darkcyan
	yellow
	brown
	white
	black
	lightgray
	darkgray
	buttonface (varies with user's color scheme)

It is possible to have only one ForegroundColor$ for each
window, so all text, statictext, radiobutton, checkbox and
groupbox captions will appear in the designated 
ForegroundColor$.

It is also possible to have only one BackgroundColor$ for
each window.  Since statictext uses the designated
BackgroundColor$ for its color, it is not possible to have
different colors for separate statictext controls on a single
window.  This also applies to groupboxes, radiobuttons and
checkboxes.

Buttons ignore color statements.  Buttons are always filled with
the color set by the user's system value for buttonface.  This 
color is defined by Liberty BASIC as "buttonface" and it changes 
depending upon the user's color scheme.

Controls that can be colored individually are:

	Textbox,    with TextboxColor$
	Texteditor, with TexteditorColor$
	Listbox,    with ListboxColor$
	Combobox,   with ComboboxColor$

If a single control color statement is issued before 
the controls are created, then all controls of that type 
will be the same color.  In the following example, all 
three textboxes will be cyan-colored.

    TextboxColor$="cyan"
    textbox #main.1, 10,10,100,24
    textbox #main.2, 10,40,100,24
    textbox #main.3, 10,70,100,24

It is possible to have several controls of the same type, each
with its own unique color.  To accomplish this, issue
a new color statement before the statement to create each
control, and the control will use the designated color.  Do
this for each color change desired.  The following code will
produce three textboxes, one green, one blue and one red.

	TextboxColor$="green"
	textbox #main.1, 10,10,100,24

	TextboxColor$="blue"
	textbox #main.2, 10,40,100,24

	TextboxColor$="red"
	textbox #main.3, 10,70,100,24


The following self-contained demo shows how to have colorful
controls in Liberty BASIC windows.

nomainwin

WindowWidth=600:WindowHeight=400

list$(1)="First"
list$(2)="Second"
list$(3)="Third"

ForegroundColor$="yellow"
BackgroundColor$="darkcyan"

button #main.quit, "Quit",[quit],UL,450,320,100,24

groupbox #main.g, "Groupbox",120,10,120,120
radiobutton #main.r, "Radiobutton",[quit],[quit],130,40,110,30
checkbox #main.c, "Checkbox",[quit],[quit],130,80,110,30
statictext #main.s, "Statictext",10,100,100,24

TextboxColor$="green"
textbox #main.1, 10,10,100,24

TextboxColor$="blue"
textbox #main.2, 10,40,100,24

TextboxColor$="red"
textbox #main.3, 10,70,100,24

TexteditorColor$="darkgreen"
texteditor #main.4, 10,140,200,160

TexteditorColor$="darkblue"
texteditor #main.5, 220,140,200,160

ComboboxColor$="darkred"
combobox #main.c1, list$(),[quit],10,320,200,200

ComboboxColor$="darkpink"
combobox #main.c2, list$(),[quit],220,320,200,200

ListboxColor$="brown"
listbox #main.b1, list$(),[quit],250,20,100,100

ListboxColor$="darkred"
listbox #main.b2, list$(),[quit],360,20,100,100


open "Color Demo" for window_nf as #main

#main.1 "One";
#main.2 "Two";
#main.3 "Three";
#main.4 "Four";
#main.5 "Five";
#main.c1 "selectindex 1"
#main.c2 "selectindex 2"
#main.b1 "selectindex 1"
#main.b2 "selectindex 2"

#main "trapclose [quit]"
wait

[quit]
close #main:end

---------------------------------------------------------
---------------------------------------------------------
UPDATING THE OPEN SOURCE EDITOR - COLORED TEXTBOXES

It is possible to have multiple controls of the same type
on a window, and allow each to have its own, separate
color.  To do this, issue a color statement before each 
control is created.

We've done it in two of the dialogs in the Open Source
Editor.  In the bitmap previewer, we have one textbox
in pink and the other in blue.  In the array maker, we
have one textbox in cyan and the other in yellow.

'in the bitmap previewer:
    TextboxColor$="blue"
    textbox #bit.t1, 20,35,300,26
    TextboxColor$="pink"
    textbox #bit.t2, 20,65,300,26


'in the array  maker:
    TextboxColor$="cyan"
    textbox #am.arrayName, 6, 31, 136, 25
    TextboxColor$="yellow"
    textbox #am.arrayItem, 6, 86, 136, 25

This technique will work for the following control colors:

	TextboxColor$
	TexteditorColor$
	ListboxColor$
	ComboboxColor$

See the updated Open Source Editor in the attached zip file.


---------------------------------------------------------
---------------------------------------------------------
TIP CORNER - INPUTTO$

INPUTTO$(#handle, delim$))

This function reads from the file #handle up to the character 
specified in delim$ or to the end of the line, whichever comes 
first.  This is handy for reading files which contain comma, 
tab, pipe, or other delimited items.

  'display each comma delimited item in a file on its own line
  open "inputto test.txt" for input as #test

  while eof(#test) = 0
      print inputto$(#test, ",")
  wend
  close #test

Remember, when reading input from files in a loop, always check
for the End Of File "EOF" marker to avoid an error that could
crash your program.  EOF(#file) will be 0 if the end of file
has not yet been reached.  When it is no longer equal to 0, then
stop reading input and close the file.

Here is a simple demo that reads data into a file, and delimits
it with the pipes character.  This is found on the keyboard as
the uppercase version of the backslash  "|".  Don't forget...
you must end every print statement with a semicolon if you
do not want to print a carriage return [chr$(13)] to the file!

'create a simple, tab delimited file:
open "atest.dat" for output as #f

print #f, "Gundel, Carl" + "|";
print #f, "Bush, George W." + "|";
print #f, "Bond, James Bond" + "|";
print #f, "Liberty BASIC" + "|";
print #f, "Wow!" + "|";
print #f, "Hello, World?" + "|"

close #f

'now open the file:
open "atest.dat" for input as #g

'read the file directly into an array:
while EOF(#g)=0
    a$(total)=inputto$(#g, "|")
    total=total+1
wend

close #g

'print contents of array:
for i = 0 to total
    print a$(i)
next


'read in a single line from the file:
open "atest.dat" for input as #h
    line input #h, item$
    print item$
close #h

end


Note that using the pipes to delimit items in the file
allows you a lot of flexibility when managing the data
that is read from the file.  It is very easy to fill an 
array directly with items from the pipes delimited file.

Look at the last routine in the program.  It reads in an
entire line from the file.  You can see what it looks
like as a single line with a pipes character between each
item.

---------------------------------------------------------
---------------------------------------------------------
Development4Life.net

This website has resources and information for many 
programming languages, including Liberty BASIC.  
Find it here:

http://development4life.net/

The webmaster is John Magne Spilling.  He has provided a
tremendous variety of programming resources on this site.
Development4Life.net includes: 

	-News 
	-Forum 
	-Articles 
	-Reviews 
	-Downloads 
	-Interactive FAQ 
	-Link Directory 
	-Online Games
	-Surveys
	-Search Site
 
The languages featured include: 
	Liberty BASIC
	Visual Dialog Script
	IBASIC
	Profan
	Dark BASIC
	RapidQ

The downloads section includes trial versions of many of 
the featured languages, and it is a mirror site for 
downloading the popular ABC (All BASIC Code) packets.

http://development4life.net/modules.php?op=modload&name=Downloads&file=index


The forum contains message boards for many areas of 
programming, and separate message boards for many of the 
featured programming languages.

http://development4life.net/board/index.php


The website also features a programmer's banner exchange.

http://development4life.net/united/

---------------------------------------------------------
---------------------------------------------------------
Why Development4life.net? by John Magne Spilling

I as many other people have been surfing and searching the 
net for software developing related sites, that is not 
limited to one programming language, but relates to software 
and game development in general - with no luck.

I therefore decided to start development4life.net to serve as 
a home for all developers.  The site currently focuses on LB, 
since it's the only language that I really know pretty well, 
and I belive it's the best language to get started with 
programming, but many members uses multiple languages.

The name was partly thought through. As one of the forum members 
said, Development is what we do, and when you get started it 
becomes a part of your life. But the name sure has its 
disadvantages; one member asked a friend to visit development4life.net. 
He replied that his health was fine. 

So I started out, using pure HTML, making a portal to the computer 
developing world. Of course that did not work. And thanks to all 
the free CGI programmers out there I was able to use PostNuke. 
PostNuke is a free portal system licensed under the GNPU license. 
My CGI knowledge is limited, but since I know programming in general 
I can see the structure and tweak the scripts into my command 
(most of the time). I also bought a forum, so we all could discuss 
code and issues that we meet on our way. I'm glad that so many 
members with all their knowledge have decided to join us, and 
we will always have room for more, both experienced and newer 
programmers.

The site is user based, which means that you, the member, are in 
charge of the content of the site. Posting an article, news, reviews, 
links or downloads is easy. There are several forms that can be 
accessed from the main navigation bar. When your contribution is 
received, one of the moderators will publish the contribution on 
the site. You do not need to be registered to make a contribution, 
but your name will show up as "Shy". If you want your name shown 
as the author and you want to take part in the contest you must 
be registered. Registration is free of course, and you do not 
receive any spam mail. You've got my word on that one.


Features of Development4life.net
-Articles, news and tutorials
You can read articles, news and tutorials that have been posted 
by other members. All resources are searchable and can be listed 
by topic. You can also say your opinion or ask a question by 
posting a comment.

-Reviews
There are reviews of tools and programming languages. We are also 
interested in reviews of your (or others) home made creations.

-Links and Downloads
We've got a link and a download directory. Download home made 
creations from fellow programmers, visit development related web 
sites. Rate and post comments or even a review of the resources.  
If some of the resources are yours you can get your website or 
creation rated directly from your site.

-Forum
A forum with the most helpfull friendly users. They've got 
experience with many languages, and authors of two 
(rumors say three) programming languages, yes that 
includes "our" Carl.

I'm always working on the site, and each month you can expect to 
see new features, small or large. Sometimes it is a new look, 
sometimes a totaly new feature. This will continue until all 
online tools for developers are avaiable at the site. At the 
moment there are three projects in development:  an advanced 
visitor counter for United Developers Banner Network members, 
a poll that you can have on your site (no scripts needed) and 
we will run a monthly "Coder of the Month Award". The last one 
is probably ready when this issue of the LB newsletters is out. 

You might say that the sites features are too much related to 
webmasters, but the special part of this is that all sites have 
to be computer related. And developers get advantages. You might 
wish that you only wanted programming related sites included, but 
if you want to show your site or product to non-programming users 
we will need more than programming sites.

United Developers Banner Network is also a part of development4life.net. 
As the name says, it is a banner exchange for developers. But we also 
accept computer in general sites since we want users of our creations, 
and potential new programmers. You can also set which type of web sites 
you want to target, and I believe it's the only banner exchange that 
has Liberty BASIC as a category. But one should note that two or more 
sites must be listed in that targeted category in order for the network 
to work. 

Featuers of the banner network:
Developers gets 10.000 starting impressions
None developing sites get 5.000 starting impressions, 
that is still a good deal.
The exchange ratio is 2:1
For each click the banner on your site gets, you get 15 impressions. 
(Without charging another member)
For each click the network banner gets, you get 20 impressions
If your site has free open source made by you, you get 1.000 free 
impressions each month.
Target you impressions
You get a free visitor counter
You can run your own newsletter, without any ads!
Banner Clicks opens in a new window
The direct url to United Developers Banner Network is 
http://development4life.net/united/

---------------------------------------------------------
---------------------------------------------------------
WRITING TO THE CONSOLE FROM LIBERTY BASIC
- sample program by Brent Thorn, used by permission
- mailto:lbgui@aol.com

NoMainWin
Open "Kernel32" For DLL As #kernel
CallDLL #kernel, "AllocConsole", success As long
If success Then

CallDLL #kernel, "GetStdHandle", _
_STD_INPUT_HANDLE As long, _
hStdIn As long

CallDLL #kernel, "GetStdHandle", _
_STD_OUTPUT_HANDLE As long, _
hStdOut As long

buffer$ = "Press any key to close this window... " + Chr$(0)
buflen = Len(buffer$) - 1
Struct bytes, number As ulong

CallDLL #kernel, "WriteFile", _
hStdOut As long, _
buffer$ As ptr, _
buflen As long, _
bytes As struct, _
0 As long, _
success As long

CallDLL #kernel, "ReadFile", _
hStdIn As long, _
buffer$ As ptr, _
1 As long, _
bytes As struct, _
0 As long, _
success As long

CallDLL #kernel, "FreeConsole", success As long
End If
Close #kernel
End

---------------------------------------------------------
---------------------------------------------------------
WRITING TO THE CONSOLE FROM LIBERTY BASIC
- API documentation from MicroSoft

To learn more about writing to the console, go here:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/conchar_5ehx.asp

MSDN PLATFORM SDK REFERENCE FOR THE FUNCTIONS
	AllocConsole
	FreeConsole
	GetStdHandle
	WriteFile
	ReadFile
	GetLastError
**********************
AllocConsole
The AllocConsole function allocates a new console for the 
calling process. 

C syntax:
BOOL AllocConsole(void);

LB syntax:
CallDLL #kernel, "AllocConsole", success As long


Parameters
This function has no parameters. 

Return Values
If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get 
extended error information, call GetLastError. 

Remarks
A process can be associated with only one console, so the 
AllocConsole function fails if the calling process already 
has a console. A process can use the FreeConsole function 
to detach itself from its current console, and then it can 
call AllocConsole to create a new console or AttachConsole 
to attach to another console. If the calling process creates 
a child process, the child inherits the new console. 

AllocConsole also sets up standard input, standard output, and 
standard error handles for the new console. The standard input 
handle is a handle to the console's input buffer, and the 
standard output and standard error handles are handles to 
the console's screen buffer. To retrieve these handles, use 
the GetStdHandle function. 

This function is primarily used by graphics applications to 
create a console window. Graphics applications are initialized 
without a console. Console applications are normally initialized 
with a console, unless they are created as detached processes 
(by calling the CreateProcess function with the DETACHED_PROCESS 
flag). 

**************************
FreeConsole
The FreeConsole function detaches the calling process from its 
console. 

C syntax:
BOOL FreeConsole(VOID);

LB syntax:
CallDLL #kernel, "FreeConsole", success As long


Parameters
This function has no parameters. 

Return Values
If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended 
error information, call GetLastError. 

Remarks
If other processes share the console, the console is not destroyed, 
but the calling process cannot refer to it. 

A process can use FreeConsole to detach itself from its current 
console, and then it can call the AllocConsole function to create 
a new console or AttachConsole to attach to another console. 

******************************
GetStdHandle
The GetStdHandle function retrieves a handle for the standard input, 
standard output, or standard error device. 

C syntax:
HANDLE GetStdHandle(
  DWORD nStdHandle   // input, output, or error device
);

LB syntax:
CallDLL #kernel, "GetStdHandle", _
_STD_INPUT_HANDLE As long, _
hStdIn As long

CallDLL #kernel, "GetStdHandle", _
_STD_OUTPUT_HANDLE As long, _
hStdOut As long


Parameters
nStdHandle 
[in] Specifies the standard device for which to return the handle. 
This parameter can be one of the following values. 
Value Meaning 
STD_INPUT_HANDLE Standard input handle 
STD_OUTPUT_HANDLE Standard output handle 
STD_ERROR_HANDLE Standard error handle 


Return Values
If the function succeeds, the return value is a handle to the 
specified device.

If the function fails, the return value is the INVALID_HANDLE_VALUE 
flag. To get extended error information, call GetLastError. 

Remarks
Handles returned by GetStdHandle can be used by applications that 
need to read from or write to the console. When a console is created, 
the standard input handle is a handle to the console's input buffer, 
and the standard output and standard error handles are handles of the 
console's active screen buffer. These handles can be used by the 
ReadFile and WriteFile functions, or by any of the console functions 
that access the console input buffer or a screen buffer (for example, 
the ReadConsoleInput, WriteConsole, or GetConsoleScreenBufferInfo 
functions). 

All handles returned by this function have GENERIC_READ and 
GENERIC_WRITE access unless the SetStdHandle function has been 
used to set a standard handle to be some handle with a lesser 
access. 

The standard handles of a process may be redirected by a call to 
SetStdHandle, in which case GetStdHandle returns the redirected 
handle. If the standard handles have been redirected, you can 
specify the CONIN$ value in a call to the CreateFile function to 
get a handle to a console's input buffer. Similarly, you can 
specify the CONOUT$ value to get a handle to a console's active 
screen buffer. 

**********************
WriteFile
The WriteFile function writes data to a file and is designed 
for both synchronous and asynchronous operation. The function 
starts writing data to the file at the position indicated by 
the file pointer. After the write operation has been completed, 
the file pointer is adjusted by the number of bytes actually written, 
except when the file is opened with FILE_FLAG_OVERLAPPED. If the file 
handle was created for overlapped input and output (I/O), the 
application must adjust the position of the file pointer after 
the write operation is finished.

This function is designed for both synchronous and asynchronous 
operation. The WriteFileEx function is designed solely for 
asynchronous operation. It lets an application perform other 
processing during a file write operation.

C syntax:
BOOL WriteFile(
  HANDLE hFile,                    // handle to file
  LPCVOID lpBuffer,                // data buffer
  DWORD nNumberOfBytesToWrite,     // number of bytes to write
  LPDWORD lpNumberOfBytesWritten,  // number of bytes written
  LPOVERLAPPED lpOverlapped        // overlapped buffer
);

LB syntax:
CallDLL #kernel, "WriteFile", _
hStdOut As long, _
buffer$ As ptr, _
buflen As long, _
bytes As struct, _
0 As long, _
success As long


Parameters
hFile 
[in] Handle to the file to be written to. The file handle must 
have been created with GENERIC_WRITE access to the file. 
Windows NT/2000/XP: For asynchronous write operations, hFile 
can be any handle opened with the FILE_FLAG_OVERLAPPED flag by 
the CreateFile function, or a socket handle returned by the 
socket or accept function. 

Windows 95/98/Me: For asynchronous write operations, hFile can 
be a communications resource opened with the FILE_FLAG_OVERLAPPED 
flag by CreateFile, or a socket handle returned by socket or accept. 
You cannot perform asynchronous write operations on mailslots, 
named pipes, or disk files. 

lpBuffer 
[in] Pointer to the buffer containing the data to be written to the file. 

nNumberOfBytesToWrite 
[in] Specifies the number of bytes to write to the file. 
A value of zero specifies a null write operation. The behavior of a 
null write operation depends on the underlying file system. To 
truncate or extend a file, use the SetEndOfFile function. 

Named pipe write operations across a network are limited to 65,535 bytes. 

lpNumberOfBytesWritten 
[out] Pointer to the variable that receives the number of bytes written. 
WriteFile sets this value to zero before doing any work or error checking. 
Windows NT/2000/XP: If lpOverlapped is NULL, lpNumberOfBytesWritten cannot 
be NULL. If lpOverlapped is not NULL, lpNumberOfBytesWritten can be NULL. 
If this is an overlapped write operation, you can get the number of bytes 
written by calling GetOverlappedResult. If hFile is associated with an I/O 
completion port, you can get the number of bytes written by calling 
GetQueuedCompletionStatus. 

If I/O completion ports are used and you are using a callback routine to 
free the memory allocated to the OVERLAPPED structure pointed to by the 
lpOverlapped parameter, specify NULL as the value of this parameter to 
avoid a memory corruption problem during the deallocation. This memory 
corruption problem will cause an invalid number of bytes to be returned 
in this parameter. 

Windows 95/98/Me: This parameter cannot be NULL. 

lpOverlapped 
[in] Pointer to an OVERLAPPED structure. This structure is required if hFile 
was opened with FILE_FLAG_OVERLAPPED. 

If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter 
must not be NULL. It must point to a valid OVERLAPPED structure. If hFile 
was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the 
function can incorrectly report that the write operation is complete. 

If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not 
NULL, the write operation starts at the offset specified in the 
OVERLAPPED structure and WriteFile may return before the write operation 
has been completed. In this case, WriteFile returns FALSE and the 
GetLastError function returns ERROR_IO_PENDING. This allows the calling 
process to continue processing while the write operation is being completed. 
The event specified in the OVERLAPPED structure is set to the signaled 
state upon completion of the write operation. 

If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, 
the write operation starts at the current file position and WriteFile does 
not return until the operation has been completed. 

WriteFile resets the event specified by the hEvent member of the 
OVERLAPPED structure to a nonsignaled state when it begins the 
I/O operation. Therefore, there is no need for the caller to do so. 

Windows NT/2000/XP: If hFile was not opened with FILE_FLAG_OVERLAPPED 
and lpOverlapped is not NULL, the write operation starts at the offset 
specified in the OVERLAPPED structure and WriteFile does not return 
until the write operation has been completed. 

Windows 95/98/Me: For operations on files, disks, pipes, or mailslots, 
this parameter must be NULL; a pointer to an OVERLAPPED structure causes 
the call to fail. However, Windows 95/98/Me supports overlapped I/O on 
serial and parallel ports. 

Return Values
If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error 
information, call GetLastError. 

Remarks
Note that the time stamps may not be updated correctly for a remote file. 
To ensure consistent results, use unbuffered I/O. An application must meet 
certain requirements when working with files opened with 
FILE_FLAG_NO_BUFFERING: 

File access must begin at byte offsets within the file that are 
integer multiples of the volume's sector size. To determine a volume's 
sector size, call the GetDiskFreeSpace function. 

File access must be for numbers of bytes that are integer multiples of 
the volume's sector size. For example, if the sector size is 512 bytes, 
an application can request reads and writes of 512, 1024, or 2048 bytes, 
but not of 335, 981, or 7171 bytes. 

Buffer addresses for read and write operations must be sector aligned 
(aligned on addresses in memory that are integer multiples of the 
volume's sector size). One way to sector align buffers is to use the 
VirtualAlloc function to allocate the buffers. This function 
allocates memory that is aligned on addresses that are integer 
multiples of the system's page size. Because both page and volume 
sector sizes are powers of 2, memory aligned by multiples of the 
system's page size is also aligned by multiples of the volume's 
sector size. 

If part of the file is locked by another process and the write 
operation overlaps the locked portion, this function fails. 

Accessing the output buffer while a write operation is using the 
buffer may lead to corruption of the data written from that buffer. 
Applications must not write to, reallocate, or free the output buffer 
that a write operation is using until the write operation completes.

Characters can be written to the screen buffer using WriteFile with a 
handle to console output. The exact behavior of the function is 
determined by the console mode. The data is written to the current 
cursor position. The cursor position is updated after the write operation. 

The system interprets zero bytes to write as specifying a null write 
operation and WriteFile does not truncate or extend the file. To 
truncate or extend a file, use the SetEndOfFile function. 

When writing to a nonblocking, byte-mode pipe handle with insufficient 
buffer space, WriteFile returns TRUE with 
*lpNumberOfBytesWritten < nNumberOfBytesToWrite. 

When an application uses the WriteFile function to write to a pipe, 
the write operation may not finish if the pipe buffer is full. The 
write operation is completed when a read operation (using the ReadFile 
function) makes more buffer space available. 

If the anonymous read pipe handle has been closed and WriteFile attempts 
to write using the corresponding anonymous write pipe handle, the 
function returns FALSE and GetLastError returns ERROR_BROKEN_PIPE. 

The WriteFile function may fail with ERROR_INVALID_USER_BUFFER or 
ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding 
asynchronous I/O requests. 

To cancel all pending asynchronous I/O operations, use the CancelIo 
function. This function only cancels operations issued by the calling 
thread for the specified file handle. I/O operations that are canceled 
complete with the error ERROR_OPERATION_ABORTED. 

If you are attempting to write to a floppy drive that does not have a 
floppy disk, the system displays a message box prompting the user to 
retry the operation. To prevent the system from displaying this message 
box, call the SetErrorMode function with SEM_NOOPENFILEERRORBOX. 

*************************
ReadFile
The ReadFile function reads data from a file, starting at the position 
indicated by the file pointer. After the read operation has been 
completed, the file pointer is adjusted by the number of bytes actually 
read, unless the file handle is created with the overlapped attribute. 
If the file handle is created for overlapped input and output (I/O), 
the application must adjust the position of the file pointer after the 
read operation. 

This function is designed for both synchronous and asynchronous operation. 
The ReadFileEx function is designed solely for asynchronous operation. 
It lets an application perform other processing during a file read 
operation.

C syntax:
BOOL ReadFile(
  HANDLE hFile,                // handle to file
  LPVOID lpBuffer,             // data buffer
  DWORD nNumberOfBytesToRead,  // number of bytes to read
  LPDWORD lpNumberOfBytesRead, // number of bytes read
  LPOVERLAPPED lpOverlapped    // overlapped buffer
);

LB syntax:
CallDLL #kernel, "ReadFile", _
hStdIn As long, _
buffer$ As ptr, _
1 As long, _
bytes As struct, _
0 As long, _
success As long


Parameters
hFile 
[in] Handle to the file to be read. The file handle must have been created 
with GENERIC_READ access to the file. 

Windows NT/2000/XP: For asynchronous read operations, hFile can be any 
handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile 
function, or a socket handle returned by the socket or accept function. 

Windows 95/98/Me: For asynchronous read operations, hFile can be a 
communications resource opened with the FILE_FLAG_OVERLAPPED flag by 
CreateFile, or a socket handle returned by socket or accept. You cannot 
perform asynchronous read operations on mailslots, named pipes, or 
disk files. 

lpBuffer 
[out] Pointer to the buffer that receives the data read from the file. 

nNumberOfBytesToRead 
[in] Specifies the number of bytes to be read from the file. 

lpNumberOfBytesRead 
[out] Pointer to the variable that receives the number of bytes read. 
ReadFile sets this value to zero before doing any work or error checking. 
If this parameter is zero when ReadFile returns TRUE on a named pipe, the 
other end of the message-mode pipe called the WriteFile function with 
nNumberOfBytesToWrite set to zero. 

Windows NT/2000/XP: If lpOverlapped is NULL, lpNumberOfBytesRead cannot 
be NULL. If lpOverlapped is not NULL, lpNumberOfBytesRead can be NULL. 
If this is an overlapped read operation, you can get the number of bytes 
read by calling GetOverlappedResult. If hFile is associated with an I/O 
completion port, you can get the number of bytes read by calling 
GetQueuedCompletionStatus. 

If I/O completion ports are used and you are using a callback routine to 
free the memory allocated to the OVERLAPPED structure pointed to by the 
lpOverlapped parameter, specify NULL as the value of this parameter to 
avoid a memory corruption problem during the deallocation. This memory 
corruption problem will cause an invalid number of bytes to be returned 
in this parameter. 

Windows 95/98/Me: This parameter cannot be NULL. 

lpOverlapped 
[in] Pointer to an OVERLAPPED structure. This structure is required if 
hFile was created with FILE_FLAG_OVERLAPPED. 

If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter 
must not be NULL. It must point to a valid OVERLAPPED structure. If hFile 
was created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the 
function can incorrectly report that the read operation is complete. 

If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, 
the read operation starts at the offset specified in the OVERLAPPED structure 
and ReadFile may return before the read operation has been completed. In this 
case, ReadFile returns FALSE and the GetLastError function returns 
ERROR_IO_PENDING. This allows the calling process to continue while the 
read operation finishes. The event specified in the OVERLAPPED structure 
is set to the signaled state upon completion of the read operation. 

If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, 
the read operation starts at the current file position and ReadFile does 
not return until the operation has been completed. 

Windows NT/2000/XP: If hFile is not opened with FILE_FLAG_OVERLAPPED and 
lpOverlapped is not NULL, the read operation starts at the offset 
specified in the OVERLAPPED structure. ReadFile does not return until 
the read operation has been completed. 

Windows 95/98/Me: For operations on files, disks, pipes, or mailslots, 
this parameter must be NULL; a pointer to an OVERLAPPED structure causes 
the call to fail. However, Windows 95/98/Me supports overlapped I/O on 
serial and parallel ports. 

Return Values
The ReadFile function returns when one of the following is true: a write 
operation completes on the write end of the pipe, the number of bytes 
requested has been read, or an error occurs. 

If the function succeeds, the return value is nonzero. 

If the return value is nonzero and the number of bytes read is zero, 
the file pointer was beyond the current end of the file at the time of 
the read operation. However, if the file was opened with 
FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the return value is 
FALSE and GetLastError returns ERROR_HANDLE_EOF when the file pointer 
goes beyond the current end of file.

If the function fails, the return value is zero. To get extended error 
information, call GetLastError. 

Remarks
If part of the file is locked by another process and the read operation 
overlaps the locked portion, this function fails. 

An application must meet certain requirements when working with files 
opened with FILE_FLAG_NO_BUFFERING: 

File access must begin at byte offsets within the file that are integer
 multiples of the volume's sector size. To determine a volume's sector 
size, call the GetDiskFreeSpace function. 

File access must be for numbers of bytes that are integer multiples of 
the volume's sector size. For example, if the sector size is 512 bytes, 
an application can request reads and writes of 512, 1024, or 2048 bytes, 
but not of 335, 981, or 7171 bytes. 

Buffer addresses for read and write operations must be sector aligned 
(aligned on addresses in memory that are integer multiples of the volume's 
sector size). One way to sector align buffers is to use the VirtualAlloc 
function to allocate the buffers. This function allocates memory that is 
aligned on addresses that are integer multiples of the system's page size. 
Because both page and volume sector sizes are powers of 2, memory aligned 
by multiples of the system's page size is also aligned by multiples of the 
volume's sector size. 

Accessing the input buffer while a read operation is using the buffer may 
lead to corruption of the data read into that buffer. Applications must 
not read from, write to, reallocate, or free the input buffer that a read 
operation is using until the read operation completes.

Characters can be read from the console input buffer by using ReadFile 
with a handle to console input. The console mode determines the exact 
behavior of the ReadFile function. 

If a named pipe is being read in message mode and the next message is 
longer than the nNumberOfBytesToRead parameter specifies, ReadFile returns 
FALSE and GetLastError returns ERROR_MORE_DATA. The remainder of the 
message may be read by a subsequent call to the ReadFile or 
PeekNamedPipe function. 

When reading from a communications device, the behavior of ReadFile 
is governed by the current communication time-outs as set and retrieved 
using the SetCommTimeouts and GetCommTimeouts functions. Unpredictable 
results can occur if you fail to set the time-out values. For more i
nformation about communication time-outs, see COMMTIMEOUTS.

If ReadFile attempts to read from a mailslot whose buffer is too small, 
the function returns FALSE and GetLastError returns 
ERROR_INSUFFICIENT_BUFFER. 

If the anonymous write pipe handle has been closed and ReadFile attempts 
to read using the corresponding anonymous read pipe handle, the function 
returns FALSE and GetLastError returns ERROR_BROKEN_PIPE. 

The ReadFile function may fail and return ERROR_INVALID_USER_BUFFER or 
ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous 
I/O requests. 

The ReadFile code to check for the end-of-file condition (eof) differs 
for synchronous and asynchronous read operations.

When a synchronous read operation reaches the end of a file, ReadFile 
returns TRUE and sets *lpNumberOfBytesRead to zero. The following sample 
code tests for end-of-file for a synchronous read operation:

// Attempt a synchronous read operation. 
bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, NULL) ; 
// Check for end of file. 
if (bResult &&  nBytesRead == 0, ) 
{ 
    // we're at the end of the file 
} 
An asynchronous read operation can encounter the end of a file during 
the initiating call to ReadFile, or during subsequent asynchronous operation. 

If EOF is detected at ReadFile time for an asynchronous read operation, 
ReadFile returns FALSE and GetLastError returns ERROR_HANDLE_EOF.

If EOF is detected during subsequent asynchronous operation, the call to 
GetOverlappedResult to obtain the results of that operation returns 
FALSE and GetLastError returns ERROR_HANDLE_EOF.

To cancel all pending asynchronous I/O operations, use the CancelIo 
function. This function only cancels operations issued by the calling 
thread for the specified file handle. I/O operations that are canceled 
complete with the error ERROR_OPERATION_ABORTED. 

If you are attempting to read from a floppy drive that does not have a 
floppy disk, the system displays a message box prompting the user to 
retry the operation. To prevent the system from displaying this message 
box, call the SetErrorMode function with SEM_NOOPENFILEERRORBOX. 

*************************
GetLastError

The GetLastError function retrieves the calling thread's last-error 
code value. The last-error code is maintained on a per-thread basis. 
Multiple threads do not overwrite each other's last-error code. 

C syntax:
DWORD GetLastError(VOID);

LB syntax:
open "kernel32" for dll as #kernel
calldll #kernel, "GetLastError", errorCode as ulong
close #kernel


Parameters
This function has no parameters. 

Return Values
The return value is the calling thread's last-error code value. 
Functions set this value by calling the SetLastError function. The 
Return Value section of each reference page notes the conditions 
under which the function sets the last-error code. 

Windows 95/98/Me: Functions that are actually implemented in 16-bit 
code do not set the last-error code. You should ignore the last-error 
code when you call these functions. They include window management 
functions, GDI functions, and Multimedia functions. 

Remarks
To obtain an error string for system error codes, use the FormatMessage 
function. For a complete list of error codes, see System Error Codes.

You should call the GetLastError function immediately when a function's 
return value indicates that such a call will return useful data. That is 
because some functions call SetLastError with a zero when they succeed, 
wiping out the error code set by the most recently failed function. 

Most functions that set the thread's last error code value set it when 
they fail; a few functions set it when they succeed. Function failure is 
typically indicated by a return value error code such as zero, NULL, or 
1. Some functions call SetLastError under conditions of success; those 
cases are noted in each function's reference page.

Error codes are 32-bit values (bit 31 is the most significant bit). Bit 
29 is reserved for application-defined error codes; no system error code 
has this bit set. If you are defining an error code for your application, 
set this bit to one. That indicates that the error code has been defined 
by an application, and ensures that your error code does not conflict 
with any error codes defined by the system. 

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

Send submissions to alycewatson@charter.net

---------------------------------------------------------
---------------------------------------------------------
VOLUNTEER TO PUBLISH THE LB NEWSLETTER

from Alyce:

I enjoy publishing the newsletter, but I've had a long run
of it, and I will be happy to hand over the reins of the 
Liberty BASIC Newsletter to any kind volunteer who would 
like to take over, at any time.

Requirements:
	must be over 18 years of age
	must be willing to publish one newsletter per month
	must be prepared to write the newsletter.
		(although contributions from the community
		  are encouraged, they cannot be relied upon)
	must be prepared to manage the mailing list and
		the lbnews website, including files area,
		polls, subscribers, etc.

Articles can be anything of interest to LB programmers -
coding routines, explanations of LB commands, news about
LB, or the LB community, spotlight on programmers, websites,
programs written in LB, or coding tools.

The publisher may include code and information published in the
various LB forums, but only with permission from the authors
of the messages.

To volunteer, send a message to Alyce:
mailto:alycewatson@charter.net
or Carl Gundel,
mailto:carlg@libertybasic.com

---------------------------------------------------------
---------------------------------------------------------
    Comments, requests, submissions or corrections: 
            Simply reply to this message!

			The Team:
Alyce Watson, Publisher and Editor: alycewatson@charter.net
Carl Gundel, Author of Liberty BASIC: carlg@libertybasic.com
Bill Jennings, Contents and Indexes: bbjen@bigfoot.com
Andrew Sturges, Contributing Editor: andrew@britcoms.com
---------------------------------------------------------