The XBasic language is clean, readable, powerful, and complete. The XBasic compiler translates programs from source form into fast, compact, binary machine instructions in memory where it is executed and debugged. After they're debugged, XBasic programs can be translated into assembly language to assemble and link with conventional tools to make standalone EXE programs and DLL libraries.
XBasic is as well suited to novices as programming wizards, and is appropriate
for virtually all programming tasks. For science and engineering
XBasic has extensive math libraries, built-in complex number arithmetic
and function library, and very extensive graphics. For business, XBasic
has a 64-bit integer data type, user-defined types optimized for database
I/O. For system programs, XBasic has high level language replacements
for low level programming features that are much easier to read, understand,
and maintain. For all applications, XBasic designed to support rapid
development of compact, efficient, reliable, readable, portable, well structured
programs.
XBasic Features
Online XBasic Resources
http://www.maxreason.com/software/xbasic/xbasic.html
Description: The original XB site for XB as published by Max Reason.
It contains info on the development of XBasic as well as a place to download
v6.0022 for Windows and Linux.
Maintained by: Max Reason
http://xbasic.sourceforge.net
Description: The XBasic development page. Download the most recent
version of XB from this site. Here you can also find information
about new XBasic releases, file bug reports and read news concerning XB.
Maintained by: Eddie Penninkhof
http://www.xbasic.org
Description: The official XBasic Website. Check here for news and
links on XBasic.
Maintained by: Vic Drastik
http://www.thecavac.com
Description: German/Austrian non-commercial software site, most/all
progs written in XBasic. This is a german-speaking site.
Maintained by: Rene Schickbauer
http://xb.thecavac.com
Description: European XB Mirror-Site download Server. Download
the most recent version of XB from this site.
Maintained by: Rene Schickbauer
http://xbasicdocs.freeservers.com/
Description: Contains a lot of info to get you started with XBasic,
including several tutorials geared for newbies.
Maintained by: Vincent Voois
http://groups.yahoo.com/group/xbasic/files/
Description: The online file depository for Yahoo XBasic message
group members. You can download the current version of XBasic from the downloads
section at
http://groups.yahoo.com/group/xbasic/files/downloads/
Maintained by: Vic Drastik
XBasic Reference Manual
Description: This HTML reference manual contains information on
each of the functions in the XBasic libraries. It was designed to
be a standard x-reference guide in a simple, printable format. The direct
download:
http://groups.yahoo.com/group/xbasic/files/docs/XbasicDocv3.zip
Maintained by: Tom Stout
http://groups.yahoo.com/group/xbasic
Description: XBasic Mailing List on Yahoo Groups.
Maintained by: Vic Drastik
Post message: xbasic@yahoogroups.com
Subscribe:
xbasic-subscribe@yahoogroups.com
Unsubscribe:
xbasic-unsubscribe@yahoogroups.com
List owner:
xbasic-owner@yahoogroups.com
The most current FAQ may be found at:
http://groups.yahoo.com/group/xbasic/files/docs/
Description: The XBasic Frequently Asked Questions FAQ. This FAQ
is a collaborative effort on the part of the Xbasic mailing list.
Maintained by: David Szafranski
dszafranski@infonie.fr
Last modified:
October 2001
If not, you installed improperly and the only solution is to remove everything you installed already and install XBasic again.
Assuming you didn't delete the file you downloaded, you don't need to
download it again.
The default font for XBasic, or any other XBasic application, is chosen when the application starts up. First XBasic creates an xxx/fonts.xxx file that contains a list of bitmap fonts that may be appropriate as the default font. Then XBasic reads in file xxx/font.xxx and sets the default font to the first font name not preceded by a ' comment character that is known to the system. If no xxx/font.xxx file exists, XBasic chooses the default font it thinks best.
You can select a larger font for the development environment and console
windows with Option Misc.
' ######################Execute this entry function to cause a divide by zero runtime error at a = y \ z since z = 0 as set by the previous line. But you can now display the variables window (F8) and make z non-zero and continue program execution. Alternatively, you can set the text cursor on a later line and select Run Jump to move the execution line past the error line, then continue execution.
' ##### Entry () #####
' ######################
'
FUNCTION Entry ()
x = 0
y = 11
z = 0
a = y \ z ' a = 11 divided by 0 - divide by zero error>
b = XLONGAT(x) ' b = contents of memory at address 0x00000000 - invalid memory address
PRINT x,y,z,a,b ' print results
END FUNCTION
XuiSendMessage (g, #SetImage, 0, 0, 0, 0, 0, @"\\xb\\xxx\\xstart.bmp")
XuiSendMessage (g, #SetImage, 0, 0, 0, 0, 0, @"xxx\\xstart.bmp")
The second example skips the leading " \\xb\\ " part of the filename, which loads xstart.bmp from the xxx subdirectory of any current directory.
Of course the name of the bitmap file can be changed to a variable or expression:
XuiSendMessage (g, #SetImage, 0, 0, 0, 0, 0, @imageStart$)
XuiSendMessage (g, #SetImage, 0, 0, 0, 0, 0, imagePath$ + "start.bmp")
GuiDesigner puts an XuiReportMessage() at the top of all those xxxCode() functions it generates so you can easily see what kind of messages the xxxCode() is receiving. If you comment out that XuiReportMessage() line, your program will stop reporting messages to you, both in the development environment and in standalone programs.
When you are developing GuiDesigner programs, remember you can always
add one of these XuiReportMessage() calls to the top of ANY grid-function
or xxxCode() function to "see what's happening".
In your program, make sure you have IMPORT "xst" in your PROLOG, then you can use
1. Debug program in PDE
2. Create an assembly language file
3. Compile the assembly language file
Step 1.
Before you attempt to create a standalone executable or library, completely
debug your program in the program development environment.
Step 2.
To convert your program into a standalone executable or library, select
R un A ssembly or R un
L ibrary from the PDE main menu. The PDE compiles your source
program into an assembly language file of the same name, except with a .s
suffix. At the same time, the PDE creates a .DEC file, a .def file, and
a .mak file.
prog .x - your source program (replace prog with its real
name)
prog .s - source program compiled into assembly language
prog .dec - type, function, constant declaration file
prog .def - import/export definition file required by library manager
prog .mak - makefile directs tools to create standalone .exe or .dll
You can also compile a program directly from a DOS window with the following command lines:
xb prog.x ' for standalone executable
program
xb prog.x -lib ' for standalone executable library
Step 3.
To create your standalone program or library with Win32 tools:
Click the MS-DOS icon to start a DOS window or: Start > Programs >
MS-DOS Prompt .
Then, enter in the DOS window...
cd \xb
'for v6.0022
OR
cd c:\progra~1\xbasic\myDir\ 'for v6.1+
with v6.1+, you need to set the environment variables (if you haven't already set them in your autoexec.bat file) by calling a batch file. So at the prompt enter:
xbvars.bat
to set the current directory to the program development directory or the directory where your program resides. Then type
nmake -f prog .mak
(where prog is the name of your program) to create a standalone executable prog.exe or a library prog.dll .
You can rename standalone executables, but never copy a standalone executable into the /xb development directory or your /bin directory and attempt to run it there. It will runtime link to the wrong xb.dll and the program development environment will start instead of your program !!!
prog.exe/prog.dll is your standalone executable program/library.
They contain everything specific to your program/library, but not any of
the XBasic library functions in xst, xui, xgr, or xma. The Xbasic library
functions are contained in the XBasic runtime dll in \xb\run\xb.dll
or \windows\xb.dll.
XstDisplayConsole() 'display a previously hidden console
XstHideConsole() 'hide console window
XstShowConsole() 'show console window
XBasic reads the property file on startup, and if it finds code like this it will run full screen down to the sys tray in windows9x. The 1015, and 706 are the window size for my 17" monitor, if yours is a different size then change these numbers accordingly. The font line will change the PDE fonts. Use whatever your system has that you want.
xb Environment XuiSendMessage (*, #ResizeWindow, 4, 23, 1015, 706, 0, 0)
xb Environment XuiSendMessage (*, #SetFont, 280, 400, 0, 0, 1, @"courier new")
XstDisplayConsole() 'display a previously hidden console
XstHideConsole() 'hide console window
XstShowConsole() 'show console window
One way console can be disabled is by adding the following code into your InitProgram( ) function:
XstGetApplicationEnvironment (@standalone, @reserved)
IF standalone THEN XstHideConsole()
It won't prevent the console from popping up, but it will hide the console as soon as XstHideConsole ( ) is executed. XstGetApplicationEnvironment ( ) will look if your program is running stand-alone executable or within the PDE. If it is in the PDE, it won't hide the console so that you can still use commands to display debug output.
Two command-line switches affect the console-window, "-HideConsole" and "-NoConsole". When applications are launched by clicking desktop icons, a simulated command-line is executed, so either of these switches can eliminate the console during application startup. "-HideConsole" has a major advantage - it can be printed-to even while hidden, and your code can display and hide it anytime. For example, you might want to print a running record of the steps the user and application take, but make it visible only if and when the user so request. Or you might only display disasterous error messages.
If you truly want the console eliminated, the "-NoConsole" switch
makes XBasic never create the console grid/window. But then the console
is permanently unavailable.
xb XuiTextArea XuiSendMessage (TextLower, #SetColorExtra, $$White, -1, -1, -1, 0, 0)
The color is XORed to the screen backgound color, so the color you see
will be different from what you specify. I use a blue background,
and a $$White cursor is actually yellow while a $$LightYellow value will
display a blue cursor on a white background.
about = 0
the about window will only diplay if you select help|about from the PDE
menu. If you make it "about = -1", the window always appears. Normally it
is a positive number which increases each time you run the PDE.
XB windows aren't using controls called from the Win32 APIs. The grids/widgets/controls in a XBasic window are drawn by XBasic. The XBasic windows do not automatically redraw its contents when it is dragged around or off the screen. To fix this problem while using the PDE:
Right click anywhere on the main Windows desktop display.
From the popup window, select Properties.
In the Display Properties dialogue, select the Effects tab.
Deselect the Show Window Contents While Dragging property and hit
the Apply button.
To fix this problem in your own GUI programs, try modifying the Entry ( ) function as follows:
DO ' the message loop
XgrPeekMessage (@wingrid, @message, @v0, @v1, @v2, @v3, r0, r1) IF message = #WindowResized THEN
XgrGetWindowGrid (wingrid, @grid)
XuiSendMessage (grid, #Redraw, 0, 0, 0, 0, 0, 0) END IF XgrProcessMessages (1) ' process one message LOOP UNTIL terminateProgram ' and repeat until program is terminated
After executing "make install", you may wish to replace the old runtime dll (C:\windows\xb.dll) with the new one which has been copied to the \bin directory as xbrun.dll.
copy %XBDIR%\bin\xbrun.dll C:\windows\xb.dll
(And answer yes when it asks if you want to overwrite the old file.)
The functions for Win32 are declared in user32.dec, gdi32.dec, kernel32.dec, and shell32.dec. Each .dec file corresponds to a Windows dynamic link library (.dll) file that exports the various API functions: user32.dll, gdi32.dll, kernel32.dll, and shell32.dll. In order to use an API function, you first need to know which dll library the function is included in.
For example, the function Rectangle (hdc, x, y, w, h) is in gdi32.dll and is listed in gdi32.dec. In order to use this function, you must IMPORT the gdi32.dll library using the IMPORT statement in the beginning of your PROLOG:
IMPORT "gdi32"
Once imported, all the functions in the dll are available to use just like any other XBasic function. See the example program api.x.
The *.dec files to not list EVERY available Win32 API function call. If
the function you wish to use is not shown in the appropriate *.dec file, then
simply add it to the *.dec file.
[1] Determine the library's name and location.
It should be called *.dll and be on your path , ideally in the current
directory (while testing) or in c:\windows\system\ (for general use)
[2] Determine the exact name of the function you wish to call.
This can either be found in reference information, or directly with an
appropriate program - I use the great freeware file manager PowerDesk 4 for
this, from http://www.ontrack.com
. Powerdesk displays this information automatically , but it occasionally
doesn't work, so then I use the MS freeware DLL utility called Dependency
Walker , from http://www.dependencywalker.com
. This is simple to use , and does a recursive descent , listing all the
functions and DLLs used by a given DLL and the functions and DLLs used by
them, and so on. Highly recommended.
[3] You now need to know how to pass information (commands , parameters
,etc.) to the DLL.
You could get this by disassembling the DLL , but a much easier way is
to look it up. There are many references on the Net giving this information
for various languages like C, and these are easily adapted to Xbasic. Using
this information , you must create a header file of the form dllname.dec
, where dllname corresponds to dllname.dll . For examples , just look in
your c:\xb\
directory and model your .dec file on these.
[4] Finally , you need to add this information to your program.
Put the statement
IMPORT "dllname"
in the prolog of your XB programme , and you can then use the functions
in the DLL as if you had included the source code of the DLL directly into
your program.
Most programs with asynchronous aspects simulate asynchronous behavior by setting and starting GraphicsDesigner grid timers which add TimeOut messages to the message queue when they expire. When these TimeOut messages are subsequently processed by XgrProcessMessages() , a grid function receives the TimeOut message and can process the asynchronous timer event in the normal straightforward manner because the asynchronous timer has been synchronized by its passage through the message queue.
Programs with asynchronous aspects that cannot be simulated by timers often employ a similar technique. One line is added to the message processing loop in their Entry() function to call a function that performs asynchronous activity. Again, apparently asynchronous activity is processed in a synchronous manner.
DO
XgrProcessMessages (0)
Asynchronous () ' check/process asynchronous
program aspects
LOOP
Though there are many other methods to handle asynchronous activity in a synchronous way, some programs require some true asynchronous processing. Consider a program that needs to respond to certain conditions within a limited period of time, but also contains one or more functions that may take longer to complete than the response interval. The synchronous way to handle this situation is to add a line that calls an asynchronous processing function in as many places as necessary to assure adequate response time. The shorter the response interval gets, however, the more places the asynchronous processing function must be called. Furthermore, the length of time required to execute various parts of a program depends on computer speed, and is therefore not portable unless written for the slowest possible machine.
The standard function library contains two functions that support fully
asynchronous processing, namely XstStartTimer() and XstKillTimer() . Timers
created by XstStartTimer() are not associated with GraphicsDesigner or
the message queue. When they expire, the function associated with the timer
is called immediately, potentially between ANY two machine instructions.
Program variables can thus be in any state, and its even possible for these
timers to interrupt programs between machine instructions that update the
two 32-bit parts of GIANT and DOUBLE variables! Therefore the program must
be written to anticipate all possible adverse interactions and avoid them.
As long as asynchronous processing functions are not themselves interrupted
and do not read variables that are altered elsewhere in the program, they
can be fairly simple. Otherwise careful and detailed design of handshaking
is required to avoid disastrous interaction between the normal and asynchronous
parts of programs.
Note that Windows and some versions of UNIX automatically give the process that created the selected window a higher priority than all others. Many XBasic programs run visibly slower when none of its windows are selected.
One way to conditionally lower the priority of an XBasic process follows:
'
' message processing loop at bottom of Entry()
'
DO
XuiProcessMessages (1)
IF condition THEN XstSleep (msec) ' add this line
LOOP UNTIL terminateProgram
END FUNCTION
XuiSendMessage (grid, #GetTimer, @msec, 0, 0, 0, kid, 0)
XuiSendMessage (grid, #SetTimer, msec, 0, 0, 0, kid, 0)
XuiSendMessage (grid, #StartTimer, 0, 0, 0, 0, kid, 0)
Note that running timers are disabled by #SetTimer with msec = 0 .
But your programs can call callback functions too. You can arrange arguments to simulate a callback, or you can arrange the arguments in any other way you wish. Near the top of most callback functions, you'll find something like the following:
FUNCTION TestCode (grid, message, v0, v1, v2, v3, kid, r1)The following three lines were added to the GuiDesigner generated code to prepare the callback function for special purpose messages from your program:
$MenuBar = 1 ' kid #1
$TextLine = 2 ' kid #2
$Button = 3 ' kid #3
$Custom = 100 ' custom kid #
'
IF (message = #Callback) THEN
callback = r1
message = r1
END IF
'
SELECT CASE message
CASE #Selection : GOSUB Selection ' normal #Selection message
CASE #Custom : GOSUB Custom
' or custom code right here
END SELECT
RETURN
'
SUB Selection
SELECT CASE kid
CASE $MenuBar : ' code to handle MenuBar selections
CASE $TextLine : ' code to handle TextLine selections
CASE $Button : ' code to handle Button0 selections
CASE $Custom : ' code to handle custom capability
END SELECT
END SUB
$Custom = 100 ' custom kid #
CASE #Custom : GOSUB Custom ' or custom code right here
CASE $Custom : ' code to handle custom capability
To invoke the CASE #Custom : GOSUB Custom line, your program calls:
TestCode (grid, #Custom, v0, v1, v2, v3, kid, r1)To invoke the CASE $Custom line, your program calls:
Sample applications acircle.x and ademo.x contain an example. Also
make sure you
XgrRegisterMessage (@"Custom", @#Custom)
in InitProgram().
If three programs are linked into three executables, however, all three
programs has its own trouble .
XuiSendMessage (g, #SetImage, 0, 0, 0, 0, 0, dir$ + "my.bmp") .
http://groups.yahoo.com/group/xbasic/files/files/api%2Bdll/
and click on xbrandom.zip, or here is the direct URL :
http://groups.yahoo.com/group/xbasic/files/files/api%2Bdll/xbrandom.zip
The instructions are included.
IO.DLL can be downloaded from
http://www.southwest.com.au/~jfuller/bulback/
or directly from
http://www.southwest.com.au/~jfuller/bulback/io.dll
Otherwise, there's a whole page of similar DLLs listed here:
http://www.doc.ic.ac.uk/~ih/doc/par/doc/data.html
Also, you should see the post under DLLs, How can I read/write to the parallel or serial ports in XB?
Here's what I did to make IO.DLL work, I'm sure the others are fairly similar:
Create the io.dec and io.def files as shown below.
------------ io.dec file -------------------------I made the IO.LIB file, required for linking to standalone, with the following dos command:
EXTERNAL CFUNCTION PortOut (ioPort%%, ioValue@@)
EXTERNAL CFUNCTION PortIn (ioPort%%)
EXTERNAL CFUNCTION SetPortBit (ioPort%%, ioBit@@)
EXTERNAL CFUNCTION ClrPortBit (ioPort%%, ioBit@@)
EXTERNAL CFUNCTION NotPortBit (ioPort%%, ioBit@@)
EXTERNAL CFUNCTION GetPortBit (ioPort%%, ioBit@@)
------------ io.def file -------------------------
LIBRARY io
EXPORTS PortOut
EXPORTS PortIn
EXPORTS SetPortBit
EXPORTS ClrPortBit
EXPORTS NotPortBit
EXPORTS GetPortBit
LIB /def:io.def
In PROLOG section of application source...
IMPORT "io"Commands used to call DLLs would vary depending on the DLL. The IO.DLL uses the following commands:
x = PortIn(portadr%%)
PortOut(portadr%%, byte@@)
FUNCTION Test ()
STATIC USHORT array[]
IFZ array[] THEN GOSUB Initialize
'
' body of the function
'
RETURN
'
' ***** Initialize *****
'
SUB Initialize
DIM array[65535]
FOR i = 0 TO 65535
array[i] = i
NEXT i
END SUB
END FUNCTION
This works correctly because XBasic arrays are always empty
until they are DIMensioned.
So
IFZ array[] THEN
is all it takes. The dimensions [and contents] of static arrays
never change unless code in the function does it.
' ...This code executes the first part of the IF block when the program is run as a standalone executable, and the second part when the program is run in the PDE. A standalone program will thus take its command line arguments from the command line, while the same program run in the environment will take its command line arguments from those explicitly defined in the second part of the IF block. If you'll be doing lots of command line argument testing, you could write a fancier second part of the IF block to input accept a variable number of arguments from the console each time the program is run.
'
XstGetApplicationEnvironment (@standalone, 0)
'
IF standalone THEN
XstGetCommandLineArguments (@argc, @argv$[])
ELSE
argc = 3
DIM argv$[2]
argv$[0] = "progname.exe"
argv$[1] = "foobar.dat"
argv$[2] = "-flag"
END IF
'
' code that processes command line arguments in argv$[]
'
Alternatively XstSetCommandLineArguments (argc, @argv$[]) sets the command line arguments.
The following code returns the original command line arguments, even after they have been changed.
argc = -1The following code reinstates the original command line arguments after they have been changed.
XstGetCommandLineArguments (@argc, @argv$[])
argc = -1
XstGetCommandLineArguments (@argc, @argv$[])
XstSetCommandLineArguments (argc, @argv$[])
Variables are automaticly XLONG unless you specify otherwise.
You can specify types of variables in groups if you don't want to use loads of define lines:
DOUBLE #InterDouble1, #InterDouble2, #InterDouble3, ##GlobalDouble4The examples also show the prefix used to stamp variables as local, internally global and environmentally global.
SSHORT #InterShort%, ##GlobalShort2%, LocalShort3%
STRING ##GlobalA$, LocalB$, LocalC$
x# = 5.51
x = ULONG(x#)
Here is a function that will round any value to any number of decimal places desired.
FUNCTION Entry ( )
a# = Round(10512.3456#, -3)
b# = Round(10512.3456#, -2)
c# = Round(10512.3456#, -1)
d# = Round(10512.3456#, 0)
e# = Round(10512.3456#, 1)
f# = Round(10512.3456#, 2)
PRINT a#; b#; c#;,d#; e#; f#;
END FUNCTION
FUNCTION DOUBLE Round (DOUBLE number, power)
pTen# = 10# ** power
RETURN INT(number / pTen# + .5#) * pTen#
END FUNCTION
Running the above example gives these results:
10512.346 10512.35 10512.3 10512
10510 10500
filenum% = OPEN ("c:\TEST.DB", $$RW)
These are correct:
filenum% = OPEN ("c:/test.db", $$RW)
filenum% = OPEN ("c:\\TEST.DB", $$RW)
It is suggested that every XBasic programmer ALWAYS choose the / "forward
slash" as the path/directory separator. This works for filenames on Linux
and Windows and internet-addresses. That's because every path/filename
argument in every XBasic intrinsic and library function converts path separators
to the appropriate character.
Furthermore, the \ "backslash character" is a confusing path separator because in literal strings the \ "backslash character" is an "escape" character that needs to be \\ doubled-up to produce a single backslash.
To always select the / "forward slash" path separator is ALWAYS easier
and more reliable.
So, to add double quote characters to your string, you would use \" instead.
s$ = "some characters and \"this is in quotes\"."
The complete list of backslash codes (as we call them) is as follows:
\a alarm (bell)
\b backspace
\d ASCII DELETE (CHR$(127)), not the Delete key
\e escape (CHR$(27))
\f formfeed (CHR$(12))
\n newline (CHR$(10))
\r return (CHR$(13))
\t tab
\v vertical tab
\z CHR$(255)
\0 through \9, CHR$(0) through CHR$(9)
\A through \V, ASCII codes 10 through 31
\" a quote (since you can't otherwise put a quote inside a string)
\\ a backslash
\xnn (where the n's are hexadecimal characters),
the character whose ASCII code has the hex
value nn
With any other character (say, !), the code \! will just be translated as ! (with the backslash removed).
These codes - and the general note about backslash - apply to literal
string, strings you type on program lines. Strings read from files or by
user input do not use backslash codes unless you were to use the library
function XstBackStringToBinString$(string$) to convert them.
Just assigning simple values to an array in a sorted order is pretty simple:
FOR X = 0 TO 10When your data is not an ordered series.
Array[X] = X + 1
NEXT X
' Array[0] - Array[10] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
ArrayStepper = 0
FOR X = 0 TO 100 STEP 10
Array[ArrayStepper] = X
INC ArrayStepper
NEXT X
' Array[0] - Array[10] = 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100
'Data stored in a string where each piece of data is 4 characters longThis would work of course with string information too like:
' 123412341234123412341234
data$= "123 23 4 138934 3 "
'
'find out how long the data$ is
upper = UBOUND(data$)
'
'same as INT(upper\4)
numberOfDataPieces = upper/4
'
DIM dataArray[numberOfDataPieces]
'
pointer = 1
FOR i = 0 TO numberOfDataPieces
'DOUBLE will return the value of the string
dataArray[i] = DOUBLE(MID$(data$,pointer,4))
pointer = pointer + 4
NEXT i
'
FOR i = 0 TO numberOfDataPieces
PRINT dataArray[i]
NEXT i
123456789123456789123456789123456789123456789MID$ is slower than Data${i} but if you want to convert it's ascii-value back to a string-value to display it probably doesn't matter that much...
month$ = "January Febuary March April September"
For storage (from memory to disk) using the Var${pos} is the quickest way.
Another method:
Data$ = "496967496740947676496749505038264807"You can enter byte data into a string using escape hex notation thus :
FOR i = 0 TO UBOUND(Data$)
PRINT i , Data${i}
NEXT i
STRING sThis prints
s = "\x41\x42\x43\x61\x62\x63"
PRINT s
FOR i = 0 TO UBOUND(s)
PRINT i , s{i}
NEXT i
ABCabcYou can enter nybble data using a string which can then be processed into bytes or higher data types - here is a simple example using XB escapes :
0 65
1 66
2 67
3 97
4 98
5 99
s = "\0\1\2\3\4\5\6\7\8\9\A\B\C\D\E\F"with output
FOR i = 0 TO UBOUND(s)
PRINT i , s{i}
NEXT i
0 0Another favorite method is pseudo-hex notation , as follows :
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
12 12
13 13
14 14
15 15
s = "0123456789:;<=>?"- output as above.
FOR i = 0 TO UBOUND(s)
PRINT i , s{i} & 0xF
NEXT i
Or you can use ordinary hex(here the conversion is a little more tricky):
s = "0123456789ABCDEF"The 4-bit nibbles you extract from the DATA string can then be built up into higher data types using the usual XB intrinsics , or directly , as in:
FOR i = 0 TO UBOUND(s)
PRINT i , (s{i} - 48 + 7 * ( s{i}>57 ))
NEXT i
FOR i = 0 TO UBOUND(s) STEP 4If you want to read them from files this can be done even easier, yet depending on what kind of binary structure the file and your data has...
c0 = s{i} & 0xF
c1 = s{i+1} & 0xF
c2 = s{i+2} & 0xF
c3 = s{i+3} & 0xF
xlongvariable = (c3<<24) OR (c2<<16) OR (c1<<8) OR (c0)
NEXT i
Does it has multiple type keys?
Are the types 32-bit aligned?
If your elements are aligned in 32-bit dividable blocks, you can read the whole slug in one pass....
DIM MyArray[256]Here's an example displaying the reading of a user / composite type reading an aligned range of various typed elements into a whole array:
FileHandle = OPEN(file$, $$RD)
READ [FileHandle], MyArray[]
' 256 * 4 bytes = 1024 bytes are just read into the array
CLOSE(FileHandle)
PROLOGIf your data-file has an non-32 bit aligned format like above the following would happen if you would try to read data in one pass to the array:
'This is an aligned TYPE:
TYPE MyRecordStructure
UBYTE .Byte1 '-|
UBYTE .Byte2 ' four byte
UBYTE .Byte3 ' aligned block = 32 bit block 1
UBYTE .Byte4 '-|
ULONG .Long1 ' one four byte block = 32 bit block 2
SSHORT .Short1' two 2 byte
SSHORT .Short2' blocks = 32 bit block 3
END TYPE
END PROLOG
FUNCTION Entry()
' Now declare the array:
MyRecordStructure RecordData[256]
FileHandle = OPEN(file$, $$RD)
READ [FileHandle], RecordData[]
' 256 * 12 bytes (3072 bytes) are read into the array.
CLOSE(FileHandle)
END FUNCTION
' Now what can you do with an unaligned type?
TYPE MyRecordStructure
UBYTE .Byte1 '-|
UBYTE .Byte2 ' four byte
UBYTE .Byte3 ' aligned block = 24 bit block!
ULONG .Long1 ' one four byte block = 32 bit block 2
SSHORT .Short1' two 2 byte
SSHORT .Short2' blocks = 32 bit block 3
END TYPE
The first four bytes are read, the first three will be put in the three ubytes, the fourth will be discarded then the ULONG will contain the four bytes of which the last one supposed to belong in the first byte of the first short and also the byte of short2 is shifted downwards...
To make a long story short...
Unaligned data reading can only be done this way:
PROLOG
'This is an UNaligned TYPE:
TYPE MyRecordStructure
UBYTE .Byte1 '-|
UBYTE .Byte2 ' four byte
UBYTE .Byte3 ' aligned block = 24 bit block!
ULONG .Long1 ' one four byte block = 32 bit block 2
SSHORT .Short1' two 2 byte
SSHORT .Short2' blocks = 32 bit block 3
END TYPE
END PROLOG
FUNCTION Entry()
' Now declare the array:
MyRecordStructure RecordData[256]
FileHandle = OPEN(file$, $$RD)
FOR X = 0 TO UBOUND(RecordData[])
READ [FileHandle], RecordData[X].Byte1,RecordData[X].Byte2,
RecordData[X].Byte3, RecordData[X].Long1
READ [FileHandle], RecordData[X].Short1, RecordData[X].Short1
NEXT X
' 256 * 11 bytes (2816 bytes) are read into the array per element.
CLOSE(FileHandle)
END FUNCTION
MyFunction (v0, @v1, @string$, @array[])
v0 is passed by value
v1, string$, and array are passed by reference
If v1, string$, or array[] are modified within MyFunction ( ), then on the return of the function, these arguments will hold their new values and be available to the calling program.
Shared variables are globally available to all functions within your program. However, you must declare the shared variables within each function that uses them.
FUNCTION Entry ( )
SHARED v0, v1, string$, array[]
MyFunction ( )
PRINT v0, v1, string$, array[0], array[1]
END FUNCTION
FUNCTION MyFunction ( )
SHARED v0, v1, string$, array[]
v0 = 5 : v1 = 10 : string$ = "a string"
REDIM array[1]
array[0] = 15 : array[1] = 20
END FUNCTION
A good example can be found in the xma.dec file (which is the file you see in the PDE by selecting help|math). Towards the end of that file, after the function declarations, mathematical constants such as $$PI and $$E are declared.
$$PI = 0d400921FB54442D18
In order to determine the representation of a particular DOUBLE value, you would have to use DHIGH and DLOW to convert the binary representation into two XLONG values, then convert those into two hex strings. Example:
FUNCTION DoubleImage$ (DOUBLE x)
xhigh = DHIGH(x)
xlow = DLOW(x)
RETURN ("0d"+HEX$(xhigh, 8)+ HEX$(xlow, 8))
END FUNCTION
x# = -1.2345
d$ = DoubleImage$ (x#)
PRINT x#, d$, DOUBLE(d$)
This gives us the following results:
-1.2345 0dBFF3C083126E978D -1.2345
So we can define our constant for -1.2345 as:
$$neg = 0dBFF3C083126E978D
The DOUBLE image doesn't need a negative sign since the highest order bit IS the sign bit.
A SINGLE image is "0s" followed by 8 hex digits. For that, you'd use XMAKE
to read the 32-bit SINGLE as if it were an XLONG, and convert the result
to hex with HEX$, prefixing the required "0s" to it. (Note, that's a number
zero followed by s, not a letter O; similarly double image was number zero
followed by d.)
1. In XBasic, arrays can only be passed by reference which requires a @ prefix, or passed by address for passing to C functions which requires the & prefix.
2. In XBasic, arrays are always followed by their [] square-brackets, in every context. In XBasic,
myarray
and
myarray[]
are entirely independent; myarray is a variable, myarray[] is an array, myarray[n] is an array element.
By the way, the same goes for function names, which ALWAYS
must be followed by ( ) parentheses.
So if you want to pass the address of an XBasic function func()
as a callback function, you need
&func()
not
&func
&func is the address of a variable, while &func()
is the address of a function.
If you mean "shared by all functions in the same program/module", then they can - in at least two ways:
SHARED [TYPENAME] array[]
inside every function that wants to share the array, where data-type is XLONG unless specified in the variable declaration by TYPENAME, or
#array[]
Note: the # in #array[] is part of the name, so
#array[]
and
array[]
are entirely separate arrays.
Arrays that start with # are automatically SHARED everywhere they appear in the module/program.
If #array[] is XLONG, then you need not declare #array[] in the PROLOG, because the default data-type is XLONG. Also, you need not declare arrays whose data-type is made explicit by a type suffix, like:
#array![]
#array#[]
Other arrays made SHARED by virtue of starting with an # character must be declared in the PROLOG like:
SHARED SINGLE #array[]
or
SINGLE #array[]
' i think this works
If "global" means "shared by all statically linked modules", then replace SHARED with EXTERNAL in the above discussion, or the # prefix with ## prefix. But the ## prefix only works to share with modules created with XBasic, since the ## is part of the name and C/C++ doesn't support that. So to make this work with C/C++ modules, the EXTERNAL declaration in the PROLOG is the only workable way, as in:
EXTERNAL array[]
or
EXTERNAL SINGLE array[]
What also won't work is:
EXTERNAL array![]
because the ! is part of the array name in XBasic, not just a data-type specifier.
You can use the function XstGetDateAndTime as a simple timer but it
is misleading to think that it can achieve nanosec resolutions.
In using nanos in XstGetDateAndTime, Max was thinking ahead to a time
when future processors can achieve such a thing. But as it stands now,
this function at its best can only do 55 msecs between calls to itself.
Listed below are the various results I got for various Win9x and XB
timing functions while trying to time a 1 msec interval:
XstGetDateAndTime 55 msec
XstGetSystemTime 5 msec (which uses GetTickCount)
GetTickCount 5 msec (kernel32.dll)
timeGetTime 1 msec (winmm.dll)
QueryPerformanceCounter 4 microsec (kernel32.dll)
QueryPerformanceCounter which is found in kernel32.dll is used in conjunction
with QueryPerformanceFrequency. These two functions are not currently in the
XB kernel32.dec file so you would need to add them to that file in order to use them.
For more information on timing functions and for a test program, see the
following posts:
http://groups.yahoo.com/group/xbasic/message/4707
http://groups.yahoo.com/group/xbasic/message/4713
http://groups.yahoo.com/group/xbasic/message/4715
http://groups.yahoo.com/group/xbasic/message/4719
http://groups.yahoo.com/group/xbasic/message/7614
display XgrGetGridBoxDisplay (grid, @x1Disp, @y1Disp, @x2Disp,
@y2Disp)
window XgrGetGridBoxWindow (grid, @x1Win, @y1Win, @x2Win,
@y2Win)
local XgrGetGridBoxLocal (grid, @x1, @y1, @x2, @y2)
grid XgrGetGridBoxGrid (grid, @x1Grid, @y1Grid,
@x2Grid, @y2Grid)
scaled XgrGetGridBoxScaled (grid, @x1#, @y1#, @x2#, @y2#)
For purposes of drawing, there are three coordinate systems:
local XuiDrawLine (grid, color, x1, y1, x2, y2)
grid XuiDrawLineGrid (grid, color, x1Grid, y1Grid,
x2Grid, y2Grid)
scaled XuiDrawLineScaled (grid, color, x1#, y1#, x2#, y2#)
The name of every GraphicsDesigner drawing function determines the coordinate system the function draws in, as follows:
Drawing functions that do not specify a coordinate system, like XgrDrawLine() , draw in local coordinates and manipulate the local coordinate drawpoint.
Drawing functions that end with " Grid ( ", like XgrDrawLineGrid() , draw in grid coordinates and manipulate the grid coordinate drawpoint.
Drawing functions that end with " Scaled ( ", like XgrDrawLineScaled()
, draw in scaled coordinates and manipulate the scaled coordinate drawpoint.
Sometimes you want to draw program-specific graphics into a grid - like the charts in my futures programs or optical design cross-sections in my optics programs. In the XBasic samples, you'll find a sample called "acircle.x" that draws a pretty circular picture made of line segments. When that window is uncovered, or minimized and redisplayed, GuiDesigner has no record of all the lines the program has drawn, so it cannot redraw them. But GuiDesigner has a convenient way to deal with these situations with so-called "image grids" and "buffer grids".
An "image grid" is just like a regular grid except it is invisible and cannot be displayed. You can do anything to an "image grid" as any other grid, including set color, border, text & other properties, resize, redraw, etc. Though programs can't display an "image grid", they can copy their contents onto normal grids, and thereby display their images.
GuiDesigner supports the notion "buffer grid" to make capturing images very, very simple. A "buffer grid" is just an "image grid" that is "attached" to a regular grid. Once attached, the "buffer grid" captures a copy of everything drawn onto the normal grid it's attached to. Whenever a grid is exposed or displayed, GuiDesigner sees if a buffer grid is attached to the grid, and if so, draws the image in the buffer grid onto the normal grid, and thereby restores the image.
Once you create and attach an "image grid" to a normal grid, the grid is redrawn properly for you automatically by GuiDesigner and your program can forget it even exists, except if and when the grid it's attached to is resized. Then you need to resize the buffer grid too.
For illustration, the sample program "acircle.x" has exactly the "problem" you describe. If you click the "Pause" button to pause drawing, then cover-and-uncover the drawing grid, the image is not restored. By adding a few lines of code to the "SUB Resize" subroutine, you can solve the problem with a buffer grid.
Below I reproduce "SUB Resize" in the Circle() function, with a marked
section of code added to create and manage the buffer grid. This is the
only change to the program. Obviously the code for a grid in a non-resizable
window is even simpler - just create and attach the image grid once, with
no calculations to decide the sizes and positions of grids.
########################################
##### modified Resize subroutine #####
########################################
'
'
' ***** Resize *****
'
SUB Resize
v2Entry = v2
v3Entry = v3
GOSUB GetSmallestSize
v2 = MAX (v2, v2Entry)
v3 = MAX (v3, v3Entry)
'
XuiPositionGrid (grid, @v0, @v1, @v2, @v3)
'
innerWidth = v2 - bw - bw
innerHeight = v3 - bw - bw
gw = innerWidth
gh = innerHeight - h
bw0 = innerWidth / 3
bw1 = bw0
bw2 = innerWidth - bw1 - bw0
bx0 = bw
bx1 = bx0 + bw0
bx2 = bx1 + bw1
by = v3-h-bw
'
XuiSendMessage (grid, #Resize, bw, bw, gw, gh, 1, 0)
XuiSendMessage (grid, #Resize, bx0, by, bw0, h, 2, 0)
XuiSendMessage (grid, #Resize, bx1, by, bw1, h, 3, 0)
XuiSendMessage (grid, #Resize, bx2, by, bw2, h, 4, 0)
XuiResizeWindowToGrid (grid, #ResizeWindowToGrid, 0, 0, 0, 0, 0, 0)
'
' ##### start new code : create buffer grid first time through this
subroutine
'
XuiGetValues (grid, #GetValues, @g, @i, 0, 0, 0, 0)
'
IFZ i THEN
XuiSendMessage (grid, #GetGridNumber, @g, 0, 0, 0, $DrawingArea, 0)
XgrCreateGrid (@i, 1, 0, 0, v2, v3, r0, g, 0)
XgrSetGridBuffer (g, i, 0, 0)
XgrClearGrid (g, 0)
XuiSetValues (grid, #SetValues, g, i, 0, 0, 0, 0)
END IF
'
XgrSetGridPositionAndSize (i, 0, 0, gw, gh)
'
' ##### end new code : buffer grid resized same as $DrawingArea kid
grid
'
XuiGetSize (grid, #GetSize, 0, 0, @width, @height, 0, 0)
XuiCallback (grid, #Resized, 0, 0, width, height, 0, 0)
END SUB
This works perfectly fine for the vast, vast, vast majority of situations. For example, when you clear a grid, graphicsDesigner clears just that part of the window that is allocated to the grid. When you draw grid borders, GraphicsDesigner draws in the grids boundaries. Since grids (in the GuiDesigner sense) draw themselves - and GraphicsDesigner does the 'right thing' in all the simple and normal situations - only people drawing graphics ever find out grids are just "smoke and mirrors"! :-)
Anyway, Linux XBasic has REAL subwindows so drawing outside grids does not happen in Linux. Anywhere you might have this problem, which means where you draw graphics of a type that might spill outside the grid, send a #SetClipGrid message to the "dangerous" grid with its own grid #. This will clip drawing outside the boundary of the grid itself.
XuiSendMessage (grid, #SetClipGrid, grid, 0, 0, 0, 0, 0)will normally do the trick if you have the grid number of the grid, but if you need to send this message to a kid grid, you'll have to get the grid number of the kid grid first, like this:
XuiSendMessage (grid, #GetGridNumber, @kkkk, 0, 0, 0, 0, $TheKid, 0)Where you know your graphics will not spill outside a grid, like in my math function and the circle in ademo.x and acircle.x - you don't need to clip. There is a slight overhead, but not much.
XuiSendMessage (kkkk, #SetClipGrid, kkkk, 0, 0, 0, 0, 0)
FreeImage - Version 1.44 of this OpenSource imaging library works
great with Win32 XBasic. It can load BMP, ICO, JPEG, KOALA, PCD, PCX, PNM,
PNG, RAS, TARGA, and TIFF format files. It can save images in BMP, JPEG,
PNG, PNM, and TIFF formats. If you are interested in this version
of the library, the author of this FAQ can send you the dll, lib, and dec
files, and an XB demo program.
http://www.6ixsoft.com/
Intel JPG Library - A Win32 library for only JPEG images. This
library can save and load JPG images and has been tested with XBasic. If
you are interested in the lib and dec files, email the author of this FAQ.
ftp://download.intel.com/design/perftool/perflibst/ijl/exes/ijl15.exe
(1851 kb)
DevIL - Developers Image Library (DevIL) is a cross-platform image
library utilizing a simple syntax to load, save, convert, manipulate, filter
and display a variety of images with ease, including JPEG and PNG. This
library is currently untested with XB but looks very promising!
http://sourceforge.net/projects/openil/
In most circumstances, the vast majority of extended characters display whatever image the font contains for the specified character value. But a few of these extended characters like null=0x00 , tab=0x09 , return=0x0D , newline=0x0A have common meanings. For example, when you press an enter or newline key, you usually don't expect to insert the image the font contains for the newline character ( 0x0A ), you expect the text cursor to move to the next line without drawing a character.
The only reason characters like null , tab , and newline don't display images is that input functions check for these characters and execute alternate actions. But most output/drawing functions draw the font image for every character.
For example, XgrDrawText (grid, $$Black, @"A\tB\nC") draws five characters at the current drawpoint, which will usually look something like:
A Yð B Wð C or A § B © C
The character images the font contains for tab and newline are displayed. The tab does not cause blank space between the A and B , and the newline does not place the C on a separate line. When a program draws text and needs to interpret certain characters as something other than their font images, the program must perform multiple operations to draw the text. To draw the A § B © C example with tab and newline characters interpreted as space control characters takes three XgrDrawText() calls to draw the ABC characters, separated by two XgrSetDrawpoint() calls for tab and newline space.
Software that wants tab , newline , and possibly other extended characters
to be interpreted as non-visible spacing commands or anything other than
font images, must watch for these characters and take appropriate actions.
A number of GuiDesigner grid types take alternate actions in response to
extended characters. For example, XuiTextLine and XuiTextArea grids expand
tab characters into variable width horizontal space to support alignment
of text into columns. On the other hand, XuiTextLine and XuiTextArea display
the font image for the other extended characters, including the newline characters.
Each string in the string array assigned to the TextArray property of an
XuiTextArea grid is displayed on a separate line. Any newline character in
the TextArray is displayed as the 0x0A font image within the line and does
not break the line.
Common grid types that recognize TabWidth and/or TabArray include:
XuiList
XuiPullDown
XuiTextArea
XuiTextLine
The following functions get and set TabArray and TabWidth .
XuiGetTabArray (grid, #GetTabArray, 0, 0, 0, 0, 0, @tab[])
XuiSetTabArray (grid, #SetTabArray, 0, 0, 0, 0, 0, @tab[])
XuiGetTabWidth (grid, #GetTabWidth, @width, 0, 0, 0, 0, 0)
XuiSetTabWidth (grid, #SetTabWidth, width, 0, 0, 0, 0, 0)
TabArray takes precedence over TabWidth . If TabArray is not empty, its contents contain tab stop locations. If a line of text has more tabs than TabArray has elements, TabWidth becomes active for the rest of the line.
TabArray must be an XLONG array.
TabArray and TabWidth specify pixel tab stops.
Most functions of XBASIC require characters be between 32 and 127. You
could enter it as hexadecimal (\xE9, like above) or as octal (\351). There's
a command to do the conversion called XstBinStringToBackString$, and of
course a command which does the opposite as well. GUI Designer has to use
this function to convert embedded quotes to \", and your characters were
converted as well. It should work properly as a string with backslash codes,
if not then you'll have to convert it back with the opposite function XstBackStringToBinString$..
1 - a grid with a text area
2 - a statement to load the text.
Assuming you have one already designed and steady:
filename$ = "C:\\my documents\\word2txt.txt"
XstLoadStringArray(filename$, @text$[])
'[kid] should contain the TextAreaKidNumber of the grid you want to send the text to.
XuiSendMessage(grid, #SetTextArray, 0, 0, 0, 0, kid, @text$[])
XuiSendMessage(grid, #RedrawText, 0, 0, 0, 0, kid, 0)There are also a few sample-files in the XBasic package, they all start with "a", try the examples: aedit.x and aeditors.x
The functions that set or get text from the clipboard are in Xgr,:
XgrGetClipboard (clipboard, clipType, @text$, @image[])
XgrSetClipboard (clipboard, clipType, @text$, @image[])
There are 8 possible clipboards, where clipboard 0 is shared with windows
, and 1 thru 7 are internal clipboards. The clipType 1 is for text and 2 is
for BMP images. To set or get a BMP image from the clipboard, set the clipType
to 2 and make sure you assign a type UBYTE to your image array.
To send text to the windows clipboard:
UBYTE image[]
' a null array
yourText$ = "Send this text to clipboard"
' text to send
XgrSetClipboard (0, 1, @yourText$, @image[])
BuildCommDCB
BuildCommDCBAndTimeouts
ClearCommBreak
ClearCommError
CommConfigDialog
DeviceIoControl
EscapeCommFunction
GetCommConfig
GetCommMask
GetCommModemStatus
GetCommProperties
GetCommState
GetCommTimeouts
PurgeComm
SetCommBreak
SetCommConfig
SetCommMask
SetCommState
SetCommTimeouts
SetupComm
TransmitCommChar
WaitCommEvent
The file input and output (I/O) functions (CreateFile, CloseHandle, ReadFile, ReadFileEx, WriteFile, and WriteFileEx) provide the basic interface for opening and closing a communications resource handle and for performing read and write operations.
Otherwise, you a free to use any external I/O dll that provides you with the necessary port functions.
Port I/O resources:
Two 3rd party DLLs that will work with XBasic are:
WinIO.dll - Version 1.3 allows direct I/O port and physical memory access under Windows 9x, ME, NT and 2000 http://www.internals.com/
DLPortIO.DLL - Simple user mode DLL and NT kernel driver to allow
direct hardware I/O access.
http://www.sstnet.com/
- go to the Download page and download the "Windows 95/NT Port I/O Driver".
WinIO is simpler and smaller, but DLPortIO is faster. The LIB file that comes with WinIO is not compatible with XBasic, so if you want to make a standalone EXE from your XBasic program you need a new LIB. See this post on the XBasic YahooGroups ML for instructions and .lib files http://groups.yahoo.com/group/xbasic/message/7240
PC Interfaces and Controlling Devices - General information
and links
http://www.epanorama.net/pc/interface.html
Programming The Parallel Port In Visual Basic
http://www.aaroncake.net/electronics/vblpt.htm
Windows 95 I/O DLL [32-bit] - This tiny DLL allows port input and
output under Windows 95. Note that there are limitations to this technique
due to limitations in Win32, and that this DLL will not work under NT.
The included documentation describes these limitations.
http://www.ping.be/~ping0751/winio.htm
ftp://ftp.softcircuits.com/tools/win95io.zip
IBM-PC Parallel Printer Port Reading & Writing Data
http://www.doc.ic.ac.uk/~ih/doc/par/doc/data.html
dllGuide is a program to help in the process of preparing a third-party DLL for use by an XBasic program.
ftp://ftp.microsoft.com/softlib/mslfiles/opengl95.exe
Yes, there is some activity on implementing OpenGL with XBasic. The necessary .dec and .lib files along with a test program can be found in the YahooGroups XBasic file vault http://groups.yahoo.com/group/xbasic/files/ Look for the file openglxb.zip .
Some tutorials for using OpenGl can be found at NeHe Productions
http://nehe.gamedev.net/
The best starting points for OpenGL is The OpenGl Web Site
http://www.opengl.org/
http://groups.yahoo.com/group/xbasic/files/files/Printing%20Routines/
The following line worked fine on WindowsNT 3.51:
a = SHELL ("READ C:\xb\test.txt") ' print file "test.txt"
You can also try printing directly to "lpt1" as follows:
linesPerPage = 66
XstLoadStringArray (fileName$, @text$[])
prt$ = "LPT1"
pfile = OPEN(prt$, $$WR)
IF pfile > 0 THEN
FOR i = 0 TO UBOUND(text$[])
'Print to console
PRINT text$[i]
'Print to LPT1
text$ = text$[i]
IF text$ THEN
PRINT[pfile], text$
END IF
INC count
IF count > linesPerPage THEN
PRINT[pfile], CHR$(12)
count = 0
END IF
NEXT i
'Print form feed to eject last page
PRINT[pfile], CHR$(12)
error = CLOSE(pfile)
Unsubscribe: xbasic-unsubscribe@yahoogroups.com
Or you can sign into your YahooGroups account and go to your My Groups page on YahooGroups:
http://groups.yahoo.com/mygroups
Then on the right side press the button Edit My Groups. Then under the
Membership column dropbox for the xbasic group, select unsubscribe.
Then click on Save Changes button.
- Stable releases. Stable releases all have an even sub-version number, e.g. 6.0.0, 6.0.8, 6.2.0, 6.4.0, 7.0, ... As a general rule only bugfixes will be added to this version(s), no new features. The latest available stable version is 6.0.8 (a.k.a. 6.008). Bugs in this version will be treated with a high priority. Bugfixes for the 6.0 version should be sent to max (please respect his conditions: i.e. "The ONLY way I can put any changes into the releases is if all the work has been done already and all I have to do is replace files & recompile."). Bugfixes for versions 6.2 (not yet available) and up should be sent to me.
- Unstable (or 'beta') releases: Unstable releases all have an odd sub-version number, e.g. 6.1.0, 6.1.1, 6.3.0, 7.1.0. In this versions new features are added. To be able to introduce fundamental changes without breaking many installations these releases should ONLY be used by beta-testers and/or experienced XBasic users. Bugs in this version will be treated with a lower priority. After a while a 'feature freeze' will be announced during which time only bugs will be fixed. After that the unstable version will become the next stable version. There is no unstable release version available yet. I hope to release version 6.1.0 within the next few weeks. All bugfixes for unstable releases should be sent to me.
- CVS snapshots: These are the current sources the XBasic developers are working on. These are only usefull for people working on new features. There is no need to sent in bugreports/fixes for this version because bugs in it are probably already known by the developers. For details on how to retrieve a CVS snapshot see the XBasic project page on SourceForge:
http://sourceforge.net/cvs/?group_id=1657
http://www.maxreason.com/software/xbasic/share.html
Select either the Windows or LINUX download page, then select the appropriate sourcecode zip. For windows, you can download the from this url:
http://groups.yahoo.com/group/xbasic/files/downloads/xbwindowssource.zip
Or, you can download the CVS (current version source) for XBasic at the XB SourceForge site. These are the current sources the XBasic developers are working on. These are only useful for people working on new features. For details on how to retrieve a CVS snapshot see the XBasic project page on SourceForge:
http://sourceforge.net/cvs/?group_id=1657
Note: The following directions apply only to XBasic v6.0022. The newest version of Xbasic v6.2+ requires the installation of a few Cygwin utility programs. To recompile v6.2+, see either README.linux or README.win32 files in the sourcecode files.
After you download the source file zip, unzip the files into your \xb directory. If you have the following files in your \xb directory, then move them to xb\lib xlib.s xstart.s xzzz.s You should only have to do this once.
To recompile XBasic, start a DOS window, Start >> Programs >> MS-DOS Prompt, get into your XBasic directory by typing the following at the prompt:
cd \xb
If you have previously compiled XBasic, then you should delete all of the previous .s and .o files so at the prompt, type:
del *.o
del *.s
and then build Xbasic by entering the following:
nmake -f xb.mak
If you want to rebuild the runtime XB dll (the xb.dll found in \xb\run) then type:
(sorry, there is no short description and there are many different kinds
of 'open source').
Do not immediately submit the bug in the bug-tracking system. Something that might seem a bug to you might not be a bug after all, or someone might already have a solution or workaround for it.
Do not submit the bug to any of the XBasic developers directly. These bug-reports will be ignored.
2. If there comes no solution from the mailinglist: add the bug to the bug-tracking system at https://sourceforge.net/project/?group_id=1657 . You (the first submitter of the bug) are responsible for this. If you don't submit the bug to the bug-tracking system changes are the bug will be forgotten. In general noone else will submit the bug to the bugtracking system.
3. If you have fixed a bug: please send the modifications you made to eddie@xbasic.org . You may as well send it to the mailing-list but don't send it to the mailinglist only, because I might miss it.
Patches should be send preferably as 'context diffs' (diff -U4) or the changed functions/subs. If that's not possible: you can send the complete sourcefile.
Patches should preferably be zipped or gzipped.
The XBasic runtime library is covered by the LGPL, not the GPL. You can't charge for XBasic or for the library (other than a reasonable distribution cost), but your program (commercial, shareware, or otherwise) can use the runtime library without any change in the status of your program.
What you may not do is incorporate any part of the PDE or compiler into your program and then sell that - even as shareware. The PDE and compiler are the portions covered by the GPL, the runtime libraries are not.
Any name similarities between Windows and GraphicsDesigner are coincidence! A Windows window handle is not a GraphicsDesigner window or grid number. A Windows window procedure is not a GuiDesigner window or grid function.
Windows API function SendMessage() is totally incompatible with XgrSendMessage() or XuiSendMessage() . SendMessage() calls a Windows "window procedure". This window procedure is not the same as any GraphicsDesigner window function or grid function.
The Windows message queue is not the GraphicsDesigner message queue !!!
These message queues are completely independent, separate, and different.
GraphicsDesigner processes some of the messages from the Windows message
queue, and discards the rest. Sometimes GraphicsDesigner adds one of its
own messages to its own message queue as a result of a Windows message, but
your program never, ever sees or deals with the Windows messages. Programs
should never call SendMessage() to deal with a GraphicsDesigner window or
grid.
Windows XuiTextArea operation performed
Ctrl+X Ctrl+X or Delete cut selected
text and put in clipboard
Ctrl+C Ctrl+C or Ctl+Insert copy selected text and put in clipboard
Ctrl+V Ctrl+V or Insert paste clipboard
text at text cursor position
Applications can process the TextEvent callback message from text grids like XuiTextArea and XuiTextLine to implement new keystroke conventions. Related messages recognized by these text grids include:
#GetTextSelection
#GetTextCursor : #SetTextCursor
#TextDelete : #TextInsert : #TextReplace