XBasic FAQ

XBasic is a comprehensive program development environment that integrates a powerful editor, compiler, debugger, and GuiDesigner into a seamless working environment encompassing the whole process of creating fast, efficient, reliable programs.

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


Index of Sections


Index of Questions:

Section A - Program Development Environment (PDE)


Section B - General Programing

Section C - Graphics


Section D - Text


Section E - External DLLs


Section F - Printing


Section G - Mailing List


Section H - Open Source


Section I - Misc.


Section J - Installation


Section K - GUI Programming

Section L - File and Database Processing

Section M - Multimedia & Game Support



Section A - Program Development Environment (PDE)

Q.A1- Why can't I see the icons on the toolbar?

This usually happens when you install XBasic wrong.
You can install XBasic on any hard-drive (c: d: e: etc), but you must install into the \ root directory and select the "recreate subdirectories" option.
For v6.0022, you should have the following directories (the c: can be d: or e:)
c:\xb
c:\xb\app
c:\xb\doc
c:\xb\xxx
While for v6.2, the images are stored in c:\program files\xbasic\images .

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.

Q.A2- Are the default font and default colors settable in a dialog?

Default colors are set by XgrSetDefaultColors().

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.

Q.A3- Is there an "autosave" feature in the event of crashes?

When crashes occur the PDE saves the current application code as file xb.sav.  Only rarely is the PDE unable to save the current application.  Look for xb.sav !!!

Q.A4- When a fatal runtime error occurs, can I change a value and continue running?

Yes.  You can change the values of variables and/or change where the program will continue executing.  Consider the divide by zero and segment violation errors in the following function as examples.
' ######################
' ##### 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
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.

Q.A5- Why do bitmap files have to stay in the same place as during development?

Bitmap files can be located anywhere they can be opened.  Perhaps you are referring to the fact that images selected for grids with the GuiDesigner AppearanceWindow generate full path file names when design windows are converted into grid functions by Window ToFunction .  If you do not change these names, the locations of the bitmap image files are in fact fixed, just as you say.  To change to a relative path name, edit the grid function as in this example:

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")

Q.A6- Why don't the accelerator key sequences appear to function (eg Alt-e, g etc)?

The "accelerator" hot-keys for menus are currently disabled in the PDE environment. But they will work fine in your programs. This is a known problem.

Q.A7- How do I get rid of the "report messages" screen when I run my program?

When you select "Window ToFunction", GuiDesigner converts the window you designed into two functions - a grid function that creates and operates the window, and a callback function or xxxCode() function that gets sent callback messages when something important happens.

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".

Q.A8- Why do I sometimes I get unresolved external symbol errors when I shouldn't?

When the PDE compiles more than one program, it sometimes looks for symbols that existed in a previous compilation. This rare bug has not yet been tracked down and exterminated. For now you'll have to exit the PDE and restart it.

Q.A9- Is there a command to clear the console window of all text?

Do you know you can double/triple/quadruple click in GuiDesigner text grids to select word/paragraph/all-text? That makes it LOTS quicker to highlight all text, then a simple "delete" keystroke will do the trick.

In your program, make sure you have IMPORT "xst" in your PROLOG, then you can use

XstClearConsole ( )

Q.A10- How do I compile my application to an executable? I don't see any option in the PDE that does this.

You don't see an option there, because there are actually three steps to making an executable program or a DLL.

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.

Q.A11- Why does the text I enter in any TextLine box in the Appearance Setup Window clear the value when I press the on screen "Enter" button?

After you type some text into any TextLine box in the Appearance Setup Window, eg, HintString, HelpString, or TextString, you need to press your keyboard Enter key for the data to be entered correctly. If you click on the Enter PushButton first, before hitting the Enter key, then your text string will be lost. Sorry, but it's just the way it works...

Q.A12- Is there any way to reopen the console window after you've closed it?

In your PROLOG, make sure you have IMPORT "xst" uncommented. Then use any of the console functions in your program to hide or display the console:

XstDisplayConsole()   'display a previously hidden console
XstHideConsole()      'hide console window
XstShowConsole()      'show console window

Q.A13- How do I keep the PDE window from re-sizing after program execution?

Go to the property.xxx file in your xxx directory, and put these lines of code in that file.

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")

Q.A14- Why don't any of the help items in the help-menu work properly? Why doesn't the instant help feature work either?

If you are using Windows, and starting Xbasic with shortcut icon. it may not be set up properly. You must spesifically name the startup directory of the shortcut, (ususally "c:\xb") Now everything should work fine .

Q.A15- How can I copy and paste Xbasic text program results from the console window (eg. into notepad)? The usual Ctrl-c Ctrl-v doesn't work.

Try the old fashioned DOS method CTRL-INS and SHIFT-INS.

Q.A16- How do I  keep the console window from appearing in my program?

In your PROLOG, make sure you have IMPORT "xst" uncommented. Then use any of the console functions in your program to hide or display the console:

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.

Q.A17- Is there a way to permanently set the cursor color in TextArea grids?

You can add a line to your xbasic/templates/property.xxx file.  The property.xxx file contains the various grid function properties to be used on start-up. To change the cursor color, you would change the dull color property for all XuiTextArea grids, including the PDE lower TextArea.

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.

Q.A18- How can I prevent the XBasic Information window from appearing at start-up?

The "About" start-up window normally only appears the first 10 times you start the program, plus once every 16 times after that. If you edit C:\windows\xb.ini to include the line

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.

Q.A19- How do I prevent the PDE windows from being smudged and distorted when moved off the display area or over another window?

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

Q.A20- How do I recompile Xbasic from the source code?

To be able to compile XBasic itself you need the following things
 - A working XBasic compiler (note: XBasic is largely written in XBasic itself)
 -  The XBasic source code found on SourceForge  ( http://sourceforge.net/project/showfiles.php?group_id=1657&release_id=11540 )
 - The Cygwin utilities. This can be the full distribution (available from http://sources.redhat.com/cygwin/ ) or a 'light' distribution (available from http://groups.yahoo.com/group/xbasic/files/files/Cygwin%20Files/ ) or from the the XBasic SourceForge file page shown above, look for xbasic-Util-1.0.exe

To compile XBasic:
  1. Unpack the sources into a separate directory from the XBasic binary directory (usually C:\xbasic-6.2.1 by default)
  2. In a DOS window, change to that directory (at prompt type cd xbasic-6.2.1)
  3. xbvars
  4. make
  5. make install
The installer for the Cygwin utilities added a couple of lines to C:\windows\xbvars.bat to specify where you installed them.
 
The source files do have a path included in the ZIP archive, same applies if you had downloaded the binary files as a ZIP. You MUST tell your unzip program to restore the original directory structure, it won't work otherwise. So if you tell it to extract to C:\, it will create a directory C:\xbasic-6.2.1 along with several subdirectories.
 
To recompile XBasic under Windows, open a DOS prompt. Change to the directory the source files are in
 
  cd xbasic-6.2.1
 
then run xbvars.bat, and then just type "make".
 
  xbvars
 make
 
The Cygwin make utility (which is a Windows version of the Linux make utility) automatically looks for a file named "Makefile" in the current directory, and then follows the instructions in that file. You'll see the XBasic Console window open and close several times as it compiles the files in the source directory, and quite a few lines printed after you originally typed "make".
 
That only builds the files though, to actually install them to your current XBasic directory you then need to type
 
  make install
 
If for some reason you wanted to install to a different directory (say you want to be sure your new version works before overwriting the old one), you'd have to reset the environment variable XBDIR to your new directory, as in
 
  set XBDIR=C:\XBasic-Test
 make install

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.)

Provided you didn't make any errors in your changes to the source code, that should be all there is to it.
 
(Since XBasic is mostly written in XBasic, you need a working XBasic to compile the files. The same would apply if you were rebuilding a C compiler, which would itself be written in C).
 
If you are running Linux rather than Windows, you already have the Linux versions of the Cygwin utilities and there is no "xbvars.bat". You'd just switch to the source directory, type "make" followed by "make install" and that would be it.



Section B - General Programing

Q.B1- How does one call Win32 API functions from XBasic?  

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.

Call Win32 API functions exactly the same way that you call any function within a DLL.

[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.

Q.B2- How can I add message queue asynchronous timer interrupts to my program?

Normal programs, and especially GUI programs, are synchronized by the message queue. When a message is processed by XgrProcessMessages() , all actions caused by processing the message are performed in the expected order before the next message is processed. Programs can therefore assume that program variables will not be unexpectedly modified during message processing. This reduces the complexity of programs enormously.

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.

 

Q.B3- How can I make my process take less CPU time under certain circumstances?

XstSleep(msec) causes a process to yield to other processes for a specified number of milliseconds.  As a convenience, msec = 0 tells the process to yield the rest of its time slice, and be activated again the next time it is it's turn.

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

 

Q.B4- How do I put timers into my GuiDesigner application?

One of the sample applications is xgrids.x.  This file is a collection of grid functions that implement many basic grid types. The XuiPressButton() grid function exercises the grid timer in all ways.  Timer related messages include:

 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 .

Q.B5- How do I call a callback function and have it execute a particular subroutine.

When you select Window ToFunction in the toolkit, GuiDesigner converts the currently displayed design window into a pair of functions, a "grid function" and a "callback function".  When your program is running and something important happens in the window, the grid function calls XuiCallback() , which in turn calls the callback function with a #Callback message, and the real message in r1 .   Usually the original message is #Selection .

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)
$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
The following three lines were added to the GuiDesigner generated code to prepare the callback function for special purpose messages from your program:
$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:
TestCode (grid, #Selection, v0, v1, v2, v3, $Custom, r1)

Sample applications acircle.x and ademo.x contain an example.  Also make sure you
XgrRegisterMessage (@"Custom", @#Custom)
in InitProgram().
 

Q.B6- Can I send messages to functions whose windows don't have focus?

Programs can call grid functions and callback functions without regard to keyboard or mouse focus. Everything works the same with or without focus. The only thing focus does is route keyboard input to the focus window. Your program can set the keyboard focus to a particular grid by sending the grid a #SetKeyboardFocus message.

 

Q.B7- Why aren't EXTERNAL variables visible between programs?

EXTERNAL variables are shared between statically linked programs, not libraries.  In other words, if three programs declare EXTERNAL trouble, and the object files of the three programs are linked together into a single executable, a single trouble variable is referenced by all three programs, and trouble is therefore shared by all three programs.   The executable can be a .EXE or a .DLL .

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") .

Q.B8- How do I get a Random Number, ie. a =RND(5)+1?

XBasic does not have a built-in random number generator (RNG). There is a random number library available, as a DLL and as source code. It can be found on the XBasic Yahoo web site file vault. Go here:

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.

Q.B9- Does XBasic support basic parallel port I/O functions?

No it does not, but it is fairly easy to use an external DLL for port access. First you find one, figure out the lib command and make a .lib file for it if it didn't come with one, create .dec and .def files for it, declare external in your code and after that its use is transparent. I used Fred Bulback's IO.DLL file. A VB example for using this DLL is found at I/O Control Using Using Visual Basic .

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 -------------------------
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
I made the IO.LIB file, required for linking to standalone, with the following dos command:
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@@)

Q.B10- Are STATIC arrays supported in XBasic?

I have zillions of static arrays all over the place!  The easiest and best way to dimension and initialize them is like the following:

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.

Q.B11- How do I make command line arguments work the same in the environment and a standalone executable?

Programs call XstGetCommandLineArguments (@argc, @argv$[]) to get command line arguments. But the command line arguments a standalone executable will receive are not available to the program when it is run in the environment. To test the effect of various command line arguments on a program in the environment, you need code like the following:
'  ...
'
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$[]
'
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.

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 = -1
XstGetCommandLineArguments (@argc, @argv$[])
The following code reinstates the original command line arguments after they have been changed.
argc = -1
XstGetCommandLineArguments (@argc, @argv$[])
XstSetCommandLineArguments (argc, @argv$[])

Q.B12- Is there a command at the beginning of every program that will make all variables double, or do you have to specify each and every variable?

You have to specify your variables IF they have to be of any other type than XLONG.

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, ##GlobalDouble4
SSHORT #InterShort%, ##GlobalShort2%, LocalShort3%
STRING ##GlobalA$, LocalB$, LocalC$
The examples also show the prefix used to stamp variables as local, internally global and environmentally global.

Q.B13- How do I round off numbers in Xbasic?

If you want to round off a float variable to the nearest integer, just convert to an integer using ULONG ( ) or SLONG ( ):

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

Q.B14- What is the correct way to show the path for a file using OPEN function?

This is incorrect:
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.

Q.B15- How do I put a double quote " character inside of a string variable?

Special characters can be embedded in strings by using the "escape" backslash character "\".  You can't type a newline
inside a string, so you can type \n instead. But this means any backslash you actually want to type must itself be escaped, in order to PRINT a single backslash you'd actually have to say PRINT "\\".

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.

Q.B16- How can I assign individual values to arrays without the use of READ/DATA like in previous Basic languages?

Here are some ideas:

Just assigning simple values to an array in a sorted order is pretty simple:

FOR X = 0 TO 10
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
When your data is not an ordered series.
'Data stored in a string where each piece of data is 4 characters long
'       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
This would work of course with string information too like:
123456789123456789123456789123456789123456789
month$ = "January  Febuary  March    April    September"
MID$ 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...

For storage (from memory to disk) using the Var${pos} is the quickest way.

Another method:

Data$ = "496967496740947676496749505038264807"
FOR i = 0 TO UBOUND(Data$)
  PRINT i , Data${i}
NEXT i
You can enter byte data into a string using escape hex notation thus :
STRING s
s = "\x41\x42\x43\x61\x62\x63"
PRINT s
FOR i = 0 TO UBOUND(s)
  PRINT i , s{i}
NEXT i
This prints
ABCabc
0   65
1   66
2   67
3   97
4   98
5   99
You 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 :
s = "\0\1\2\3\4\5\6\7\8\9\A\B\C\D\E\F"
FOR i = 0 TO UBOUND(s)
  PRINT i , s{i}
NEXT i
with output
0   0
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
Another favorite method is pseudo-hex notation , as follows :
s = "0123456789:;<=>?"
FOR i = 0 TO UBOUND(s)
  PRINT i , s{i} & 0xF
NEXT i
- output as above.

Or you can use ordinary hex(here the conversion is a little more tricky):

s = "0123456789ABCDEF"
FOR i = 0 TO UBOUND(s)
  PRINT i , (s{i} - 48 + 7 * ( s{i}>57 ))
NEXT i
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) STEP 4
  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
If 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...

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]
FileHandle = OPEN(file$, $$RD)
READ [FileHandle], MyArray[]
' 256 * 4 bytes = 1024 bytes are just read into the array
CLOSE(FileHandle)
Here's an example displaying the reading of a user / composite type reading an aligned range of various typed elements into a whole array:
PROLOG
'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
If 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:

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
 

Q.B17-How can I play a WAVE .wav sound file?


 

Q.B18-What is the difference between passing values by reference and sharing variables with SHARE?

You can pass arguments in functions by value or by reference.  Arguments that are passed by reference must use the @  prefix. All strings and arrays MUST be passed by reference.

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

Q.B19- How does one enter a negative DOUBLE/SINGLE constant in XB?

 It takes a little work to determine the value, but you would enter it as a "DOUBLE image" preferably. A DOUBLE image is more accurate than entering the decimal anyway. It is written as the prefix "0d" followed by 16 hex digits.

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.)

Q.B20- How do I pass an array to a C function?

Cfunction (&myarray[])

 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.

Q.B21- How do I determine the path of the executing XBasic program?

XstGetProgramFileName$() retrieves the full path and file-name of the executing program. You can use one of the 'path-splitting' functions like XstGetPathComponents() to retrieve the directory path. It's both implemented on Win32 and Linux, but only in 6.1.x and higher.

Q.B22- What is the best way to determine if a string variable a$ is a number?

There is a function in the standard library xst XstStringToNumber() that can check this for you. This function will convert the string to the appropriate type. It returns -1 if the string is not a valid number.

Q.B23- How can arrays be made global?

What do you mean by "global"?

 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.

Q.B24- Is there a timer that has 1 millisec or better resolution?

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



Section C - Graphics

Q.C1- Does GraphicsDesigner support three or five coordinate systems?

For purposes of coordinate conversion, there are five coordinate systems:

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.

 

Q.C2- How do I keep my graphics in my grid from being erased when it is covered by another window or when I minimize/maximize my window? How do I create an "image or buffer" grid to make my images "stick"?

When an XBasic GuiDesigner grid is resized or uncovered, it's contents are lost. If the contents are graphics understands, like background color, border graphics and text strings, BMP images, then GuiDesigner typically automatically redraws the grid - unless you prevent it from doing so.

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

Q.C3- How can I prevent the drawing functions from drawing outside the boundaries of the target grid?

Fundamentally, grids are "fictions". The programmer may think there are subwindows everywhere there's a grid, but in fact there is only the outer window (or the whole screen potentially). The only "reality" to grids are coordinates in the main window (screen). So when you clear a grid or draw text in a grid or whatever, all that's happening is that the GraphicsDesigner function adds the x,y position of the grid to the coordinates you specify and clear/draw/whatever.

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)
XuiSendMessage (kkkk, #SetClipGrid, kkkk, 0, 0, 0, 0, 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.

Q.C4- I have added a BMP image resource to my EXE, how do I use it from within XBasic?

You can add BMP or icon, or cursor resources to your standalone EXE and then access them from within your program. The following posts discuss how this is accomplished:
http://groups.yahoo.com/group/xbasic/message/5041
http://groups.yahoo.com/group/xbasic/message/5053

Q.C5-  How do I load JPG images?

XBasic can only load BMP format images. However, you can use just about any image format with XB by using an imaging library. There are several OpenSource imaging libraries available that can enable XBasic to use not only the JPEG format, but also, TIFF, PNG, PGM, TARGA and others.

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/

Q.C6-

Q.C7-

Q.C8-

Q.C9-

Q.C10-


Section D - Text

Q.D1- Why do null bytes and backslash characters like \t and \n in text strings display as little blobs or images in grid text?

Many fonts have images for more than common or standard ASCII characters. ASCII values from 0x20 to 0x7E represent a reliable set of standard characters. But many fonts contain character images for most or all extended characters from 0x00 to 0x1F , and from 0x80 to 0xFF . The font images for these extended characters are not consistent between fonts. Nonetheless, the images for these characters can be displayed, and in certain circumstances they are.

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.

Q.D2- How can I create neat columns of text with proportional fonts?

Two grid properties relate to tabs, namely TabWidth, and TabArray.  Unfortunately, many grid types ignore TabWidth and TabArray at this time, generally because they display the font 0x09 character image instead of space.

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.

Q.D3- Why does SPACE$(1) create a different width space with different fonts?

SPACE$(n) creates a string containing n space characters. When strings are displayed by a GuiDesigner grid, the character width of every character, including the space character is determined by the font - by typeface, size, boldness, italic. In monospace typefaces, the width of the space character is the same as the width of all other characters in the same font. In proportional typefaces, the width of every character varies by design, so no characters, including the space character, is necessarily the same width as any other character. In addition, when proportionally spaced text is "full justified", meaning a straight left and right margin, the apparent width of space characters is varied to flush the margins.

Q.D4- Sometimes it's a little hard to find the text cursor in a large XuiTextArea?

The color of the text cursor in XuiTextArea and XuiTextLine grids can be globally changed with OptionTextCursor in the Main Window.  The text cursor is drawn in XOR drawing mode, so depending on the number of bits per pixel and whether a system is palette or direct map, the text cursor will not be the same color on all systems.  To change the color of the text cursor in a XuiTextArea or XuiTextLine grid in a design window, change its DullColor property with the AppearanceWindow.  Remember, the cursor color is not the DullColor itself, but the XOR of the DullColor and whatever the cursor is written over in the grid.  For example, a yellow text cursor might be created by setting DullColor to $$LightBlue.

Q.D5- How do I show special language characters (i.e. ANSI) in the internal text editor of Xbasic?

That's a simple matter of changing the font the editor uses. The font you're using is what Windows calls an OEM font - it uses the original IBM PC character set. You'll have to choose a font which has the characters you want in it. Go into the file \xb\xxx\font.xxx, comment out "OEM_FIXED_FONT" and choose another (say, ANSI_FIXED_FONT), or to only change in the editor there edit \xb\xxx\property.xxx, adding a line to set the font in any xuiTextArea of xb to your chosen font.

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$..

Q.D6- How can I load a text file for viewing?

Well loading a text file needs two important things:

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 

Q.D7- How do I send or retrieve text from the clipboard?

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[])

Q.D8-

Q.D9-

Q.D10-


Section E - External DLLs

Q.E1- Can I use Dlls written in any language or do I have to use Dlls created in C/C++?

It doesn't matter in which language a .DLL is written; it's just a compiled, binary piece of code with a fixed 'interface'. As long as you (are able to) use that interface you can call any language from any language.

Q.E2- How can I read/write to the parallel or serial ports in XB?

There is not currently a built-in x-platform library for port communications. There are direct APIs that can be called from Win9x API functions. The following are the Win9x API functions used with communications resource (kernel32.dll). A communications resource is a physical or logical device that provides a single bidirectional, asynchronous data stream. Serial ports, parallel ports, fax machines, and modems are examples of communications resources. See kernel32.dec.

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

Q.E3- How do I know if an external 3rd party DLL will work with XBasic?

If the library was created from a C program, then it will probably be compatible with XBasic. There is a utility program called dllGuide that can help you determine if any particular DLL is compatible.

dllGuide is a program to help in the process of preparing a third-party DLL for use by an XBasic program.

This program will work only in Windows, and only with XBasic 6.2.0 or above.
Download it from http://groups.yahoo.com/group/xbasic/files/members/dllGuide.zip
(size about 70kb)

Q.E4-Is somebody working on implementing the OpenGL libs?

 The OpenGL libraries are (c) (tm) by Silicon Graphics. They are not OpenSource, however, they can be used by gaming programmers freely...and are routinely included as part of the OS distribution for Windows, MacOS, and for LINUX. The OpenGL v1.1 library for Windows can be downloaded from

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/

Q.E5-

Q.E6-

Q.E7-

Q.E8-

Q.E9-

Q.E10-


Section F - Printing

Q.F1- How can a program send text to the printer?

There is a printer library for XB Windows called xpr.x which can be found in the XB YahooGroups file library:

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)
 

Q.F2-

Q.F3-

Q.F4-

Q.F5-

Q.F6-

Q.F7-

Q.F8-

Q.F9-

Q.F10-


Section G - Mailing List

Q.G1- How do I unsubscribe to the Xbasic Mailing list?

In order to unsubscribe to the YahooGroups XBasic group, you can send an e-mail to the list with a subject of Unsubscribe:

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.

Q.G2- How do I get to My Groups in the YahooGroups mailing list?

When you sign in, the first page displayed is My Groups. You can get to My Groups by clicking the MyGroups link at the top of every page. 

Q.G3- How do I remove groups from the My Groups page at the YahooGroups site?

To remove a group from appearing on the My Group page, you must unsubscribe from that group. Simply choose "Unsubscribe" from the drop-down box to the right of the group name. Unsubscribe will remove the group from My Groups, and you will stop receiving messages from other members. 

Q.G4-

Q.G5-

Q.G6-

Q.G7-

Q.G8-

Q.G9-

Q.G10-


Section H - Open Source

Q.H1- What are the guidelines for XBasic features and bug fixes?

There are 3 different 'releases' of XBasic:

- 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

Q.H2- How do I make an XBasic build from the Xbasic source files?

The source for Xbasic v6.0022 can be downloaded from either the XBasic web site:

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:

nmake -f xbrun.mak

Q.H3- If I want to help with the development of XBasic how(where) do I start?

The best way to start is to read / write in the XBasic mailinglist. There are a lot of tasks that can be done but you should check on the mailinglist, chances are somebody else is already working on something. 

Q.H4- Is XBasic open source?

Yes. All source of the XBasic compiler, development environment and runtime library is available. The source of the compiler and development environment is released under the GPL license and the source of the runtime library under the LGPL license. For more info on the GPL and LGPL licenses, see:

http://www.fsf.org

Q.H5- Why is the runtime library released under a different license from the compiler/development environment?

The GPL (amongst other things) obliges you to make your sourcecode available if you use any part of a GPL sourcecode. It means that if the runtime library was released under the GPL every program linked with it (that is, in fact, every program compiled by the XBasic compiler) would be subject to the GPL too. That would prohibit closed source programs to be written in XBasic and that's not what we want. So the runtime library is released under the LGPL.

Q.H6- What does open source mean?

See:

http://www.opensource.org

(sorry, there is no short description and there are many different kinds of 'open source').

Q.H7- What is the procedure for reporting and fixing bugs?

1. Submit a bug report to the XBasic mailinglist ( xbasic@egroups.com ). Be brief, but as complete as possible. Preferably: add a short (the shortest possible) program that demonstrates the bug.

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.

Q.H8- Do my XBasic programs have to released under LPGL?

Of course not. You can write anything you want with XBasic and release it under any terms or license as you want, be it open source, freeware, shareware, commercial ware, public domain, LPGL, etc.

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.

Q.H9- What is Xbasic's SourceForge address?

http://sourceforge.net/project/?group_id=1657

Q.H10- What is SourceForge?

SourceForge is a website that donates resources (webspace, CVS repositories, mailinglists, ...) to Open Source projects. See:

http://sourceforge.net

Q.H11-

Q.H12-

Q.H13-

Q.H14-

Q.H15-


Section I - Misc.

Q.I1- Messages sent with Windows API function SendMessage() disappear. Why?

Windows messages are not the same as GraphicsDesigner or GuiDesigner messages. They have different names, different values, and different arguments. They are utterly and totally incompatible. But that's not all by a long shot !!!!!!!!

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.

 

Q.I2- How can I make Windows standard cut/grab/paste work in XuiTextArea?

Here is how cut/grab/paste works in Windows vs XuiTextArea and XuiTextLine :

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

Q.I3- What about differences between HelpGuiDesigner and the manuals?

The differences between the software and manuals sometimes occur. When you request help on one of the libraries from the Help menu in the main window, the PROLOG of the library is displayed in the HelpWindow. Since these .dec files contain the actual declaration of types, functions, and constants from the libraries, these files