I thought this may interest you. More info on Xbase++ is available from http://www.alaska-software.com Regards, Jamal ---------- GUIDE TO GETTING STARTED WITH XBASE++ Introduction. . . . . . . . . . . . . . . . . . . . . 1 Installation. . . . . . . . . . . . . . . . . . . . . 2 Removing a previous Xbase++ installation. . . . . . . 2 Installation of Xbase++ . . . . . . . . . . . . . . . 2 Typical installation. . . . . . . . . . . . . . . . . 3 Custom installation . . . . . . . . . . . . . . . . . 3 Before you move on. . . . . . . . . . . . . . . . . . 5 Windows 95 environment limit. . . . . . . . . . . . . 5 Working with Xbase++ and Clipper. . . . . . . . . . . 5 The professional way to get started with Xbase++. . . 7 All begins with "Hello World" . . . . . . . . . . . . 8 The mouse rules the world . . . . . . . . . . . . . . 9 The preprocessor translates commands. . . . . . . . .10 The first GUI program . . . . . . . . . . . . . . . .11 The smooth migration from DOS to GUI. . . . . . . . .12 Xbase++ knows three application types . . . . . . . .14 More migration ideas. . . . . . . . . . . . . . . . .15 GUI straight and simple . . . . . . . . . . . . . . .16 Developing new GUI applications . . . . . . . . . . .19 More Xbase++ technology . . . . . . . . . . . . . . .21 A complete GUI database application . . . . . . . . .23 One more DatabaseEngine . . . . . . . . . . . . . . .25 External resources for GUI programs . . . . . . . . .26 Project maintenance with Xbase++. . . . . . . . . . .27 What is compatible: Clipper or Xbase++? . . . . . . .29 How to proceed... . . . . . . . . . . . . . . . . . .34 Online-documentation. . . . . . . . . . . . . . . . .37 Introduction Welcome to Alaska Xbase++, the superior database development package for 32-bit operating systems. Please read the following instructions carefully and entirely. You will be guided through the Windows installation procedure of your Xbase++ development package, and you receive important information about your system configuration. If you like, you also can follow a 3-hour Getting Started tour around Xbase++ that gives you valuable head-start information about the development package and its numerous features. The tour is is composed of experiences from our technical support and marketing departments, as well as material from Xbase++ training seminars. This initial training course is designed for self-study. It includes exercises which enable you to obtain a thorough overview over a wide range of Xbase++ features in the shortest possible time. We hope you enjoy it, Your ALASKA Team Installation Removing a previous Xbase++ installation If you have a previous version of Xbase++ already installed, you should uninstall this software via the software control panel: Click the Start button Select Settings -> Control panel Click the icon Add/remove programs Select Xbase++ from the list in the Install/Uninstall tab page Note that the uninstall program can only remove installed files. It does not remove files created after installation, such as OBJ or EXE files in the ..\SAMPLES directory, for example. If such files exist, a warning message is displayed stating that the program could not be removed. In this particular case, you can ignore the message. When a previous version is removed, you should check the PATH, LIB and INCLUDE entries in the AUTOEXEC.BAT (Windows95) or in the registry key HKEY_CURRENT_USER\Environment (WindowsNT), respectively, for old values. After a new installation, you must recompile all the programs which you have compiled with a previous Xbase++ version. Installation of Xbase++ Insert the CD in the CD-ROM drive and start the Windows Explorer. Select the directory \XPPW32\INTL on the CD to install the international version of Xbase++. The program SETUP.EXE can be found in this directory. It installs Xbase++ and guides you through the installation procedure prompting you for Typical or Custom installation. Note: The Xbase++ installation does not change or replace any system DLL files. All DLL files required by Xbase++ are stored in newly created directories. Typical installation The Xbase++ development package is installed by default on drive C: with \ALASKA\XPPW32\ as the root directory : |--BIN Compiler and service programs |--BOOK Online help |--LIB Runtime library |--INCLUDE #include files |--RESOURCE Resource files |--RUNTIME Runtime libraries |--SOURCE Source code |--SYS Source for System level files |--COMPAT Compatibility functions for Clipper '87 |--SAMPLES Example programs During installation your system configuration is changed to reflect the new directories. For Windows NT, the changes are applied to the registry database under \HKEY_CURRENT_USER\Environment, while AUTOEXEC.BAT is changed for Windows 95. The following registry keys or environment variables, respectively, are modified or created if missing: PATH = C:\ALASKA\XPPW32\BIN;C:\ALASKA\XPPW32\LIB; LIB = C:\ALASKA\XPPW32\LIB; INCLUDE = C:\ALASKA\XPPW32\INCLUDE; XPPRESOURCE = C:\ALASKA\XPPW32\RESOURCE; Default file associations are defined for PRG, CH, XPJ and XFF files during a typical installation. Use custom installation to suppress this automatic feature. In this case, you must apply required changes manually. Custom installation Custom installation allows you to select individual components of the Xbase++ package to be installed. Also, the definition of file associations can be selected individually. CH Include files are associated with Windows' Notepad and the Xbase++ compiler. The compiler performs a syntax check for a CH file when invoked. PRG Source code files are associated with Window's Notepad and the Xbase++ compiler. A PRG file is compiled. XFF Form definition files are associated with the Xbase++ FormDesigner. XPJ Xbase++ Project files are associated with the ProjectBuilder. A left double click on an XPJ file builds a project. Note: The file XPP.REG is available in the root directory of the Xbase++ installation. If file associations are not defined during installation they can be defined later by importing XPP.REG to the Windows registry using REGEDIT.EXE. Default file associations can also be changed by editing the XPP.REG file. For example, if you want source code files to be associated with the editor of your choice, replace the string "notepad.exe" in XPP.REG with the name of your editor and import the changed file to the registry. Be aware that XPP.REG contains a snapshot of HKEY_CURRENT_USER\Environment as it is before you install Xbase++. If you change the registry later by installing other software, for example, these changes are not reflected in XPP.REG. Before you import XPP.REG into the registry, make sure that HKEY_CURRENT_USER\Environment is correct or remove this section entirely from the XPP.REG file. Before you move on If you have installed Xbase++ under Windows 95 or work with both Clipper and Xbase++ on the same workstation, please read the following sections before you start using Xbase++. Windows 95 environment limit In Windows 95 the space for environment variables is limited to 1024 bytes by default. This can lead to problems when many paths are defined in AUTOEXEC.BAT pointing to numerous directories. If the memory space for environment variables is exhausted, it is most likely that paths are not defined completely or are not available in the system's environment at all. This is also the case if all paths are listed correctly in AUTOEXEC.BAT, since the environment table is full. When you encounter system error messages like "not sufficient environment space" you must increase the size of the environment table using the SHELL statement in your CONFIG.SYS file. The following line is an example that sets the environment space to 2048 bytes: SHELL=C:\win95\command.com C:\win95 /E:2048 /P Note that changes in CONFIG.SYS become only effective when you reboot your computer. Note also that C:\win95 is only an example where the command processor COMMAND.COM is located. It can be in a different directory on your computer. Working with Xbase++ and Clipper Xbase++ needs certain system environment variables to be set correctly. These include PATH, INCLUDE, LIB and XPPRESOURCE which are defined during default installation. However, if you work with Clipper on the same computer, there can be a conflict with the INCLUDE path. Both compilers search this path for include files. Also, both products use the same include file names such as STD.CH, for example, but the file contents differ to a great extent. Therefore, it is necessary that the INCLUDE path points to the correct include directory when you invoke either compiler. A clear indication of a wrong include file being used is given when the Xbase++ linker reports an unresolved external function which begins with two underscores (for example: __SetFormat(), __Quit(), __Keyboard()). These function calls occur only if Clipper's STD.CH file is included. In general, there are no functions in Xbase++ which begin with a double underscore. Switching the environment In order to change the system environment settings for Xbase++ or Clipper more easily, two batch files are available after installation: DINO.BAT and AUTOXPP.BAT. The file DINO.BAT is located in the root directory of your C: drive and AUTOXPP.BAT is found in the root directory of the Xbase++ installation. DINO.BAT contains a pre-installation snapshot of the system's environment variables. When invoked, it resets the system settings back to the values that where current before the installation of Xbase++. Executing AUTOXPP.BAT sets the search paths for Xbase++. The two batch files, therefore, set the environment variables appropriate for Xbase++ or Clipper and let you switch the environment for either compiler on the fly. The professional way to get started with Xbase++ Alaska Xbase++ is an extremely powerful development package that not only understands the Clipper language but adds a huge amount of long awaited features to this language. We are convinced we have created an excellent product with a great future. It comes along with one of the best online-documentations you can find in the software market, showing hundreds of ready to compile, or ready to Cut&Paste, examples (it fills approximately 2500 pages when printed on paper). There is usually a common question that arises after successfully installing complex software: Where do I start? This question cannot be answered in general. The correct answer must take into consideration individual skills and experiences of a programmer. Xbase ++ can be used by programmers who are thinking in the procedural or object-oriented way, those who know Clipper or FoxPro, those who stayed in text-mode all their life, or those who have never programmed before. Even C++ professionals who play the "Windows piano" from the lowest to the highest tune and want to become more productive in the field of database applications need some advice, or hints, regarding what to do first after installation. Our recommendation Before you try anything with Xbase++, take three hours of your time, unplug your telephone or activate your voice mailbox, sit well back in front of your computer and read the following chapters. They include a Getting Started training course that is composed of experiences from our technical support and marketing departments, as well as material from Xbase++ training seminars. This initial training course is designed for self-study. It includes exercises which enable you to obtain a thorough overview over a wide range of Xbase++ features in the shortest possible time. Note: the Getting Started training really takes three hours time to complete. You are also well advised to have pen and paper within your reach in order to write down questions that remain open during the initial training course. These questions can be answered later by the Xbase++ online-documentation or by our technical support. All begins with "Hello World" The most popular program just displays "Hello World" on the screen and that's why the Getting Started course begins with this program. For this, you open a terminal window, or DOS prompt (Start->Programs->DOS Prompt), and create a new directory named XPPFIRST. All files you will be creating within the next three hours will be stored in this directory. When you have finished, you can delete this directory and all contained files. You start working with Xbase++ by using the tool you know best: your editor. So, the first thing is to open your editor in the directory XPPFIRST as a separate process ("Separate process" means: you must be able to change between the terminal window and your editor. Entering START NOTEPAD on the DOS prompt, for example, invokes Windows Notepad as a separate process). Type the following four lines of code in your editor: PROCEDURE Main CLS ? "Hello World" RETURN Save these lines in the file HELLO.PRG and change to the terminal window. There you enter this command on the DOS prompt: [C:\XPPFIRST]xpp hello This invokes the Xbase++ compiler which is the file XPP.EXE in the ..\BIN directory of your Xbase++ installation. By entering xpp hello, the compiler creates the file HELLO.OBJ from the file HELLO.PRG. To create the executable file (EXE file) you enter on the DOS prompt: [C:\XPPFIRST]alink hello The Xbase++ development package includes a 32-bit linker ALINK.EXE which links OBJ files to executable files. The result is HELLO.EXE. Run the program HELLO.EXE by entering hello in the terminal window. The result is: the terminal window is cleared and the string "Hello World" is displayed. What did I learn? With the "Hello World" program I have successfully completed an Edit, Compile, Link, Run cycle. I know how to compile a source code file (PRG file) and how to link the resulting OBJ file. I have invoked the Xbase++ compiler (XPP.EXE) and the Alaska linker (ALINK.EXE) Error: "Hello World" does not work If HELLO.EXE is not created or the program throws an error message, you most likely did not reboot your computer after installation, or the PATH and LIB environment variables are not correct, or you are using Windows 95 and the memory space for environment variables is exhausted (to correct this, please re-read the Installation chapter and follow exactly the instructions). Note for Clipper programmers: You start using Xbase++ at the point where you have left Clipper, and you continue working without the need of passing a steep learning curve. You can write PRG code as usual and compile it. The Xbase++ compiler knows the same compiler-switches like the Clipper compiler. However, we have added a few more compiler-switches that allow for detecting more errors in the PRG code. Keep this in mind: the Xbase++ compiler detects more errors in your code during compile time than Clipper. The mouse rules the world Integrating the mouse as the major input device is a Must in today's world and a problem for many programmers. This is especially true for Clipper programmers who have not yet moved their applications to the Clipper 5.3 version. Xbase++ supports Clipper code from version Summer '87 to 5.2e and integrates the mouse with only one function call. Take the following code as an example and type it in your editor. This is your new exercise: PROCEDURE Main LOCAL cVar1 := "Hello" LOCAL cVar2 := "World" SET COLOR TO N/W,W+/B // define the color SET CURSOR ON // activate the screen cursor SetMouse( .T. ) // activate the mouse CLS @ 10,10 SAY "Hello " GET cVar1 @ 12,10 SAY "Who ? " GET cVar2 READ ? cVar1, cVar2 RETURN Store this program code in the file MOUSE.PRG and create the executable file MOUSE.EXE by entering xpp and alink on the DOS prompt. Run the program MOUSE.EXE. It displays a simple Get entry mask with two Get fields. Click both entry fields with the mouse and terminate the program by pressing the Esc or Return key. Comment the function call SetMouse(.T.) with an asterisk (*) at the beginning of the line and rebuild MOUSE.EXE. Try clicking the Gets again. What you will see is this: all that is needed to make an @..SAY..GET mask mouse-aware is SetMouse(.T.). The program runs in text-mode but is a real 32-bit application. You can run the program in a terminal window or in full screen mode. Try it! Press the key combination Alt+Return while the program is running. This toggles between the two operating modes of Windows. What did I learn? The function call SetMouse(.T.) is sufficient in Xbase++ to change my existing procedural Get input masks to an event driven Windows program that is mouse-aware. Boy, that's easy! Note for Clipper programmers: SetMouse(.T.) not only makes the @..SAY..GET command mouse-aware but also MENU TO and functions like AChoice(), DbEdit() or MemoEdit(). The preprocessor translates commands Compile the file MOUSE.PRG again but use the compiler switch /p this time. You enter on the DOS prompt: [C:\XPPFIRST]xpp mouse /p Then load the file MOUSE.PPO into your editor and have a look at the result of the preprocessor. All @..SAY..GET commands are translated to function calls, and this is actually the code that is processed by the compiler. The Clipper compiler works in the very same way. However, the resulting PPO file is different. If you are a Clipper programmer you should now open a new terminal window and copy the file MOUSE.PPO to XMOUSE.PPO. Set the environment variables LIB, INCLUDE and PATH to point to Clipper's directories by running C:\DINO.BAT, and re-compile MOUSE.PRG with Clipper: [C:\XPPFIRST]clipper mouse /p Compare the files XMOUSE.PPO and MOUSE.PPO and find out the differences. Then you can close the terminal window with the Clipper environment and re-compile MOUSE.PRG with Xbase++. What did I learn? Xbase++ really knows the Clipper language and has a preprocessor just like Clipper (Super, I can re-use my own CH files!). But I need to be careful: PPO files differ between Xbase++ and Clipper. I must always make sure that the path set in the INCLUDE environment variable points to the right directory. The first GUI program If you have never created a Windows GUI program before, this is your day, because that is what you are going to do next. You take the @..SAY..GET example from MOUSE.PRG and create a GUI program instead of a text-mode application. In Xbase++, the difference between text-mode and GUI application is simply a linker option: [C:\XPPFIRST]alink mouse /PM:PM Link the file MOUSE.OBJ with the linker Option /PM:PM and watch the program. You may be disappointed: it has the same look as before. The only difference is that the program uses a new window instead of the terminal window. Well, this window is special in Xbase++ and we are sure you will love the concept behind it pretty soon: in this window, you can combine graphic output with text oriented output as you like. To understand what this means, you only need to add two lines of code to MOUSE.PRG: #include "Gra.ch" // <--- insert this line PROCEDURE Main LOCAL cVar1 := "Hello" LOCAL cVar2 := "World" SET COLOR TO N/W,W+/B SET CURSOR ON SetMouse( .T. ) CLS // insert the next line GraBox( NIL, {72,176}, {200,256}, GRA_FILL, 30, 30 ) @ 10,10 SAY "Hello " GET cVar1 @ 12,10 SAY "Who ? " GET cVar2 READ ? cVar1, cVar2 RETURN Compile the program again and link it with /PM:PM. There is a slight chance that the linker issues an error message: ALINK: fatal error ALK4001: cannot open file "mouse.exe" If that is the case, you forgot to terminate MOUSE.EXE in the previous exercise. The program is still active and that's why the linker is unable to create the EXE file again. The function call GraBox() draws a black rectangle with rounded corners around the Get fields. The function uses graphic X/Y coordinates (pixels) instead of row/column coordinates (character) as in the @..SAY..GET command. Graphic coordinates specify a point in the coordinate system and are always defined using an array with two elements: the values for X and Y. The origin of the graphic coordinate system is the lower left corner of a window, while it is the upper left corner in the text-oriented coordinate system. Link the program once more without the option /PM:PM and run it again. Read the error message in the Alert box and press the Return key. Runtime errors like this occur when you try to perform graphic output in a text-mode application. What did I learn? Ok, there are graphic functions in Xbase++ that I can use to draw. Gee, wait a minute! I can draw graphic stuff in text-oriented windows? Then I can give my old DOS program a complete new look just by adding a few lines of code (Well, I better get used to graphic coordinates). I must link a program that uses graphic output with the linker option /PM:PM, otherwise I'll get a runtime error. The smooth migration from DOS to GUI You don't need your editor in this exercise. So click it away and open the folder with the example programs of Xbase++ via the Start menu (Start-> Programs-> Alaska Xbase++ 1.1 Intl.-> Xbase++ Samples). From there open the folder Migrate and then the folder Dbget. First start the program DBGET1.EXE by double clicking the corresponding symbol with the left mouse button. This program is a typical example of a text-mode Get mask that is used for editing database fields. The function SetKey() is used to implement database navigation, or to move the record pointer, respectively. Try pressing the different function keys F1 to F5 to see how data changes and terminate the program with F6. Let's have a look at DBGET2.EXE now. This program is derived from DBGET1.EXE and shows an intermediate step on the way from DOS to GUI: the Get mask is still the same but the function keys are replaced by graphic controls. The Get mask is mouse-aware and the record pointer can be changed by clicking graphic pushbuttons. Just click between Gets and pushbuttons to see how seamlessly graphic controls are integrated into a former text-mode application. You can use 10% GUI controls in your programs or 100%. That is up to you. Xbase++ gives you all the flexibility you need, and you can make the transition to GUI step-by-step at your own pace. This is a unique feature that cannot be found in any other software available on this planet. It is something we are a bit proud of. By the way, we call the graphic controls Xbase Parts because they provide for the "real stuff" in application development. Xbase Parts are designed to perform highly complex tasks automatically which you, the programmer, don't need to care about. You can concentrate on your major task: implementing business logic. Terminate the program DBGET2.EXE now and have a look at the program code in DBGET1.PRG and DBGET2.PRG. You can load both files into your editor or view them with Windows' notepad by double clicking the PRG file symbols. If you are a Clipper programmer, you will immediately recognize DBGET1.PRG as plain Clipper code. As a matter of fact, this file can be compiled with Clipper or Xbase++. You will notice no difference except when you open Windows' task manager and watch the CPU usage. Try it! When you compare DBGET1.PRG and DBGET2.PRG, note how easy program control is changed from SetKey() to pushbuttons: ** DBGET1.PRG ** SETKEY ( K_F2, {|| DBSKIP(1), GetRefresh(GetList) } ) ** DBGET2.PRG ** PushButton ( { 120, B_TOP }, { 50, B_HEIGHT }, "Next", ; {|| DbSkip(1), GetRefresh(GetList) } ) FUNCTION PushButton ( aPos, aSize, xCaption, bBlock ) <...> button:Activate := bBlock // <-- Pushbutton receives code block <...> Instead of attaching a code block to a function key using SetKey(), the same code block is assigned to an instance variable of an Xbase Part (here: pushbutton). The Xbase Part executes the code block automatically when the user clicks the pushbutton. You can now close the folder DbGet. What did I learn? I know how to execute Xbase++ example programs and where to find the corresponding source code. I have seen that I don't need to re-write Clipper legacy code entirely when making the transition to GUI. Instead, I can do this one step at a time. Hold on, buddy! If I can go step by step, why don't I start the migration process with those parts of my Clipper application that are accessed most frequently by the users? Less frequently used parts can still remain in text-mode. This way I can present a Windows program with the right Look & Feel much faster to my customers. What a great idea! Xbase++ knows three application types Select the folder Migrate again and open the folder Login. There you find a complete transition of a Clipper program to a GUI application in three steps. The program is a simple login routine and each migration step is represented by one EXE file. Run the three programs in the following order: LOGIN_T.EXE This program is typical for many Clipper applications: a company logo is displayed as ASCII graphic and the user is prompted to enter user-ID and password with @..SAY..GET (by the way, T means text-mode, and the password is "Alaska"). LOGIN_H.EXE The letter H is synonymous for hybrid-mode. This is how we name the operating mode for applications which combine text-oriented output with graphic output. The major program logic is unchanged because user-ID and password are still being retrieved using the @..SAY..GET command. However, the Gets are mouse-aware and the appearance of the program has changed dramatically. Look and see for yourself! LOGIN_G.EXE This is a true GUI program without any text-oriented elements. Entering user-ID and password is moved to a modal dialog window. "Modal" means that the user must close the window before he or she can proceed in the program. This migration example demonstrates that in Xbase++ a particular window is used depending on the operating mode of an application. In text-mode, Windows terminal window is used (it doesn't know graphic output), the XbpCrt window supports hybrid-mode (a combination of text and graphic) and the XbpDialog window is the right choice in true GUI applications (text-oriented output, like @..SAY or QOut(), is no longer possible). After you have seen how the appearance of a former Clipper program changes during the course of the migration process, you probably want to study the source code and see what has changed in there. You find the code in the files LOGIN_T.PRG, LOGIN_H.PRG and LOGIN_G.PRG, and you should read the files in exactly this order. Don't be confused when you see the code of the procedure PassWord() in the LOGIN_G.PRG file. Ninety percent of this code has been written by the Xbase++ FormDesigner (we'll see the FormDesigner later). Don't use too much time in studying the code and don't expect to understand everything at first sight. You will have more opportunities for this later. For now, close the folder Login. What did I learn? I know that Xbase++ supports three different application types (text-mode, hybrid-mode, graphic-mode) and that I have to select the appropriate window (terminal window, XbpCrt window and XbpDialog window). I think, I'm going to study this in the online-documentation later. I better write this down so that I won't forget it. Note: If you want to get more knowledge about application types and windows, you'll find the right information in the table of contents of the online-documentation: Xbase++ Basics-> User Interface and Dialog Concepts. More migration ideas If you are a Clipper programmer and plan to port existing Clipper programs to Xbase++, you should take a quick look at two example programs in the Migrate folder before you continue with Getting Started (you can skip this step if you like). Open the folder Prompt and start the program MENUTO.EXE. It demonstrates how the Clipper commands MENU TO and @..PROMPT are transformed to a GUI representation by means of the preprocessor. When you have seen it, read the corresponding files MENUTO.PRG and MENUTO.CH. Then close the folder. After that, open the folder CrtBox and start CRTBOX.EXE. This program shows that even single function calls (here: MemoEdit() and Achoice()) can be isolated in a separate and modal XbpCrt window which results in a completely different appearance. Close the folder when you are done. What did I learn? The preprocessor is really a great tool. I just include a CH file into MENUTO.PRG and that's all I need to achieve full GUI quality. I will think more about this approach. I have seen Achoice() and MemoEdit() running in a modal XbpCrt window and must admit: this looks pretty much GUI-like. Which parts of my application are well isolated and could run in a separate XbpCrt window? (hold on, I'm gonna write down this question...) GUI straight and simple We are going to leave now the topics "Migration" and "Clipper compatibility" and proceed with "What does Xbase++ offer beyond Clipper?". You have already seen some things on this subject (application types, window types, graphic functions, Xbase Parts) but now we're diving deep into Xbase++. You will need a database file (DBF file) for the following exercises in the XPPFIRST directory. You can copy any DBF file of your choice into that directory. If you don't have a DBF file at hand, you find the files CUSTOMER.DBF and CUSTOMER.DBT in the ...\SOURCE\SAMPLES\DATA directory of your Xbase++ installation. In the exercise, this customer database is used and you can copy both files to XPPFIRST. Start your editor again and create a new file APPTEST.PRG that contains the following lines of code: #include "AppEdit.ch" PROCEDURE AppSys RETURN // no default application window PROCEDURE Main USE Customer // open database APPEDIT // create Edit window APPDISPLAY // display Edit window RETURN Compile the file APPTEST.PRG and link it for graphic-mode: [C:\XPPFIRST]xpp apptest [C:\XPPFIRST]alink apptest /PM:PM Start the program APPTEST.EXE and see the power of Xbase++'s Application Parts. You probably don't know it yet, but that is what you have just programmed and what you see now on the screen: an Application Part that creates an Edit window for databases. With only 12 lines of code you have programmed a complete GUI application with database access, sizeable window and scollbars, editing of database fields, keyboard and mouse control. You can even run the application in a multi-user network because automatic record locking is included. Application Parts contain Xbase Parts and are especially designed for achieving fast results with very little programming efforts while keeping a maximum amount of flexibility. Give it a try and change the APPEDIT command in the file APPTEST.PRG as follows: APPEDIT ; POSITION CENTER ; STYLE FANCY Note the semicolons (line continuation character) in the first two lines. The APPEDIT command is extremely powerful, and for readability reasons it is recommended to start a new line with each new option of this command. Rebuild the program and run it again. What do you think? Just two more lines of code and the whole thing looks completely different. But there is more going on behind the scenes! Terminate the program and change APPTEST.PRG again: #include "AppEdit.ch" #include "AppBrow.ch" // <-- insert this line PROCEDURE AppSys RETURN PROCEDURE Main USE Customer APPEDIT ; POSITION LEFT, CENTER ; // <-- LEFT, is new STYLE FANCY APPDISPLAY MODELESS // <-- MODELESS is new APPBROWSE ; // <-- insert these POSITION RIGHT, CENTER // two lines APPDISPLAY // <-- insert this line RETURN Save the file, proceed with the compile and link cycle as usual but watch the compiler messages closely. When the compiler reports a syntax error, it is most likely that a comma is missing between LEFT, CENTER or RIGHT, CENTER. Start the program when it is successfully created. You see two Application Parts now: the Edit window and a Browse window. Move the cursor in the Browse window and watch the Edit window: it is automatically synchronized with the Browse window. Of course, this works the other way round, too. If you change the record pointer in the Edit window or if you edit data, the Browse window is updated accordingly. Close both windows, take a breath and re-think what you just have done: with 22 lines of code you have programmed an Edit window and a Browse window. Both access a database and are synchronized with each other. Most important: the program is a true 32-bit GUI application. Wow! Accept our compliments! No C-programmer could accomplish this in such a short period of time. If you are wondering how one Application Part informs the other about a necessary screen update or how both windows exchange messages, we must disappoint you: both Application Parts are independent from each other and there is absolutely no exchange between the two windows, whatsoever. The automatic sychronization behavior of both windows is a result of Xbase++'s database technology. Yes, right, the reason is database technology! The database CUSTOMER.DBF is managed by the Xbase++ DatabaseEngine. When one Application Part attempts to move the record pointer, it is actually the DatabaseEngine that performs this task and, at the same time, tells the other Application Part to update itself. It is just that simple when software is based on sound technological concepts that seamlessly supplement each other. And you can believe us, Xbase++ is full of High Technology which you don't see at a first glance. Maybe the Application Part example has given you an idea... What did I learn? I have seen the concept of Application Parts. That's simply great! I have never imagined before that such little code can produce these big results under Windows. When I need to outline a prototype quickly, I'm going to do this with Application Parts. Developing new GUI applications In this exercise you are going to develop a GUI application that needs much more code than the Application Part example. However, you don't need your editor for this, you need space on your monitor instead. Therefore, close your editor and enter on the DOS prompt: START XPPFD. This way, you start the Xbase ++ FormDesigner and it sees already your working directory XPPFIRST (you could invoke the FormDesigner via Windows' Start menu as well, but then you would need to select the proper directory later). Follow the instructions below: 1. First, you should get used to the different icons visible in the FormDesigner's main window. For this, you open the online-help by selecting the menu items Help-> Help index and enter "File management" in the online-help. Press the Return key and read the description for the first three icons on the left side. 2. Press Ctrl+PgDn and then again Ctrl+PgDn to read the description for the other icons. 3. Click one icon contained in the tabpage and move the mouse pointer over the window titled New form. Position the insertion frame in this window (this works with the mouse or the cursor keys) and click the desired position with the left button. The first Xbase Part is created! 4. Get used to the marking frame by playing around a bit. Change the positon and/or size of the Xbase Part with the mouse. 5. Press the Ctrl key and hold it down while clicking the Xbase Part. This creates a copy of the marked Xbase Part. Position the copy, select both Xbase Parts and click an icon in the window Alignment Palette. It offers eight different possibilities to define position and/or size for multiple Xbase Parts. Try all eight possibilities, if you like. 6. Mark all Xbase Parts and press the Del key to delete them all. 7. Select the tabpage Statics in the main window of the FormDesigner and click the icon showing an uppercase letter "A". Position this Xbase Part, it displays "Text". 8. Mark the Xbase Part and open the Property Monitor by selecting the menu items Options-> Property Monitor. The monitor displays in its upper part the class names of Xbase Parts defined in the window New form, and the lower part is a two-column browser. The left column Property displays names of instance variables of the Xbase Part and the right column Value shows the corresponding values. 9. Select the item XbpStatic in the upper part of the property monitor. Then click into the third last row of the browser (Property = caption) and double click the right column. Type "Hello World" in the entry field and proceed with changing the values in the third, fourth and fifth row (ColorFG = forground color, ColorBG = background color, Font = typeface). Each time you leave a row, the changed value is assigned to the Xbase Part and becomes visible. 10. Save the form by clicking the diskette symbol in the main window and use TEST.XFF as the file name. 11. Select the menu items Form-> New to destroy the current form. Then click the icon in the upper left corner. It displays an open folder symbol. Select the file TEST.XFF in the file dialog to restore the saved form. 12. Delete the Xbase Part (click it and press Del ) and open the field assistent via the menu items Assistents-> Fields. Select two fields in the right listbox and click Ok. Then move the mouse pointer to the position in the form where both fields should be inserted and press the left button. 13. Add two pushbuttons for database navigation. You create them by selecting the menu items Xbase Parts-> Pushbutton-> Next and XbaseParts-> Pushbutton-> Previous. When you have positioned both pushbuttons, you save the form. 14. Select the menu items Form-> FUNCTION Code-> Create code and enter TEST.PRG as the file name. This instructs the FormDesigner to create the source code for the form. 15. Close the FormDesigner, compile the file TEST.PRG and link it for graphic-mode with /PM:PM. Start the program TEST.EXE. It displays the form that you have just designed. 16. The program displays your form and an additional window. This is the default application window created in Xbase++'s AppSys() procedure. 17. Load the file TEST.PRG into your editor and insert two lines of code in front of PROCEDURE Main : PROCEDURE AppSys() RETURN These lines suppress the creation of a default application window and the program TEST.EXE displays only one window: your form. When you have followed these 17 steps actively, you have passed a crash-course about the Xbase++ FormDesigner. The FormDesiger works like "Click me, I'll write your code". The created code looks complicated at first sight but it is not difficult to understand. It is the amount of created code that leads to the impression of complexity. The code follows a strict pattern and the amount is due to the fact that GUI programs need more code than text-mode programs. Just think of the two coordinate systems: 80x25 columns/rows versus 1280x1024 pixel in X and Y direction. The exact positioning in a pixel-oriented coordinate system simply blows up program code. However, this is the kind of work the FormDesigner does for you. What did I learn? I know how to utilize the FormDesigner and I'm able to create function-oriented program code. I have noticed during the crash-course that the FormDesigner can create CLASS code, or object-oriented code, respecively. I haven't seen this yet but I will try it later and study it in the online-help. Cool! Note: You can find detailed information about the FormDesigner in the Table of Contents of the online-documentation: Programming Tools-> The Xbase++ FormDesigner. More Xbase++ technology If you have seen our ads in computer magazines or if you have received flyers from Alaska Software, you know that Xbase++ beats competitive products with its unique multi-threading ability. This does not mean that other products do not support multi-threading. It simply means that there is no other product in this world that offers you an easier way to access the real power of 32-bit operating systems than Xbase++. With multi-threading you can run different parts of your program parallel at the same time. If you have never used multiple threads before, you will probably need some time to discover the fantastic possibilities of this technology. However, Xbase++ makes it extremely easy for you. Give it a try and start your editor again. Load the file MOUSE.PRG that you created at the beginning of the Getting Started course and insert one line in front of the first @..SAY..GET command: SetTimerEvent( 100, {|| DispOutAt( 0, 0, Time() ) } ) @ 10,10 SAY "Hello " GET cVar1 // These lines @ 12,10 SAY "Who ? " GET cVar2 // exist already READ // in MOUSE.PRG Create MOUSE.EXE again and start the program. It displays the time continuously in the upper left corner of the window and you can edit the two Get fields at the same time. The program runs in two different threads. One executes the READ command and the other calls the Time() function once a second and displays the return value. It is also possible to display the time continuously in a DOS Clipper program, but this requires quite some effort. In Xbase++ it is a one-liner. If you are interested in the multi-threading technology, you should take a look at two of our favorite example programs which are hard to implement without this technology. One program is a real-world simulation of a programmer team accessing a lonely coffee machine (the program demonstrates special aspects of program control in multi-threading) and the other program implements intelligent tooltips that you can re-use some day in your own GUI applications. You may further investigate multi-threading or you can proceed with the Getting Started course by continuing with the next chapter. In the Samples folder open the folder Basics and there you open Thread. Start the program COFFEE.EXE and let it run for one or two minutes (start it now and let it run while you proceed with reading). The program consists of 10 threads. One thread represents the coffee machine and nine other threads simulate the programmer team. Although the program runs in text-mode, it comes close to a real-world situation: A programmer needs coffee for working. If he has no coffee, he goes to get some. When he finds the coffee machine empty, he fills it. If a programmer fills his cup, other programmers must wait to get a refill and if the coffee machine is running, all programmers must wait until the coffee is ready. Press a key to end the program and close the two folders Thread and Basics. Then open the folders Solution and Tooltip. Start the program TOOLTIP.EXE and move the mouse pointer slowly across the entry fields or pushbuttons. When the mouse rests for a while at the same position, text is displayed. The program uses two threads. One displays the window and the other monitors the position of the mouse pointer. If the pointer does not change its position for a particular time interval, the second thread displays a help text. The text disappears after a left click. That is enough multi-threading for now. Terminate the program TOOLTIP.EXE and close the two folders Tooltip and Solution. What did I learn? I have seen that a program can run in different threads. That is very interesting and seems to be quite easy. The COFFEE program is nice but the TOOLTIP program is useful. I will probably add these tooltips to my GUI applications. Wow, there are lots of example programs in the Basics folder. It will take some time until I've seen them all. A complete GUI database application Let us focus now on the main subject Xbase++ is designed for: database applications. However, a discussion of an entire development process for a database application goes far beyond the scope of a Getting Started course. Therefore, we will have a look at an example program that comes along with Xbase++. In the Samples folder you open Apps and then the folder MdiDemo. Start the program MDIDEMO.EXE. It is a Multiple Document Interface program that manages a Customer and a Parts database. Select the menu items Document-> Customer to open a child window which displays customer data and make yourself familiar with it: press Page Up, Page Down, Tab, Return, Cursor keys and change data. Click the entry field ZIP with the right mouse button. This opens a context menu that is automatically supplied by Windows. Then click beside the entry field ZIP. This context menu is programmed in Xbase++ and has the same menu items as the Edit menu in the menu bar of the parent window. Open two more Customer windows and press Page Down in each child window to see that each window can edit a different record of the database. Unlike the Application Part example these windows are not synchronized. The reason for this is that the Customer database is opened three times by now. Therefore, each child window maintains a record pointer of its own. Clipper programmers normally avoid to open the same database file multiple times. This is due to the 255 file handle limit imposed by DOS. Xbase++ does not know this limit and you can take all advantages of opening the same file more than once. Close all Customer windows by selecting Window-> Close all in the main menu and open a Parts window (Document-> Parts ). The Parts database contains textual data, like part number or description, for example, and binary data for images. The image displayed is a bitmap and you can watch the different images quickly by skipping through the database with Page Down. The bitmaps are stored in a memo field of the Parts database. Bitmap data can be imported into the database when the pushbutton Bitmap is clicked. Now let us explain the major difference between the Customer and Parts databases: both are managed by two different DatabaseEngines which use memo files in DBT and FPT format. In the DBT format (Customer) only text can be stored in a memo field, while the FPT format (Parts) accepts binary data as well. Terminate the program by selecting Document-> Exit and refrain from reading any source code file. The different aspects of MDIDEMO.EXE are discussed in detail in the Basics chapter of the online-documentation. You can take enough time later to study both source code and documentation. For now, you should proceed with Getting Started. However, there is one particular PRG file in the MdiDemo folder that is good to see right now: DBESYS.PRG. It contains the code that assembles the two DatabaseEngines DBFNTX and FOXCDX. The code is easy to understand and gives you an immediate impression about the Xbase++ DatabaseEngines. Have a look at DBESYS.PRG now. The procedure DbeSys() is executed automatically when a program starts and its purpose is to load DatabaseEngines. This is done with the function DbeLoad(). There are different types of DatabaseEngines: those which handle DBF files together with memo files and others manage index files. These types are combined with DbeBuild() to a new DatabaseEngine which is then capable of handling DBF, memo and index files. The DatabaseEngine DBFNTX is Clipper compatible (DBT memo and NTX index), while the DatabaseEngine FOXCDX is compatible with FoxPro (FPT memo and CDX index). The different components could also be combined to a DBFCDX or FOXNTX DatabaseEngine. Close the file DBESYS.PRG and the MdiDemo folder. What did I learn? I have seen a Multiple Document Interface application where multiple child windows access the same database but can edit different records. This is possible when the database file is opened multiple times. Then I've learned something about memo file formats: DBT can store text only while FPT can store text and binary data. If I want to store bitmap images in a database, I have to use the FPT format which is managed by the FOXDBE. I think I've understood the DatabaseEngine concept. First I load a DatabaseEngine for DBF files and then one for index files. I combine both with DbeBuild() and I'm done. That's what the procedure DbeSys() is good for. One more DatabaseEngine You have seen the modular concept of our DatabaseEngines (DBE). It differs completely from Clipper's RDDs (Replaceable Database Drivers), which must be linked to the EXE file. In contrast, the Xbase++ DatabaseEgines are loaded dynamically at runtime and can be released as well. But the major advantage is: DBEs consist of components which can be combined. You gain an enormous flexibility by combining DBEs and this is something we would like to demonstrate to you with an example program. For this you open the folder Basics and then Dbe. First you should read the program code in the file SDF.PRG because what SDF.EXE displays on the screen is not very exciting. The program simply displays a database with a few records in both physical and logical order. The really interesting part of the program is the database format: it is an ASCII file in SDF format (System Data Format) that is handled by a DatabaseEngine. This means that the ASCII file can be opened with the USE command, just like any DBF file, and commands like GO TOP, SKIP or GO BOTTOM can be used to navigate the record pointer. You understood this right, the ASCII file has a record pointer. It can even be indexed! To accomplish this, the DatabaseEngine for the SDF file format is simply combined with the DatabaseEngine for the NTX file format, and an index file is created. Afterwards it is possible to search data in the ASCII file using the SEEK command. The Xbase++ DatabaseEngines separate a database completely from the programming language. Whether you open a DBF file or an ASCII file with the USE command is nothing you need to care about. The only thing to make sure of, is to have loaded the appropriate DatabaseEngine. You can close now the folders Dbe and Basics. What did I learn? Ok, I got the grip about DatabaseEngines: they consist of components that handle different file formats and can be combined. Heck, why didn't anybody else discover this DatabaseEngine concept? It is so logical! With Xbase++ I can combine the NTX DatabaseEngine with the SDF DatabaseEngine and get SDFNTX. I also can glue together the CDX DatabaseEngine with the DBF DatabaseEngine and the result is DBFCDX. They're really good, these Alaska guys... External resources for GUI programs When you develop a GUI application, the source code consists not only of PRG and CH files but also of so-called External Resources which contain graphic data. Bitmaps and icons, for example, are external resources which are displayed at runtime by your program (EXE file). To guarantee the availability of external resources, they are linked to the executable file. This is accomplished by the Alaska linker. It links binary resource files to an EXE file. The creation of binary resource files, however, is the task of the Alaska Resource Compiler (ARC.EXE), and this is what we are going to see now; what it can do and what it is good for. But before we start, you should first get an overview of the many resource files that come along with Xbase++ and can be used in your applications. Therefore you open the folders Apps and ImgView and start the program IMGVIEW.EXE. This is an Xbase++ program for displaying bitmap files (if you have not yet closed the Basics folder, don't confuse the folder Basics->App with the folder Apps ) You see a tree view in the left part of the window. Double click the item XppW32 and then Resource. After that, the listbox displays names of bitmap files (external resources) which you can use in your programs. Feel free to see what is available or to play a bit with the program. Select the file TILE12.BMP in the listbox and click the radio button Normal. We will use this file as background for the dialog window you have created with the FormDesigner. Terminate IMGVIEW.EXE and load the file TEST.PRG into your editor. Insert one line in the code: oDlg:visible := .F. oDlg:drawingArea:bitmap := 100 // <-- insert this line oDlg:create() The new line must appear before the line oDlg:create(). Save the file TEST.PRG, create a new file TEST.ARC in your editor and type this line: BITMAP 100 = "tile12.bmp" Note that BITMAP must be written in uppercase letters. Save the file TEST.ARC and change to the terminal window. The external resources for your test program are now defined in TEST.ARC. The resource compiler creates from it a binary resource file. To create the test program, enter the following commands on the DOS prompt: [C:\XPPFIRST]xpp test.prg [C:\XPPFIRST]arc test.arc [C:\XPPFIRST]alink test.obj test.res /PM:PM Watch the screen messages of the different tools. If no error message appears you can start TEST.EXE. The bitmap is repeatedly drawn until the entire background of the window is filled. However, there is one detail that disturbs the whole beauty: the text on the left side of the entry fields is surrounded by gray rectangles. This is the background color for static text. You can switch this color to "transparent" by changing one line in your code: Old: drawingArea:setColorBG( GRA_CLR_PALEGRAY ) New: drawingArea:setColorBG( XBPSYSCLR_TRANSPARENT ) Rebuild the program by compiling the PRG file and calling the linker (you don't need to rebuild the RES file since the ARC file is unchanged). Start the program again. The text must be visible now without a background color. What did I learn? I have used the Alaska Resource Compiler ARC.EXE and know how to declare external resources in an ARC file. I know that the resource compiler produces a RES file that is linked together with OBJ files by the linker. Note: the reason why ARC.EXE has found the file TILE12.BMP is the environment variable XPPRESOURCE. It points to the directory where ARC.EXE searches for external resources. Project maintenance with Xbase++ Meanwhile, you might have noticed that it becomes a tedious job to invoke the different tools for the creation of a GUI application from the DOS prompt: first the Xbase++ compiler, then the resource compiler and finally the linker. In addition, file names must be specified each time. How is this going to work with a large software project? Well, the maintenance of software projects is the task of the Xbase++ ProjectBuilder and you learn how to use it now. It requires a file PROJECT.XPJ which contains the description of a project. The term project describes an executable file that is created from source code files. You are going to create the file PROJECT.XPJ for the program TEST.EXE. The source code for this program is contained in the files TEST.PRG und TEST.ARC. You begin with a new file TEST.LST that lists the names of all source files for TEST.EXE. You need to type only two file names: TEST.PRG TEST.ARC The file TEST.LST consists of only two lines, each of which contains a file name. Save TEST.LST and enter on the DOS prompt: [C:\XPPFIRST]pbuild @test.lst Note the character "@". By entering this you start PBUILD.EXE (the ProjectBuilder), it reads the file TEST.LST and creates from it the file PROJECT.XPJ which looks like this (the comments written by PBUILD.EXE at the beginning of the file are omitted): [PROJECT] COMPILE = xpp COMPILE_FLAGS = /q DEBUG = yes GUI = no LINKER = alink LINK_FLAGS = RC_COMPILE = arc RC_FLAGS = /v PROJECT.XPJ [PROJECT.XPJ] test.EXE [test.EXE] test.prg test.arc Change the line GUI = no to GUI = yes. The program TEST.EXE must be created for graphic-mode and this is how the ProjectBuilder gets this information. Save the file and enter on the DOS prompt: [C:\XPPFIRST]pbuild -g The switch -g instructs the ProjectBuilder to analyze the dependencies between all files that make up your software project, and to generate a new list of files in the project definition file. Reload PROJECT.XPJ into your editor. You will be amazed what the ProjectBuilder is able to find. Make sure that the program TEST.EXE is no longer active (maybe it still is running). Delete the files TEST.EXE, TEST.OBJ and TEST.RES, and enter PBUILD on the DOS prompt. This rebuilds the deleted files and you can restart TEST.EXE when the ProjectBuilder has finished. What did I learn? I know how to use the ProjectBuilder which manages my software projects. The ProjectBuilder cannot detect the application type that I want. I must define the desired application type with GUI=no or GUI=yes in the PROJECT.XPJ file. The ProjectBuilder seems to be pretty smart: it finds all CH files that are part of a project and lists them in the project definition file. What is compatible: Clipper or Xbase++? The end of this Getting Started course focuses again on the subject "Compatibility between Xbase++ and Clipper". For this, we will port a Clipper application to Xbase++ that is known by all Clipper developers: DBU.EXE. This is of interest for about 90% of the persons who currently plan to use Xbase++. If you are not a Clipper developer, you can skip this chapter. There is no product but Xbase++ that is more compatible with Clipper, except Clipper itself. However, we have determined from experience that the word compatibility is not well defined. If we ask three different programmers, we get three different definitions for compatibility. Our understanding of Clipper compatibility is that the Xbase++ compiler understands the Clipper language by 100%. We have choosen this wonderful programming language for our compiler because it is the most powerful language in the xBase language arena. Some Clipper programmers, however, fill the word compatibility with the meaning identity. They expect that Xbase++ is identical to Clipper. If we take this definition, Xbase++ is not Clipper compatible because we have not rebuilt the Clipper compiler, we have built a compiler that understands the Clipper language. If Xbase++ was identical to Clipper, the following lines of code would not work in Xbase++: PRIVATE aArray[1000000] MemoEdit( Replicate("A", 1000000) ) MyFunc( @FIELD->NAME ) MyFunc( @aArray[22] ) MyFunc( @oGet:row ) CLASS MyBrowse FROM TBrowse x := &("aArray[n]") ? oGet:&(x) In our opinion, these lines of code are 100% compatible with the Clipper language. However, either the Clipper compiler cannot translate them or the Clipper program will bomb when the code is executed (these lines create compile time errors or runtime errors with Clipper). Xbase++ processes these lines without any problem. This raises the question: Which compiler is more compatible with the programming language, Clipper or Xbase++? (judge for yourself). Xbase++ is designed to give you access to 32-bit operating system concepts in the programming language you are familiar with. This means that Xbase++ uses the same language as Clipper but different concepts. Just think of memory management, for example. An array with 1 million or more elements or a 5MB string is impossible in Clipper. It is possible in Xbase++ because a 32-bit operating system supports this. We agree with thousands of Clipper programmers that the Clipper language needs an object-oriented model, and we have implemented one in Xbase++. There is also a general consensus that a programmer should be able to store complex data types (array, code block and object) in a file. We have provided this feature in Xbase++. We also think that "minor details" are important, like passing a field variable per reference to a user defined function, for example, or sending a message to an object via the macro operator. Things like this must be possible in a dynamic programming language. The Clipper compiler fails in this respect but the Clipper language has room for these features. That's why you can do these things with the Xbase++ compiler : it really understands the Clipper language. This discussion should make you aware of the fact that Xbase++ is not identical to Clipper. Instead, Xbase++ adds more power to the already powerful Clipper language. Xbase++ understands your code but uses 32-bit concepts rather than 16-bit concepts. This requires you to change your Clipper code here and there when you want your applications to run under DOS/Clipper as well as under Windows/Xbase++. We cannot estimate the amount of required changes but we want to give you an idea of what you may encounter when porting your Clipper applications to Xbase++. One application whose source code is known by all Clipper developers is DBU.EXE, the database utility of Clipper. We are going to port this program to Xbase++ and outline all problems we have encountered. You will face similar problems with your Clipper code. One note before we begin: we use the DBU code from Clipper version 5.2e. Create a new directory \XPPDBU and copy the original Clipper PRG files from Clipper's \SOURCE\DBU directory into the new one. Create a project file for DBU.EXE by entering this command on the DOS prompt: [C:\XPPDBU]dir *.prg /b > dbu.lst This lists all PRG files for the DBU project in the file DBU.LST. Now let the ProjectBuilder create the PROJECT.XPJ for you. It is a two-step process: [C:\XPPDBU]pbuild @dbu.lst [C:\XPPDBU]pbuild -g Have a look at the file PROJECT.XPJ (you don't need to change it), and enter PBUILD on the DOS prompt. The ProjectBuilder then attempts to create DBU.EXE but will fail sooner or later and terminate with an error message. We don't know when the ProjectBuilder will fail on your computer because we don't know your version of DBU.EXE (the DBU source code has changed with each Clipper version from Summer 87 to 5.2e). Therefore, we list below only the changes we have made for version 5.2e. Some of them are valid for all DBU versions, or Clipper programs, respectively. DBU.PRG Rename PROCEDURE Dbu to PROCEDURE Main. The start routine of all Xbase++ programs must be named Main. DBUEDIT.PRG Correct an implementation error which is tolerated by Clipper but not by Xbase++: if ( "->" $ cEditField ) cAlias := Substr(cEditField, 1, At("->", cEditField) + 1) This Plus must be a Minus ----------------^^^ Note: Some of our customers have detected implementation errors in their Clipper code after they have compiled it with Xbase++. The programs have been running just fine for years. The error finally appeared because the Xbase++ compiler is more strict than the Clipper compiler. Change one Inkey() call to Inkey(0.1): Old: WHILE (( keystroke := INKEY()) == 0 ) New: WHILE (( keystroke := INKEY(0.1)) == 0 ) The DO WHILE loop is permanently executed in the Clipper code as long as there is no keyboard input. This leads to an undesireable situation in Xbase ++ as a result of the multi-threaded architecture of Xbase++ programs: each Xbase++ program runs in several threads which you neither notice nor need to care about. For example, the garbage collector runs in one thread, or the screen is updated in another thread. As was said before, you don't need to care about this. But if the thread that executes your program code always asks if No keyboard input has occurred, it is scheduled for CPU access on preference by the operating system, and other threads get less CPU access. This again leads to the situation that the screen is updated slower than possible and you get the impression that the Xbase++ program itself is slow. Therefore, you should carefully look for DO WHILE loops that check for Inkey()==0. In this case, you should give the operating system 1/10th of a second time to service other threads. DBUVIEW.PRG The declaration of LOCAL variables must be done in Xbase++ before the PARAMETERS statement appears in the code. Search for local saveColor and move all these declarations in front of the PARAMETERS statement. Change the code in FUNCTION bar_menu to reflect a slightly different behavior of Xbase++'s Achoice() function. Clipper's Achoice() does not display array elements which contain null strings while Xbase++ does: FUNCTION bar_menu -------------------- Old: local saveColor New: local saveColor, nElem -------------------------------- Old: IF M->num_d < LEN(M->array) num_d = M->num_d + 1 array[M->num_d] = " " ENDIF New: nElem := LEN(M->array) IF M->num_d < nElem num_d = M->num_d + 1 array[M->num_d] = " " ASize( m->array, M->num_d ) ENDIF ------------------------------ Old: IF array[M->num_d] == " " array[M->num_d] = "" ENDIF New: IF array[M->num_d] == " " ASize( M->array, nElem ) AFill( M->array, "", M->num_d ) ENDIF DBUUTIL.PRG In this file, LOCAL variables are declared again after the PARAMETERS statement. This is not allowed in Xbase++. LOCAL must appear before PARAMETERS. Change the code accordingly. Change the line where releations between databases are defined: Old: SET RELATION ADDITIVE TO &k INTO &t New: DbSetRelation( t, &( "{||"+ k +"}" ), k ) This change is necessary because Xbase++ creates code blocks according to the late binding principle. There is no early binding like Clipper does it occasionally. The only way to enforce early binding in Xbase++ is to compile a string expression with the macro operator to a code block. DBUCOPY.PRG LOCAL declarations appear after the PARAMETERS statement in this file. The Xbase++ compiler creates error messages for this. Move the offending LOCAL declarations in front of PARAMETERS. When this is done, you have applied all changes necessary and you can invoke the ProjectBuilder again to create DBU.EXE. Start the program, it looks like the original Clipper application but it is a true 32-bit program that uses very little CPU resources. Summary We had to apply the discussed changes in the source code of DBU.EXE in order to let the program run with both Clipper and Xbase++. You will encounter similar problems when you port your Clipper code to Xbase++. We know about these differences and our technical support is available for you when you face problems in the transition to Xbase++. We will assist you! The differences between Xbase++ and Clipper are justified. They are mainly a result of the differences between 16-bit and 32-bit operating systems. When we have had to decide whether Xbase++ should behave like Clipper '87 or 5.01 or 5.2a or 5.2e, we have choosen the most consistent behavior. When we introduced new 32-bit concepts into the Clipper language, we have abandoned 16-bit concepts that would have contradicted the new concepts. We believe in the future of the Clipper language and we are convinced that this language will still exist in the 64-bit world (at least, we have constructed our compiler in a way that it can create 64-bit code). We are prepared for the future and we invite you to join us on our way to the 64-bit world because we are talking the same language: Clipper. How to proceed... You have passed the Getting Started course and you have seen a variety of example programs, but you have not seen all of them. You know that the examples are divided up into four categories, or folders, respectively. They are listed below again for your convenience: Apps This category contains stand alone applications made up from multiple PRG source code files. Each application targets program design, like Single or Multiple Document Interfaces, for example. Basics Each example program in the Basics category focuses on one particular feature of Xbase++. The samples are not intended for reuse, but rather show programming techniques which solve a particular problem. "How to display text using an italic font?", "How to create a modal window?" or "How to use a thread?" are questions answered by samples in this category. Migrate Migrating Clipper code to GUI is one of the strengths of Xbase++. Therefore, samples are included in this category which show various possibilities and intermediate steps in the transition of a text mode application to a full featured GUI application. Solution This category collects example programs which provide solutions to common programming problems. All of them are stand-alone programs. However, they include program code which implement a test scenario for the actual example. The example is ready for reuse in your programs when you discard the code for the test scenario. We recommend that you work through all example programs. Once you have seen them, you will have a good impression of the features of Xbase++. After this, where to go and how to proceed is up to you. You are well-advised to read all Basics chapters in the online-documentation, but making further recommendations depends on your programming background and the language you have used so far. Xbase++ has an online-documentation which is a huge source of information for answering almost any question. It is designed to be understood by a novice as well as an advanced programmer. Depending on your programming experience, you will find below some directions where to look in the online help for more and appropriate information. Maybe you can identify yourself with one of the following programmer types: I have never used an xBase language When you don't know anything about the xBase language, you should get familiar with its concepts. See the following chapters in the online-documentation: * Language Elements of Xbase++ * Elements of an Xbase++ Program * Data Types and Literals * Operators * Declarations and Statements * Operations and Operators for Simple Data Types * Procedures, Functions and Special Operators * Operations and Operators for Complex Data Types I know the xBase language but have never used Clipper If you are familiar with other xBase dialects such as FoxPro or dBase, for example, you should get a grasp about things possible in Xbase++. This includes the declaration of lexically scoped variables as well as data types such as Code block, Array and Object. You might be interested in the preprocessor too, since it can be used to translate your existing code to valid Xbase++ syntax. Have a look at these chapters in the online-documetation: * Declarations and Statements * Operations and Operators for Simple Data Types * Operations and Operators for Complex Data Types * The Xbase++ Preprocessor * Error Handling Concepts Make yourself familiar with the functions and commands available in Xbase++. You will find them listed in alphabetical order when you open the Table of Contents tab in the online-documentation. I am a Clipper programmer If you are a Clipper programmer, you first should read the chapter "Information for Clipper programmers" in the online-documentation. It gives you head-start information about migration issues. I know Clipper but I don't know GUI If you are a Clipper programmer who wants to migrate existing code to Windows, you should be familiar with the sample programs in the Basics and Migrate directory. Also, read the chapter "User Interface and Dialog Concepts" in the online-documentation. You should obtain a working knowledge of the following functions as well (you will find them in the index of the online help) * AppEvent() * PostAppEvent() * SetAppWindow() * XbpCrt() * XbpDialog() I have programmed Windows GUI applications already You are familiar with the event-driven programming approach and you are not afraid of object-oriented programming. If this is the case, you should become familiar with the concept of Xbase Parts. They let you use GUI controls easily. Also, Xbase++'s multi-threading features are of interest for you. Read these chapters in the online-documentation: * Basics of Xbase Parts * Class hierarchy of Xbase Parts * Multi-tasking and multi-threading Online-documentation Xbase++ includes a comprehensive Windows online help ...\BOOK\XPPREF.HLP. It is invoked via the Start button or by typing WINHLP32 XPPREF on the command line or by clicking the respective icon in the Xbase++ folder or the Windows explorer. To search for information If you are looking for a particular piece of information and don't know where to find it, try using the powerful search facilities provided by WINHLP32.EXE. The help file provides four ways to search for information: Table of contents The table of contents shows a hierarchical structure of all help panels. The first section Xbase++ Basics provides basic knowledge about features and programming concepts while other sections point to reference parts of the documentation. The Xbase++ Basics section is recommended for getting fundamental information about Xbase++. Index The index tab page provides fastest access to a particular help topic. If you know the name of the function or command you are looking for, type it in this tab page and press the Return key. Full text search The full text search lets you search for a particular word in the entire documentation. All help panels which contain the specified word are listed. When this search option is used for the first time, WINHLP32.EXE asks for the creation of a word list for referencing help panels. This takes some time and creates the file XPPREF.FTS. Once this file is created, the full text search feature is available. Quick reference The quick reference is a special feature of the Xbase++ online help. It is invoked by clicking the QuickRef pushbutton in a help panel or by pressing Alt+Q. Then a window is displayed which lists help topics in alphabetical order. There are two Quick Reference windows. One lists functions and commands, while the other lists instance variables and methods. At the top of each Quick Reference window, a pushbutton is displayed which toggles both windows (Toggle QuickRef). Accelerator keys in the help system Accelerator keys are added to the Xbase++ online help to obtain fast access using the keyboard rather than the mouse. Alt+C Activates the Table of Contents tab page Alt+Q Opens the Quick Reference window Alt+S Accesses the Full Text Search Alt+X Activates the Index tab page Alt+Y Opens the History window Ctrl+PgDn Displays Next help topic Ctrl+PgUp Displays Previous help topic All quick selections are also available in the context menu. It appears when clicking the help window with the right mouse button or by pressing the Ctrl+Return keys. ---------- End of Document .