The functions in this chapter provide access to the Netware broadcast message system. With the utility SEND, Netware allows you to send messages between workstations. The NNETSN() functions of CA-Clipper Tools make it possible to send messages from within a CA-Clipper application.
Each Netware user knows the problem of getting a message during a running application: the application is usually interrupted when a message is received. CA-Clipper Tools provide two possibilities to solve this problem: suppressing incoming messages with the NNETBRDCST() function (corresponding to the Novell utility CASTOFF) or using the CA-Clipper Tools broadcast system. The broadcast system allows you to receive messages in the background and read the messages later from the broadcast buffer.
The functions of this chapter allow the start and termination of capture processes from within a CA-Clipper application. Additionally, the most important parameters for a capture process can be set.
The Print Job Definition chapter can be substituted for these functions. When working with print job definitions you do not have to worry about the settings of capture processes. You only have to activate a print job definition that can be created and maintained with the Novell utility PRINTCON.EXE.
This chapter provides functions that return information about the connection between workstations and file servers and allow you to set up or terminate connections. Even the login of a user from within a CA-Clipper application is possible. With the functions in this chapter, you can create a list of file servers within the internal network and all attached file servers, and you can determine the network address of a workstation.
Important! The term "attach" in conjunction with CA-Clipper Tools only describes the setup of a logical connection between a workstation and a file server and does not include a login, as is the case with the Novell utility ATTACH.EXE.
The functions presented in this chapter are a useful extension of database handling. For example, you can determine if there is a memo file (.dbt) associated with a database, the number of decimal places, or the data type of a particular field.
This section contains functions that make many date computations easier to perform. Date-type values have been a feature of the xBASE language standard, and is preserved in CA-Clipper. In spite of this, it is always necessary to develop UDFs to execute certain technical financial computations. CA-Clipper Tools offers an alternative that not only spares you the work of writing a UDF, but also provides implementation in Assembler to guarantee fast execution.
This chapter also contains clock time functions. These include time changes, time span computations, time control of loops, and memory- resident clock display.
Please note that valid date tests are already carried out in CA-Clipper. CA-Clipper internal date tests cannot be canceled, so it is impossible to implement an individual UDF for error handling , if there is an invalid date.
CA-Clipper always replaces an invalid date with a null date. These internal tests are carried out by keyboard input, as well as by CToD() allocation. For this reason, there are no examples with invalid dates in the date function descriptions. Rather, the result of a function with a null date is shown.
Netware provides the ability to manage printer and form information in a database (NET$PRN.DAT). The functions of this chapter allow a read access to the contents of NET$PRN.DAT and make it possible to connect an application's printer management with Netware.
One of the biggest problems in stable application development is how to handle errors. Errors that occur during hard or floppy disk operations are especially frustrating. You may also encounter critical errors, which disable the program or operating system. The result, known to all CA-Clipper programmers, are the DOS error choices: (A)bort, (R)etry, (I)gnore.
Avoiding Errors
Error trap functions allow you to react to this type of error, but a strategy to avoid them completely is better. Therefore, CA-Clipper Tools includes functions to make it easier to handle floppy and hard disk errors.
Backup Systems
Backup systems, another component of the CA-Clipper application, are also discussed in this chapter. The recursive FileSeek() system, which allows you to format disks with DISKFORMAT(), is particularly useful. Complete directories can be scanned recursively, and queries regarding detailed information for every file can be made. The ideal time to carry out this process is during source and target drive back ups, because only the information that has changed is copied.
To avoid the annoying and not particularly fault-tolerant "RUN FORMAT", you can format the file disks directly from the application in all commonly available formats. Since the control UDF for DISKFORMAT() uses a concept similar to dbEdit(), you can display the format procedures on the screen as desired.
You can also determine a good deal of varied information about disk drives, files, and other things. This information far exceeds that of the FileSeek() system.
File Attributes
Following is the coding for each function where a file can be designated:
Table 1:
Value Symb. constants Assigned attribute
0 FA_NORMAL
1 FA_READONLY READ ONLY
2 FA_HIDDEN HIDDEN
4 FA_SYSTEM SYSTEM
8 FA_VOLUME VOLUME
16 FA_DIRECTORY DIR
32 FA_ARCHIVE ARCHIVE
If multiple attributes are implemented for a file, then the table values are added accordingly. For example, if the HIDDEN and SYSTEM attributes are implemented, the function must pass a 6 (2 + 4) as the attribute mask.
All file attributes do not behave the same. To initiate a file into the process, you must explicitly specify the HIDDEN, SYSTEM, VOLUME and DIR attributes. However, if either no attribute, R/O, or ARCHIVE is implemented with a file, it does not matter which value is passed. These rules for attribute handling are grounded in DOS, which compares the specified value with the actual file attributes in this way. Since in some circumstances this may lead to problems, the FileSeek() function allows you to switch on an additional EXACT ATTRIBUTE MATCHING.
Share Modes
For DOS version 3.0 or higher, if a function uses the DOS OPEN FILE call internally, it must pass a share mode. This way, one station determines how all other stations in the network can access the open file. This is valid for as long as the file remains open. The following variations exist:
Table 3: Share Mode
Code Symb. constants Share Modes
0 SHARE_COMPAT Compatibility mode. Here, DOS or the
network software itself, determines the
share mode. In Novell networks, the
SHAREABLE attribute plays an important role
in this relationship.
1 SHARE_EXCLUSIVE Both read and write by other programs are
locked out
2 SHARE_DENYWRITE Write by other programs are locked out
3 SHARE_DENYREAD Read by other programs are locked out
4 SHARE_DENYNONE Not locked. Read and write by other
programs is allowed
With the basic setting, all files are opened in the compatibility mode (relating to older DOS). As a rule, the share mode depends on file attributes or the network software setting.
Also in this chapter is the SETSHARE() function, which determines the share mode that enables all CA-Clipper Tools functions to open a file. CA-Clipper commands or functions are not affected in any way.
Use the CSetSafety() function as a safety switch to protect existing files from unwanted overwriting during file operations with CA-Clipper Tools functions. You will find this function in the chapter on Switches and Status Information, since it concerns all CA-Clipper Tools file operations.
The functions in this chapter let you manipulate the drive mapping of workstations. New mappings can be executed, and existing mappings can be deleted. Furthermore, you can query information about current mappings. The basic function of this group of functions is NNETMAP(). NNETMAP() is used to create or delete an allocation. All extended possibilities, such as search drives and fake roots, are supported. Drive mappings can be defined temporarily. Temporary mappings are deleted automatically at the end of an application.
In conjunction with the ability to log in a user with NNETLOGIN(), the functions of this chapter allow you to set up the complete network environment of a workstation within an application.
In addition to supporting the window functions, the CTUS.LIB extended driver contains a series of independent functions, all of which are described in this chapter.
We are concerned here with functions that relate directly to CA-Clipper keyboard input, screen and printer output, or other internal functions. To use these internal functions, the driver must be linked in. The use of CTUS.LIB does not mean that all the code for all the functions contained in CTUS.LIB is linked to your application. An intensive modularization effort causes RTLINK to link only those portions that are actually needed.
b>The Use of CTUS.LIB
The extended driver is delivered as an .OBJ file (CTUS.OBJ) to allow replacement of the CA-Clipper driver module in CLIPPER.LIB during linking. The extended driver must be included in the list of object files.
b>Video Modes
Some functions which relate to screen adapters are found in the Video Modes chapter rather than in the Video Functions chapter.
This is a very important switch for CA-Clipper Tools that impacts many functions and other modules. DSETWINDOW() determines whether or not the output of external programs or modules is redirected to a window. (CA-Clipper Tools functions are considered "external").
The default setting for this switch (.T.) redirects the output. To make this possible, the driver changes the interrupt vector 10H. Under certain circumstances external programs will not accept changes in particular interrupt vectors, which is why you must call DSETWINDOW(.F.) before you call the RUN function.
Certain other functions, like ISANSI() or NUMCOL(), return false or differing values in conjunction with DSETWINDOW(). Pay attention to the accompanying notes in the function descriptions.
b>System Settings Are Saved
When you end an application under CA-Clipper's control (normal program termination, Alt-C, or ending after a CA-Clipper error message), the cursor type, color attribute, and interrupt vectors 0 to 127 are restored.
However, if you exit a program in any other way (usually with an external module containing errors) then the extended driver system settings cannot be restored. Previously changed interrupt vectors are probably still changed, which sooner or later result in a system crash. If this occurs, reboot as soon as possible.
b>The QUIT File
A QUIT file can be added to any of the extended driver functions. The QUIT file provides information at the next program start as to whether the previous run ended correctly. Additionally, the user's keyboard input is also recorded.
The default name for this file is the same name as your CA-Clipper program except that it has a .Q extension instead of a .EXE extension. However, you can select another name for the file. For more information, please see DSETQFILE(), DSETQNAME() and KEYREAD().
This chapter includes network functions for IBM PC LAN/Microsoft MS-NET software.
b>PC LAN/MS-NET
PC LAN/MS-NET is software that has been offered for networks by IBM and Microsoft. Both programs are based upon the NETBIOS protocol; CA-Clipper does not directly affect the NETBIOS protocol. All internal function calls to the network software occur under DOS, which requires version 3.1 or higher. The functions in this group are in the format NETXXX().
An exception is the NetDisk() function. It can also determine whether a drive is local or remote under other network software. This assumes that the network software properly supports DOS in the background.
CA-Clipper enables you to program nested GET/READ masks. The functions in this chapter are retained in CA-Clipper Tools for compatibility reasons and to make them easy to use.
The active GET is saved with the help of a character string and restored through this string later. This allows you to newly query inputs without losing your main input mask. You can save KEYTRAP() definitions the same way and redefine them as you wish.
Important! It is impossible to use the saved information any longer that the runtime of an application. The character string that results cannot be saved to a file and reloaded later.
Other functions in this chapter return information about GET fields, such as screen position, the names of the accompanying variables, or information about whether a field is currently active.
CA-Clipper Tools was designed for use with the CA-Clipper compiler. Therefore it should only be used on IBM PC/XTs, PC/ATs, or completely compatible systems. The screen functions may not work on a system where a modified CA-Clipper driver module has been used. (The string functions, on the other hand, are generally hardware independent.)
CA-Clipper Tools requires PC-DOS or MS-DOS, version 2.10 or higher, but some functions work with system calls which are not supported until PC/MS-DOS version 3.1 or higher. This applies, for example, to network functions: if you work with network functions under a DOS version earlier than 3.1, the functions will not work properly.
We cannot guarantee that CA-Clipper Tools will work under any operating system other than PC-DOS or MS-DOS.
Installation Program
CA-Clipper Tools is supplied with an installation program, located on Disk 1. To install CA-Clipper Tools, perform the following steps:
■ Insert Disk 1 in drive A
■ Type A: and press Return to change the default drive to A
■ Type INSTALL and press Return to start the installation
procedure
The installation procedure is self-explanatory. You will be prompted to insert other disks as the installation program needs them. (Some of the files are compressed; therefore you cannot use the DOS COPY command to copy them to your hard disk. You must use the installation program.)
When the installation is complete, read the READ.ME file (located on disk 1) to learn about any last minute changes or enhancements.
Compatibility
CA-Clipper Tools is generally compatible with previous versions, but there are some deviations. If you require full compatibility for existing applications developed under CA-Clipper S'87, you must link in the #include file ct.ch. Notice, however, that we do not recommend this procedure for development of new applications.
As CA-Clipper develops, some of the functions in previous versions of the CA-Clipper Tools program are no longer meaningful. These functions remain unchanged in CA-Clipper Tools to avoid problems during the compilation of existing applications, but they have been flagged with asterisks (*) at the function name. Again, we do not recommend that you use these functions to develop new applications.
Documentation
All of the CA-Clipper Tools functions are described in detail in this four-volume Reference Guide. To allow you to find the function you need in a particular situation, the Reference Guide is divided into chapters. Each chapter presents a group of functions that serve a particular purpose, such as date functions, database functions, or system functions. Each function is then described in detail on a separate page. Appendixes provide keyboard tables, DOS error codes, and Novell network error codes.
A Quick Reference Guide gives the complete syntax and a short description of every function. In this booklet, the functions are organized in alphabetical order for quick reference. A chapter and page number tells you where to look in this four-volume Reference Guide for a complete description of the function.
The CA-Clipper Tools software contains a text retrieval system that lets you search online for the expression you need. This text retrieval system finds the appropriate function for your purpose in seconds — even if you don't know what that function is — and provides complete documentation on that function online.
CA-Clipper Tools contains over 800 functions which you can use to develop CA-Clipper applications and system-level routines. These functions give CA-Clipper programmers capabilities previously reserved for C or Assembler programmers with detailed system knowledge.
In order to use working memory as economically as possible, virtually all the functions are written in Assembler and are highly optimized. This guarantees high speed with a minimal use of memory. This efficiency is further supported by the modularity of the software within the CA-Clipper Tools library.
Each Netware file server maintains a database of users and resources available on the network. This special-purpose database is called the bindery. The bindery contains objects uniquely specified by an object name and an object type. Possible object types are: users, user groups, print queues, or print servers. Each object has associated with it a number of properties that can be addressed with names and contain information about the object. For example, the property GROUPS_I'M_IN contains a list of user groups of which a user is a member.
The functions of this chapter allow a low level access to the bindery. This provides you with maximum flexibility for programming within Novell. The low level functions allow the creation of your own bindery objects as well as the development of bindery analyzers.
However, even though the bindery concept has a high security level, incorrect use of the low level bindery functions can be very dangerous if you have supervisor or equivalent access rights. The network could be brought to a standstill. You should use these functions only with extensive knowledge of the bindery concept, the Novell API, and bindery management. For example, you must know the terms object, item, and set property.
For frequent, complex purposes that require bindery access, like adding a user to a group, CA-Clipper Tools provides high level functions that can be used without a problem. These functions are based on the low level functions and are available in CA-Clipper source code.
Netware internally uses a high low sequence to store numeric values, which is contrary to the standard format of the 80x86 processor family (low high sequence). For efficiency reasons, the Netware functions of CA-Clipper Tools expect numeric values that are passed to Netware (object types or object IDs) in the high low sequence. However, this will not affect the practical work with the CA-Clipper Tools because symbolic constants are defined in the high-low format in the header file CTNNET.CH for the most important object types.
This chapter offers an array of interesting mathematical functions to implement in CA-Clipper. It includes trigonometric functions, finance- oriented math computations, and functions to determine the factorial, sign, or the next-largest integer of a value.
SetPrec() is important for trigonometric functions. With this function you can specify the precision as a number of places to the right of the decimal. However, if it is less accurate, the speed is greater.
Functions that do not belong in any other module are assembled in this group under the Miscellaneous heading. However, this does not imply they are less useful. For example, use KeyTime() or KeySec() to activate a CA-Clipper procedure at a specific time, after a delay of seconds, implement file saves, or control demo programs.
This module enables you to determine complements, determine data types, and query keyboard scan codes.
b>Passing Parameters by Reference
Finally, this chapter discusses functions that permit you to pass parameters by reference. To find more information on this subject, see Chapter 4, String Manipulations.
This chapter contains some useful functions that do not belong in any other chapter of network functions. The functions HexToStr() and StrToHex() are not network functions, but these functions have been included in CA-Clipper Tools specifically for working with internet addresses that are returned or are required by functions such as NNETADR() or IPXOPEN(). The function NNETVER() is very useful if you are developing applications that access Netware 2.2 and Netware 3.11 servers because the behavior of some CA-Clipper Tools functions depends on the Netware version used (for example, NNETRIGHTS(), NNETPURGE()). Other functions are available for only one Netware version (for example, NNETSNDLOG(), NNETSALLST()).
This module discusses number and bit manipulation. Specifically, the numeric section deals with conversions between two different number systems, and the creation of random numbers.
The bit manipulation section covers such required binary operations as AND, OR, XOR, and NOT, and how to test, set and clear bits. The NumLow() and NumHigh() functions are important for CA-Clipper Tools functions that take two 8-bit values and return them as combined 16-bit numbers. An example is the GETCURSOR() function from the Extended Drivers module.
Many of the functions in this module have a value parameter type. In this case, a number can be in the range of 0 to 65535 (or 4 294 967 295) and/or a hexadecimal string in the range of "0000" to "FFFF" (or "FFFFFFFF").
Despite the many capabilities of CA-Clipper Tools, there are times when direct port or memory access is needed. The functions in this chapter serve this purpose. For example, you can read memory regions by byte, word, or as a string through the PEEK function. POKE functions enable you to write a byte or word to working memory, but not a string.
Warning! POKE functions can be very dangerous. If you write to the wrong area in memory it can cause a lot of problems you may not foresee. Use POKE functions ONLY if you have extensive system knowledge.
This also applies to all the IN/OUT functions in this chapter, which allow you to directly manipulate a port. For example, if you address a disk controller improperly, the result may lead to data loss.
The CA-Clipper Tools contain functions that allow direct communication between workstations in Novell or NetBIOS compatible networks by bypassing the file server. This type of communication is called Point- To-Point communication.
The data exchange between two workstations is interrupt controlled. Incoming data is copied in the background to a receiving buffer and can then be read with CA-Clipper Tools functions. As soon as the receiving buffer is full, incoming data is discarded. Outgoing data is copied to a sending buffer. While the CA-Clipper application continues, data is sent in the background from the sending buffer to the target address. Interrupt controlled sending of data is necessary to avoid a long wait when you send large datasets. When you use IPX/SPX communication or one of two possible NetBIOS communication variants, the data is broken up into packets internally. The packet size depends on the protocol used (IPX: 546 bytes, SPX: 534 bytes, NetBIOS: 512 bytes). The packets are sent sequentially.
Normally, the packet structure of the transmitted data is transparent and does not affect the handling of the data. The receiving buffer of the target workstation receives the data in the same way that the data has been written to the sending buffer. When you use IPX/SPX protocols in addition to the data, a header that is included in each IPX or SPX packet can be transmitted to the receiving buffer. This header makes a number of packet specific functions possible. The tables 31.1 and 31.2 describe the structure of the IPX and SPX header. The header positions start with 1, corresponding to string functions.
The NetBIOS communication variants have no similar mechanism available.
Table 31.1: IPX Packet Header
Position Length Description
1 2 Checksum
3 2 Packet length in bytes
5 1 Transmission control
6 1 Packet type (4=IPX)
7 4 Network number of target station
11 6 Station ID of target station
17 2 Target socket (High, Low format)
19 4 Network number of source station
23 6 Station ID of source station
29 2 Source socket (High, Low format)
Table 31.2: SPX Packet Header
Position Length Description
1 2 Check sum
3 2 Packet length in bytes
5 1 Transmission control
6 1 Packet type (5=SPX)
7 4 Network number of target station
11 6 Station ID of target station
17 2 Target socket (High, Low format)
19 4 Network number of source station
23 6 Stations ID of source station
29 2 Source socket (High, Low format)
31 1 Connection control
32 1 Datastream type
33 2 Connection number on source station (High, Low format)
35 2 Connection number on target station (High, Low format)
37 2 Sequence number (High, Low format)
39 2 Acknowledge number (High, Low format)
41 2 Allocation number (High, Low format)
When you install a communication buffer (a communication buffer can contain a sending and a receiving buffer), you receive a communication handle as a return value. You should store this handle in a variable as it is absolutely necessary for further operations with the communication buffer.
The functions for Point-To-Point communication fall into two groups: protocol specific functions and functions that can be used for any kind of communication buffer. Protocol specific functions are functions for a connection setup: (IPXOPEN(), SPXESTBCON(), SPXLISTCON(), NBDOPEN(), NBSCALL(), and NBSLISTCON()). The name of a protocol specific function always starts with three characters that describe the respective protocol (IPX, SPX, NBD: NetBIOS Datagram, NBS: NetBIOS Session).
Functions that write or read a buffer, or query the buffer status, are not protocol specific and can be used for any kind of communication buffer. The names of these functions start with PPC (Point-To-Point Communication). For example, the function PPCWRITE() is used to write data to a communication buffer. The protocol specific process of the data is regulated internally.
IPX/SPX Communication
Novell Netware (including Netware Lite) allows the direct use of the IPX and SPX communication functions. By loading the Novell NetBIOS emulator (NETBIOS.EXE), you can also use NetBIOS communication functions in Novell networks. However, the use of the emulator compared to IPX/SPX reduces the performance and the available memory. Therefore, you should use the IPX/SPX communication functions for applications running only in Novell networks.
IPX (Internetwork Packet Exchange Protocol) is a rudimentary protocol whose main advantage is that data can be sent to all waiting workstations in an internal network with only one call. However, IPX has no suitable handshake mechanism available that guarantees a successful delivery and a correct process of the sent data on the destination workstation. (Related mechanisms can be implemented with the IPX functions of CA-Clipper Tools. However, these mechanisms are application specific and have no general validity.)
The SPX protocol (Sequenced Packet Exchange Protocol) only allows communication between two workstations within an internal network. SPX has mechanisms available that guarantee the successful delivery of sent data.
Unlike SPX, which can be seen as real Point-To-Point communication protocol, the IPX communication is implemented as a pseudo Point-To- Point communication. When you use IPX, data for a specific workstation can be received by any workstation. However, a destination address is defined for interrupt controlled sending. (This address can specify all workstations within an internal network.) The destination address is not defined by the protocol, so it is not necessary to specify the destination address each time you access the send buffer. When you use the SPX protocol, a connection between two workstations is established.
The IPX/SPX communication between two workstations is based on two sockets on each side of the connection that can be opened and closed, similar to files. Sockets are represented by numeric values between 1 and 65535. Some socket numbers are reserved either by the Netware operating system or by Novell for third party vendors. The sockets between 16384 and 20480 (4000h - 5000h) are the dynamic sockets, meaning there are no reserved sockets in this range. A collision with socket numbers reserved by Netware can be avoided by using sockets out of that range.
NetBIOS Communication
The NetBIOS communication functions can be used in all networks that are based on NetBIOS specifications. In CA-Clipper Tools, two kinds of NetBIOS communication have been implemented: NetBIOS datagram and NetBIOS session communication. The NetBIOS datagram communication can be compared to the IPX communication; a successful delivery of sent data on the destination workstation is not guaranteed by the protocol. Like IPX, the datagram connection can also be implemented as pseudo Point-To- Point communication between two workstations. Additionally, a workstation can communicate with a group of workstations or with all workstations in a network.
Like an SPX connection, a session connection is a fixed connection between two workstations. The dataflow between two workstations is supervised internally by a protocol that guarantees the delivery of sent data on the destination workstation.
For the communication with other workstations in a NetBIOS network, NetBIOS names are used. A NetBIOS name can be up to 15 characters long and is case sensitive. NetBIOS differentiates between two kinds of names: station names that specify a workstation and are unique in a network, and group names that can be assigned to any number of stations. Each workstation contains a local name table with up to 20 NetBIOS names. A workstation can be addressed with each name in the name table. Once you have defined single or group names, messages can be sent easily to a station or a group of stations.
Because of the importance of NetBIOS names for the Point-To-Point communication, CA-Clipper Tools not only includes functions for the sending and receiving of data, but also functions for creating and deleting NetBIOS names.
With the Novell utility PRINTCON.EXE, print job definitions that contain the settings for a capture process can be created. The functions in this chapter allow you to control the print job definitions of the current users and all other users on a file server. You can create new job definitions and query or modify settings in existing definitions. It is possible to read the settings of a job definition and to directly start a capture process (NNETPJCAPF()). This function call is equivalent to a call of the CAPTURE utility with the parameter /J=.
Important! Within the Netware documentation the term "job" is used to describe a print job within a queue and also a set of capture parameters (print job definition). Within this chapter the term "job" or "job definition" only describes the definition of capture parameters.
The functions in this chapter cover the entire area of print queue control under Netware. Print queues can be created or deleted. Users, operators, and print servers for a print queue can be defined or removed. The queue functions allow you to manipulate jobs within a queue. All settings for a print job can be queried or modified if the job is not currently processed (provided that you have sufficient access rights). Jobs can be deleted or moved within a queue.
Important! Within the Netware documentation the term "job" is used to describe a print job within a queue and also to describe a set of capture parameters (print job definition). Within this chapter the term "job" only describes a print job.
Under Netware 3.x, control of network printers is no longer handled by a file server but by a print server. (However, as an NLM, the print server can also run on a file server.) Under Netware 2.2, a print server VAP is available. The functions of this chapter provide the ability to access the most important information and functions of a print server. For example, you can determine the status of a print server printer. In conjunction with the functions for Point To Point communication, a CA-Clipper application is able to emulate a remote printer (see sample program RPRINTER.PRG).
This chapter discusses printer output. Although CA-Clipper handles printer errors with an error trap, it is always better to avoid them completely. As a result, error traps for printer output will not become superfluous, since errors also occur during output. You can also determine a wide variety of information, such as the number of available printers or the printer status.
This chapter also describes functions that support DOS print spoolers. To implement these functions, prior to starting the respective application, you must run the DOS PRINT program to make the print spooler memory resident. Files can then be exclusively passed from a program to the spooler. However, you must first reroute your print output to a file (SET PRINTER TOfile), before you can output it in the background.
A semaphore controls certain states: for example, the states between two applications that run on different workstations. To enable all stations to access existing semaphores, each Netware file server has a table available to manage these semaphores.
Semaphores can be interpreted as variables kept on the file server. Each semaphore is assigned a name when it is created. A semaphore name can be up to 127 characters long and is not case sensitive. An application can access a semaphore by opening the semaphore with its name (NNETSEMOPN()).
A semaphore can be opened by any number of workstations. For each workstation, the semaphore has the same value. The semaphore value cannot be modified; however, by using specific functions it can be incremented (NNETSEMSNG()) or decrements (NNETSEMWAI()) by 1.
Each semaphore is assigned information in addition to the semaphore value. For each semaphore, the file server counts the number of stations currently accessing the semaphore. This information can be determined with the function NNETSEMOPC(). For example, a semaphore named after an application can be used to limit a resource to this application.
Semaphores are often used to implement logical lockings for any kind of resource. A semaphore is assigned to each resource. Before the resource is accessed, the application tries to decrement the semaphore's value by one (NNETSEMWAI()). If the resulting value is negative, the resource is locked by another station. When an application is finished using a semaphore's resource, the function NNETSEMSNG() must be called to increment the semaphore's value.
There are a number of ways that the serial port can be used. Modems, bar code readers, and many other devices deliver data over this port or are regulated by it. Although standards do exist, in the final analysis, the type of communication is different every time.
The functions in this chapter offer possibilities for data transmission and allow you to influence control signals. These functions do not support any particular protocol or any specific instrument. For a few expanded applications, like the XMODEM protocol, you should find sufficient information in the example programs for CA-Clipper Tools.
b>Port Parameters
All the parameters for the port, like baud rate, parity, file length, and stop bits, are fully adjustable. It is possible to change the settings for a port without closing it. In this way the transmission speed can be changed without losing the contents of the buffer or terminating an existing connection (DTR-signal).
b>Data Transmission
Using CA-Clipper Tools, you can use up to four serial ports simultaneously. You can create a sending and a receiving buffer of up to 64kB in size. The characters for the background transmission mode are placed in the sending buffer, while characters received through the port are stored using an interrupt handler. You can determine the number of characters in the receive buffer from your CA-Clipper program, and as many of the available characters as you like can be read. Additional special control functions exist for the sending buffer that give the governing program full control. It is also possible to engage a software or hardware handshake that is performed completely in the background.
b>Handshake
As previously mentioned, CA-Clipper Tools functions support both a hardware and software handshake. As soon as the receiving buffer threatens to overflow by at least one page, a special handshake character is transmitted that tells the other side that no further data should be transmitted. Whether you implement the hardware or software handshake depends upon the type of data transmission. Hardware handshakes use physical port controls. These port controls are usually RTS and CTS, so within the scope of CA-Clipper Tools functions, these control ports cannot be used for modem transmission. Modems are generally not able to reproduce port controls directly over the transmission route (i.e. telephone connection). A software handshake must be implemented in such cases.
A software handshake uses characters from the ASCII character set to control the data flow. The ASCII character set is a standard which defines the XOFF (stop data, transmission off) as Chr(19) and the XON (continue transmission, transmission on) as Chr(17). (You will recognize the similarity to your keyboard since Chr(19) corresponds to Ctrl-S, and Chr(17) corresponds to Ctrl-Q).
If one of the handshake processes is implemented, the software must test both sides to see if the receiving buffer has been filled. The software then either deactivates the CTS controls or sends an XOFF character. By contrast, when sending data you must constantly test to see if the RTS input from the remote station has been deactivated or if an XOFF character has been received. In both cases transmission must stop immediately.
Since you can never be sure if the remote stations stop immediately after receiving an XOFF character, the internal handshake becomes active when the buffer is 75% full. If the remote stations ignore the handshake, the 75% limit is probably insufficient at a set buffer size of 100 byte (which equals a 25 byte reserve).
The techniques described here for the handshake are managed completely by the CA-Clipper Tools routines. They do not concern themselves with the interface cards or the Universal Asynchronous Receiver Transmitters (UARTS). It is sufficient to activate the selected method, which allows your program to regulate the status of the sending and receiving buffers on an ongoing basis.
b>Protocols
As previously mentioned, remote data transmission is, as a rule, implemented only through a software handshake. A significant disadvantage to this method is that the characters used for flow control, CHR (19) and Chr(17) can no longer appear in the original data. Because these characters appear in binary files, remote data transmission is not possible — transmission protocols must be used. You find XMODEM routines written in CA-Clipper in the example programs. Using the CA-Clipper Tools port functions and this example as a basis, other protocols can be developed fairly simply.
Firm protocols are not provided within CA-Clipper Tools because their realization in CA-Clipper code presents no real advantage. It is more important that you have the ability to create your own protocols so that you are not locked into whatever protocol is within CA-Clipper Tools.
b>Control Signals
You can set or query all important port connector control signals, like CD (carrier detect), DTR (data terminal ready), etc.. To simplify your programming, there is a separate function for each signal. For all other status and control information, which is seldom required in serial communications, you can read or describe the corresponding UARTS register of the port directly.
b>Direct Hardware Access
All CA-Clipper Tools port functions directly address the hardware. Working over BIOS or even DOS calls would be impractical or even impossible. We therefore presuppose 100% hardware compatibility with the established IBM personal computer industry standard.
In order to guarantee that everything is functioning properly, both ports must be equipped with either UART 8250 or the compatible 16450. When you use the 8250, interrupt controlled transmission is only possible up to 2400 baud. Technical details regarding the ports and the UART registers can be found in the corresponding technical instructions, like the IBM Technical Reference Manuals.
b>I/O Addresses and Interrupt Requests
CA-Clipper Tools assumes the following basic settings for the four ports:
Table 1: Standard Port Settings
Port I/O Address IRQ
COM1: 3F8H 4
COM2: 2F8H 3
COM3: 3E8H 4 - Not specifically defined
COM4: 2E8H 3 - Not specifically defined
In contrast to COM1 and COM2, the I/O addresses and IRQs for other ports are often different. If you want to use hardware that is not entirely compatible, CA-Clipper Tools has additional functions that you can use: com_SetIO() and com_SetIRQ(). When you use these functions, the I/O and IRQ settings for the port routines can be changed to the selected values. However, please notice that incorrect settings can have a wide range of consequences when they come in conflict with other hardware. These consequences include data loss or damage to hardware.
The correct settings for your hardware can be found at any given time in its accompanying documentation.
b>Possible Hardware Conflicts
CA-Clipper Tools recognizes the four addresses mentioned above for the ports COM1 to COM4. The com_Num() function uses these addresses to determine the number of available ports. For example, if the PC has a built-in ArcNet adapter, you can have a conflict between the I/O addresses. The CA-Clipper Tools routine addresses 02EAh, which is defined totally differently for the ArcNet adapter than for a serial interface. In this case an existing network connection would probably be disconnected. The com_SetIO() function can provide assistance by designating the second parameter as 0:
com_SetIO(port,0)
The corresponding standard address within the internal address table is deleted and access to other hardware is avoided. However, this is only possible if the com_Num() function has not previously been called within the program. (In this case the interface would have already been marked "in use.")
b>Important Notes
As the table of default settings indicates, it is possible for multiple ports to use the same IRQ — a procedure known as interrupt sharing.
While CA-Clipper Tools functions support these procedures, standard port hardware usually does not. Specialized multiple port cards are available from different manufacturers for this purpose.
Generally we cannot guarantee that interrupt sharing can be implemented.
CA-Clipper Tools supports up to four ports, each with sending and receiving buffers of up to 64kB and speed of up to 19200 baud. This is not to say that all this could be used at the same time to its highest limit. Eight buffers at 64kB are not possible. The buffers must be in conventional memory because the buffers are handled by interrupt routines. The number of ports and the speed with which they can function correctly is dependent upon the computer being used.
b>Differences from BASIC
In contrast to other programming languages (like BASIC), com_Open()/com_Init() do not influence control signals. If you want to address a modem over the serial port using CA-Clipper, you must set DTR and any other signals yourself, using the corresponding CA-Clipper Tools functions.
In this chapter, the group of functions determine the switch status and were implemented in the CA-Clipper Tools (CA-Clipper Summer 1987 release). CA-Clipper implemented the Set() function, so that these settings can be determined, set, and saved with this version. Therefore, some functions in this chapter only exist to enable compatibility with existing programs. All the affected functions are flagged with an "*".
If the functions relate to the CA-Clipper switches (SET's), the function name is represented as follows: CSET + the first four characters of the switch name. For example, if the switch is named CONFIRM, then the function that corresponds is CSETCONF(). If the parameter is optional and unspecified, the function returns the current setting for its switch, without a status change. When called with parameters, the function sets the switch to the passed value and returns the prior status as a value. In this way, a function call can both change a switch and save the old status. The logical value .T. corresponds to the ON setting of a switch; .F. corresponds to OFF.
b>Example
In the following example, the CONFIRM switch was set to .F.:
lOldValue:= CSETCONF(.T.)
After execution, the old variable lOldValue has a value of .F.; while the CONFIRM switch is ON (.T.).
In addition to their usefulness with CA-Clipper switches, these functions determine an assortment of other status information. For example, you can determine the current status of the debugger, set LASTKEY, and differentiate key traps. You can also determine the status of CAPS-LOCK, NUM-LOCK, INSERT, and SCROLL-LOCK.
There are an abundance of powerful string functions described in this chapter. A high degree of speed is assured because these functions and all of the CA-Clipper Tools are written exclusively in Assembler.
We have made an effort to find an appropriate example for as many unusual variations as possible. In view of this, we would like to take this opportunity to clarify a few ground rules regarding the use of these functions.
b>Passing Parameters by Reference
This chapter includes functions that pass parameters by reference. The following paragraphs contain clarification about these functions.
It has been possible to pass parameters of the character string type by reference to a UDF since the summer of 1987. This means that a reference to the original string is passed, thus avoiding the creation of an internal copy. When a function accepts this type of parameter and changes it, the original string is actually changed. This behavior does not normally apply to CA-Clipper functions. However, some CA-Clipper Tools functions behave differently and take parameters passed by reference. These functions and their corresponding parameters are described as reference sensitive in this section and are identified with [@] in the argument section of each function's description.
Passing parameters by reference has advantages and disadvantages. The most important advantage is that memory requirements are reduced. This allows you to avoid runtime errors that could result when there is insufficient memory available for string manipulation.
Whether or not the insufficient memory is a disadvantage depends on the function being used. Often you will want to change the original string. In a call that does not pass parameters by reference, the copy changed by the function must then be passed back to the "original" string again:
VAR := "Hello" VAR := FUNCTION(VAR)
When you work with very long strings, this method takes memory and time!
Here is an example of the reference method:
VAR := "Hello" FUNCTION(@VAR)
With most CA-Clipper Tools functions, it doesn't make any sense to pass parameters by reference. In some cases, a result is different when a parameter is passed in this way. However, when you do pass by reference, the functions change the parameters passed by the string directly. Memory is saved, and the functions work more quickly because you no longer need to make an internal copy. Watch for the [@] marker, indicating that a parameter is reference sensitive.
Functions which change the length of a string cannot, in principle pass by reference. Here is an overview of the functions that change length, or depending upon usage, could change if you attempt to pass by reference.
This function additionally allows you to significantly optimize reference sensitive functions with regard to execution speed and memory use. Full details can be found in the corresponding function description later in this chapter.
The functions in this chapter provide system information about the operating system (MS-DOS), the BIOS, and hardware. It determines a large number of system facts and settings — from the DOS-COUNTRY setting to the mathematical coprocessor. It is even possible to warm or cold boot a computer from within a program. In addition, you can query and set DOS VERIFY and BREAK.
This chapter provides functions for the use of the TTS within a CA-Clipper application. The use of the TTS within a CA-Clipper application requires more than start and termination or cancellation of a transaction with the related CA-Clipper Tools functions. With regard to the architecture, the application must be oriented to the specifics of TTS. The TTS takes into consideration only files managed on a server volume.
Transaction tracking occurs only on the files that have been marked as transactional. The transactional bit is an extended file attribute that can be set with the Novell utility FLAG.EXE or with the related CA-Clipper Tools function NNETEXTATT(). All files related to a .DBF file, (.NTX, .DBT) must also be marked as transactional.
The time between the start and the termination or cancellation of a transaction should be as short as possible. Avoid direct entries into database fields. Use memory variables for data input and then update the database within a transaction.
The reason for minimizing the transaction time is a characteristic of the Netware operating system that cannot be influenced by the application. When data in a file is modified, Netware physically locks the affected file area. In contrast to a logical locking with RLock(), the affected data cannot be read as long as the transaction is incomplete. If the transaction has been terminated successfully, the database record is updated. If the transaction has been interrupted, the record is reset to the previous value. A successful read access by another workstation could lead to fatal logical errors. The physical lock is removed automatically after the transaction has been completed or canceled. If a workstation tries to access a physically locked area, CA-Clipper causes an ACCESS DENIED error message and evaluates the error block. Normally, this results in a branch into the error recovery routine. An error message box is displayed, and the user can cause a repetition of the operation that failed. The error message text can be adapted to the running transaction. However, the problem is that from the beginning the application is not able to determine whether the ACCESS DENIED error results from a running transaction or another error source. Therefore, an application using the TTS should have a mechanism available that allows it to determine if a transaction is active for a specified group of files or not. Using Netware semaphores, for example, allows you to check to see if a transaction is active, either during the error recovery or before a file is accessed.
The functions of the User and Group Management chapter are based exclusively upon low level bindery accesses and could be accomplished completely with the low level bindery functions. However, working with low level bindery functions can be dangerous (see the Introduction to the Low Level Bindery Access chapter). Therefore, CA-Clipper Tools provide a number of high level functions for the most common requirements of user and group management. The functions in this chapter allow you to add or remove users, or groups of users, to or from groups. Various lists can be created: established users or groups, currently logged in users, members of a group, or groups of which a user is a member. You can determine if a user is a member of a specified group. For example, this allows you to combine the availibility of menu options with Netware settings.
A number of functions in this chapter have been developed in CA-Clipper with the use of low level bindery functions. The source code for these functions can be found on the product disks and can be used as an example for the use of the low level bindery functions.
To use the CA-Clipper Tools functions in your programs, specify the CT.LIB library during the LINK procedure. If required, also specify the CTUS.OBJ Extended Driver file. (See the section called "Extended Driver" below.)
All CA-Clipper rules apply when calling functions. For example, a function's return must not be assigned to a variable.
Both types of calls are possible:
FUNCTION(par1, par2) Var=FUNCTION(par1, par2)
Linking
CA-Clipper Tools functions can be linked with MS-LINK (often referred to as the DOS linker) as well as with RTLink.
Here is an example using MS-LINK:
LINKProg1+Prog2+CTUS,,,CT/SE:nnn/NOE
With the exception of small test programs, MS-LINK requires that a value be assigned to the /SE: switch. We cannot recommend an adequate value for nnn.
Here is an example using RTLink in FreeFormat mode:
RTLINK FIProg1,Prog2,CTUS LIB CT
RTLink also contains a positional mode. When using this mode, the link command has to be identical to that in MS-LINK. Further information regarding RTLink can be found in the CA-Clipper Programming and Utilities Guide.
PLL Files
CA-Clipper Tools cannot be implemented in conjunction with the BASE50.PLL file created at CA-Clipper installation. You can, however, create a new corresponding .PLL file with the linker script file CT.LNK included in CA-Clipper Tools. Use the following command:
RTLINK @CT
This will exchange a particular module from the CA-Clipper library as well as several I/O routines out of TERMINAL.LIB for others in CTUS.OBJ or CT.LIB. The new .PLL file is called CT.PLL. If a new .PLL file is not created, then the alternative I/O routines and therefore many of the CA-Clipper Tools functions will not work for all the programs generated via prelinking.
If the CT.PLL file has been created once, the link procedure can be called as follows:
RTLINK FIprogLIB CT PLL CT
The CTUS.OBJ Extended Driver must not be specified, since it is already in the .PLL file.
Further CA-Clipper Tools modules have not been included in this or other .LNK files, since prelinked modules are always loaded at program start and increase memory usage accordingly. Creation of a .PLL file in conjunction with other external libraries becomes an individual procedure. However, all CT.LIB modules can be prelinked. You simply need to include a public for the desired module by inserting the REFER command.
Here is an example. By inserting:
REFER COM_BREAK, ACOS
the _COM and _TRI3 modules (serial interfaces and trigonometric functions) will be prelinked. The names of the module and the publics can be determined with a library manager like MS-LIB.
CA-Clipper Libraries
None of the preceding examples mentions any of the files belonging to CA-Clipper itself. This is because, during compiling, CA-Clipper's default setting enters the names of its four libraries in the resulting .OBJ file. When you influence this procedure, for example by using the /r compiler switch, all the required libraries must be called explicitly at linking.
Static Overlays
Most functions or CA-Clipper Tools modules cannot be stored to a static overlay, as they contain interrupt service routines. They may not reside in an overlay. The functions affected are KeySec(), KeyTime(), ShowTime(), SHOWKEY(), PRINTSCR(), PRINTSCRX(), and SETTIC(), as well as serial interface functions that also work interrupt controlled.
The Extended Driver CTUS.OBJ may never be placed in an overlay, since it is needed by CA-Clipper for every input and output. Linking CTUS.OBJ in an overlay will result in a system crash immediately after the start of your application. Therefore, be aware that the overlay will always have to be loaded in order for the function to be available.
All CA-Clipper Tools functions can be called from an overlay. The program code for some functions, however, cannot be placed within an overlay.
Possible Linking Problems
When implementing CA-Clipper Tools in an existing application for the first time, the linker warning message "Duplicate Definitions" may occur. In this case, probably one of your own procedures or functions or a function from another library has a name that was also used by one of the CA-Clipper Tools functions. If the name of this other function or procedure cannot be changed, it must be specified as a separate .OBJ file. Otherwise CT.LIB must be designated as the last library.
Note, also, that an .OBJ file will always overwrite a library module with the same name, independent of its position in the LINK command line. Therefore, the CA-Clipper Tools Extended Driver is delivered as an .OBJ file.
Extended Driver
In addition to the CT.LIB library, you will find a separate .OBJ module on your disk called CTUS.OBJ. This is the CA-Clipper Tools Extended Driver. If this is linked in, it replaces the CA-Clipper library driver. Above all, the Extended Driver is important for the implementation of window functions, but it also offers other interesting possibilities. For this reason all the functions in the chapter on the Extended Driver in this Reference Guide form a part of this module.
The CTUS.OBJ must only be added to the .OBJ file list to be linked. The sequence is not important. The Extended Driver replaces the CA-Clipper library driver module, so storing out to an overlay is not possible. You will find further information in the Extended Driver chapter.
Debugging
Working with CA-Clipper Tools makes additional debugger features available. These features are also controlled via the CLIPPER environmental variable, by setting a switch DEBUG:n.
How Problems Arise
There are many possible screen modes, fonts, windows, and virtual screens, so various problems can arise. The debugger also uses windows, as you can see on the debugger Windows menu. To avoid a collision with the windows of your application, the debugger has an additional windowing system.
Working with One Screen
When working with one screen, the debugger must be able to switch between the application screen and its own screen. The contents of the application screen must be saved. This can happen in an area of the available memory or in a free screen page.
Using a screen page saves memory and offers better performance, but it takes a screen page of the application. This is, however, taken into account by CA-Clipper Tools. The MAXPAGE() function, for example, returns a reduced value. The default value for the application is screen page, which can be changed with the environmental variable.
Working with Two Screens
Working intensively with CA-Clipper Tools video functions and the debugger on one screen is difficult. For this situation, the debugger supports two screens. This is possible because the PC can operate two cards simultaneously, for example, a Hercules card and a VGA card. The application output always occurs on the screen from which it was started, while the debugger output is displayed on the other screen. This capability is set via the CLIPPER environmental variable, by specifying DEBUG:2.
DEBUG Values
The DEBUG: n switch can be set with a numeric value. Each individual bit has a certain meaning. At this time, only two bits are used:
Bit: When set: Default
1 use PAGE 1
2 two screens 0
Note: Particular switch combinations in the CLIPPER environmental variable can lead to problems. Please construct your environmental variable as follows:
SET CLIPPER=/Fnnn /Ennnn /DEBUG:2 /SWAPPATH:"path"
Reference Sensitive[@]
CA-Clipper can pass parameters of the character string type to a UDF by reference. This means that what is actually passed is a pointer to the original, thus avoiding the creation of an internal copy. When a function takes on this type of parameter and changes it, it is the original that is actually changed. Here is an example:
VAR := "Hello" MYFUNC(@VAR)
Passing of parameters by reference has advantages and disadvantages. An important advantage is that memory usage is reduced. This avoids runtime errors that result from not having enough memory for string manipulation. If, on the other hand, you do not want the original string to be changed, passing of parameters by reference is a disadvantage.
With a normal call (that is, not by reference), it is the copy that is changed by the function. The change must then be passed back to the original:
VAR := "Hello" VAR :+ MYFUNC(VAR)
Particularly in the case of long strings, this method takes up memory and time.
It is not a good idea to pass parameters by reference for most of the CA-Clipper Tools functions. (In some cases there will even be a difference in the result when a parameter is passed this way.) The functions then change the string passed as a parameter directly. This saves memory space and the functions work more quickly, since there are no internal copy procedures taking place. Watch for the [@] identifier meaning reference sensitive.
This function allows you to further optimize memory requirements and speed for different string functions. This assumes that a function is only working with data passed as a parameter and avoids internal copies of returned values as well. When CSetRef() is set, the affected function no longer returns a value.
You will find more information on this function in the chapter on string functions.
This module discusses video functions that are either directly or indirectly concerned with the screen. Included are all functions that deal with such screen adapters as CGA, EGA and Hercules. Different modes on various adapters are supported, such as a 40-column CGA, a 43- line EGA, or a 50-line VGA.
Many of the functions in this chapter depend on setting the DSETWINDOW() switch. This switch determines if the screen output of external programs, as well as DOS, are redirected to a window. CA-Clipper Tools output functions are also valid as external. If the default setting in DSETWINDOW() is .T. or on, this rerouting is carried out. Some functions will then return inaccurate, or at the very least, different results. Examples of this are ISANSI() or NUMCOL()
Attribute
Many of the functions in this module work with color attributes designated as parameters. These arguments are carried out in three different ways:
A numeric value, which corresponds to a combined color attribute (e.g., 7).
A string in the "NN/NN" form, with two specified numeric values (e.g., "7/0").
A string in the "CC/CC" form, with two specified attributes are designated in the form CA-Clipper requires (e.g., "W/N").
With many functions, the attribute returns a combined numeric value. Attributes for the foreground and background are tied together this way.
Color attributes are constructed as follows:
Bit 8 7 6 5 4 3 2 1 Attribute * R G B + R G B
_ _ _ _ _ _ / _ _ _ _ _ _
Background / Foreground
Each attribute consists of four bits, which represent a value in the range of 0 to 15. Therefore, there are a total of 16*16, or 256, different values from 0 to 255. These numeric values can be changed into the "nn/nn" format, that can be used under CA-Clipper with the NTOCOLOR function. However, it is possible to directly influence this combined attribute value. The following examples show this and relate back to the chapter on number and bit manipulation:
NumOr( nattr, 128) // Flashing on NumAnd(nattr, 127) // Flashing off NumXor(nattr, 128) // Change flashing NumOr(nattr, 8) // High intensity on NumAnd(nattr, 247) // High intensity off NumXor(nattr, 8) // Switch high intensity
Special Parameter Type
With many functions, a parameter may be of the mIcCharacter|nCharacter type (e.g., an individual character). This can occur in two different ways:
Numerically, as the ASCII code of the desired character (e.g., 7).
Alphanumeric as the character (e.g., ":").
Because of this, you must not use the Chr() function to change special characters.
CLEARA and CLEARB
Some of the CA-Clipper Tools functions use a standard attribute and character to delete lines or screen areas. This attribute is described as CLEARA; the character as CLEARB. You can query both CLEARA and CLEARB with the corresponding functions. At the same time, certain preset values are in effect for CLEARA and CLEARB. The attribute "W/N" is the standard preset for CLEARA, while Chr(255) is the character used for CLEARB. If you use this character for CLEARB, it fills the background with the corresponding color for every deletion on every screen adapter.
Use the following functions to set standard values for CLEARA and CLEARB:
If you use the SETCLEARx() functions in conjunction with the corresponding parameters (Attribute or Character), the currently existing default value is replaced by a parameter.
Clipper Functions and Commands Which Delete
If you use the CA-Clipper Extended Drivers, Chr(255) is used instead of a space for all CA-Clipper functions and commands that delete the screen in one way or another (see CLEARB). A Chr(255) is helpful on many screen adapters, since in contrast to a space, you can assign it a color. Then, the screen will not appear so fuzzy.
More precisely, the functions and commands concerned always use the delete character set by SetClearB(), which uses Chr(255) as the default setting. If you want to use a space to clear in CA-Clipper or CA-Clipper Tools, insert a SetClearB(32) into the program.
Re-implement a space for clear:
SetClearB(32) CLEAR // The affected Clipper command
Video Modes
Occasionally, there is some confusion about video modes. You will not be able to work in EGA mode just because your computer has an EGA adapter built into it. By the same token, you will not get either EGA or VGA modes, if you do not work with graphics.
EGA43 / VGA50 / VGA28, etc.
In this section, the concern is not to just get a mode "hardwired"' into a card, but for CA-Clipper Tools it is to generate corresponding fonts and other settings. For these reasons, the GETMODE() and GETSCRMODE() functions generate their own values that are greater than 255.
For example, changes to the screen mode concerned with line count can be combined with a 40-column mode:
You cannot implement functions that change the base address for screen memory while windows are open. This includes all mode changes, as well as SETPAGE and SETSCRSTR.
This chapter combines functions that deal with server volumes and files on server volumes. The NNETVOLXXX() functions return information about server volumes. The functions, NNETDIRS() and NNETFILES(), allow you to determine extended directory information (analogous to the Novell utility NDIR). The chapter also includes functions used to query and set rights, extended file attributes, and functions that can perform the tasks of the Novell utilities PURGE and SALVAGE. The operation of the functions NNETPURGE() and NNETSALVAG() depends on the Netware version.
It is hard to imagine using CA-Clipper without using windows. Windows are the best way to show multiple tasks so you can get a genuine overview of the system operation. The functions in this chapter offer a particularly valuable extension to CA-Clipper in this area.
b>The Window System
If you are only working with one screen, the CA-Clipper Tools functions permit up to 255 windows, depending on available memory. In conjunction with the MONISWITCH() function from the Video Function chapter, CA-Clipper Tools can even support two screens linked to a single CPU, with one monochrome screen and one color screen. In this way two entirely independent window systems, each with 255 windows, are available.
The window functions take into account the fact that CA-Clipper Tools supports larger screens than the common 25 rows x 80 columns. A screen, and therefore also a window, can be up to 255 rows or 255 columns in size. However, the complete contents of a screen can never require more than 32 KB of memory. So with 255 rows, no more than 128 columns are possible.
b>Moving Interactively
As soon as SCROLL LOCK is activated, the active window can be moved with different cursor keys. Depending on how you open them, windows can even overlap. The gray Plus key in the numeric key pad works like the function WCenter(). You use the Plus key to move a partially visible window back into a completely visible area. All window movements done after you activate SCROLL LOCK can be undone using the ESC key.
b>Programming with Window Functions
■ Each window is assigned a number between 1 and 255 when it is
opened. This number is known as the window handle. Handle 0 is the original screen, with no open windows. The window handle returned will be used to refer to that window during programming. (For example, you need the window handle when you select a background window.)
WMode(.T., .T., .T., .T.) // Overlap permitted
nWindow1 := WOpen(....) nWindow2 := WOpen(....) // This is the active window
WSelect(nWindow1) // Activate first window
■ The coordinates used for screen output are relative only to
the selected window, and not the entire screen.
nWindow1 := WOpen(....) // Selected window
@ 02, 02 SAY "CA-Clipper Tools"
■ Since a window behaves exactly as the normal screen would,
QOut() style output (?, ??, etc.) will be scrolled up as soon as it reaches the bottom row.
■ The window in the following example, which extends to row 24,
will not overwrite the help message on row 25:
@ 24, 00 SAY "........ HELP-ROW........" nWindow1 := WOpen(0, 0, 23, 79) // Protects the last row FOR nI = 1 TO 100
? "CA-Clipper Tools ...."
NEXT nI
■ A window displays as a full value, but is a virtual screen,
which differs from the original physical screen only in size. Extended drivers make the MaxRow() and MaxCol() functions available in a version enhanced over and above CA-Clipper to accommodate the changed size. Now the coordinates of virtual screens can also be determined; these functions return the last row or column concerned with the currently selected window:
■ The underlying screen area is saved automatically when a new
window is opened. This applies equally to any area of the screen that becomes overlapped by the movement of a window. At the same time, all settings in the areas that have been overwritten are saved. These settings include cursor shape and position, as well as color attributes. So you do not have to save anything out of the affected screen area; CA-Clipper Tools takes over this task automatically.
■ The following example shows you how the window functions save
both the color and cursor setting:
SET COLOR TO R // Set color RED ? "Test-Text 1 ..." // Output in RED nWindow1 := WOpen(10, 10, 20, 55) WBox() // RED window border
SET COLOR TO BG // Set color CYAN ? "Test-Text 2 ..." // Output in CYAN Inkey(0) // Wait for keystroke
WFCLOSE() // Close window again
? "Test-Text 3 ..." // Output again in RED
// and directly below "Text 1"
b>Active Windows
After you close a window, the active window with the highest handle is the one selected, not the window that was previously active. If, for example, the highest window handle is 9 and window 5 was just selected, a newly opened window is assigned handle 10. However, after you close this window number 10, window 9 is selected. It is therefore important to save the window's handle to a variable when you open it, so that you can select the required window later.
You can save the active window handle by calling WSelect() with no parameters.
■ The external output of programs called with RUN within a
CA-Clipper program can be tied to windows:
DSETWINDOW(.T.) nWindow1 := WOpen(10, 10, 22, 70) RUN DIR // Display results in window
The only prerequisite is that such output is through DOS or BIOS. The DSETWINDOW() function controls whether or not this output is subsequently redirected. The Extended Driver chapter has more details.
In addition to the examples shown here there are many more window functions available for use that contribute to a comprehensive windows system.
cString [@] Designates the character string that is processed.
nValue Designates the value that is added to the ASCII value of the character.
nPosition Designates the position of the character to which the nValue is added. The default value tells CA-Clipper Tools to add to the ASCII value of the last character.
Returns
AddAscii() returns the modified character string.
Description
This function is very useful when you call procedures using macros. When you use AddAscii(), the string representing the macro can be changed without needing to include functions like Left(), Right(), Asc(), or SubStr() (see example).
This function also allows you to subtract a value. However, a conversion is necessary. If a lower case letter is converted into an upper case letter, a value of 32 must be subtracted. This occurs according to the following formula:
Chr((Asc(Character) + 256 - Difference) % 256)
Notes
■ If the nPosition is greater than the length of cString or
less than 0, the string remains unchanged.
■ Zero changes the value of the last character.
■ CSetRef() can be used to suppress the returned value for this
function in order to save space in working memory.
Examples
■ A value of 1 is added to the next to the last position in a
string and to the last position in a string (Chr(Asc("2")+1) yields
"3" etc.):
? AddAscii("macro21", 1, 6) // "macro31"
? AddAscii("macro21", 1) // "macro22"
■ You can also subtract; -- 32 is the difference between lower
case and upper case letters, therefore Chr((Asc("m")+256-32) %256):
? AddAscii("macro21", 224, 1) // "Macro21"
If CA-Clipper Tools functions that change interrupts are not properly uninstalled or if the Extended Driver is not implemented, you could use the INTSAVE.EXE and INTOFF.EXE programs as additional security.
INTSAVE
Drive:INTSAVE[/S|/R[FileName]]RETURN
INTSAVE saves all 256 interrupt vectors to a file called INSAVE.TAB. Alternatively, a different filename can be selected, if multiple applications need to access the same path in a network. A call with the /S switch saves the interrupt vectors,while a call with /R restores them.
If the program is called without parameters, it explains its operation on the screen and, if required, displays a list of interrupt vectors that have been changed.
INTOFF
Drive:INTOFF RETURN
This program represents an "emergency brake". It sets the vectors described below to an IRET in the system ROM, so that there is no danger of a system crash as a result of erroneous interrupt vectors. The mouse interrupt (033h) is also newly initialized and the timer tic rate is reset. Memory resident programs are uncoupled from their interrupt vectors as well and are thereby rendered unusable. The program sets the following interrupt vectors to harmless IRETs:
Operation Vector Use in CA-Clipper Tools
IRET Timer 1C KeySec(), SHOWIME()
Alarm 4A KeyTime()
COM1 0C V24 Functions
COM2 0B V24 Functions
INIT Mouse 33 If foreign routines linked in
Timerspeed SETTIC()
Both programs could be linked into a batch job which starts your CA-Clipper application. This would look as follows:
dDate Designates the date to which the nMonth months is added. The default is the system date.
nMonth Designates the number of months to add to dDate.
Returns
AddMonth() returns the new date after nMonth is added to dDate.
Description
Use this function to calculate payment due dates based on an invoice date and for similar applications. It permits you to add months to a given date. If you use a negative number, months are subtracted.
Notes
■ An empty date parameter will result in an empty date.
Examples
Show today's date, plus 36 months:
? "The payment period ends on: ", AddMonth(36)
cSearchFor Designates the string for which the function searches.
cString Designates the string to search.
nCounter Designates which occurrence of cSearchFor within cString is found. The default value specifies the last occurrence in the search expression.
nIgnore Designates the number of characters that are eliminated from the search. The default value ignores none (0).
Returns
AfterAtNum() returns the remainder of the cString string from the first character after the nth (nCounter) occurrence of cSearchFor. If the last character in the sequence located is also the last character in the string being searched, then a null string is returned.
Description
This function finds the nth (nCounter) occurrence of cSearchFor within cString and returns the remainder of the string from the first position behind the located sequence.
In order to determine the nth (nCounter) occurrence of cSearchFor, AfterAtNum() searches from the left for each instance of this sequence. If CSetAtMupa() is off, then the search is continued after the last character of the sequence most recently found. Otherwise the search is continued after the first character of the sequence most recently found.
Notes
■ Implementing SetAtLike() allows you to use wild card
characters within cSearchFor.
Examples
■ Search a string for the last appearance of "aa" in two
different ways:
CSetAtMupa(.T.)
? AfterAtNum("aa", "aBaaBaaX") // "X"
CSetAtMupa(.F.)
? AfterAtNum("aa", "aBaaBaaX") // "aX"
■ Search a string for the third existing "xx" within the string,
where the first four characters are ignored! Notice the differing
results, depending on the multi-pass mode!
String := " AxxBBBBxxCCCCxxxDxxEExx"
CSetAtMupa(.T.)
? AfterAtNum("xx", String, 3, 4) // "DxxEExx"
CSetAtMupa(.F.)
? AfterAtNum("xx", String, 3, 4) // "EExx"
■ Examples for SetAtLike() can be found under the corresponding
function description.
AlloFree([<lMode>]) → nFreeMemory
* This has been retained in CA-Clipper for compatibility purposes.
Use the CA-Clipper Memory() function to develop future
applications.
Arguments
lMode If passed as .T., the total available memory size is returned. The default value is the largest contiguous block (.F.).
Returns
AlloFree() returns the maximum possible size for a contiguous memory block or the total amount of free memory available.
Description
Use this function to help avoid "memory fault" error messages. You can implement it in conjunction with other functions that use a string area as a buffer (as when you read files).
Notes
■ If there is not enough room on the stack, AlloFree(.T.)
returns a value of -1.
Examples
■ This is what can happen if you try to print a maximum-length
string without enough free memory:
Var := Space(65520)
■ Make a string of the maximum-length possible:
Var := Space(AlloFree()) // Under no circumstances
// call with .T.!
? Len(Var) // How long has it become?
■ Read in a file...
FileStr("Bigfile", AlloFree()) // The largest possible buffer
■ Entire available memory:
? AlloFree(.T.) // Available memory
Finds the sum of the ASCII values of all the characters of a string
Syntax
AsciiSum(<cString>) → nASCIISum
Arguments
cString Designates the character string for which the sum of all the ASCII values is computed.
Returns
AsciiSum() returns a number that corresponds to the sum of the ASCII codes of all the characters in cString.
Description
AsciiSum() allows you to form simple checksums for character strings. For example, this can be implemented during remote data transmission to identify transmission errors.
Notes
■ This function does not take character position into account,
so it cannot determine a character transposition. The Checksum() function should be used to determine character transposition.
cSearchFor Designates the character string for which the function searches, or the character string that provides the reference point for adjustment.
cString Designates the character string within which the adjustment occurs.
nTargetPosition Designates from which position within the character string the search expression is adjusted.
nCounter Designates which occurrence of the Searchexpression is taken into account. The default value is for the last occurrence.
nIgnore Designates the number of characters at the beginning of the search string that are removed. The default value is none.
nCharacter|cCharacter Designates a character, as necessary, to carry out the adjustment. It can be an individual character or an ASCII value between 0 and 255. The default value is a space Chr(32).
Returns
AtAdjust() returns the modified character string.
Description
The function first looks for the cSearchFor parameter within the character string. From this point, the rest of the cString is moved (adjusted) by either inserting or removing blanks until the nTargetPosition is reached. In lieu of blanks, nCharacter| cCharacter can be used as a fill character.
Additionally you can specify that the nth occurrence of cSearchFor be used and whether or not a specific number of characters at the beginning of the search string is eliminated.
Notes
■ Using CSetAtMupa() can influence how the search is performed.
Using SetAtLike() permits the use of wild cards within the search sequence.
Examples
■ Align comments at column 60. The search is for the first
occurrence of "//". Since there is usually at least one space before
each "//", search for " //":
? AtAdjust(" //", Line, 60, 1)
■ Move the extensions for the following list of file names to
position 10 and eliminate the ".":
WINDOW.DBF
PLZ.DBF
BACK.DBF
HELP.DBF
LOG.DBF
CharRem(".", AtAdjust(".", File, 10))
WINDOW DBF
PLZ DBF
BACK DBF
HELP DBF
LOG DBF
■ Use AtAdjust() with CSetAtMupa(). There is always a problem
determining whether "AA" occurs twice or three times in "AAA".
Depending on CSetAtMupa(), the function searches behind the last
character, or starts from the last character of a located sequence:
CSetAtMupa(.F.)
? AtAdjust("AA", "123AAABBB", 7, 2) // Sequence not found
CSetAtMupa(.T.)
? AtAdjust("AA", "123AAABBB", 7, 2) // "123A AABBB"
Atn2() returns the angle sine in radians, where the sine and the cosine of a given point have been specified. The function returns results for all four quadrants and corresponds to a call of Atan(x/y). One advantage of the Atn2() function is that no "divide by zero" error can occur. The returned value is in the range of -pi to +pi.
Notes
■ The SetPrec() function can influence the precision of the
result.
Examples
■ Compute the sine and cosine of 30 degrees. DToR() is then
used to convert these into the radian value:
SET DECIMALS TO 4
X := Sin(DToR(30))
Y := Cos(DToR(30))
■ Use RToD() to compute the result in degrees:
? RToD(Atn2(x, y)) // 30.0000
cSearchFor Designates the expression for which the function searches.
cString Designates the character string to search.
nCounter Designates which occurrence of cSearchFor within cString is determined. The default value is for the last occurrence of the search expression.
nIgnore Designates the number of characters that should be excluded from the search. The default value is none (0).
Returns
The function returns the position where cSearchFor begins. If no corresponding position can be determined, the function returns 0.
Description
AtNum() determines the initial position of the nth (nCounter) occurrence of cSearchFor within the cString. Additionally, the function takes into account the CSetAtMupa() setting, which causes differing results.
AtNum() searches from the left in order to determine the nth (nCounter) occurrence of the cSearchFor. If CSetAtMupa() is off, the search continues after the last character of the sequence most recently located. However, if the CSetAtMupa() is on, the search always continues after the first character in the most recently located sequence.
If the nIgnore parameter is not specified, the function initiates the search with the first character of cString. If the nIgnore parameter is specified, nIgnore characters are ignored from the start of the string and are excluded from the search.
Notes
■ If no value is specified for nCounter, the function
determines the last occurrence of the cSearchFor sequence.
■ When you implement SetAtLike(), wildcard characters can be
used within the search expression.
Examples
■ Search for the last occurrence:
? AtNum("bc", "abcdeabc") // Result: 7
■ Search for the first occurrence:
? AtNum("bc", "abcdeabc", 1) // Result: 2
■ Search for the first occurrence, excluding the first three
characters:
? AtNum("bc", "abcdeabc", 1, 3) // Result: 7
■ Determine the impact of CSetAtMupa() on a search for the last
occurrence of "aa" in "aaa":
CSetAtMupa(.F.) // Off
? AtNum("aa", "aaa") // Result: 1
CSetAtMupa(.T.) // On
? AtNum("aa", "aaa") // Result: 2
cSearchFor Designates the expression for which the function searches.
cString [@] Designates the character string that is searched.
cReplace Designates the character string that is exchanged for the sequence in cString.
nCounter Designates which or how many occurrences of cSearchFor within cString are replaced by cReplace. The default value is for the last occurrence of the search expression.
lMode Designates if only the nth (nCounter) sequence is replaced (.T.), or if all sequences up to the nth (nCounter) are replaced (.F.). The default value (.F.) designates that all sequences are replaced.
Returns
The function returns a character string in which one or many of the cSearchFor sequences have been replaced by cReplace.
Description
AtRepl() allows you to replace one or more sequences within cString. cReplace can be shorter or longer than cSearchFor.
nCounter specifies that the function searches for the nth occurrence of the sequence. If no value is specified, then the last occurrence is used. All occurrences of cSearchFor, up to and including the one sought, are replaced unless nCounter is assigned a value greater than 0 and lMode is designated .T..
The CSetAtMupa() setting is only checked when the length of cReplace is shorter than or equal to that of cSearchFor, yielding different results. Beginning on the left, the character string is searched for each occurrence of the cSearchFor sequence. If CSetAtMupa() is off (.F.), then the search continues after the last character of the replaced sequence. However, if CSetAtMupa() is on, the search always continues from the first character of the replaced sequence.
Notes
■ By implementing SetAtLike() you can use wildcard characters
within the search sequence.
■ cString can be passed by reference. If this is the case,
then both cSearchFor and cReplace must be the same length.
■ If cSearchFor and cReplace are identical, the function
terminates immediately. Such an exchange makes no sense, and if CSetAtMupa() is (.T.), the exchange results in an endless loop.
Examples
■ Exchange all "123" with "ab":
? AtRepl("123", "123_123_123", "ab") // "ab_ab_ab"
■ Replace "789" with a longer string "abcd" (ignore multi-pass):
? AtRepl("789", "789_789", "abcd") // "abcd_abcd"
■ Exchange all "123" with "ab", up to and including the second
occurrence:
? AtRepl("123", "123_123_123", "ab", 2) // "ab_ab_123"
■ Exchange only the second occurrence of "123" with "ab":
? AtRepl("123", "123_123_123", "ab", 2, .T.) // "123_ab_123"
■ Exchange all "aa" for "a" and the change the influence of
CSetAtMupa():
CSetAtMupa(.F.)
? AtRepl("aa", "aaaa", "a") // "aa"
CSetAtMupa(.T.)
? AtRepl("aa", "aaaa", "a") // "a"
■ Exchange "abc" with "ab", with and without multi-pass:
CSetAtMupa(.F.)
? AtRepl("abc", "123abcc456", "ab") // "123abc456"
CSetAtMupa(.T.)
? AtRepl("abc", "123abcc456", "ab") // "123ab456"
cString Designates the character string that is passed.
cDelimiter Designates the delimiter list used to identify the tokens.
nCounter Designates which token's position is determined. The default value is for the last token located.
Returns
AtToken() returns the beginning position of the nth (nCounter) token within the cString.
Description
AtToken() allows you to determine the beginning position of a token in cString. This value can be extremely helpful when you work with other string functions. The function uses the following list of delimiters as a standard:
CHR 32, 0, 9, 10, 13, 26, 32, 138, 141
and the characters ,.;:!?/<<>>()^#&%+-*
This list can also be replaced with your own list of separators, cDelimiter. Here are some examples of useful delimiters:
Table 4-1: Recommended Delimiter Sequences
Description <cDelimiter>
Pages Chr(12)(Form Feed)
Sentences ".!?"
File names ":\."
Numerical strings ",."
Date strings "/."
Time strings ":."
Examples
■ Find the beginning position of the last token:
? AtToken("Good Day") // 6
■ Find the beginning position of the fourth token:
? AtToken("What a beautiful day.", 4) // 18
■ Attempt to determine the beginning position of an unavailable
token:
? AtToken("What a beautiful day.", 6) // 0
cSearchFor Designates the string for which the function searches.
cString Designates the string that is searched.
nCounter Designates which occurrence of the cSearchFor within the cString is determined. The default value is for the last occurrence in the search expression.
nIgnore Designates the nuber of characters that are eliminated from the search. The default value ignores none (0).
Returns
The function returns all the characters in cString in front of the sequence determined. If no corresponding sequence is found, then a null string is returned.
Description
This function determines the beginning position of the nth (nCounter) occurrence of cSearchFor within cString and returns the string segment before this sequence. Additionally, the function takes into account the CSetAtMupa() setting, which can cause differing results.
In order to determine the nth (nCounter) occurrence of the cSearchFor, BeforAtNum() searches from the left for each instance of this sequence. If CSetAtMupa() is off, then the search continues after the last character of the sequence most recently found. If CSetAtMupa() is on, the search continues after the first character of the sequence most recently found.
Notes
■ Implementing SetAtLike() allows you to use wildcard characters
within the search sequence.
Examples
■ Search a string for the last appearance of a sequence:
? BeforAtNum("ab", "abcabdabe") // "abcabd"
■ Search a string for the first occurrence of a sequence:
? BeforAtNum("ab", "abcabdabe", 1) // ""
■ Search a string for the first occurrence of a sequence, where
the first three characters are not considered in the search:
? BeforAtNum("ab", "abcabdabe", 1, 3) // "abc"
■ Search a string for the third occurrence of "xx", where the
first four characters are not considered! Notice the different
results when you use the multi-pass mode:
String := "AxxBBBBxxCCCCxxxDxxEExx"
CSetAtMupa(.T.)
? BeforAtNum("xx", String, 3, 4) // "AxxBBBBxxCCCCx"
CSetAtMupa(.F.)
? BeforAtNum("xx", String, 3, 4) // "AxxBBBBxxCCCCxxxD"
nInteger Designates a number in the range of 0 to 65535, which corresponds to a bit pattern.
cBitpattern Designates a character string with a maximum of 16 characters. Each character corresponds to a bit in nInteger, where the last character corresponds to the lowest-value bit.
lMode When this optional parameter is designated as .T., 0 bits change to blanks. The default is no change.
Returns
The returned string contains the corresponding characters passed by the bit pattern.
Description
The BitToC() function changes the bits of a number into a sequence of corresponding characters. This facilitates work with such bit-coded information as file attributes. Depending on the lMode logical parameter (the l in lMode symbolizes logical), 0 bits either displays no character (.F.) or a blank (.T.).
Notes
■ If lMode is designated as .T., the string length that
results always corresponds to cBitpattern.
Examples
■ Change file attributes:
■ The number 2 corresponds to a binary "00000010":
? BitToC(2, "ADVSHR") // "H" as the next to
// last character
■ The number 5 corresponds to a binary "00000101":
? BitToC(5, "ADVSHR") // "SR"
■ The number 5, with the 0 bit displayed as a blank:
? BitToC(5, "ADVSHR", .T.) // " S R"
As a rule, all industry-standard PC's insert a generated date at a particular memory location in the BIOS. Based on this date, incompatibilities known to exist up to a particular release can be acknowledged. The function returns a date-type value and spares you an elaborate PEEK.
Notes
■ Although unlikely, you may not find a date at this BIOS
position. Therefore, you should test to see if a date is returned.
Examples
Is this an older computer?
IF BIOSDATE() < CToD("01/01/85")
? "Older version ...!"
ENDIF
expValue[@] Designates any valid expression; the type is not important.
lMode Designates whether or not the length of the expValue is to change in the event that expValue is a string. If .T. is designated, the length is retained. The default value is Change Length (.F.).
Returns
Blank() returns a blank value with the same data type as the expValue parameter.
Description
Blank() clears desired data fields with the variables. Blank() returns the following results:
Table 13-1: Data Type Blank Values
Argument Returned Value
Character string Null string or blank string
Numeric Value of 0
Logical .F.
Date A blank date
The default for lMode is .F. and produces a null string when a character string is input. However, if this parameter is designated as .T.., the string length is not changed.
Notes
■ SET DATE has no affect on how Blank() handles a date. The
blank date display is created in the format you select.
■ You can suppress the value this function returns by
manipulating strings through CSetRef() implementation. To save room in the working memory, designate lMode as .T..
dDate Designates a date for which the first day of the month that contains this date, is determined. The default is the system date.
Returns
BoM() returns the first day of the month in which dDate lies.
Description
BoM() allows you to determine the first day of the month that contains dDate. This allows you to determine how many days have past since the beginning of the month.
Notes
■ If no date is passed, then the function automatically uses the
system date. An empty date parameter always returns an empty date.
Examples
Display the elapsed days in the current month:
? Date() - BoM()
Determines the date for the beginning of a quarter
Syntax
BoQ([<dDate>]) → dBeginningOfQuarter
Arguments
dDate Designates a date for which the first day of the quarter in which it lies is determined. The default is the system date.
Returns
BoQ() returns the date at the beginning of the quarter that contains dDate.
Description
For example, use BoQ() to determine when the current quarter that contains dDate began, and then compute the number of days that have elapsed since the quarter began.
Notes
■ If you do not specify a date, the function automatically uses
the system date. An empty date parameter always returns an empty date.
Examples
Display the date of the first day of the current quarter:
? "The first day of the current quarter is:", BoQ()
BOOTCOLD() allows you to restart the system after a critical error (assuming anything is still working), or to allow any program changes you have made in CONFIG.SYS or AUTOEXEC.BAT to take effect. The function calls for a cold start. This means a RAM check and POST (power on self test) are carried out.
Notes
■ Close all files prior to a boot. You can use CLOSE DATABASES.
■ If there is a large system memory, a RAM check takes a long
time. To avoid this lengthy procedure, you might consider using the BOOTWARM() function for a restart after changing CONFIG.SYS.
Examples
An error in an error trap can no longer be changed:
CLOSE DATABASES
BOOTCOLD()
This function allows changes in CONFIG.SYS or AUTOEXEC.BAT to become effective. This function restarts the system just like BOOTCOLD(), but no RAM check or POST (power on self test) are carried out.
Notes
■ Close all files before you boot. You can use CLOSE DATABASES
to do this.
■ BOOTWARM() is the same as pressing the Ctrl-Alt-Del keys.
Examples
A new CONFIG.SYS is created within the program and the system reboots:
COPY TO CONFIG.SYS SDF
CLOSE DATABASES
BOOTWARM()
nComPort Designates the serial interface (1 to 4) where a break is set.
nDuration Designates the time in milliseconds that the break remains active. The default value is 100 milliseconds.
Returns
com_Break() returns .T. when the break has been successfully set.
Description
The output of a break means that the transmission line of an interface is held at a specific level for a fixed period of time. This time can be selected as a numeric parameter between 1 and 65535 milliseconds.
As a rule, a break is usually between 100 and 350 milliseconds long.
Examples
Output a 200 millisecond on interface COM1:
com_Break(1, 200)
Clears the receiving buffer and closes the com port
Syntax
com_Close(<nComPort>) → lClosed
Arguments
nComPort Designates which port is closed, COM1(1) to COM4(4).
Returns
A return of .T. indicates that the port is open and can be closed successfully.
Description
This function closes one of the ports (1 to 4). This means that the buffer is cleared, and all signals in the modem control register (MCR) are deactivated. Characters remaining in the buffer are lost. The DTR and RTS signals become inactive, and any existing modem connection is broken.
Notes
Warning! All characters in the buffer are cleared, and the status register is set to 0. Existing connections are always broken!
Examples
nCharacter := com_Count(1) // How many characters in
// the buffer ?
IF nCharacter > 0
* Read everything from buffer!
cContent := com_Read(1, nCharacter)
ENDIF
com_Close(1)
Counts the number of characters in the input buffer
Syntax
com_Count(<nComPort>) → nTotalCharacters
Arguments
nComPort Designates the port (1 to 4) for which the number of characters in the input buffer is determined.
Returns
com_Count() returns the number of characters in the selected buffer.
Description
This function allows you to determine the number of characters in one of the four possible buffers. This lets you determine how many characters can be read with the com_Read() function.
Notes
■ If an attempt is made to read the number of characters
available in a closed port, the function returns a value of -1.
Examples
nCharacter := com_Count(1) // Number of characters-port 1
IF nCharacter > 0
com_Read(1, 1) // Read 1 character
ENDIF
cString Designates the character string for which a CRC is computed.
nStart Designates a starting value that is added to the CRC. This value is computed in order to form a CRC for multiple character strings. The default value is 0.
nPolynomial Designates another polynomial. The maximum is a 17- bit polynomial. The default polynomial is CRC-16 X.25 (see below).
Returns
com_CRC() returns the 16-bit CRC for cString as a numeric value between 0 and 65535.
Description
CYCLIC REDUNDANCY CHECK Many file transfer protocols use CRC for accurate error recognition. This CRC function offers you decisive help when programming your own protocols, like XMODEM or KERMIT.
The specific CRC value always depends on the polynomial that you use. This information can be passed as an optional parameter in the form of an integer so that the function has almost universal utility. The CRC 16 X.25 polynomial used in X.25 systems,. XMODEM is the default value used in the examples below.
A few examples of polynomials:
Table 3-1: The Different Polynomials
Type Arguments Polynomial
Parity 3 2^1+1
LCR-8 257 2^8+1
CRC-12 5011 2^12+2^11+2^3+2^2 +2^1+1
CRC-16 X.25 69665 2^16+2^12+2^5+1
CRC-16 98309 2^16+2^15+2^2+1
Notes
■ If nStart is not passed, then the loss of the previous
Chr(0) out of cString is not detected by a later CRC review. This can be avoided if nStart is given a starting value that is not equal to 0.
■ A function called XMoBlock() is available for building XMODEM
blocks.
Examples
■ These are simple CRC calculations:
com_CRC("abc") // 40406
com_CRC("cba") // 54260
■ These are calculations for multiple strings:
nCRC1 := com_CRC("123")
nCRC2 := com_CRC("456", nCRC1)
? nCRC2 == com_CRC("123456") // .T., values are equal
■ Form a block for data transmission. The string is appended to
the data:
cData := "ABCDEFGHIJKLMNOP"
nCRC := com_CRC(cData)
cCRCSTR := I2Bin(CRC) // CRC as a string
cCRCSTR := CharSwap(cCRCSTR) // Exchange both bytes
cBlock := cData + cCRCSTR // Transmission block
■ The CRC must be 0 for the entire transmitted block!
? com_CRC(cBlock) = 0 // .T., when correctly
// transmitted
nComPort Designates the port (1 to 4) for which CTS is tested.
Returns
A return of .T. indicates that CTS is active (MSR Bit 5 = 1). A return of .F. indicates that CTS is inactive (MSR Bit 5 = 0).
Description
com_CTS() lets you check the Clear To Send (CTS) signal within a program. Whether CTS is used for a hardware handshake or for other purposes, depends on the external hardware that you use.
Notes
■ If Delta-CTS is required, you must use com_MSR().
Examples
DO WHILE .NOT. com_CTS(1) // Wait for CTS
* ...
ENDDO
com_Send(1, "Good Morning") // Transmit text
nComPort Designates the port (1 to 4) on which DCD is tested.
Returns
A return of .T. indicates that DCD is active (MSR Bit 8 = 1). A return of .F. indicates that DCD is inactive (MSR Bit 8 = 0).
Description
com_DCD() lets you check the Data Carrier Detect signal within a program. When you use a modem, DCD indicates that you have a remote connection.
Notes
■ If Delta-DCD is required, you must use com_MSR().
Examples
A connection is only established when a valid DCD signal has been
recognized:
? "Call recognized..."
DO WHILE .NOT. com_DCD(1) // Wait for carrier (DCD)
* ...
ENDDO
? "Carrier recognized - connection established ..."
cString Designates a string that is output through DOS.
nLine Designates the line number where the string is output. The default position is the cursor position.
nColumn Designates the column number where the string is output. The default position is the cursor position.
Returns
This function always returns a null string.
Description
com_DosCon() allows you to output a string through DOS. This function can be used to provide an interpretation of ANSI control sequences through ANSI.SYS. The installed status of the ANSI driver can be determined using the ISANSI() function.
In this way you can easily create a communications program with ANSI terminal emulation.
Notes
■ Notice that DSETWINDOW() should be switched off when using
this function. Otherwise the output is routed through the CA-Clipper driver module, and operates like a print (?) with a position instruction.
Examples
When ANSI.SYS is linked in, output is through DOS. This makes a simple
terminal emulation possible!
DSETWINDOW(.F.) // Important for ISANSI()
cData := com_Read(1) // Data read in
IF ISANSI() // ANSI driver present?
com_DosCon(cData)
ELSE
* Own ANSI handling
ENDIF
nComPort Designates the port (1 to 4) on which DSR is tested.
Returns
A return of .T. indicates that DSR is active (MSR Bit 6 = 1). A return of .F. indicates that DSR is inactive (MSR Bit 6 = 0).
Description
com_DSR() lets you check the Data Set Ready signal within a program.
Notes
■ If Delta-DSR is required, you must use com_MSR().
Examples
Many modems give an active DSR as soon as a connection is established:
DO WHILE .NOT. com_DSR(1) // Wait for DSR (Call)
* ...
ENDDO
? "Call recognized."
nComPort Designates the port (1 to 4) on which DSR is tested.
lNewDTRStatus Designates the status of DTR. .T. designates that the DTR signal is active, and .F. designates that the signal is inactive. If the parameter is not specified, CA-Clipper Tools does not affect the DTR exit signal.
Returns
The returned value corresponds to the DTR signal status prior to the new setting, or in the absence of lNewDTRStatus, the returned value corresponds to the current DTR. A return of .T. indicates that the DTR is active (MCR bit 1 = 1). A return of .F. indicates that the DTR is inactive (MCR bit 1 = 0).
Description
com_DTR() queries the DTR signal status. If the second parameter is not supplied, the DTR signal status does not change.
Notes
■ The com_Close() function resets DTR (to inactive). By
contrast, COM_OPEN does not automatically make DTR active!
Examples
A com_Open() does not set the DTR signal. You must specifically set the
DTR signal.
nBuff_size := 4000 // 4000 byte buffer
lComOk := com_Open(1, nBuff_size) // Open COM1
IF lComOk
com_DTR(1, .T.) // Activate DTR Port 1
* ...
ENDIF
nComPort Designates the port (1 to 4) where an external line termination character is established.
nErrorCharacter|cErrorCharacter Designates the individual error character, which can be given as a number or a character. When it is not specified, the port functions do not set any error character in the buffer.
Returns
com_ErrChr() returns .T. when the opened port is addressed.
Description
It is always possible that characters received during a file transmission from the port, UART, are recognized inaccurately. In such cases either an error procedure must be called (i.e. com_Key()) or the inaccurate character must be flagged. During remote transmission, a "trash" character is output. Chr(177) is the default "trash" character; however, you can use whatever error character you choose or you can suppress the output of a "trash" character entirely.
Notes
■ The Line Status Register (LSR) setting is used to determine
whether or not characters were inaccurately received.
Examples
■ Use Chr(250) as an error character for port 2:
? com_ErrChr(2, 250) // .T., when accepted
■ Switch off the use of an error character for port 4:
? com_ErrChr(4) // .T., when accepted
Designates which event at the port triggered a key trap
Syntax
com_Event(<nComPort>,<nMode>) → nCode
Arguments
nComPort Designates the port (1 to 4) that is tested for the event.
nMode Designates a numeric value between 1 and 5 (see table 3-2).
Returns
This function returns the code of an incoming character, MSR status, LSR status, or the number of errors that have occurred to date as a function of the nMode parameter value.
Description
As a rule, it is necessary to determine the cause of a trap if a character is placed in the keyboard buffer and the procedure specified with SET KEY TO is called. The numeric parameter determines what information is accessed. The information returned for modes 1 to 5 are defined as follows:
Table 3-2: Query Codes for Event Information
Code Event Information
1 The function will return the ASCII code of the incoming
character. If no character is available, a -1 is returned.
2 The function returns the status of the MS register at the time
of the interrupt.
3 The function returns the status of the LS register at the time
of the interrupt.
4 The value of the internal error counter will be returned. The
error events in the LSR since the last com_Init() will be
counted.
5 Returns the number of characters which had to be rejected
because the buffer was 100% full.
Notes
■ With the exception of the error counter, all status
information is reset when you open the port or when you call com_Key() again.
■ The conditions of MSR and LSR are considered at each interrupt
and are linked to the respective status byte in the internal environment through a logical OR operation. It is therefore possible to place multiple bits in one of the registers.
■ Overrun errors, parity errors, and frame errors (bits 1 to 3)
are counted as errors exclusively.
Important! The input lines on conventional PC interface cards are normally not terminated. This can lead to inexplicable results when you query the MSR.
Examples
Determine the number of errors that have occurred:
nErrorCnt := com_Event(1, 4)
IF nErrorCnt > 25
* more than 25 errors?
? "Too many errors - terminate program!"
lRelease := .T.
ENDIF
nComPort Designates the port (1 to 4) for which the receiving buffer is cleared.
Returns
If the receiving buffer can be cleared successfully, the function returns .T..
Description
This function allows you to flush all the characters in a receiving buffer. This makes it unnecessary to tediously determine how many characters are currently in the buffer in order to remove them with a read procedure.
com_Flush() guarantees a truly empty buffer. However, a new character can be received between the time that you call a com_Count() and a com_Read().
Notes
■ A com_Flush() on an unopened port is ineffective.
Examples
cHayes := "ATZ" // Hayes modem reset command
com_Send(1, cHayes) // Issue Hayes command
Inkey(1) // Wait one second
com_Flush(1) // Reject modem reply messages
nComPort Designates the port (1 to 4) to which the current I/O address is delivered.
Returns
com_GetIO() returns the I/O address of the designated port. With an invalid parameter or an unavailable port, the function returns a value of -1.
Description
com_GetIO() determines with which port I/O address CA-Clipper Tools functions communicate. This function only returns a value known to CA-Clipper Tools software. It cannot determine the I/O address of an interface card!
Examples
■ Determine the COM1 I/O address:
? com_GetIO(1) // 1016
■ Specify that you need the address in hexadecimal form:
? NToC(com_GetIO(1), 16) // "3F8"
■ Specify an invalid port number:
? com_GetIO(5) // -1
nComPort Designates the port (1 to 4) to which the IRQ currently in use is delivered.
Returns
com_GetIRQ() returns the IRQ currently in use for the designated port. When there are incorrect parameters, the function returns a value of -1.
Description
com_GetIRQ() determines which IRQ is served by the CA-Clipper Tools functions for a particular port. This value corresponds to an internal CA-Clipper Tools software setting. You cannot determine which IRQ is using a particular port.
Examples
■ Determine the interrupt request for IRQ to COM2:
? com_GetIRQ(2) // 3
■ Specify an inaccurate port number:
? com_GetIRQ(5) // -1
nComPort Designates the port (1 to 4) for which the hardware handshake is switched on or off.
lNewHandshake Designates whether the handshake is on (.T.) or off (.F.).
lDTR/DSR Designates whether the function uses the DTR/DSR handshake or the RTS/CTS handshake. When passed as .T., the function uses the DTR/DSR handshake instead of the RTS/CTS handshake.
Returns
When called only with nComPort, the com_Hard() returns .T. if the hardware handshake is on and .F. if the hardware handshake is off. When lNewHandshake is passed, the function returns the status prior to the new setting.
Description
The size of a receiving buffer is always limited. To avoid overflow, and thereby a loss of characters, software or hardware handshakes are usually implemented. During a hardware handshake, the port monitors the RTS signal. If you use this function to switch this handshake on, the signal is activated as soon as the buffer is 75% full. As soon as the buffer content is once again reduced to 50% or less, the port (the RTS signal) is once again released. Some printers use the port signals, DTR (output like RTS) and DSR (entry like CTS) instead of RTS/CTS, to avoid buffer overflow. In this case, lDTR/DSR can be passed with .T..
Notes
■ The hardware handshake only supports background transmission
(when com_Open() is implemented with the third parameter nBufferOut).
■ This function works for data input as well as output.
■ If you use a hardware handshake, then the RTS signal should no
Turn on the hardware handshake at a port:
com_Open(2, 1000, 1000) // Open COM2, background send
// buffer
com_Hard(2, .T.) // RTS/CTS Hardware handshake
// for port 2
nComPort Designates the port (1 to 4) that is initialized.
nBaudRate Designates the selected baud rate for the port. Settings of 300, 600, 1200, 2400, 4800, 9600 and 19200 baud are possible. The default value is 300 baud.
cParity Designates parity in the following form: (E)ven, (O)dd, (M)ark, (S)pace, or (N)one. The default value is (N)one.
nDataLength Designates the data length; seven or eight bits are possible. The default value is eight bits.
nStopBits Designates the number of stop bits, one or two. The default value is one stop bit.
Returns
If the com port is initialized successfully, the function returns .T..
Description
In order to use the serial port after you open it, four operating parameters must have been passed to this function. These operating parameters are the transmission speed (baud rate), the data length, the parity, and the number of stop bits. Today most bulletin boards use the configuration "300 - 9600 baud, 8N1". This configuration means eight data bits, no parity, and one stop bit. What is important is that all these parameters can be changed while the port is closed. Neither the data buffer or the modem status register (DTR, etc.) are affected.
Notes
■ The port must have been opened previously. It is impossible
to initialize a port prior to opening it.
■ If any or all of the four operating parameters are not
designated, or are designated incorrectly, the standard arguments of 300 baud, no parity, eight data bits, and one stop bit is used.
Examples
■ Open and initialize a port:
nBuff_size := 4000 // 4000 character buffer
lComOk := com_Open(1, nBuff_size) // Open port
IF lComOk
* The port is open, now it is to be initialized with 1200
* baud, no parity, eight data bits, and one stop bit.
lInitOk := com_Init(1, 1200, "N", 8, 1)
IF .NOT. lInitOk
? "Port cannot be initialized !"
ENDIF
ENDIF
■ You can also omit the last three parameters in the above
example because they correspond to the default settings:
lInitOk := com_Init(1, 1200) // Init. with 1200, N, 8, 1
nComPort Designates the port (1 to 4) where particular activities are monitored.
nKeyValue1 Designates the key code placed in the keyboard buffer in case an interrupt occurs. Values permitted with CA-Clipper's SET KEY TO command are allowed, as a numeric value or a character. If this parameter is not specified, then the port interrupts are not monitored.
nKeyValue2 Designates another key code that is placed in the keyboard buffer when the receiving buffer is 75% or more full. Values permitted with CA-Clipper's SET KEY TO command are allowed, as a numeric value or a character. If this parameter is not specified, the buffer overflow is not monitored.
Returns
com_Key() returns .T. when at least one trap is switched on and returns .F. when all monitoring is switched off.
Description
com_Key() allows you to monitor a port while the program is in a READ. In this way, various events at the port can cause a particular key code, selected by the programmer, to be placed in the keyboard buffer. This happens when:
■ Data arrives at the port.
■ A transmission error or a BREAK is recognized in the LSR.
■ One of the signals in the MSR changes.
■ The receiving buffer becomes 75% or more full.
The MSR and LSR status, the number of errors that have already occurred, and the receipt of individual characters can be monitored through the nKeyValue1 key code. All information is saved in an internal memory area and can be queried from there using the com_Event() function. This procedure is important because the register or the flags that release the interrupt, are automatically reset during read access. Otherwise, the information is lost.
If the nKeyValue2 parameter is specified, then one more procedure can be specified using the SET KEY TO command when the receiving buffer is 75% or more full. If the nKeyValue2 parameter is specified, the nKeyValue1 key code is no longer placed in the keyboard buffer when characters are received. However, you can still monitor the MSR and LSR.
Notes
■ The status of the various interface registers are connected to
the internal memory for as long as the event is "serviced" by a new com_Key() function call. This means that the modifications made during this period cannot be lost.
■ COM_KEY must be newly activated after every executed trap.
This deletes information concerning the internal environment.
■ When com_Key() places a character into the buffer because the
buffer is close to full, it does so independently of the com_Soft() or com_Hard() functions.
Examples
Chr(227) is placed in the keyboard buffer and calls the COMERRORS
procedure if an error is recognized at port 2 or if the modem status
signal changes. As soon as the buffer is 75% full or more, Chr(228) is
placed in the keyboard buffer. When Chr(228) is placed in the keyboard
buffer, the BUFFERFULL procedure is called:
#include ctcom.ch // Symbolic constants
// for interface
com_Open(2, 1000) // Open COM2
CON_INIT(2, 1200, "N", 8, 1) // Initialize COM2
SET KEY 227 TO ComErrors
SET KEY 228 TO BufferFull
com_Key(2, 227, 228) // Monitor COM2
cName := Space(20) // The port can arrange
PROCEDURE COMMERRORS(A, B, C)
nMSR_Status := com_Event(2, 2) // Read accumulated
// MSR data
nLSR_Status := com_Event(2, 2) // Read accumulated
// LSR data
com_Key(2, 227, 228) // Reactivate traps, reset
// internal values of COM_EVENT
IF IsBit(nMSR_Status, MSR_RI) // Ring bit set?
? "Call (ring) acknowledged!"
ELSE
IF ISBIR(nLSR_Status, nLSR_Break) // Break bit set?
? "Break acknowledged!"
ENDIF
ENDIF
RETURN
PROCEDURE BUFFERFULL(A, B, C)
* The input buffer must be read!
com_Key(2, 227, 228) // Traps activated here
cData := COM.READ(2) // Read all data
SELECT MESSDAT
REPLACE ComDat WITH cData // Save data
SKIP
SELECT INPUT
RETURN
nComPort Designates the port (1 to 4) for which the Modem Control Register (MCR) is read or set.
nMCR Designates a specified parameter between 0 and 255. If this parameter is not specified, then MCR is read only.
Returns
com_MCR() returns the contents of the Modem Control Register.
Description
The Modem Control Register can be read only and/or read and set. The second optional parameter determines if a new value is set. The bits have the following meaning:
Table 3-4: MC Register Coding
Bit Symb.Const. Definition
0 MCR_ERROR Parameter error
1 MCR_DTR Data terminal ready (DTR)
2 MCR_RTS Request to send (RTS)
4 MCR_OUT_1 OUT 1
8 MCR_OUT_2 OUT 2
16 MCR_LOOP LOOP
Notes
■ The OUT1, OUT2, and LOOP control bits can only be changed
using this function. Additional functions are available for DTR and RTS.
Examples
nStatus := com_MCR(1) // Port 1 MCR is read only
IF NumAnd(nStatus, 3) = 3
? "DTR and RTS are active!"
ENDIF
nComPort Designates the port (1 to 4) for which the Modem Status Register is read. COM1(1) to COM4(4) are possible.
Returns
com_MSR() returns a value between 0 and 255 that corresponds to the contents of the MSR.
Description
Not all the values for this status register can be determined from separate functions. For example, if you need Delta status information, you can use this function and test the corresponding bit. The individual bits are defined as follows:
Table 3-5: MC-Register Coding
Bit Symb. Const. Definition
0 MSR_ERROR Parameter error
1 MSR_DELTA_CTS DELTA ready to send (DCTS)
2 MSR_DELTA_DSR DELTA data terminal ready (DDSR)
4 MSR_TERI Trailing edge RING (TERI)
8 MSR_DELTA_DCD DELTA data carrier detected (DDCD)
16 MSR_CTS Clear to send (CTS)
32 MSR_DSR Data terminal ready (DSR)
64 MSR_RI RING indicator (RI)
128 MSR_DCD Data carrier detected (DCD)
Notes
■ The simultaneous testing of multiple bits in the MSR is fairly
simple when using a logical AND operation.
■ All delta bits in this register are reset using a read
Gives the number of the highest available serial interface port
Syntax
com_Num() → nMaxCom
Returns
com_Num() returns the number of the highest available serial interface port.
Description
This function returns the number of the serial interface port available. This is not to say that a return value of 3 necessarily means that ports 1 through 3 are available; for example, COM2 could be missing. Whether or not a serial port can actually be used can be tested using the com_Open() or com_Init() functions.
Normally the addresses described in the Introduction to this chapter are scanned for available ports. Scanning can happen over alternate addresses selected through com_SetIO().
Important! Four I/O addresses are assigned to ports COM1 - COM4, internal to the port functions. The com_Num() function goes through these four addresses and tests to see if a port is available there. This can lead to problems if some other hardware is installed in one of the address areas. For example, problems like this have been noted in conjunction with ArcNet network cards, which conflict in the address area with COM4. The critical address areas are listed in the table below.
Table 3-6: I/O Addresses for COM1-COM4
Port I/O Addresses
COM1 03F8h - 03FFh
COM2 02F8h - 02FFh
COM3 03E8h - 03EFh
COM4 02E8h - 02EFh
If any kind of hardware is found within this I/O address area, then the conflicting COM port can be masked. Additionally, using com_SetIO() (nComPort, 0) the accompanying base address within the internal table is deleted. You can only mask the conflicting port when com_Num() has not previously been called in the program. If com_Num() has been called in the program, the interface is marked "in use".
Examples
■ Determine the number of ports at the standard addresses:
? com_Num() // e.g. 4
■ Determine the number of ports at unusual addresses:
com_SetIO(3, "110") // COM3, 110h
com_SetIO(4, "120") // COM4, 120h
? com_Num()
com_Open(<nComPort>,<nBufferIn>,<nBufferOut>,
[<lTrapMode>]) → lStatus
Tip: The new optional parameter is an enhancement over previous
versions!
Arguments
nComPort Designates the number of the port (1 to 4).
nBufferIn Designates the size of the receiving buffer up to 64 kByte. The default value is 100 bytes.
nBufferOut Designates the size of the sending buffer for background transmission up to 64 kByte. The default specification is a no send buffer.
lTrapMode Designates when the port triggers an interrupt. When this parameter is .T., the port only triggers an interrupt while receiving data, and not as a result of transmission failure. The default value causes the port to trap all occurrences.
Returns
com_Open() returns .T. when the port has been successfully opened and you can select the buffer.
Description
This function allows you to open a serial interface port from COM1 to COM4. These ports have particular I/O addresses. For example, CA-Clipper Tools uses 3F8H as a base address for COM1. DOS or BIOS routines are not even involved; I/O addresses are not read from the BIOS data area. The default values described in the Introduction to this chapter are applied, or the values are set using com_SetIO(). The availability of a port is tested for these addresses before the port is opened.
Receiving Data A buffer of up to 64 kByte can be reserved for each com port. All arriving characters are saved here, even when the CA-Clipper program is active elsewhere with another process. The number of characters in the buffer can be checked and partially read.
Sending Data You can also reserve a sending buffer. If you reserve a sending buffer, com_Send() controls the interrupt function for data transmission, which means that the interrupt occurs in the background. Several functions are available to control the send buffer.
Interrupts during Transmission Errors If lTrapMode is specified as .T., the UART port only triggers an interrupt when there is data incoming or interrupt driven data being sent. Events connected with the MSR or the LSR are no longer taken into account. This affects the status signal and particularly affects transmission errors.
This capability was added as the result of research that indicated that some adapter ports seemed to trigger interrupts for no reason. These interrupts are caused by "trash" on the lines; as a rule, serial port incoming lines were not terminated (electronically closed). Overflowing interrupts can disturb program execution and lead to significant loss of performance.
Notes
Important! In contrast to other programming languages, like Basic, com_Open() and com_Init() do not affect any control signals. If you want to address a modem at the serial interface through CA-Clipper, you must set the DTR and every other signal using the correct CA-Clipper Tools functions.
■ Buffer size can be between 100 bytes and 64 kByte. Settings
too large or too small are corrected, increased or decreased, accordingly.
■ To ensure compatibility with earlier versions of CA-Clipper
Tools, the nComPort, nBufferIn, and lTrapMode parameters can be used without nBufferOut (see the example).
Examples
■ Open a port with monitoring:
IF com_Num() > 0
nBuffSize := 4000 // 4000 byte buffer
ComOk := com_Open(1, nBuffSize) // Open COM1
IF .NOT. ComOk
? "Port cannot be opened !"
ENDIF
ENDIF
■ Open COM3 with the corresponding send and receive buffer:
? com_Open(3, 1000, 1000) // .T. when successful
■ Trigger interrupts for incoming data only, not for
transmission failure (receiving buffer 1000 characters, normal
transmission):
? com_Open(3, 1000, .T.) // .T. when successful
nComPort Designates the port (1 to 4) that is read.
nLength Designates the number of the characters in the buffer that are read. The default value reads all characters.
lNoDelete Designates whether or not characters are removed from the buffer as they are read. The default setting removes all characters from the buffer as they are read. However, if the parameter is .T., the characters remain in the buffer as long as it is not full.
Returns
The returned string contains the corresponding characters from the receiving buffer.
Description
All characters arriving at the serial port are stored in the appropriate buffer under interrupt control. It is possible to determine the number of characters in the buffer and to read one, several, or all of the characters. If the nLength parameter is not specified, then all the characters in the buffer are read.
Notes
■ Remember that you can receive additional characters between
Wait until at least 10 characters have been received:
DO WHILE com_Count(1) < 10 // Wait until 10
// characters in buffer
*...
ENDDO
cInput := com_Read(1, 10) // Read in 10 characters
? cInput // Display characters
// that are read
nComPort Designates the port (1 to 4) where an external line termination character is established.
nCharacter|cCharacter Designates a line termination character, which could be a numeric value or a character. When it is not specified, the existing line termination character (if any) is canceled. The default character is the no line termination character.
Returns
com_Remote() returns .F. if the specified port is invalid.
Description
When longer text is sent, the receiver should be able to break off the transmission session or to delete the sending buffer. To do this, a character can be defined as an external line termination character. If this character is received, it deletes the background buffer of the sending station, as if you had called com_SFlush(). The sending CA-Clipper program no longer concerns itself with this session.
com_SMode() can help you determine if the buffer of the remote station has been deleted.
Notes
■ Before a binary file transfer, an existing line termination
character should be canceled because the transmission could be terminated accidentally.
Examples
■ The remote station can terminate using Ctrl-X (Port 2):
com_Remote(2, 24)
com_Send(2, cLongText)
IF IsBit(com_SMode(2), 4)
? "Sending buffer is deleted automatically by remote station!"
ENDIF
■ Eliminate the external line termination character:
com_Remote(2)
nComPort Designates the port (1 to 4) on which the ring line is tested.
Returns
A return of .T. indicates that the ring line is active (MSR bit-7 = 1). A return of .F. indicates that the ring line is inactive (MSR bit-7 = 0).
Description
com_Ring() lets you check the ring line of a port from within a program.
Notes
■ When TERI (Trailing edge ring) is required, use the com_MSR()
function.
Examples
Modems generally show the ring signal of an incoming call. This does
not mean that a trouble free connection has been established.
DO WHILE .NOT. com_Ring(1) // Wait for call (RING)
* ...
ENDDO
? "Call detected..."
nComPort Designates the port (1 to 4) where the RTS signal is queried or changed.
lNewRTSStatus Designates the RTS signal status. When the parameter is .T., the function activates the RTS signal. When the parameter is .F., the function deactivates the RTS signal. If no parameter is specified, CA-Clipper Tools does not affect the current DTR output signal setting.
Returns
The returned status corresponds to the RTS signal status prior to the new setting.
A return of .T. indicates that the RTS signal is active (MCR Bit-2 = 1). A return of .F. indicates that the RTS signal is inactive (MCR Bit-2 = 0).
Description
com_RTS() queries or changes the status of the Request To Send signal (RTS). If lNewRTSStatus is not specified, the RTS status remains unchanged.
Notes
■ The com_Close() function resets (deactivates) the RTS signal.
The com_Open() function does not automatically activate it!
Examples
Set an individually programmable hardware handshake:
com_RTS(2, .T.) // Request to send a port 2
DO WHILE .NOT. com_CTS(2)
*...
ENDDO
com_Send(2, "The quick brown fox jumps over the lazy dog")
Counts the number of characters in the background sending buffer
Syntax
com_SCount(<nComPort>) → nLength
Arguments
nComPort Designates the port (1 to 4) for which the send buffer length is returned.
Returns
com_SCount() returns the number of characters in the sending buffer of the selected port.
Description
com_SCount() determines the number of characters in one of the four possible sending buffers. This is only possible when the com interface is interrupt controlled, meaning that data is sent in the background.
Notes
■ If you attempt to determine the character count in a port that
is not open, the function returns a value of -1.
Examples
nCharacter := com_SCount(1) // Number of characters
// in Port 1
com_Send(<nComPort>,<cString>) → nLength
Tip: An enhancement over previous versions is that there are no new
parameters!
Arguments
nComPort Designates the port (1 to 4) from which transmission occurs.
cString Designates the string that is transmitted by the selected port. If you only need to transmit a single character, then the second parameter can also be numeric and thereby pass the ASCII character code directly.
Returns
When transmission is successful, a 0 is returned. If transmission is not successful, the number of characters that have not been transmitted or could not be placed in the sending buffer is returned.
Description
com_Send() transmits one or more characters from one of four ports. This transmission can be interrupt driven (i.e. occurs in the background). The third parameter of com_Open() determines whether or not the transmission is direct or occurs in the background.
"Normal" Transmission During "normal" transmission, program execution can continue only when all of the characters have been sent to the port. A unique situation presents itself when the hardware handshake is activated. As soon as the receiving station deactivates the CTS signal from the sending station, any transmission is immediately stopped. To prevent the CA-Clipper program from hanging, com_Send() is terminated and a numeric value representing the number of characters not yet sent is returned. com_CTS() can determine if CTS input has been deactivated by the remote station. The software handshake is not supported in this mode!
Background Transmission The background mode supports software and hardware handshakes. The handshake automatically occurs in the background. Several new functions are available to help you maintain control of the transmission buffer in this situation. For example, com_SMode() allows you to determine if the buffer is waiting for an XON character to release the software handshake. Since this kind of wait can prove futile, you can use com_Flush() from within the program to empty the transmission buffer.
Notes
■ The handshake is only supported when the transmission buffer
is sending in the background. Use small packets during direct transmissions, and regularly query com_Soft_R().
■ Software and hardware handshakes are switched on using the
■ This is an example of "normal" transmission at port 1, with no
transmission buffer open:
com_Open(1, 1000) // Receiving buffer only
com_Hard(.T.) // Hardware handshake
ACCEPT "Please input name " TO cInput
nRest := com_Send(1, cInput) // 1st attempt to transmit
DO WHILE nRest > 0
cInput := Right(cInput, nRest) // Characters not yet sent
nRest := com_Send(1, cInput)
ENDDO
■ Here is an example for background or interrupt controlled
transmission at port 1. Everything else can proceed through "normal"
transmission:
com_Open(1, 1000, 1000) // 1000 byte transmission buffer
nRest := com_Send(1, "Attempt") // Place characters in buffer
nComPort Designates the port (1 to 4) for which a new I/O address is selected.
nIOPort|cIOPort Designates a valid I/O address for the selected port. The parameter can be a decimal or hexadecimal string. For information about the default value, see the Introduction this chapter.
Returns
com_SetIO() returns .T. if the new I/O address is successfully set.
Description
As is the case for other interface card settings, no true standard exists for I/O addresses. This is particularly true for the COM3 and COM4 ports. By using com_SetIO(), CA-Clipper Tools software can be adapted to the I/O addresses of the most eccentric interface card.
Notes
■ The function tests to see if there is a port available at the
selected I/O address. com_SetIO() returns .T. or .F. accordingly.
Examples
■ This is an example of a setting for port 2, with the I/O
address as a decimal:
com_SetIO(2, 504) // Address 1F8h
■ This is an example of a setting for port 4, with the I/O
address as a hexadecimal:
com_SetIO(4, "1F8") // .T.
■ This is an example of an invalid I/O address; the value
exceeds 1023:
com_SetIO(4, "10F8") // .F.
nComPort Designates the port (1 to 4) where the interrupt request (IRQ) is set.
nIRQ|cIRQ Designates the new IRQ number for the selected port. This parameter can be a decimal or a hexadecimal string and can be from 2 to 15.
Returns
The function returns .T. when the new IRQ has been successfully set.
Description
Unfortunately, there is not a binding standard for serial ports, particularly for COM3 and COM4.
Each interface card uses an interrupt request line to advise the interrupt controller that a character has been received. The controller then passes this information on to the CPU, which calls a service routine through the corresponding interrupt vector. XT systems have eight such interrupt lines available. AT systems have more than 16 available interrupt lines, some of which are usually occupied with other peripherals. The allocation of a new IRQ is no small matter and requires considerable technical expertise. Determining which IRQ is available and is not currently in use can usually be done by studying the configuration of all external devices and the technical documentation that accompanies your computer system. Typically IRQ's 0 and 1 are used for internal purposes (timer), 2 and 9 for network adapters, 5 and 7 for the printer, and 6 and 14 for floppies or hard disks.
Tip: As you will notice from the default setting in the Introduction to this chapter, it is possible for multiple ports to use the same IRQ (interrupt sharing). While CA-Clipper Tools functions do support this process, standard port hardware usually does not. However, special multiple port cards for this purpose are offered by a variety of manufacturers.
Notes
■ Please notice that the base settings that CA-Clipper Tools
uses for COM1 to COM4 are described in the Introduction to this chapter.
■ com_SetIRQ() does not test to see if a port is actually
serving the selected IRQ.
Examples
■ Set COM3 and COM4 to IRQ 5. This example requires two calls:
? com_SetIRQ(3, 5) // .T.
? com_SetIRQ(4, 5) // .T.
■ Set port 4 to IRQ 10. IRQ in hex:
? com_SetIRQ(4, "A") // .T.
■ This is an example of an incorrect value for IRQ:
? com_SetIRQ(2, 0) // Timer tick not allowed .F.
? com_SetIRQ(3, "10") // This would be decimal 16 .F.
nComPort Designates the port (1 to 4) for which the sending buffer is deleted.
Returns
If the selected sending buffer is successfully deleted, the function returns a .T.
Description
com_SFlush() eliminates all the characters in a sending buffer. This can be useful when the send routine has been futilely waiting for an XON character (bad software handshake).
Notes
■ A com_SFlush() to a closed port does not work.
■ It is not necessary to test for characters in the sending
buffer to carry out a com_SFlush().
Examples
When the sending buffer is waiting for an XON character and the
transmission has been delayed 30 seconds, the sending buffer is deleted:
nStart := Seconds() // When sent
com_Send(2, cSendText)
IF IsBit(com_SMode(2), 2) // Waiting for XON?
IF Seconds() - nStart > 30 // 30 second delay ...
com_SFlush(2) // Delete sending buffer
ENDIF
ENDIF
nComPort Designates the port (1 to 4) that is monitored in the background during transmission.
nKeyValue1|cKeyValue1 Designates the key code placed in the keyboard buffer as soon as the port send buffer has been cleared. Like the values available in CA-Clipper's SET KEY TO command, the key value can be a numeric value or an individual character. When this parameter is not passed, the supervision of buffer overflow can be switched off.
nKeyValue2|cKeyValue2 Designates the key code that the function places in the keyboard buffer at the start of a software or hardware handshake. Like the values in CA-Clipper's SET KEY TO command, the key value can be a numeric value or an individual character. When this parameter is not passed, the supervision of buffer overflow can be switched off.
Returns
com_SKey() returns .T. when the selected character is placed in the keyboard buffer by the corresponding event.
Description
This function allows you to monitor a transmission in the background with regard to the hardware or software handshake and the contents of the buffers. If you have designated nKeyValue1, it is deposited in the keyboard buffer as soon as the sending buffer is empty.
If the software or hardware handshake has been implemented by com_Soft() or com_Hard(), then the COM interface program places nKeyValue2 in the keyboard buffer when an XOFF is encountered or the CTS input is deactivated. If you have passed nKeyValue1, it is deposited in the keyboard buffer as soon as the sending buffer is empty.
Both events can prove very effective when combined with a CA-Clipper key trap. In this way the program does not constantly have to review the status of the sending buffer; it simply "takes note" when something happens. The specific event is then determined with com_SMode() within the called procedure.
Notes
Important! After each execution of a trap, com_SKey() must be reactivated.
Examples
■ Determine if the port 2 buffer is empty:
com_SKey(2, , 225) // Place code 225
■ Monitor the software and hardware handshakes for port 2:
SET KEY 225 TO HANDSHAKE
? com_SKey(2, , 225) // OK when returns .T.
com_Soft(2, .T.) // Software handshake on
com_Hard(2, .T.) // Hardware handshake on
com_Send(2, LongText) // Transmit something...
■ It is important that you always send the parameter:
PROCEDURE HANDSHAKE(A, B, C)
* Your Program
com_SKey(2, 225) // Must be reactivated
RETURN
Determines the current status of a background transmission
Syntax
com_SMode(<nComPort>) → nSendMode
Arguments
nComPort Designates the port (1 to 4) for which the background transmission status is returned.
Returns
com_SMode() returns a number for which the bits represent various meanings shown in the table below.
Description
The ability to transmit in the background demands the ability to control the sending buffer. For example, com_SMode() allows you to check to see if the sending buffer is waiting for an XON character when the software handshake is enabled. The bits in the returned value represent the different modes:
Table 3-7: Coding the Sending Mode
Bit Symb. Const. Definition
1 SMODE_EMPTY Sending buffer empty
2 SMODE_SOFT Wait for software handshake release(XON)
4 SMODE_HARD Wait for hardware handshake release(CTS)
8 SMODE_RFLUSH Deleted from remote station
Notes
■ If no sending buffer has been set up for the designated port
using com_Open(), the function returns a value of 0.
Examples
■ Determine whether the port 2 sending buffer is empty:
IF IsBit(com_SMode(2), 1)
? "Port 2 sending buffer empty!"
ENDIF
■ Wait 20 seconds while the send buffer for port 2 is waiting
for an XON, then release:
WaitPeriod(2000)
DO WHILE IsBit(com_SMode(2), 2) .AND. WaitPeriod()
*...
ENDDO
■ Clear the send buffer when XON is not received:
IF IsBit(com_SMode(2), 2)
com_SFlush(2) // Clear send buffer port 2
ENDIF
Tests to see if an XOFF character has been received
Syntax
com_Soft_R(<nComPort>,[<lXOFFFlag>]) → lXOFFFlag
Arguments
nComPort Designates the port (1 to 4) for which the XOFF flag is tested.
lXOFFFlag Designates whether the flag is set (.T.) or reset (.F.). The default value (.F.) resets the flag.
Returns
This function returns .T. after the last inquiry or after you open the port when the port has received an XOFF character (Ctrl-S). Subsequently the port does not receive an XON character (Ctrl-Q).
Description
If the software handshake is turned on, the receipt of an XOFF character is noted with an internal flag. This flag can be queried using com_Soft_R(). The receipt of an XON character resets that flag again. Since in some situations an XON character is never transmitted by the remote station, the flag can be reset using the second parameter.
Notes
■ If incoming XOFF characters are monitored, then it is best to
transmit relatively small strings through com_Send(). You can use com_Soft_R() to monitor between incoming XOFF characters.
Examples
■ First open the port:
com_Open(1, 1000)
■ Transmit until an XOFF character is recognized:
nPos := 1
DO WHILE .NOT. com_Soft_R() .AND. nPos <= Len(cString)
com_Send(1, SubStr(cString, nPos, 1))
nPos := nPos + 1
ENDDO
Tests to see if the buffer has automatically sent an XOFF character
Syntax
com_Soft_S(<nComPort>) → lXOFFFlag
Arguments
nComPort Designates the port (1 to 4) for which the XOFF flag is tested.
Returns
This function returns .T. when the remote station indicates that the buffer is 75% or more full.
Description
If the software handshake has been selected and the buffer is more than 75% full, an XOFF character is automatically transmitted to the remote station. This is noted with an internal flag, which can be queried using com_Soft_S(). When the buffer empties to 50% or less, it generates the transmission of an XON character, and this flag is reset.
Notes
■ When selecting the size of the buffer, decide whether the
remaining 25% will be sufficient at high baud rates.
Examples
Test to see if a 75% full buffer automatically transmits an XOFF
character:
IF = com_Soft_S(1)
? "It's time to empty the buffer! "
...
ENDIF
nComPort Designates the port (1 to 4) for which the software handshake is set.
lNewHandshake Designates whether the handshake is on (.T.) or off (.F.). If this parameter is omitted, the function returns the current setting.
cXONchar Designates any character you choose as an XON character. The default character is ASCII 19 - Ctrl-S.
cXOFFchar Designates any character you choose as an XOFF character. The default value is ASCII 17 - Ctrl-Q.
Returns
The function returns the previously set value.
Description
With modem connections, a hardware handshake is impossible, which is why we are making a software handshake available with this function. When a buffer is 75% full, an XOFF character (Ctrl-Q) is transmitted to the remote station. As soon as the buffer has again been emptied to 50% or less, the XON character (Ctrl-S) is transmitted. You can use characters other than Ctrl-S or Ctrl-Q for individual protocols, which would then be taken into account in the situations described above.
Notes
■ The software handshake only supports background transmission
(when com_Open() has been implemented with the third parameter nBufferOut).
■ When you want to transmit binary data, the software handshake
cString Designates the character string that you choose to center.
nLength Designates the length of the line within which the cString sequence is centered.
cPadCharacter Designates the character with which the cString sequence is centered. The default character is a space.
lMode Designates whether only the beginning, or both sides of cString are padded. The default value (.F.) only fills the beginning.
Returns
The processed string is returned.
Description
The Center() function provides a simple way to center text in any line. Center() is able to pad only on the left or on the left and right using any selected character. Leading and trailing blanks (if any) are replaced with the new character.
When nLength is not specified, Center() assumes the maximum available line width to be MaxCol() + 1, so that the correct output appears in the windows. Additionally, the current cursor position or the column position selected through a SAY command is also noted. So, if there is an output on an 80-column line that begins at column 20, a section of 40 characters from column 20 is used to center the output.
Notes
■ If the sum of the pad characters is odd, then one more
character is inserted at the beginning of the character string.
Examples
■ Center the output with an available line length of 10, and
insert the leading characters:
? Center("xx", 10) // " xx"
■ Fill on the left and on the right:
? Center("xx", 10, .T.) // " xx "
■ When characters that match the <cPadCharacter> are present,
these characters are removed prior to centering:
? Center("xx ", 10, .T.) // " xx "
■ Fill with other characters:
? Center("xx", 10, ".") // "....xx"
? Center("xx", 10, ".", .T.) // "....xx...."
? Center("x", 10, ".", .T.) // ".....x...."
■ In the following example, the "X" is intended to represent a
40-character wide screen. The string "CLIPPER" is centered there
with the "." character, starting at position 10:
@@ 1, 10 SAY Center("CLIPPER", ".", .T.)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXX.......CLIPPER......XXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
lMonochromeMode Designates the 40ûcharacter mode. If this parameter is .T., the function switches to the monochrome CGA 40-character mode. If this parameter is.F., the function switches to the 40-character color mode. The default value is .F..
Returns
CGA40() returns .T. if the screen adapter you use permits a switch.
Description
This function can be used with any screen adapter that has CGA emulation capability. You can switch to CGA 40-character mode, color or monochrome. The function IsColor() also returns .T. in the monochrome mode because this option activates a "color summing" of the screen adapter and does not switch to the monochrome mode for a hercules adapter or a monochrome text adapter.
Notes
Important! This function cannot be implemented when windows are open.
■ Modes set through this function can also be combined with
lMonochromeMode Designates the 40ûcharacter mode. If this parameter is .T., the function switches to the monochrome CGA 80-character mode. If this parameter is .F., the function switches to the 80-character color mode. The default value is .F..
Returns
CGA80() returns .T. when the screen adapter you use permits a switch.
Description
This function can be used with any screen adapter that has CGA emulation capability. You can switch to CGA 80-character mode, color or monochrome. The function IsColor() also returns .T. in the monochrome mode because this option activates a "color summing" of the screen adapter and does not switch to the monochrome mode for a hercules adapter or a monochrome text adapter.
Notes
Important! This function cannot be implemented when windows are open.
■ A call with .T. corresponds to BIOS mode 2. A call with .F.
corresponds to BIOS mode 3.
Examples
■ Switch to 80-character mode (color):
? CGA80() // .T., if successful
■ Switch to 80-character mode (monochrome):
? CGA80(.T.) // .T., if successful
cString1 [@] Designates the character string to which values from a second character string cString2 are added.
cString2 Designates the character string that is added, character for character, to cString1.
Returns
The processed character string is returned.
Description
You can use CharAdd() to produce simple character string coding. The function can prove very useful when processes are coded by individual characters in a string.
Notes
■ When both character strings are the same length, then the
first byte of cString1 can be linked with the first byte of cString2, and the second byte of cString1 can be linked with the second byte of cString2, and so on. If cString2 is shorter than cString1, then as soon as the last byte of cString2 is reached, the process continues and starts again with the first byte of cString2. However, if cString1 is shorter than cString2, the process terminates with the end of cString1.
■ Values greater than 256 can result when adding values. The
new value is then formed based on the following formula:
(Asc(Character1) + Asc(Character2))% 256.
■ Implementing CSetRef() can suppress the return value for this
function to save room in working memory.
Examples
■ Add a value of 1 to each character:
? CharAdd("01234", Chr(1)) // "12345"
■ Adding a value of 255 to each character corresponds to
subtracting 1:
? CharAdd("12345", Chr(255)) // "01234"
Links corresponding ASCII codes of paired strings with an AND operation
Syntax
CharAnd(<cString1>,<cString2>) → cString
Arguments
cString1 [@] Designates the character string to which characters are added.
cString2 Designates the character string that contains the characters that are added to the characters in cString1.
Returns
The processed string is returned.
Description
CharAnd() can be used as a simple way to reset the high bit for all the characters in a string. The function joins (links bit by bit using an AND operation) each character in cString1 with the corresponding character in cString2.
Notes
■ When both character strings are the same length, then the
first byte of cString1 can be linked with the first byte of cString2, and the second byte of cString1 can be linked with the second byte of cString2, and so on. If cString2 is shorter than cString1, then as soon as the last byte of cString2 is reached, the process continues and starts again with the first byte of cString2. However, if cString1 is shorter than cString2, the process terminates with the end of cString1.
■ Implementing CSetRef() can suppress the return value for this
function to save room in working memory.
Examples
The second parameter is shorter than the first parameter in this
example. As a result, the "1", the "a", and the first blank are joined
with AND to the "1" in "123"; the "2", the "b", and the second blank are
joined with AND to the "2" in "123"; and the "3", the "c", and the third
blank are joined with AND to the "3" in "123":
? CharAnd("123abc ", "123") // "123!"# "
Returns characters in the even positions of a string
Syntax
CharEven(<cString>) → cString
Arguments
cString Designates the character string from which all even characters are returned.
Returns
CharEven() returns a string containing all the even characters of cString.
Description
CharEven() assembles all even characters within a string into a new character string. This allows you to process variables consisting of the characters and attributes of a video screen's contents very simply. This function can be implemented in conjunction with functions from the video section. You can return the attributes from a screen string, with all the characters removed.
Notes
■ The first position in a string is 1, and therefore is not
even.
Examples
■ Assemble all even characters:
? CharEven("1234a") // "24"
■ Return the expanded text to "normal":
? CharEven(" H e l l o") // "Hello"
CharList() returns a list in which each character in cString appears only once.
Description
CharList() determines the list of characters that appear in the cString. Each character only appears in the list once.
Notes
■ The CharList() function's return value is never longer than
256 characters.
■ If you sort this result with CharSort(), you have an ascending
list of characters.
Examples
■ What letters are contained in the text?
? CharList("Hello goodbye") // "Helo gdby"
■ Show a sorted list of all letters in a text:
? CharSort(CharList("Hello goodbye")) // "Hbdegloy"
cString [@] Designates the character string that is mirrored.
lBlank Designates whether the function mirrors everything (.F.) or does not mirror the blanks at the end of a character string (.T.). The default value is .F..
Returns
CharMirr() returns the processed cString.
Description
CharMirr() reverses a string. The function returns a palindrome of cString.
The optional logical parameter allows you to mirror a string and ignore the blanks. This permits you to build index entries that end with a particular sequence.
Notes
■ The returned value of this function can be suppressed by
implementing CSetRef() to save room in working memory.
Examples
■ This example shows a simple exchange:
? CharMirr("abc321") // Result: "123cba"
■ This example shows one of the best known palindromes:
? CharMirr("ABLE WAS I ERE I SAW ELBA")
■ When you index, you must do it without spaces because this is
the only way a reverse string can be searched for:
INDEX ON CharMirr(Field, .T.) TO Index
■ Search for all expressions in the mirrored index, ending in
"per":
SEEK "rep"
cString1 Designates a string that is mixed with cString2.
cString2 Designates a string that is mixed with cString1.
Returns
CharMix() returns a string that is double the length of cString1, assuming that cString2 contains at least one character.
Description
This function allows you to mix the characters from two character strings together. The characters from cString1 and cString2 appear alternately in the result string. The length of cString1 forms the basis for the maximum count of the resulting mix. A longer cString2 string is cut down to the length of cString1. A shorter cString2 is processed from beginning to end, wrapping to the beginning again until there are no more characters in cString1.
Notes
■ This function can be used to recombine strings extracted by
■ This is an example of a simple mix:
? CharMix("ABC", "123") // "A1B2C3"
■ This is a mix where the second string is shorter:
? CharMix("ABCDE", "12") // "A1B2C1D2E1"
■ This is a mix where the second string is longer:
? CharMix("AB", "12345") // "A1B2"
■ What you can do with this?
? CharMix("HELLO". " ") // "H E L L O"
■ If the second parameter is null, then the first parameter is
returned unchanged:
? CharMix("HELLO", "") // "HELLO"
Lists the characters that do not appear in a string
Syntax
CharNoList([<cString>]) → cNotContained
Arguments
cString Designates the string that is processed. The default value is for an empty string.
Returns
CharNoList() returns a character string that contains all characters not found in cString.
Description
This function determines all characters that are not contained in cString. The resulting characters might be used as replacement characters or for complex deletion procedures.
Examples
■ Delete all characters except "XYZ":
String := "ABXCDYEF"
? CharRem(CharNoList("XYZ"), String) // "XY"
■ Generate a list of all 256 ASCII characters:
? CharNoList()
■ To save text to a memo field, all null characters (Chr(0))
must be exchanged for a character that is not being used:
cNoList := CharNoList(cMemoText)
cNoChar := SubStr(cNoList, 1, 1)
CharRepl(Chr(0), @cMemoText, cNoChar)
cString [@] Designates the string that is negated.
Returns
The processed cString is returned.
Description
This function negates each bit in cString. This makes it possible to get a decreasing index sequence.
Notes
■ The returned value of this function can be suppressed by
implementing CSetRef() to save room in working memory.
Examples
When a character string that has already been negated is negated again,
the result is identical to the original:
CharNot("123ABCabc") // " ¥£ "
CharNot(" ¥£") // "123ABCabc"
Returns characters in the odd positions of a string
Syntax
CharOdd(<cString>) → cString
Arguments
cString Designates the character string from which all the odd characters are returned.
Returns
CharOdd() returns a character string that contains all the odd characters from cString.
Description
CharOdd() assembles all odd characters within a string into a new character string. This allows you to process variables where screen content, consisting of characters and attributes, is saved. This function can then be used in conjunction with functions from the video section.
Notes
■ The first position in a string is 1, and therefore is odd.
Examples
■ Assemble all odd characters:
? CharOdd("1234a") // "13a"
■ Return the expanded text to "normal":
? CharOdd("H e l l o ") // "Hello"
cDeleteCharacter Designates the characters that have their adjoining duplicates removed from cString. The default value removes all adjoining duplicate characters.
cString Designates the character string that is processed.
Returns
The processed cString is returned.
Description
CharOne() searches within the cString for repetitions of adjoining characters. When a character is removed, all of the characters but the first are deleted. This differs significantly from the CharList() function, where multiple occurrences of characters within the context of the string are removed.
Notes
■ Without the cDeleteCharacter parameter, all the repeating
characters are removed. If the parameter is specified, only those characters in cDeleteCharacter are removed.
Examples
■ Check for double occurrences of each character in the
character string:
? CharOne("122333a123") // "123a123"
? CharOne("A B CCCD") // "A B CD"
■ Delete multiple side-by-side blanks:
? CharOne(" ", "A B A B") // "A B A B"
■ Make the letter "o" only appear once in the character string:
? CharOne("o", "122oooB12o") // "122oB12"
Determines the common denominator between two strings on the basis of individual characters
Syntax
CharOnly(<cString1>,<cString2>) → cString
Arguments
cString1 Designates a sequence of characters that are not removed from cString2.
cString2 Designates the string that is processed.
Returns
CharOnly() returns the processed string cString2.
Description
CharOnly() removes all characters from cString2 that are not in cString1. The function is particularly useful when comparing data that should have a standard format but has been input by different people. This category can consist of things like telephone numbers, part numbers, customer numbers, etc. (see example).
Examples
Since numbers are the only characters that are relevant in a telephone
number, any characters that are not numbers are removed. The result in
each case is "2133907923":
? CharOnly("0123456789", "213 - 39 07 923")
? CharOnly("0123456789", "213 / 390 7923")
Joins the corresponding ASCII code of paired strings with an OR operation
Syntax
CharOr(<cString1>,<cString2>) → cString
Arguments
cString1 [@] Designates the string upon which the OR operation is performed.
cString2 Designates the characters that are used when performing the OR operation on cString1.
Returns
CharOr() returns the processed cString1.
Description
The function joins (links bit by bit using an OR operation) each character in cString1 with the corresponding characters in cString2. CharOr() can therefore place particular bits within the characters.
Notes
■ If both character strings are the same length, then the first
byte of cString1 is linked with the first byte of cString2, and the second byte of cString1 is linked with the second byte of cString2, etc.. If cString2 is shorter than cString1, then when the last byte of cString2 is reached, it continues with the first byte of cString2. However, if cString1 is shorter than cString2, the process terminates at the end of cString1.
■ The return value of this function can be suppressed by
implementing CSetRef() to save room in working memory.
Examples
■ Both bytes in the first parameters are joined with OR using
the "0" character. This means that Chr(1) is converted into the
ASCII character æ1", Chr(2) into the ASCII character "2", etc.:
? CharOr(Chr(1) + Chr(2), "0") // "12"
■ All bytes in the first parameters are joined (OR) with Chr(32)
(set bit 5 only):
? CharOr("123ABCC[\]abc", CHR (32)) // "123abc(|)abc"
cString Designates the character string that is packed.
nMethod Designates which pack algorithm is used on the designated character string. The default value is method 0.
Returns
CharPack() returns the compressed string.
Description
This function allows you to compress (pack) the contents of strings. The function supports two different pack methods:
Table 4-2: Pack Methods Supported
<nMethod> Pack Algorithm
0 Modified run length encoding
1 Bit oriented algorithm
Notes
Important! A packed string can contain Chr(0) or other control characters.
Examples
Using the bit pack method, compress a text from a DOS file:
Var := CharPack(FileStr("C:\TEXT\TEST.TXT"), 1)
StrFile(Var, "C:\TEXT\TEST.PAK") // New save
CharPix() returns a value that corresponds to the number of pixel lines per character.
Description
Different screen adapters build characters from a different numbers of pixel lines. Based on the installed mode, the number of pixel lines for a particular type of screen adapter may also vary.
Use CharPix() to determine the number of pixel lines available in the currently installed mode. This information is useful when used in conjunction with SetCursor().
Examples
Display the number of pixel lines:
? CharPix() // VGA, no mode change - 16
cSearchFor1 Designates the character that is searched for in cString1.
cString1 Designates the character string to search with cSearchFor1.
cSearchFor2 Designates the character that is searched for in cString2.
cString2 Designates the character string to search with cSearchFor2.
Returns
CharRelA() returns the positions where cSearchFor1 and cSearchFor2 occur in the corresponding character strings.
Description
This function builds a relationship (CHAR RELAtion) between two character strings. It determines the positions where the characters in cSearchFor1 appear in cString1 and where the characters in cSearchFor2 appear in cString2.
Notes
■ The function returns a value of 0 if no relationship is found.
Examples
Search for the first position in which a "b" appears in the first string
and a "1" appears in the second:
? CharRelA("b", "b b b b", "1", "bbb11111") // 5
cSearchFor1 Designates one or more characters within cString1 for which to search.
cString1 Designates the character string where cSearchFor1 is found.
cSearchFor2 Designates one or more characters within cString2 for which to search.
cString2 [@] Designates the character string where cSearchFor2 is found.
cReplaceExpression Designates one or more characters to replace those at the established corresponding position within cString2.
Returns
The processed cString2 is returned.
Description
This function is easier to use than it seems. If we proceed on the assumption that both search expressions and the replacement expression are only one character long, then the following steps occur:
■ All positions are determined where cSearchFor1 is found
within cString1.
■ All positions are found where cSearchFor2 is found within
cString2.
■ The character in the cString2 string is replaced by the
character in the cReplaceExpression.
This function can be used to simplify work with variables that contain screen memory. If cPict1 contains the character "|"at position 34 and cPict2 contains the character "-" at the same position, then this position within cPict2 can be replaced with a new character, "+"', which represents the combination of the two.
Multiple Exchanges Both search expressions and the replacement expression can be longer than one character. The previously described exchange procedure occurs repeatedly — initially with the first character in the three character strings, then with the second, and so on. The number of iterations is regulated by the length of cSearchFor1. If cSearchFor2 or the cReplaceExpression are shorter, then the last byte is used again.
Notes
■ The length of cString2 determines the number of search
procedures at any one time. The length of cSearchFor1 determines the number of possible exchanges.
■ The return value of this function can be suppressed by
implementing CSetRef() to save space in working memory.
■ A use for multiple replacement using CharRelRep() can be found
in the accompanying sample programs.
Examples
Determine every position where a "b" occurs in the first string and a
"1" occurs in the second string. The respective character is then
exchanged for the one designated as the fifth parameter.
? CharRelRep("b", "b b b b", "1", "bbb11111", "x")
//"bbb1x1x1"
cDelCharacterstring Designates the characters that are removed from cString.
cString Designates the string that is processed.
Returns
The processed cString is returned.
Description
With this function you can remove particular characters from any position in cString. It is possible to ensure that the character string does not contain these characters later.
Notes
■ No changes occur if you pass invalid or incorrect parameters.
Examples
■ Remove the blanks from a string:
? CharRem(" ", " 1 2 ") // "12"
■ Remove the number "3" and the letter "y":
? CharRem("3y", "xyz123") // "xz12"
cSearchFor Designates a list of characters to search for in cString.
cString [@] Designates the character string within which to search for and replace the characters in cSearchFor.
cReplaceExpression Designates the character list that replaces characters in cString.
lMode Designates whether multiple replacements are made.
lMode Designates one pass of the cString (.T.) or multiple replacements (.F.). The default value is for .F..
Returns
The processed cString is returned.
Description
This function allows you to carry out very complex replacement procedures. Every character in the cSearchFor is searched for within the cString. If found, the character is replaced by the corresponding character in the cReplaceExpression.
If lMode is not passed, characters are exchanged repeatedly as required. This means that the function goes through each individual character in the found characters in sequence, and then searches the entire cString, exchanging cSearchFor for corresponding characters in cReplaceExpression. When you use this technique, characters that have already been replaced are exchanged again if the replacement character also appears in the search list.
However, if the optional lMode parameter is specified, the function proceeds differently. It goes through each character in cString in sequence, determining whether or not it should be replaced. Characters that have been replaced are not replaced again.
As a rule, if the same characters appear within cReplaceExpression and cSearchFor, you must check very closely to determine which lMode parameter should be used (see example).
Notes
■ If the cReplaceExpression sequence is shorter than
cSearchFor, the characters that do not have a corresponding replacement in cReplaceExpression are replaced with the last character of cReplaceExpression (see example).
■ The return value of this function can be suppressed by
implementing CSetRef() to save space in working memory.
Examples
■ The number "1" is replaced with the letter "a", the number "2"
with the letter "b", etc.. If the number "4" appeared in the
character string, it would be replaced with a "d":
? CharRepl("1234", "1x2y3z", "abcd") // "axbycz"
■ The letters a-j are replaced with the numbers 0-9; for
example, an "f" is replaced with a "6":
? CharRepl("abcdefghij", "jhfdb", "1234567890") // "08642"
■ The third parameter makes fewer characters available for the
exchange. Therefore the letters f-j are replaced with the last
characters from "12345":
? CharRepl("abcdefghij", "jhfdb", "12345") // "55542"
■ Here is an example of the difference between a specified
<lMode> parameter (.T.) and the default parameter (.F.):
? CharRepl("1234", "1234", "234A") // "AAAA"
? CharRepl("1234", "1234", "234A", .T.) // "234A"
CharSort(<cString>,[<nElementlength>],
[<nComparisonlength>],[<nIgnore>],
[<nElementPosition>],[<nSortlength>],
[<lDescending>]) → cString
Note: This version of CA-Clipper Tools contains an optional
parameter that previous versions did not include.
Arguments
cString [@] Designates the character string that is sorted.
nElementlength Designates the length of the sorting element. The default value is for 1 character.
nComparisonlength Designates the number of characters that a sorting element takes into account in a comparison. The default value is nElementlength characters.
nIgnore Designates the number of characters at the beginning of the cString that should not be taken into account in the sorting.
nElementPosition Designates an offset. This parameter designates from what position within the sorting element the comparison is made. The default value is the first character (0).
nSortlength Designates the length of the sort area relative to the nIgnore offset.
lDescending Designates whether the function sorts in ascending or descending order. If this parameter is not specified, or is specified as .F., then the function sorts in ascending order. When specified as .T., the function sorts in descending order. The default value is .F..
Returns
The sorted cString is returned.
Description
CharSort() allows you to sort the characters in a string in many different ways. Everything from the length of the sorting elements to the sort sequences is taken into account.
Notes
■ Invalid parameters return a null string.
■ The function uses a fast sort algorithm.
■ The return value of this function can be suppressed by
implementing CSetRef() to save space in working memory.
Examples
■ Sort characters in a string according to their ASCII code:
? CharSort("qwert") // "eqrtw"
■ Sort 2-byte length elements:
? CharSort("qwert", 2) // "erqwt"
■ Sort 2-byte length elements, but only use the first character
for the comparison:
? CharSort("bla4a3a2a1", 2, 1) // "a2a1a3a4b1"
■ Sort individual characters, excluding the first three:
? CharSort("XXXqwert", 1, 1, 3) // "XXXeqrtw"
■ Sort paired sequences for the entire string, where only the
second character within each sequence is used:
? CharSort("bla4a3a2a1", 2, 1, 0, 1) // "a1b1a2a3a4"
■ Sort only the first four characters within a string:
? CharSort("384172852", 1, 1, 0, 0, 4) // "134872852"
■ Sort in descending order:
? CharSort("qwert", .T.) // "wtrqe"
cString Designates a character string that is expanded with spaces or cCharacter|nCharacter characters to nLength length.
nLength Designates the length of the return string.
cCharacter|nCharacter Designates the fill character and token delimiter. It can be a numeric value or a character. If it is a numeric value, it must be between 0 and 255. The default value is a space Chr(32).
Returns
CharSpread() returns the expanded string.
Description
CharSpread() expands a string to a preset length. However, it behaves differently than the Expand() function.
CharSpread() uses cCharacter|nCharacter as the character to insert during the expansion. The string is expanded between tokens delimited by this character up to the length specified by nLength. This is similar to full justification in a text editor.
Notes
■ Previously existing fill characters cCharacter|nCharacter
are not taken into account in the redistribution (see examples). If this procedure is not satisfactory to you, then you can call the CharOne() for the string before you call CharSpread().
Examples
For clarity, these examples do not contain blanks.
■ When the delimiter does not appear in the string, no expansion
takes place:
? CharSpread("123456", 20, ".") // "123456"
■ This example shows a numeric code for the (".") character:
? CharSpread("1.2.3.4.5.6", 20, 46) // "1...2...3..4...5...6"
■ In this example, the fill character is already there:
? CharSpread("11..22..33", ".") // "11.......22.......33"
? CharSpread("11.22........33", 20, ".")
// "11....22..........33"
cString [@] Designates the character string that is processed.
Returns
The processed character string is returned.
Description
CharSwap() takes all neighboring characters in cString and exchanges them. As a result, bytes in even positions are exchanged for those in odd positions.
CharSwap() is very important when you use string integers generated by the CA-Clipper I2Bin() function that must be saved or sorted. The CharSwap() exchange must be carried out prior to calling CharSort() (low/high ordering of 16-bit integers) to achieve an accurate result.
Notes
■ Since the length of the character string is not changed, a
call by reference is recommended. This increases the speed of the function.
■ The value this function returns can be suppressed by setting
idPackCharacterstring Designates a string that was previously compressed with the CharPack() function.
Returns
CharUnpack() returns an uncompressed string.
Description
This function unpacks strings compressed by the CharPack() function. Notice that the related pack method is automatically recognized. Since we presuppose that the CharUnpack() string parameter was compressed previously with CharPack(), it is assured that the returned string is not longer than the maximum permitted under CA-Clipper.
Examples
The CharUnpack() function recreates a string:
? CharUnpack(CharPack("AAAAAAAAAAAA")) // "AAAAAAAAAAAA"
nTopline Designates the line for the top-left corner of the area.
nLeftcolumn Designates the column for the top-left corner the area.
nBottomline Designates the line for the bottom-right corner of the area.
nRightcolumn Designates the column for the bottom-right corner of the area.
cNewcharacter|nNewcharacter Designates the new character for the screen area. Specify the parameter as a numeric in the range of 0 to 255 or as a character string. The default value is the CLEARB.
cOldcharacter|nOldcharacter Designates which character to exchange. Specify the parameter as a numeric in the range of 0 to 255 or as a character string. The default is to exchange all characters.
() When no parameter is designated, the function replaces all characters in the screen area with CLEARB.
Returns
The function always returns a null string.
Description
Within a screen area, CharWin() replaces all characters or just a particular character with a new one. If cNewcharacter|nNewcharacter is not designated, the function uses the character set with SetClearB(), where the preset value is Chr(255). The upper-left and lower-right corner rows and columns are given for the borders of the area. If these arguments are missing, then the entire screen area is exchanged.
Examples
■ Exchange all characters for CLEARB:
SetClearB("X") // Exchanges within CharWin() entire screen
■ Exchange all "A" for "B":
CharWin(10, 10, 20, 70, "B", "A") // Always returns a ("") null
// string
■ Numeric characters can also be designated:
CharWin(10, 10, 20, 70, 66, 65) // A = 65, B = 66
Joins corresponding ASCII codes of paired strings using an exclusive OR operation
Syntax
CharXor(<cString1>,<cString2>) → cString
Arguments
cString1 [@] Designates the character string on which the exclusive OR (XOR) operation is performed.
cString2 Designates the characters that are joined using XOR with cString1.
Returns
The processed cString1 is returned.
Description
The function performs an exclusive OR operation on each character in cString1 with the corresponding characters in cString2.
You can use CharXor() to code passwords and text. The advantage of this function is that it can be used for both encryption and decryption.
Notes
■ If both character strings are the same length, then the first
byte of cString1 is linked with the first byte of cString2, and the second byte of cString1 is linked with the second byte of cString2, etc.. If cString2 is shorter than cString1, then when the last byte of cString2 is reached, it continues with the first byte of cString2. However, if cString1 is shorter than cString2, the process terminates at the end of cString1.
■ The return value of this function can be suppressed by
implementing CSetRef() to save room in working memory.
Examples
■ CharXor() returns the coded value once. The password should
be as long as possible:
? CharXor("Secret", "Password")
■ Call CharXor() twice to return the initial value:
? CharXor(CharXor("Secret", "Password"), "Password")
■ A double encryption is also possible:
? CharXor(CharXor("Secret", "Password"), "A12B44")
Calculates the checksum for a character string (algorithm)
Syntax
Checksum(<cString>) → nCheckSum
Arguments
cString Designates the character string for which the checksum is computed.
Returns
The number returned is the checksum for the cString.
Description
Checksum() calculates the checksum for a character string. This checksum can determine if a character string has been changed, or transmitted or typed incorrectly. Checksum() is position dependent, so the likelihood of error recognition is greater than with AsciiSum().
Notes
■ The return value is a 32-bit whole number.
■ The checksum cannot be used for definitive coding of data
because the calculated sum for two different character strings could be the same. For example, the checksum for "PASTETEN" and "PERSONAL" are identical.
■ If character strings have different lengths, the strings
cannot have identical values.
Examples
■ In this example, AsciiSum() would have returned identical
results:
? Checksum("abc") // Result: 247334
? Checksum("cba") // Result: 246822
■ Different character strings of identical length can produce
identical results:
? Checksum("PASTETEN") // Result: 530020
? Checksum("PERSONAL") // Result: 530020
■ A null string returns a result of 0:
? Checksum("") // Result: 0
nLONG|cHexLONG Designates either a decimal number or hexadecimal character string.
nBitPos32 Designates the bit numbers to delete.
Returns
ClearBit() returns a value in which the designated bits are cleared.
Description
ClearBit() resets particular bits within a field to change something like a serial port register. In contrast to NumAnd(), the bit numbers are given and do not need to be converted beforehand. The value 1 represents the bit with the lowest value, and the value 32, the bit with the highest value.
Notes
■ An invalid parameter returns a result of -1.
Examples
Bits 3, 4, and 6 are cleared in a bit pattern:
nBitPattern := 255
nBitPattern := ClearBit(nBitPattern, 3, 4, 6) // Result: 211
nRow Designates the line to be erased. The default is the cursor line.
nColumn Designates the column where the erasure is to begin. The default is the cursor column.
cAttrn|nAttr Designates the attribute used to clear. The default is CLEARA.
cCharacter|nCharacter Designates the character used to clear. The default is CLEARB.
Returns
ClearEol() always returns a null string.
Description
Use ClearEol() to clear a specific line from a given position to the end of that line. If arguments are not specified, then the current nRow cursor line and nColumn cursor column are used as the starting location. The clear always goes to the end of the line specified with the CLEARA attribute and CLEARB character, or with the Attr|nAttr attribute and cCharacter|nCharacter character.
ClearEol() has some advantages over the CA-Clipper @ Row, Column commands:
1. It lets you take the returned value of the character string type and
combine it with string outputs (e.g., LIST...ClearEol()).
2. The cursor position is not affected.
3. The arguments are optional. If they are not specified, the function
clears from the current cursor position with the CLEARA attribute and CLEARB character.
Notes
■ You can specify the cAttr|nAttr attribute and the
cCharacter|nCharacter character in a number of ways. Please refer to the chapter introduction.
■ Default attribute and character can be set with SetClearA()
■ If no arguments are specified for line or column, then the
function will automatically orients itself to the current cursor position.
Examples
■ Clear from the cursor position to the end of the line with the
CLEARB character and CLEARA attribute:
ClearEol()
■ Do the same for line 23 from the current cursor position:
ClearEol(23)
■ Do the same as before, but begin the erasure at column 55:
ClearEol(23, 55)
■ The attributes can be specified in different ways. In the
following three examples, the clear character is set with
SetClearB():
ClearEol(23, 55, 4) // red on black
ClearEol(23, 55, "4/7") // red on white
ClearEol(23, 55, "B/W") // blue on white
■ Clear with special attribute and character:
ClearEol(23, 55, "3/1", ":")
ClearEol(23, 55, "B/W", "+")
nDelay Designates the time delay in milliseconds for the individual steps in the delete procedure. The value is in the range of 1 to 65535.
nTopline Designates the line for the top-left corner of the area. The default value is the topmost line.
nLeftcolumn Designates the column for the top-left corner of the area. The default value is the leftmost column.
nBottomline Designates the line for the bottom-right corner of the area. The default value is the bottommost line.
nRightcolumn Designates the column for the bottom-right corner of the area. The default value is the rightmost column.
cCharacter|nCharacter Designates the character to use to clear the screen. The character can be numeric in the range of 0 to 255 or a character string. The default is the character set using SetClearB().
Returns
The function always returns a null string.
Description
ClearSlow() clears a screen area from the outside in, step by step, with time delays. You can designate the delay in milliseconds. If the parameters for the area coordinates are left out, the function clears the entire screen. In this case, the delete character set through SetClearB() is used. The preset value is Chr(255). CA-Clipper Tools uses this character because, in contrast to Chr(32), it accepts a color attribute on all screen adapters.
Notes
■ If no screen coordinates are designated, the entire screen is
cleared.
Examples
■ Use Chr(255) to clear the entire screen with a 50-millisecond
delay:
ClearSlow(50) // Always returns ""
■ Clear an area with spaces and use a 10-millisecond delay:
ClearSlow(10, 4, 4, 20, 76, 32) // Delete character 32 (Blank)
nTopLine Designates the topmost line where clearing is to begin. The default value is the cursor line.
nLeftCol Designates the leftmost column from which clearing is to begin. The default value is the cursor column.
nBottomLine Designates the bottommost line to clear. The default is the last screen line or window line.
nRightCol Designates the rightmost column to clear. The default is the right screen border or window border.
cAttr|nAttr Designates the attribute to use to clear. The default is the standard attribute CLEARA.
cCharacter|nCharacter Designates the character to use to clear. The default is the standard character CLEARB.
Returns
ClearWin() always returns a null string.
Description
ClearWin() clears a specified screen area. This area extends from
< nTopLine> to nBottomLine and from nLeftCol to nRightCol.
Without these parameters, the line and column that correspond to the current cursor position for nTopLine and nLeftCol, and the bottommost line and rightmost column are used for nBottomLine and nRightCol.
You can clear with the standard attribute and character (CLEARA and CLEARB), or with the cAttr|nAttr attribute and the cCharacter|nCharacter character.
Notes
■ The cAttr|nAttr attribute and cCharacter|nCharacter
character are specified in different ways. Please refer to the Introduction of this chapter for more details
■ The standard attribute and character are set with SetClearA()
■ If no parameters are specified for the line or column, the
function automatically orients itself to the current cursor position.
Examples
■ Clear from the cursor position to the end of the line with the
CLEARB character and CLEARA attribute:
ClearWin()
■ Do the same for line 23 from the current cursor position:
ClearWin(23)
■ Clear a window between line 23, column 15 and line 24, column
70:
ClearWin(23, 15, 24, 70)
■ You can specify the attributes in different ways. In the
following three examples, the CLEARB() clear character is used.
ClearWin(23, 15, 24, 70, 4) // red on black<
ClearWin(23, 15, 24, 70, "4/7") // red on white
ClearWin(23, 15, 24, 70, "B/W") // blue on white
■ Clear when specifying attribute and character:
ClearWin(23, 15, 24, 70, "B/W", "+") // blue on white
Clears characters and attributes to the end of a line
Syntax
ClEol([<nRow>], [<nColumn>]) → cNull
Arguments
nRow Designates the line to clear. The default is the cursor line.
nColumn Designates the column from which to clear. The default is the cursor column.
Returns
ClEol() always returns a null string.
Description
Implement the ClEol() function when you need to clear to black and cannot use the standard attribute and character. This function is especially useful with a monochrome video card. A significant advantage of ClEol() over ClearEol(), is the omission of the cAttr|nAttr and cCharacter|nCharacter parameters, which increase the speed of ClEol(). The function is faster because it does not note the CLEARA and CLEARB settings.
ClEol() has some advantages over the CA-Clipper @ Row, Column commands:
1. The function allows you to take the returned value of the character
string type and combine it with string outputs (e.g., LIST...ClEol()).
2. The cursor position is not affected.
3. The parameters are optional. If they are not specified, the function
clears from the current cursor position with the CLEARA attribute and the CLEARB character.
Notes
■ If no parameters are specified for line or column, the
function automatically orients itself to the current cursor position.
Examples
■ Clear from the current cursor position to the end of the line:
ClEol()
■ Clear line 23, starting from the cursor column position to the
end of the line:
ClEol(23)
■ Clear line 23 from column 15 to the end of the line.
ClEol(23, 15)
nTopLine Designates the topmost line where clearing should begin. The default is the cursor line.
nLeftCol Designates the leftmost column where erasure should begin. The default is the cursor column.
nBottomLine Designates the bottommost line to clear. The default is the last screen line or window line.
nRightColumn Designates the rightmost column to clear. The default is the right screen border or window border.
Returns
ClWin() always returns a null string.
Description
Implement ClWin() when you need to clear to black without the use of the standard attribute and character. This function is helpful when you use a monochrome video card. A significant advantage of ClWin() over ClearWin(), is the omission of the cAttr|nAtt and cCharacter|nCharacter parameters, because it increases the speed of ClWin(). The function is faster because it does not note the CLEARA and CLEARB settings.
ClWin() has some advantages over the Clipper @ Row, Column commands:
1. This function takes the returned value of the character string type
and combines it with string outputs (e.g., LIST...ClWin()).
2. The cursor position is not affected.
3. The parameters are optional. If they are not specified, the function
clears from the current cursor position.
Notes
■ If no parameters are specified for the line or column, the
function automatically orients itself to the current cursor position.
Examples
■ Clear from the cursor position to the end of the screen area:
ClWin()
■ Do the same from the current cursor position in line 23:
ClWin(23)
■ Clear from line 23, column 15, to the end of line 24:
ClWin(23, 15, 24)
■ Clear a window between line 23, column 15, and line 24, column
70:
ClWin(23, 15, 24, 70)
Closes the socket and all connected IPX/SPX handles
Syntax
CLOSESOCK(<nSocket>) → NIL
Netware: 2.2 and 3.11
Arguments
nSocket Designates the number of the socket that is closed.
Returns
CLOSESOCK() always returns NIL when closing a socket according to IPX.
Description
CLOSE SOCKETCLOSESOCK() allows you to close a socket that is used for IPX/SPX communication. At the same time, all IPX/SPX communication buffers for which nSocket has been specified as the source socket are closed. The related communication handles are then invalid.
Examples
Open and close the IPX receiving buffer with source socket 20000:
nHandle=IPXOPEN(20000,2000)
CLOSESOCKET(20000) // nHandle is now invalid
cNewAttr|nNewAttr Designates the new attribute. The default is CLEARA.
cOldAttr|InOldAttr Designates the old attribute to exchange. The default is all existing attributes.
Returns
ColorRepl() always returns a null string.
Description
ColorRepl() simplifies screen handling. This function exchanges all occurrences of the cOldAttr|nOldAttr attribute for the cNewAttr|nNewAttr attribute.
For example, after a READ, you could take the colors in all input fields, (assuming they have a common attribute), and change them. This designates these fields as no longer active.
Notes
■ If the cOldAttr|nOldAttrparameter is not specified, then all
screen attributes (without exception) are exchanged for cNewAttr|nNewAttr. If cNewAttr|nNewAttr is also missing, then cOldAttr|nOldAttr is exchanged for the CLEARA standard attribute.
Examples
■ Exchange the attribute 7 (white on black) for 0 (black on
black= invisible):
ColorRepl(0, 7)
■ Replace all attributes for attribute 116 (red on white):
ColorRepl(116)
■ Exchange the attribute "7/0" (white on black) for 116 (red on
white):
ColorRepl(116, "7/0")
■ Exchange all attributes for the CLEARA standard attribute:
ColorRepl()
■ Change the display from white on black to black on white. You
can specify different parameters:
ColorRepl("0/7", "7/0")
ColorRepl(112, 7)
■ Mixed formats are also possible:
ColorRepl("0/7", 7)
Converts NN/NN or CC/CC color values into numeric values
Syntax
ColorToN(<cAttr>) → nAttr
Arguments
cAttr Designates the alphanumeric color attribute that is converted in NN/NN or CC/CC form.
Returns
ColorToN() returns a number that corresponds to the combined numeric color attribute.
Description
COLOR TO (N)umeric The function changes an alphanumeric color attribute from NN/NN or CC/CC into a combined numeric attribute. These combined attribute values are useful with the CA-Clipper Tools functions StrScreen(), ScreenMix(), ScreenAttr(), and the CA-Clipper commands SAVE/RESTORESCREEN.
ColorToN() makes it easy to create numeric attributes for the CA-Clipper Tools functions.
Notes
■ If you specify an invalid attribute string, ColorToN() returns
the numeric attribute 0, meaning black on black (invisible).
Examples
■ Show the "normal" display (white on black); all alphanumeric
forms yield 7:
? ColorToN("07")
? ColorToN("07/00")
? ColorToN("W/N")
■ Display red on white; all alphanumeric forms yield the numeric
attribute 116:
? ColorToN("04/07")
? ColorToN("R/W")
■ If the foreground color is missing, 0 is assumed. Here it
corresponds to an inverse video display:
? ColorToN("/7")
■ High intensity (+) and flashing (*) are also recognized:
? ColorToN("BR+")
? ColorToN("BR+*")
? ColorToN("G/BR+*")
? ColorToN("+G*/BR")
■ An invalid parameter returns 0:
? ColorToN()
■ Parameters of the <cAttr|nAttr> type are allowed. A numeric
attribute remains numeric.
? ColorToN(112) // Result: 112
nTopLine Designates the topmost line to begin processing. The default is the cursor line.
nLeftCol Designates the leftmost column to begin processing. The default is the cursor column.
nBottomLine Designates the bottommost line that is processed. The default is the last screen line or window line.
nRightCol Designates the rightmost column to clear. The default is the right screen border or window border.
cNewAttr|nNewAttr Designates the new attribute to replace the old one. The default is the standard attribute CLEARA.
cOldAttr|nOldAttr Designates the old character to exchange. The default is "exchange all attributes".
Returns
ColorWin() always returns a null string.
Description
ColorWin() exchanges all occurrences of cOldAttr|nOldAttrfor the cNewAttr|nNewAttr attribute, within a particular screen or window area. The function operates in a similar way to ColorRepl(), except with ColorWin() you can define the screen area to work on.
The parameters nTopLine and nLeftCol define the row and column for the top-left corner; nBottomLine and nRightCol define the row and column for the bottom-right column.
Notes
■ If cOldAttr|nOldAttr is not specified, all attributes are
exchanged for cNewAttr|nNewAttr; if cNewAttr|nNewAttr is not specified, the attributes are exchanged for CLEARA.
Examples
■ Exchange attribute 7 (white on black) for 0 (black on black =
invisible) from the current cursor position to the end of the screen
area:
ColorWin(0, 7)
■ Exchange all attributes in the area from line 23, column 15 to
line 24, column 70 for the standard attribute CLEARA:
ColorWin(23, 15, 24, 70)
■ Replace all attributes for attribute 116 (red on white) in the
region from line 23, column 15 to line 24, column 70:
ColorWin(23, 15, 24, 70, 116)
■ Change the white on black display to black on white. You can
specify different parameters:
ColorWin(23, 15, 24, 70, "0/7", "7/0")
■ Mixed formats are also possible:
ColorWin(23, 15, 24, 70, "0/7", 7)
expValue[@] Designates any valid expression of any data type to form a complement value. Complement() only allows a character string to be passed by reference.
Returns
Complement() returns the complement value that corresponds to the same data type for expValue.
Description
Complement() returns the respective opposite value of the expValue parameter. In contrast to CharNot(), which only permits character strings, this function permits all data types. The result is the same data type as the parameter. For example, a date returns a date as a result. It corresponds to the difference between the indicated date and 12/31/2999.
■ The complement of a logical value corresponds to the use of
.NOT.:
? Complement(.T.) // .F.
? Complement(.F.) // .T.
■ Numeric values change sign:
? Complement(99) // -99.00
? Complement(0) // 0
? Complement(-99) // 99.00
? Complement(-9.9) // 9.90
? Complement(9.9) // -9.9
■ With strings, the function works like CHARNOT:
? Complement("123ABCabc") // " <157><156>"
■ The difference between 1/1/1900 and 01/01/3000:
SET CENTURY ON
? Complement(CToD("01/01/00")) // 12/31/1099
■ An empty or invalid date gives the same result -- 01/01/3000:
SET CENTURY ON
? Complement(CToD(" / / ")) // 01/01/3000
? Complement(CToD("77/77/77")) // 01/01/3000
CountGets() returns the number of currently posted fields within a READ.
Description
CountGets() determines how many GET fields are currently open in a VALID UDF or within a KEYTRAP procedure. Posted means the GET fields have been recently defined before with @ ...GET ...
Examples
■ Display the number of GET fields that are currently posted
from within a valid UDF:
@ 10, 10 GET Field1
@ 10, 20 GET Field2 VALID MYFUNC()
@ 10, 30 GET Field3
READ
RETURN
■ Returns CountGets() within the UDF:
FUNCTION MYFUNC
? CountGets() // Result: 3
RETURN(.T.)
cString Designates the character string in which the cCharacter|nCharacter character is counted.
cCharacter|nCharacter Designates the character at the beginning of the cString that is counted. The default value is a space, Chr(32).
Returns
CountLeft() returns the number of cCharacter|nCharacter characters that appear in an uninterrupted sequence at the beginning of cString.
Description
While RemLeft() removes leading characters from the cString, CountLeft() only determines the number of leading cCharacter| nCharacter characters appearing in an uninterrupted sequence at the beginning of the cString.
Examples
■ Count the blanks:
? CountLeft(" 123") // Result: 3
■ Count the "." characters:
? CountLeft("..4.123", ".") // Result: 2
■ In this example, there is nothing to count:
? CountLeft("123456") // Result: 0
cString Designates the character string in which the cCharacter|nCharacter character is counted.
cCharacter|nCharacter Designates the character at the end of the cString that is counted. The default value is a space, Chr(32).
Returns
CountRight() returns the number of cCharacter|nCharacter characters that appear in an uninterrupted sequence at the end of the cString.
Description
While RemRight() removes trailing characters from the cString, CountRight() only determines the number of trailing cCharacter| nCharacter characters appearing in an uninterrupted sequence at the end of the cString.
Examples
■ Count the blanks:
? CountRight("abc ") // Result: 3
■ Count the "." characters:
? CountRight("abc.d..", ".") // Result: 2
■ In this example, there are no spaces to count:
? CountRight("123456") // Result: 0
CPUType() returns a numeric code that identifies the microprocessor in use.
Description
This function determines which microprocessor is in use. For instance, a PC may use a Vnn microprocessor or an AT may use a 386 microprocessor. The microprocessors have the following codes:
Table 12-1: Microprocessor Coding
Value Symb. constant Processor
0 CPU_8088 8088
1 CPU_8086 8086
2 CPU_V20 V20
3 CPU_V30 V30
4 CPU_80188 80188
5 CPU_80186 80186
6 CPU_80286 80286
7 CPU_80386 80386
8 CPU_80486 80486
Examples
What type of microprocessor is on the AT?
IF CPUType() == CPU_80386
? "A 386 ..."
ENDIF
cString Designates the string that is that is encrypted.
cKeystring Designates the password with which the string is encrypted.
Returns
Crypt() returns the encrypted string.
Description
In contrast to a simple lock using CharXor(), this function has a random number generator that uses a "random seed" algorithm. This makes the lock even more secure, at least as long as this additional algorithm is not known. Of course, this additional security costs some computer time.
Encrypted character strings can be decrypted with the same password. With multiple encryptions, the decryption must occur in reverse order.
Notes
■ Passwords should be as long as possible — a minimum of six
characters, preferably more.
■ The return value of this function can be suppressed by
implementing CSetRef() to save space in working memory.
Examples
■ This example shows a simple encryption:
cVar:= Crypt("CLIPPER", "CA")
■ This example shows the decryption:
? Crypt(cVar, "CA") // "CLIPPER"
Determines the setting of the multi-pass mode for ATXXX() functions
Syntax
CSetAtMupa(<lNewMode>) → lOldMode
Arguments
lNewMode Designates the setting for the multi-pass switch for all AT functions. The default value (.F.) sets the multi-pass switch to off
Returns
If lNewMode is not specified, the current setting is returned. If lNewMode is specified, CSetAtMupa() returns the previous setting.
Description
CSetAtMupa() sets a switch, internal to CA-Clipper Tools, that affects the operation of several other CA-Clipper Tools functions. These functions permit targeted, extremely flexible substring manipulation. The affected functions are:
CSetKey(<nKeyValue>) → cProcedureName
* This function is retained for compatibility purposes. Use the
CA-Clipper Set() function to develop future applications.
Arguments
nKeyValue Designates the Inkey() for which the associated procedure name is determined.
Returns
CSetKey() returns a character string that names the procedure associated with nKeyValue.
Description
This function queries the setting for SET KEY..TO.
Notes
■ To use this function, you must include the ct.ch file at the
beginning of your program with the command:
#include "CT.CH"
Find more information on this function in CH.CH.
Examples
Save the assignment for the function key F2:
cOldF2Proc := CSetKey(-1)
Determines whether or not reference sensitive functions return a value
Syntax
CSetRef([<lNewSwitch>]) → lOldSwitch
Arguments
lNewSwitch Designates whether the return value is suppressed for specified functions. When this parameter is .T., it suppresses the return value of the functions listed below. When the parameter is .F. (default value), these functions return a value.
Returns
If no parameter is specified, the function returns the current setting. If a parameter is specified, the function returns the previous setting.
Description
A series of CA-Clipper Tools functions enable you to pass parameters by reference. After executing the function, the passed parameter already contains the result. However, each of these functions also returns this result as a value. A copy of the passed string exists for a short time in working memory, but it is invisible to you. In the worst possible case, two adjoining memory blocks would require up to 64 kB.
This behavior can be influenced by implementing CSetRef(.T.). Then the group of affected string functions no longer return a value, which can save you up to 64k of memory with large strings.
■ If, in spite of having CSetRef(.T.), you need one of the
previously listed functions to return a value, then the target variable contains .F. instead of the anticipated string.
Examples
■ Here is how CSetRef() is set to .F.:
CSetRef(.F.)
cStr1 := "HAGBDCFE"
cStr2 := CharSort(@cStr1)
? cStr1, cStr2 // "ABCDEFGH" - cStr1,cStr2 are identical
■ Here is how CSetRef() is set to .T.:
CSetRef(.T.)
cStr1 := "HAGBDCFE"
cStr2 := CharSort(@cStr1)
? cStr1 // "ABCDEFGH" - Sort cStr1
? cStr2 // .F.
■ Determine when memory will be needed:
cStr1 := Space(32000) // Create large string
CSetRef(.F.)
CharSort(@cStr1) // Additional 32000 bytes
CSetRef(.T.)
CharSort(@cStr1) // Needs no additional memory
lNewSwitch Designates whether existing files should not be overwritten during CA-Clipper Tools file operations. Designates .F. for yes; .T. for no.
Returns
CSetSafety() returns the current setting for the CA-Clipper Tools safety mode switch; or if lNewSwitch is passed, the previous setting.
Description
CSetSafety() returns a logical value for the current setting of the CA-Clipper Tools internal safety mode switch. If you designate CSetSafety() as .T., the CA-Clipper Tools functions do not overwrite existing files.
Notes
Warning! CSetSafety() only works with CA-Clipper Tools functions..
Examples
■ Query the SAFETY function:
lSafety:= CSetSafety()
■ Turn safety mode on and save the previous status:
lOldSafety:= CSetSafety(.T.)
cNewSwitchList Designates in a specific format (shown in the tables on the next page), which switches are to be on or off.
Returns
CSETALL() returns the current setting of all ON/OFF switches when no parameter is specified. When the parameter is specified, the function returns the previous setting.
Description
This function allows you to query the current setting for all CA-Clipper ON/OFF switches and change them. Since you can save 21 different switches, the function returns a 21-character string made with 0's and 1's, rather than logical values. This function makes it easy to save all the ON/OFF switches in a CA-Clipper error trap, and reset them when you exit. The following switches are contained in the character string (in the order they occur in the returned string):
Table 11-1: Clipper Switch Status
Byte Function Clipper Switch
1 CSETALTE() SET ALTERNATE
2 CSETBELL() SET BELL
3 CSETCARR() SET CARRY
4 CSetCent() SET CENTURY
5 CSETCONF() SET CONFIRM
6 CSETCONS() SET CONSOLE
7 CSetCurs() SET CURSOR
8 CSETDELE() SET DELETED
9 CSETDELI() SET DELIMITERS
10 CSETDEVI() SET DEVICE
11 CSETESCA() SET ESCAPE
12 CSETEXAC() SET EXACT
13 CSETEXCL() SET EXCLUSIVE
14 CSETFIXE() SET FIXED
Table 11-2: Clipper Switch Status
Byte Function Clipper Switch
15 ReadInsert() INSERT Mode
16 CSETINTE() SET INTENSITY
17 CSETPRIN() SET PRINT
18 CSETSCOR() SET SCOREBOARD
19 CSETSOFT() SET SOFTSEEK
20 CSETUNIQ() SET UNIQUE
21 CSETWRAP() SET WRAP
Notes
■ If you specify an invalid parameter, the function returns a
null string and does not reset any switch.
Examples
Display the current bell status:
cSwitches := CSETALL() // 010000000000000000000
IF SubStr(cSwitches, 2, 1) == "1"
? " BELL is on!"
ENDIF
Determines the content of CA-Clipper environmental variables
Syntax
CSETCLIP(<cEnvParameter>) → nEnvParameterValue
Important! CA-Clipper no longer supports all possible settings for
environmental variables in the CA-Clipper Summer 1987 release.
Therefore, CSETCLIP() is modified to reflect these changes.
Arguments
cEnvArguments Designates which SET CA-Clipper setting to return.
Returns
SETCLIP() returns the setting of the requested SET CLIPPER= option.
Description
The CA-Clipper environmental variable contains settings for a CA-Clipper application. Use CSETCLIP() to query these values from within the application. The letter you use for the respective SET CLIPPER= option is given as a parameter. This value cannot be set from a running program since memory allocation is already determined. (You must determine memory allocation before you start an application.)
Notes
■ Uppercase or lowercase letters have no impact on the
parameter.
Examples
■ Uppercase or lowercase letters do not impact the parameter:
? CSETCLIP("F") // SET CLIPPER= Fnnn
? CSETCLIP("e") // SET CLIPPER= Ennn
? CSETCLIP("X") // SET CLIPPER= Xnnn
? CSETCLIP("SWAPK") // SET CLIPPER= SWAPK:nnn
■ With an invalid parameter:
? CSETCLIP("z") // -1
CSETFUNC(<nFunctionKey>) → cCharacterString
* This function is retained for compatibility purposes. Use the
CA-Clipper Set() function to develop future applications.
Arguments
nFunctionKey Designates the function key for which the associated character string is determined.
Returns
CSETFUNC() returns the character string associated with nFunctionKey.
Description
This function queries the setting for SET FUNCTION TO.
Notes
■ To use this function, you must include the ct.ch file at the
The F10 key is assigned to Ctrl-C. The setting changes in a function
Test(). Since it is saved, you can restore it upon return:
SET FUNCTION 10 TO Chr(3)
cOldFunc := CSETFUNC(10) // Save assignment
Test() // Call UDF
SET FUNCTION 10 TO cOldFunc
CSETRDONLY([<lR/O-NewMode>]) → lR/O-OldMode
* This function is retained in CA-Clipper Tools II/5.0 for
compatibility purposes. Use the READ-ONLY clause of the
CA-Clipper USE command to develop future applications.
Arguments
lR/O-NewMode Designates the new switch status. .T. turns the read-only mode on; .F. turns it off. The default value is off.
Returns
If no parameter is passed, the function returns to the current switch setting; otherwise, it returns the previous setting.
Description
Important! Please note the changes in the CA-Clipper USE command!
This function was implemented in the CA-Clipper Summer 1987 release to allow you to open files in read-only mode. This function was also useful for CD-ROM access and the enabled you to open a network database if you lacked write permission.
However, in CA-Clipper READONLY you can append to the USE command and do not have to implement CSETRONLY(). The switch has been retained in this release to insure compatibility with previous versions of CA-Clipper Tools. You can still use it to query, but it no longer has direct impact on the open mode.
This switch functions in the enclosed CA-Clipper Tools ct.ch definition file.
Notes
■ For new applications, use the read-only key word in
conjunction with the USE command.
Examples
Set the read-only mode switch (it only functions when you use the ct.ch
header file):
? CSETRDONLY(.T.) // Returns old setting
USE .... // Open with READ ONLY access
CSETSNOW([<lNewSwitch>]) → lOldSwitch
* This function is retained in CA-Clipper Tools for compatibility
purposes. Use the CA-Clipper NoSnow() function to develop future
applications.
Arguments
lNewSwitch Designates the new status for "Snow Prevent". A .T. signifies on; .F. means off. The default value for Snow Prevent is off (.F.).
Returns
CSETSNOW() returns the current setting, when no parameter is designated; otherwise, it returns the previous setting.
Description
Snow tends be is especially bad in CGA card screen output. To prevent it, set the CSETSNOW switch.
Use the CA-Clipper NoSnow() function for new applications.
Notes
■ CSETALL() does not acknowledge the CSETSNOW() setting.
Examples
■ Output with Snow Prevent on:
CSETSNOW(.T.) // Returns old setting
■ Acknowledge existing hardware:
CSETSNOW(IsCGA()) // Snow prevent if CGA card
Queries the SET position of a particular ON/OFF switch and provides the option to set it
Syntax
CSETxxxx([<lNewSwitch>]) → lOldSwitch
* This function is retained in CA-Clipper Tools for compatibility
purposes. Use the CA-Clipper Set() function to develop future
applications.
Arguments
lNewSwitch Designates the new status for the SET xxxx command. .T. corresponds to on; .F. signifies off.
Returns
If no parameter is passed, the function returns the current setting; otherwise, it returns the previous setting.
Description
This is a group of 20 functions. If you call all these functions the same way, they return the same value. Each function name consists of "CSET", and the first four characters of the respective CA-Clipper set condition:
Table 11-4: Functions to Query Clipper Set Conditions
Function Set Condition
CSETALTE() SET ALTERNATE ON/OFF
CSETBELL() SET BELL ON/OFF
CSETCARR() SET CARRY ON/OFF (See note)
CSetCent() SET CENTURY ON/OFF
CSETCONF() SET CONFIRM ON/OFF
CSETCONS() SET CONSOLE ON/OFF
CSetCurs() SET CURSOR ON/OFF
CSETDELE() SET DELETED ON/OFF
CSETDELI() SET DELIMITERS ON/OFF
CSETDEVI() SET DEVICE TO PRINT (.T.)/SCREEN (.F.)
CSETESCA() SET ESCAPE ON/OFF
CSETEXAC() SET EXACT ON/OFF
CSETEXCL() SET EXCLUSIVE ON/OFF
CSETFIXE() SET FIXED ON/OFF
CSETTINTE() SET INTENSITY ON/OFF
CSETPRIN() SET PRINT ON/OFF
CSETSCOR() SET SCOREBOARD ON/OFF
CSETSOFT() SET SOFTSEEK ON/OFF
CSETUNIQ() SET UNIQUE ON/OFF
CSETWRAP() SET WRAP ON/OFF
Notes
■ CSETCARR() is not useful in CA-Clipper. Since this function
was in CA-Clipper Tools and also occupies a position in CSETALL(), it is retained for compatibility purposes.
Examples
■ Switch SET UNIQUE on:
? CSETUNIQ(.T.) // Returns previous setting
■ Save a setting:
lOldWRAP:= CSETWRAP()
cCharacterstring Designates a character sequence. When this sequence occurs in the second character string, each corresponding bit is set to 1.
cBitpattern Designates a sequence, with a maximum of 16 characters, from which the bit position is assigned.
Returns
CToBit() returns a number in the range of 0 to 65535 that corresponds to the created bit pattern.
Description
The CToBit() function delivers a bit pattern that corresponds to a string of individual characters. When used in conjunction with its sister function BitToC(), it facilitates work with such bit-coded information as file attributes.
Notes
■ Characters in cCharacterstring that are not found in
cBitpattern are ignored.
Examples
■ The second bit in the resulting value is set, since the letter
"H" appears in the next-to-last position in "ADVSHR":
? CToBit("H", "ADVSHR") // Result: 00000010
■ Two characters also in ADVSHR, appear at the first and final
positions in this 6-character string:
? CToBit("RA", "ADVSHR") // Result: 00100001
■ <cBitpattern> ignores previously unavailable characters:
? CToBit("XRYA", "ADVSHR") // Result: 00100001
Converts the name of the day of the week into a corresponding number
Syntax
CToDoW(<cDayofWeek>) → nDayofWeek
Arguments
cDayofWeek Designates a character string that contains the name of a day of the week.
Returns
CToDoW() returns the number of the day for the day name.
Description
Use CToDoW() to change the name of a day of the week to a number. Sunday corresponds to 1, Monday 2, etc.. If the function returns a 0 value, an invalid parameter has been passed. You can shorten the day names, but these abbreviations must be explicit to return an accurate value.
Notes
■ Uppercase and lowercase letters do not affect the name of the
day of the week.
■ The function's operation depends on the country-specific
adaptation of your CA-Clipper compiler. With an English version of CA-Clipper, only English day names are recognized.
Examples
■ What number of the day of the week is Sunday?
? CToDoW("Sunday") // Result: 1
■ Show several ways to get the day of the week for Wednesday:
? CToDoW("WEDNESDAY") // Result: 4
? CToDoW("Wednesday") // Result: 4
? CToDoW("Wed") // Result: 4
■ What number of the day of the week is Monday?
CToDoW("M") // Result: 2
cFloatingPointNumber Designates an 8-byte character string that contains a CA-Clipper number in the 64-bit floating point format.
Returns
CToF() returns the number that corresponds in the passed string.
Description
Character strings created with FToC() or XToC() are changed into CA-Clipper numbers. Note that when you use XToC(), character strings or portions of character strings, can be switched back, if they have been displayed as CA-Clipper floating point numbers.
Examples
■ Change a number and then change it back:
CToF(FToC(1234.55)) // Result: 1234.55
■ This also works for XToC():
? CToF(XToC(1234.55)) // Result: 1234.55
Converts the name of the month into a corresponding number
Syntax
CToMonth(<cMonth>) → nMonth
Arguments
cMonth Designates the name of one of the 12 months.
Returns
CToMonth() returns the number for the designated month name.
Description
Use CToMonth() to change the name of a month into a number. January corresponds to 1, February 2, etc.. If the function returns a 0 value, then an invalid parameter has been passed. If you shorten the month name, use explicit abbreviations to return an accurate return value.
Notes
■ Uppercase and lowercase letters do not affect the name of the
month.
■ The function's operation depends on the country-specific
adaptation of your CA-Clipper compiler. With an English version of CA-Clipper, only English month names are recognized.
Examples
■ Show the number for January:
? CToMonth("January") // Result: 1
■ Show several ways to determine the month number for August:
? CToMonth("AUGUST") // Result: 8
? CToMonth("August") // Result: 8
? CToMonth("Au") // Result: 8
■ The number for April:
?CToMonth("A") // Result: 4
cNumericstring Designates a numeric string to convert into a number in base nBase.
nBase Designates the number base to use in the conversion. Can be in the range of 2 to 36. The default is the decimal system, base 10.
lMode When designated as .T., allows a negative result. The default allows only positive results.
Returns
CToN() returns the converted number that corresponds to the string. The values lie in the range of 0 and 65535 or, if lMode is .T., in the range of -32768 and +32767.
Description
CToN() offers a number of ways to covert a number string into numeric data format. Almost any number can be converted, as long as the base nBase for the number system lies between 2 and 36.
Notes
■ The cNumericstring string is automatically TRIMmed left and
right.
■ If you have invalid parameters or combinations, the function
returns a value of 0.
Examples
■ Convert to base 10:
? CToN("60000") // Result: 60000
■ Convert to base 2:
? CToN("11", 2) // Result: 3
? CToN("1110101001100000", 2) // Result: 60000
■ Convert to base 16:
CToN("A", 16) // Result: 10
? CToN("ABCD", 16) // Result: 43981
? CToN("FFFF", 16, .T.) // Result: -1
■ Convert to base 36:
? CToN("XXP", 36) // Result: 43981
DATATYPE(<expValue>) → nDataType
* This is retained in CA-Clipper for compatibility purposes. Use the
CA-Clipper ValType() function to develop future applications.
Arguments
expValue Designates any valid CA-Clipper expression.
Returns
DATATYPE() returns a value that corresponds to the data type in expValue.
Description
DATATYPE() is similar to the CA-Clipper Type() function, but returns more extensive information in numeric value form. The bits in the result correspond to specific data types. Two bits can be set at the same time. It is easy to recognize specific data types with the IsBit() function. The following codes apply:
Table 13-2: Data Type Coding
Value Symb. Const. Data Type
0 TYPE_UNDEF Undefined
1 TYPE_STR Character string
2 TYPE_NUM Numeric
4 TYPE_LOG Logical
8 TYPE_DATE Date
16 TYPE_ALIAS Alias
64 TYPE_MEMO Memo field
128 TYPE_WORD Word
512 TYPE_ARRAY Array
4096 TYPE_BLOCK Code block
In addition, DATATYPE() returns the respective data type for a CA-Clipper Tools function or one of your own UDF's. This is impossible with Type().
Notes
■ An invalid expValue output results in a runtime error.
■ The function cannot determine if a parameter has passed to a
function by reference (32 + type), because this information is no longer available in CA-Clipper.
Examples
Return values of DATATYPES() used for different data types:
? DATATYPE() // 0, undefined
? DATATYPE("XXX") // 1, string
? DATATYPE(123) // 2, numeric
? DATATYPE(DoY()) // 2, numeric result
? DATATYPE(.T.) // 4, logical
? DATATYPE(3 > 2) // 4, logical expression
? DATATYPE(Eof()) // 4, logical result
? DATATYPE(Date()) // 8, date
? DATATYPE(memofld) // 1, memo field
? DATATYPE(@crlf) // 33, reference to string
? DATATYPE(@array) // 544, reference to array
? DATATYPE(array[1]) // 2, numeric element
? DATATYPE(array[2]) // 1, string element
? DATATYPE(myfunc()) // type for your own UDF
Determines the size of a selected (.dbf) file in memory
Syntax
DbfSize() → nFileSize
Returns
DbfSize() returns the byte size of the current database in working memory.
Description
DbfSize() determines how much room a database occupies, before you write this file to a disk. The function is also useful when used in conjunction with DBFDSKSIZE(). When the results for both functions indicate there is a deviation in the size of a database, this means a portion of the data is not yet written to the floppy/hard disk. You can also determine if and when new input is written to a floppy/hard disk.
Notes
■ This function always operates on the currently SELECTed work
area.
Examples
Can a (.dbf) file be copied to the target disk?
USE DATA.
IF DiskFree("A") < DbfSize().
? "The file can not be copied.".
? "Insufficient space remaining on disk.".
ELSE.
COPY TO A:COPY.
ENDIF
Determines the size of a selected (.dbf) file on a disk drive
Syntax
DBFDSKSIZE() → nFileSize
Returns
DBFDSKSIZE() returns the size of the current database on the floppy or hard disk (i.e., how many bytes are saved in this file).
Description
One of the DBFDSKSIZE() function's most useful applications is when it is used in conjunction with DbfSize(). When the results for both functions indicate there is a deviation in the size of a database, this means a portion of the data is not yet written to the floppy/hard disk. You can also determine if and when new input is written to a floppy/hard disk.
Notes
■ This function operates on the currently SELECTed work area.
Examples
Determine if a portion of data input has been written out to disk yet:
SIZEIF Dbf() - DBFDSKSIZE() >= 512
* COMMIT // Warning! Works only with DOS 3.3 and up
USE File
ENDIF
DeleteFile() returns a code that signifies its completion status:
Table 7-1: DeleteFile() Error Codes
Code Symb. constants Definition
0 NO_DISK_ERR No error occurs
-2 ER_FILE_NOT_FOUND File not found
-3 ER_PATH_NOT_FOUND Path not found
-5 ER_ACCESS_DENIED Access denied (e.g., file is read-only)
Description
In contrast to FileDelete(), which permits you to specify file groups with wildcards, DeleteFile() only accepts specific file names. However, the function avoids all DOS error messages and returns an error code directly to the calling program. This makes error-tolerant erasures in networks possible (see Examples).
Notes
■ You can use a drive designator and path name, but no
wildcards.
Examples
■ How NOT to delete a file in a network environment:
IF FILE ("TEST.DBF")
* Is it actually possible to delete the file?
DELETE FILE TEST.DBF
ENDIF
■ This is a better way:
nStatus := DeleteFile("TEST.DBF")
IF nStatus == 0
? "File deleted."
ELSE
IF nStatus == -5
? "ACCESS DENIED!"
? "File in use elsewhere!"
ENDIF
ENDIF
cDirectory Designates the path of the directory that is changed.
Returns
DirChange() returns a 0 when it successfully changes the directory; otherwise, an error code is passed. The codes are defined as follows:
Table 7-2: DirChange() Error Codes
Code Symb. constants Definition
0 NO_DISK_ERR No error occurred
-2 ER_FILE_NOT_FOUND File not found
-3 ER_PATH_NOT_FOUND Path not found
-5 ER_ACCESS_DENIED Access denied (e.g., in network)
DirChange() changes the current subdirectory or determines if a directory exists. This allows DOS error messages to be intercepted. (See also DirMake()).
Notes
■ cDirectory may contain a drive designator and a path.
Wildcards are not allowed.
Examples
Change to the "\DATA" directory:
IF DirChange("\DATA") == 0
? "Current directory is now: " + DirName()
ENDIF
cDirectory Designates the directory name to create.
Returns
DirMake() returns a 0 when it has successfully created the directory; otherwise, an error code is passed. The codes are defined as follows:
Table 7-3: DirMake() Error Codes
Code Symb. constants Definition
0 NO_DISK_ERR No error occurred
-2 ER_FILE_NOT_FOUND File not found
-3 ER_PATH_NOT_FOUND Path not found
-5 ER_ACCESS_DENIED Access denied (e.g., in network)
Description
When you install the program, directories must be the first thing you create. The DirMake() function allows you to create new directories from within your CA-Clipper application.
Notes
■ cDirectory can contain a drive designator and a path,
wildcards are not allowed.
Examples
Change to the "\DATA" directory:
IF DirChange("\DATA") == -3 // Path not found
DirMake("\DATA")
ENDIF
cDrive Designates which disk drive that you want to use.
Returns
DiskChange() returns .T., when the designated disk drive is successfully changed.
Description
DiskChange() allows you to change from the current disk drive to another. To do this, call DiskChange() with the disk drive identifier (A,B,C, etc.). The drive identifier can be specified with a colon (:).
Examples
Change to drive C:
? DiskChange("C") // Returns .T. when successful
Determines the space available on a floppy or hard disk
Syntax
DiskFree([<cDrive>]) → nFreeByte
Arguments
cDrive Designates for which drive (A, B, C, etc.) the open capacity is determined. The default value is the current drive.
Returns
DiskFree() returns the available memory capacity of the selected drive.
Description
DiskFree() determines if a disk has sufficient storage capacity for a file.
Notes
■ When cDrive is not specified, the function automatically
uses the current drive.
Examples
Determine if there is enough space to copy a database:
Required := DbfSize() // Database size
IF DiskFree("A") < Required
? "Insufficient disk space for copying!"
ENDIF
Determines the total capacity of a floppy or hard disk
Syntax
DiskTotal([<cDrive>]) → nTotalSpace
Arguments
cDrive Designates the drive for which memory capacity is determined. The default is the current drive.
Returns
DiskTotal() returns a value that corresponds to the total capacity of the data carrier in the selected drive. The default is the current disk drive.
Description
DiskTotal() determines if the capacity of the disk in use is sufficient for back up. The advantage of DiskTotal() over any capacity determined by the system, is that it recognizes bad sectors and does not include them.
Examples
Determine if disk capacity is sufficient:
nRequired := DbfSize()
IF DiskTotal("A") < nRequired
? "Error! Insufficient disk capacity!"
ENDIF
cDrive Designates which drive (A, B, C, etc.) you want to check.
nStartSector Designates a sector to serve as a starting point to check the disk in the direction of the first sector.
Returns
DISKCHECK() returns a number that corresponds to a checksum for the data carrier in cDrive. If read errors occur, the function returns a negative number when the first bad sector is found.
Description
DISKCKECK() begins its check with the last sector of the designated drive or with the nStartSector value, and works in the direction of the first sector. If a sector is found to contain errors, then it returns a negative value.
If it returns a -1, continue to check for other errors (such as a missing disk). The CA-Clipper Tools function ERRORCODE() is quite useful here. Error code returns a value that symbolizes the most-recent DOS error.
Since DISKCHECK() returns a checksum, it is easy to check for disk changes.
Notes
■ You must specify the cDrive parameter. If you omit it or
specify an unavailable drive, DISKCHECK() returns an error code of - 1. DISKCHECK() takes more time to check a hard disk.
Examples
■ Create a checksum for a floppy:
Checksum := DISKCHECK("A")
■ Show that the disks are changed:
IF DISKCHECK("A") == Checksum
? "You have not changed disks!"
ENDIF
cDrive Designates the disk drive to format. Only a floppy drive is permitted. You may optionally specify a colon (:).
nCapacity Designates the appropriate disk capacity for the disk you are about to format. Possible values are 160, 180, 320, 360, and 1200 for 5.25"; 720 and 1440 for 3.5" disks. The default is the maximum drive capacity.
cUDF Designates the name of a user-defined function call before each format step (track or head change). The default is no UDF called.
cBootText This optional parameter designates text, with a maximum of 255 characters, to display if the formatted disk is booted. The default is described in the "Notes" section on the following page.
nRepetitions Designates the number of repeat attempts you should make, to format a track before the function aborts. The default is one repetition.
Returns
The function returns 0 when the disk is successfully formatted.
Table 7-5: DISKFORMAT() Error Codes
Error Codes Symb. constants Definition
0 NO_DISK_ERROR Format successful
-1 DF_WRONG_DRIVE Illegal drive, only A: and B: allowed
-2 DF_WRONG_DISK_SIZ kB value not supported
-3 DF_INTERRUPTED Terminated by control UDF
-4 DF_WRITE Write error
Description
DISKFORMAT() formats a disk under full CA-Clipper program control, so there is no need for a RUN FORMAT. You cannot create bootable disks, only data disks.
Since you can call a separate function (UDF) prior to every track and head change and the respective track and head number are passed, you can construct the visual display of the format process constructed as desired.
You can only format floppy disks, so even with unforeseen incorrect parameters, your hard disk is safe. All the standard floppy types are supported — 160kB, 180kB, 320kB, 360kB, 1.2MB, 720kB, and 1.44MB.
DISKFORMAT() is useful for formatting disks, at least when the preset repetition rate is retained or decreased. After an unsuccessful attempt to format a track, the process is repeated one more time. If this repetition also fails, the entire format is aborted. If you want to be as safe as possible about the quality of the disk in used, select a repetition rate of 0.
The Control UDF
DISKFORMAT() calls the control UDF, which is specified as the third parameter, prior to each head and track change. Both values, head and track, are passed as a parameter to the function. As soon as all tracks are formatted and DISKFORMAT() has initialized the FAT and directory area, a value of -1 is passed for both parameters to the UDF. Please be aware that both parameters must be passed.
The numeric value returned for UDF can further influence DISKFORMAT():
Table 7-6: Control UDF Returned Values
Returned Value Explanation
0 Continue format
1 Do not format this track (parameter 1)
2 Abort format
Notes
■ If the defined control UDF does not exist, the function
uninstalls itself and triggers a runtime error. If an error message concerning a missing procedure is required during linking, you can specify EXTERNALfunction in the program.
■ If you attempt to boot with a data disk created with
DISKFORMAT() and did not designate any other text for the cBootText parameter, the following text is displayed:
"No system disk. Insert new disk, press any key to continue"
■ DISKFORMAT() begins to format a disk with the highest track
number. Therefore, an existing FAT and directory label are the last items deleted.
■ DISKFORMAT() always reformats a track, even if it is already
formatted. Therefore, when a format is successful, all the data is deleted.
■ Each track is verified again after it is formatted.
■ After the last track is formatted, the function continues to
work a few seconds more. The FAT and directory must be established and the boot text must be written.
Examples
■ An example for formatting a disk in A: drive:
DISKFORMAT() first determines whether the desired capacity is
appropriate for the drive. The control UDF "CONTROL" is concerned
with the display of the track and head that are currently being
formatted. "This is a data diskette" is used as boot text for the
disk. The repeat rate is highly effective at 0. Only the highest-
quality disks are accepted.
To provide an additional example of the return value for the UDF,
only tracks 80 to 11 are formatted here, not the first 10:
CLEAR
cBootText := "This is a data diskette"
@ 10, 02 SAY "Track:
"@ 11, 02 SAY "Head:
"IF FLOPPYTYPE("A:") = 2
// 1.2 MB disk
nErrCode := DISKFORMAT("A:", 1200", CONTROL", cBootText, 0)
IF nErrCode = 0
? "Format successful!"
ENDIF
ENDIF
RETURN
FUNCTION CONTROL(nTrack, nHead)
LOCAL nRetval
IF Track >= 11
@ 10, 08 SAY Str(nTrack)
@ 11, 08 SAY Str(nHead)
nRetval := 0 // Continue format
ELSE
nRetval := 2 // Abort
ENDIF
RETURN(nRetval)
■ Shown below is another variation of the UDF. Press the ESC
key to abort the format. If the format is completed, then the
function displays the FAT initialization and root directory:
FUNCTION CONTROL(nTrack, nHead)
LOCAL nRetval
IF Inkey() = 27
nRetval := 2 // Abort
ELSE
nRetval := 0 // Continue format
ENDIF
IF nTrack = -1
@ 10, 10 SAY "Initializing FAT and Root Directory!"
ENDIF
RETURN(nRetval)
cDrive Designates the drive designator (A, B, C, etc.) of the drive to test. The default is the current disk drive.
lDOS/BIOS This logical parameter allows you to designate whether you want the function tested through the BIOS (.F.) or DOS (.T.). The default is discussed in the Description below.
Returns
DISKREADY() returns .T. when the drive being tested is ready to use.
Description
To save space, you must frequently make multiple disk copies. DISKREADY() allows you to wait for a user disk change, without having to confront known DOS errors, or use CA-Clipper error trap functions. Be sure to differentiate between floppy tests and "true" hard disks and logical partitions.
DOS or BIOS
In the simplest case, this function tests the respective drive through DOS. If drive B is unavailable, the message "Please insert disk in drive B:..." is output from the operating system. When you test floppy drives, drive A: and B:, the BIOS route is recommended, since no message is output. In any event, A: and/or B: can be mapped drives within a network. Use the following logical expression for all the previous situations:
(NetDisk(cDrive) .OR.cDrive >= "C")
This logical expression returns .T. when the respective drive is either on the network or has a drive identifier of C: or higher.
Examples
The system waits between individual copy procedures until drive A: is
ready again:
DO Copy // Call copy procedure
? "Please insert a disk in Drive A:!"
DO WHILE .NOT. DISKREADY("A")
*...
ENDDO
DO Copy // Call copy procedure
cDriveId Designates which drive designator (A, B, C, etc.) to query. The default value is the current disk drive.
lDOS/BIOS This logical parameter allows you to specify whether you want to query the function through the BIOS (.F.) or DOS (.T.). The default is described in the Description below.
Returns
DISKREADYW() returns .T. when you query a drive that is operational and can be written to.
Description
As with DISKREADY(), this function determines if a drive is ready to use. DISKREADYW() also determines if you can write to a drive. DISKREADY() cannot tell if a disk has a write-protect marker on it. In this case, drive A: might be ready, but you could not write to it. Use this function to build write-protect detection for important disks into the program.
Network Drives
In general, drives mapped within networks are viewed by the function as accessible and return .T. as a result. For a disk, "accessible" means you can create, open, and delete files. You can clearly differentiate these rights within networks such as Novell NETWARE. Therefore, you must test for these accordingly.
DOS or BIOS
In the simplest case, this function always tests the respective drive through DOS. If drive B: is unavailable, the message "Please insert disk in drive B:" is output from the operating system. When you test floppy drives drive A: and B:, the BIOS route is recommended, since no message is output. In any event, A: and/or B: can be mapped drives within a network. Use the following logical expression to cover all the previous situations:
(NetDisk(cDrive) .OR.cDrive >= "C")
This logical expression returns .T. when the respective drive is either on the network or has a drive identifier of C: or higher.
Notes
■ Research indicates work in the OS/2 compatibility box must be
in the BIOS mode.
Examples
Determine if you can write a file to A: drive:
IF DISKREADY("A")
IF NETDISK ("A")
IF NNETRIGHTS ("A:\") // complete path
* ...
ENDIF
ELSE
IF DISKREADYW("A")
? "Disk is not write protected!"
ELSE
? "Disk is write protected!"
ENDIF
ENDIF
ELSE
? "Disk drive not ready!"
ENDIF
cDrive Designates for which physical drive identifier (A, B, C, etc.) to determine the speed. You do not need to use the colon (:).
Returns
DISKSPEED() returns a percentage comparison value to a floppy drive of a 4.77 MHz PC, which corresponds to 100%.
Description
Use this function when you want to calculate the approximate duration of such complex file operations as INDEX or SORT. Since the total duration always depends upon the remaining computer speed, you should also use the SPEED() function..
If the designated drive is unavailable or cannot be checked (network drive), the function returns a 0 value.
Notes
■ You can only implement DISKSPEED() for physical drives, not
network drives.
Examples
■ Show the speed of drive A:
? DISKSPEED("A") // depends on drive
■ Show the factor for your hard disk:
? DISKSPEED("C") // e.g. 720 Factor 7.2
cDrive Designates the drive designator (A, B, C, etc.) of the drive for which the status of the last operation is determined. The default is the current disk drive.
Returns
DISKSTAT() returns the status of the floppy or hard disk operation as a number. The bits have the following meanings:
Table 7-7: Drive Status Coding
Bit Symb. constants Definition
1 DST_INVALID Unknown command
2 DST_READONLY Address marker not found
3 DST_SECTOR Sector not found
4 DST_DMA DMA overflow
5 DST_CRC CRC error
6 DST_CONTROLLER Controller error
7 DST_SEEK Seek operation failure
8 DST_TIMEOUT Timeout error
Description
When DOS returns a "block device error" message (See ERRORORG()) and DISKSTAT() to determine a more detailed cause of the error).
Notes
■ This function passes the system status to a CA-Clipper
application. The system saves a status value for all floppy and hard disk operations. When you reaccess a floppy disk drive from within your program, the previous disk operation status is lost. The same applies to hard disk status.
Examples
Determine if the system was unable to find an address marker:
IF ERRORORG() == DST_READONLY
DiskError := DISKSTAT("A")
ENDIF
249 DT_35_SEC_9 Double sided 3.5" 9 sectors (ident. to 5.25"
HD)
240 DT_35_SEC_18 Double sided 3.5" 18 sectors
248 DT_HARDDISK Hard disk
Description
If a 360K floppy is written on an AT in a 1.2 MB drive, you may not be able to read it on other systems, particularly on PC XTs. This function determines how the floppy you are about to use is formatted and provides the corresponding warning.
Examples
Determine if an XT disk is being written to an AT:
IF IsAt() .AND. DISKTYPE("A") == DT_DS_SEC_9
? "Warning!"
? "Under certain circumstances this disk not"
?? " readable on other systems!"
ENDIF
dDate Designates the date from which to create a string. The default is the system date.
lMode Designates whether to insert a period (.) after the day (see Examples). The default is no period (.F.).
Returns
DMY() returns a character string in "DD[.] Month YY" format or "DD[.] Month YYYY" format.
Description
Use DMY() to return the date as a character string using the day, name of month, and year. The CA-Clipper SET CENTURY ON/OFF switch determines whether or not the year is displayed in two or four digits. If the lMode parameter is designated .T., the function builds in a "." after the day designation. If no date is designated as a parameter, the function automatically uses the current system date.
Notes
■ The month name returned depends on which CA-Clipper nations
module is in use.
Examples
■ Display the system date (1/1/89):
SET CENTURY OFF
? DMY() // 1 January 89
■ With ".":
? DMY(.T.) // 1. January 89
■ Display a different date:
SET CENTURY ON
? DMY(CToD("02/01/89"), .T.) // 1. February 1989
DosParam() returns the parameters from the DOS command line.
Description
DosParam() returns all the parameters passed from the DOS command when you run the application. Use DosParam() when you do not want the parameters to be separated. With this function, it is no longer necessary to check each individual parameter in a loop.
Notes
■ With the Token() function, it is easy to break down the
returned character string. It can also use your own rules.
Examples
Given the DOS command line C>MyApp A: C: /a ,
the following is true:
DosParam() // "A: C: /a"
TOKEN(DosParam()) // "A"
This way, it is easy to break down parameter lines according to your own
rules.
Determines the day of the year for a specific date
Syntax
DoY([<dDate>]) → nDayOfYear
Arguments
dDate Designates which date to use to calculate the day of the year. The default is the system date.
Returns
DoY() returns a calendar day number that specifies which day of the year dDate represents.
Description
If you frequently work with time periods, then this function is quite useful. DoY() lets you assign a calendar day number to a date that relates to the beginning of the year.
Notes
■ When no date is specified, DoY() uses the system date.
January 1 is always 1, December 31 is 366 in a leap year; otherwise, it is 365. An empty date returns a 0 result.
Examples
How long is it until Christmas?
? "There are", NToC(DoY(CToD("12/24/91"))- DoY()) ;
, " days until Christmas!"
cDrive Designates the drive (A, B, C, etc.) for which the type is determined. The default is the current drive.
Returns
DriveType() returns a numeric value for the drive type. The following codes apply:
Table 7-9: Drive Type Coding
Code Definition
0 RAM Disk
1 Floppy Disk (disk change cannot be established by system)
2 Floppy Disk (disk change can be established by system)
3 Hard Disk
Description
Warning! Only for AT-class computers.
This function determines if you are dealing with a floppy drive, a hard disk, or a RAM disk.
Notes
■ Although DriveType() returns a 0 value for logical DOS
partitions, RAM floppies, and unavailable drives, you must also differentiate with DISKTYPE(). Here, each hard disk partition returns a 248 value. A RAM floppy created with VDISK.SYS behaves like a single-sided floppy with eight sectors, which returns a 254 value. If there is an unavailable drive, the DISTYPE() returns a value of 0.
Examples
Determine if the drive is a RAM floppy:
IF DriveType() == 0 .AND. DISKTYPE() == 254
? "Drive " + DiskName() + ": is a RAM-disk!"
ENDIF
lNewKeyboardMode Designates whether the extended keyboard input mode is on (.T.) or off (.F.). The default value (.T.) designates that the extended keyboard input mode is on.
Returns
When called without the parameter, this function returns the current setting for DSetKBIOS(). If you pass a parameter, then it returns the previous setting.
Description
Beginning with CA-Clipper 5.0, all keyboard entries are read through the BIOS instead of DOS. The default setting for DSetKBIOS() is now the opposite of what it was in previous versions. The default setting for the enhanced keyboard is on (.T.). When the enhanced keyboard mode is off, keyboard entries are redirected through DOS. This function is very useful if file inputs must be read at program start.
Notes
■ Symbolic constants for keyboard coding are found in the
CTSCAN.CH include file and in Appendix A.
Examples
■ This example shows a keyboard entry that is redirected through
DOS:
C:\>TEST < KEYS.DAT
■ This example shows the application TEST.EXE:
DSetKBIOS(.F.) // Switch to DOS input mode
ACCEPT "" TO cInput
lNewLFMode Designates whether the next line feed for the screen is ignored (.T.) or not (.F.). The default value (.F.) designates that the next line feed is not ignored.
Returns
When called without a parameter, the function returns the current setting for DSETNOLINE(). If a parameter is passed, it returns the previous setting.
Description
DSETNOLINE() can be used in conjunction with a LIST command when you have empty lines you want overwritten by the next line (see example). You can also suppress a line feed issued by CA-Clipper before each LIST. This makes it possible to begin LIST output on line 0.
Examples
When you use DSETNOLINE(), records with the Art_nr field empty are
written to the screen but are overwritten by the next record where
Art_nr is present:
LIST Art_nr, Art_bez, DSETNOLINE(Empty(Art_nr))
Creates a protocol file when the program ends normally
Syntax
DSETQFILE([<lNewQuitMode>]) → lOldQuitMode
Arguments
lNewQuitMode Designates whether the automatic QUIT file is created (.T.) or not (.F.). The default value (.F.) does not create an automatic QUIT file.
Returns
When called without parameter, the function returns the current DSETQFILE() setting. If a parameter is passed, it returns the previous setting.
Description
This function allows for the creation of a QUIT file. This file can be used to determine if an application has been terminated normally or not (i.e. Ctrl-Alt-Del). When the program ends, the contents of the keyboard buffer are written to a file. This allows you to determine what keyboard input the user made, which can be used to trace errors and reconstruct files. The size of the QUIT file corresponds to the size of the keyboard buffer. To save more than the 16 default characters, you must increase the keyboard buffer size with SET TYPEAHEAD. (The maximum buffer size 32768 keystrokes.)
The name for the QUIT file is normally constructed from the name of the .EXE file with a .Q extension. SETQNAME() lets you use any file name you choose.
Notes
■ The keyboard data appears in KEYREAD() format in the QUIT file
■ Only those keyboard inputs already processed by the program
are written to the QUIT file.
■ An existing QUIT file is overwritten automatically if it has
the same name as the QUIT file that is currently being written.
Examples
■ This statement causes the program to create a standard QUIT
file when you exit the program:
DSETQFILE(.T.) // QUIT file will be created
■ Select the name of the QUIT file:
SETQNAME("C:\LOGS\PROTO.LOG")
DSETQFILE(.T.) // QUIT file will be created
// with an alternate name
Determines the size of the keyboard buffer (SET TYPEAHEAD TO)
Syntax
DSETTYPE() → nBufferSize
Returns
DSETTYPE() returns the current size of the CA-Clipper keyboard buffer.
Description
DSETTYPE() allows you to determine what size the CA-Clipper keyboard buffer has been set to with SET TYPEAHEAD TO. You can use the function to determine the number of characters that can be placed in the keyboard buffer using KEYSEND().
Notes
■ The keyboard buffer is made of memory that is internal to
CA-Clipper, which is independent of the system buffer. In CA-Clipper, the standard setting for TYPEAHEAD is 16 characters. (This corresponds to the size of the system buffer.)
■ For every character that is processed in a CA-Clipper program,
two bytes must be allocated in the keyboard buffer. DSETTYPE() determines the number of CA-Clipper characters, not the number of bytes! The standard buffer size is not 16, but 32 bytes.
Examples
The current size of the keyboard buffer is queried and increased if
needed:
nSize := DSETTYPE()
IF nSize < 256
SET TYPEAHEAD TO 256
ENDIF
Reroutes external functions and programs to a window
Syntax
DSETWINDOW([<lNewDisplayMode>]) → lOldDisplayMode
Arguments
lNewDisplayMode Designates whether the screen output from external programs or other language UDF's displays in the current window.
Returns
When called without a parameter, the function returns the current setting for DSETWINDOW(). If a parameter is passed, it returns the previous setting.
Description
DSETWINDOW() allows you to determine if only CA-Clipper screen outputs should appear in a window, or if all outputs (all external modules and programs, including DOS) should appear. If you would like to implement a subroutine for screen handling with CA-Clipper Tools window functions, you can use this switch to turn off these functions for a short time.
Important! Before you call external programs using RUN, you should set DSETWINDOW() to .F.; if you do not, some programs will not run correctly.
Notes
Important! The standard setting for DSETWINDOW() is on. This means that all program output, not written directly into the screen memory, displays in the currently active window.
■ CA-Clipper screen output is always written in a window if one
is open and active. Only screen output from external routines (like Assembler or C UDF's, or external programs called using RUN) can be affected. CA-Clipper Tools functions are also viewed as foreign or external.
■ If you call DSETWINDOW() with .T., a change in cursor position
in an external module or program also affects the cursor position in CA-Clipper. If you do not want to change the cursor position in CA-Clipper, then set DSETWINDOW() to .F. so that the CA-Clipper cursor position remains unchanged. If you still want to pass the cursor position to CA-Clipper, then use the SetRC() function without parameters.
■ Some CA-Clipper Tools functions ignore this switch because
they work directly with the physical screen memory.
■ CA-Clipper Tools has a public variable available for your own
Assembler or C routines to affect the DSETWINDOW() function. It can be addressed as follows:
EXTR _WINDOW:WORD MOV _WINDOW, 0 // Window functions OFF, all
// other values switched ON!
■ If the switch is set to on, then interrupt 16 (10h, video) and
function 19 (13h, write string), normally only available on AT's, become available on PC XT's.
Examples
■ Do not reroute other program output to the selected window:
DSETWINDOW(.F.)
■ Do a test to see if ANSI.SYS has been linked in to CONFIG.SYS:
lVar := DSETWINDOW(.F.)
? ISANSI()
DSETWINDOW(lVar) // Reset to old status
Angle Designates a valid angle measurement in degrees.
Returns
DToR() returns the radian of the specified value.
Description
In addition to expressing angle measurements in degrees, you may also need to express an angle in radians. With DToR(), you can convert degree measurements into radians.
EGA43() returns .T. if the screen graphics adapter successfully switched to the 43-line mode.
Description
This function can be used with either an EGA or VGA card. A 43-line mode is requested, and the maximum number of coordinates for the CA-Clipper screen output is automatically increased. It isn't necessary to also call the SETMAXROW() and SETMAXCOL() functions.
Notes
Important! This function cannot be implemented when windows are open.
Examples
The following example switches to 43-line mode, making lines 0 to 42
available:
IF IsEGA()
EGA43()
ENDIF
@ 42, 10 SAY "CA-Clipper" // Last line
WAIT
CGA80() // Return to 25-line mode
EGAPALETTE([<cColor1|nColor1>, [<nPalette>])
→ lValid
or
EGAPALETTE([<cColor1|nColor1>, [<cColor2>]])
→ lValid
Arguments
cColor1|nColor1 Designates the color to change as a CA-Clipper color code or a numeric in the 0 to 15 range. If only this color is given, the accompanying palette is reset to its default value.
nPalette Designates which color palette the color cColor1|nColor1 is assigned to. May be in the range of 0 to 63.
cColor1|nColor1, cColor2 If a color is also designated as a second parameter, then that color's palette is designated as cColor1|nColor1.
() When no parameters are designated, all color palettes are reset to their default values.
Returns
EGAPALETTE() returns .T. when the selected setting is successfully implemented.
Description
EGAPALETTE() allocates one of the 16 colors available to another color palette. Since the function changes the screen adapter, everything on the screen designated with cColor1|nColor1 also changes.
Instead of a palette value, you can designate a second color. Its palette setting is allocated to the one designated in cColor1|nColor1, so that two of the 16 colors are identical.
If only the cColor1|nColor1 parameter is given, then the accompanying palette is reset to its default value. When calling the function without parameters, all palettes are reset.
Notes
■ You can also implement EGAPALETTE() in VGA mode, although
■ Redefine the color blue to dark blue:
SET COLOR TO B // Set blue
? "Nantucket" // Appears in blue
EGAPALETTE("B", 8) // Affects everything blue.
■ Reset the palette for the color blue:
EGAPALETTE("B")
Reset all palettes
EGAPALETTE()
Selects the enhanced color value for SET COLOR TO output
Syntax
Enhanced() → cNull
Returns
Enhanced() always returns a null string
Description
Use Enhanced() to specify the color attribute designated as enhanced (second color value), with SET COLOR TO as the active attribute for CA- Clipper @...SAY and ? output. Use Standard() to switch back to the default attribute.
Reads the entire DOS environment table into a string
Syntax
EnvParam() → cEnvironment
Returns
EnvParam() returns a string that corresponds to the complete environment table.
Description
This function returns the entire DOS environment table. The DOS Chr(0) delimiter, which follows each variable and its setting, is replaced with CR/LF. This allows the returned string to work well with the CA-Clipper Tools string functions (especially the tokenizer).
Notes
■ With the CA-Clipper function GetEnv(), you can query
individual parameters from the environment. Initially, this may seem convenient, but there is a problem because no blanks are allowed before and after the '='.
Examples
Read in the environment and analyze it:
cVar := EnvParam() // CR/LF as delimiter
TOKENINIT (@cVar, Chr(13) + Chr(10),2) // CR/LF as delimiter,
skip 2
DO WHILE .NOT. TokenEnd()
Env := TokenNext(cVar)
? Env
ENDDO
dDate Designates the date for the last day of the quarter in which it lies, is calculated. The default is the system date.
Returns
EoQ() returns the last day for the quarter that contains dDate.
Description
EoQ() determines when the current quarter that contains dDate ends. For example, it lets you calculate the number of days that remain before the end of the quarter.
Notes
■ If you do not specify a date, the function automatically uses
the system date. An empty date parameter results in an empty date.
Examples
The last day of the current quarter is:
? "The last day of the current quarter is:", EoQ()
Recommends an action for a DOS error that has occurred previously
Syntax
ERRORACT() → nActionCode
Warning! This function requires DOS 3.1 or higher.
Returns
ERRORACT() returns a numeric code that provides more information on how to react to the last DOS error. Coding is as follows:
Table 12-2: DOS Error Action Codes
Code Definition
1 Try several times, then ask user
2 Try several times with pauses, then ask user
3 Ask user for data
4 Leave program normally
5 Leave program as soon as possible
6 Ignore
7 User should correct error and try again
Description
DOS reacts to errors in several ways. One of the best known and least preferred by programmers is the question: "(A)bort, (R)etry, (I)gnore". ERRORACT() tells you how the application should react to the last DOS error that occurred.
Examples
Show an error that requires the program to terminate:
nAction := ERRORACT()
IF nAction = 4
? "Unfortunately, the program must be terminated!"
QUIT
ENDIF
ERRORBASE() → nErrorCode
Warning! This function requires DOS 3.1 or higher.
Returns
ERRORBASE() returns a numeric code that provides additional information about the cause of the error. These codes and their definitions are in the table below:
Table 12-3: Causes for DOS Errors
Code Definition
1 Insufficient memory
2 Access temporarily denied
3 No access for this user
4 Internal error, system software
5 Hardware error
6 Error in system software
7 Error in applications program
8 File not found
9 Wrong file format or type
10 File is protected
11 Incorrect medium in drive
12 Other error
Description
If an error is detected with ERRORCODE(), use ERRORBASE() for more information about the cause of the error, from within the data returned by DOS.
Examples
Determine the cause for an error:
nCause := ERRORBASE()
IF nCause = 3
? "Access denied!"
ENDIF
Identifies a DOS error that has occurred previously
Syntax
ERRORCODE([<lKeep>]) → nDosErrorCode
Warning! This function requires DOS 3.1 or higher.
Arguments
lKeep When this parameter is designated as .T., the function returns the internal error code memory value.
Returns
ERRORCODE() returns a value that represents the error code that occurred during the most-recently executed DOS function.
Description
If you do not specify a parameter or if the parameter is .F., then ERRORCODE() calls the DOS error function (INT 21h, 59h) and returns the code value stored for the most-recent error. DOS stores the most-recent error code until a new error occurs. If your operation is error free, this value is not reset.
To take this situation into account, ERRORCODE() can alternatively be called with lkeep set to .T.. If called like this, the error code always relates to the last CA-Clipper Tools function that was executed. Since the respective CA-Clipper Tools function behavior is stored at an internal memory location, it is impossible to implement this option with regular CA-Clipper functions.
Notes
■ You can find a table that contains all the error codes in
Appendix B: Error Codes.
Examples
■ This example attempts to copy a file. If an error occurs,
FileCopy() returns a value of 0 which offers no specific error
information:
nBytes := FileCopy("TEST\TEST.PRG", "NEW.PRG")
IF nBytes = 0 .AND. ERRORCODE() = 3
? "File path not found!"
ENDIF
■ An example of two file copies is illustrated below:
The first file is unsuccessful, but the second file is not:
FileCopy("XXXXX.TXT", "YYYY.TXT")
? ERRORCODE(.T.) // 2 - File not found
? ERRORCODE() // 2 - File not found
FileCopy("SOURCE.TXT", "TARGET.TXT")
? ERRORCODE(.T.) // 0 - Last Tools
// function was successful
? ERRORCODE() // 2 - File not found
Warning! Any CA-Clipper Tools function that contains a DOS call
resets the internal variable retrieved by setting <lKeep> . The
following call series never returns the desired result, because the
first call of ERRORCODE() contains a DOS call:
? ERRORCODE(), ERRORCODE(.T.) // Result: x, 0
ERRORORG() → nError
Warning! This function requires DOS 3.1 or higher.
Returns
ERRORORG() returns a numeric code that provides more information about the device on which the error occurred. The table below details this information:
Table 12-4: Origin of DOS Errors
Code Definition
1 Unknown
2 Block device (floppy, hard disk, etc.)
3 Network
4 Character device (COM, SCRN, etc.)
5 RAM
Description
ERRORORG() tells what type of device generated the most-recent DOS error. This essential information allows you to handle the error in an appropriate way.
Examples
Determine the source of an error:
nSource := ERRORORG()
IF nSource = 3
? "Error is on the network!"
ENDIF
Returns name and directory of the current CA-Clipper program
Syntax
ExeName() → cProgram
Returns
ExeName() returns the name and path of the current .EXE program.
Description
This function determines the name and path of the CA-Clipper application in use.
Notes
■ Use the Token() function to determine the name portion of a
program within a path.
Examples
Determine if the name or path of an EXE file has changed:
cOrigPath := "C:\DATA\ADDRESS.EXE"
IF ExecName() <> cOrigPath
? "Program name or directory have been changed!"
QUIT
ENDIF
nNumber Designates the number of the cCharacter|nCharacter characters that are inserted between each character in the cString. The default value is one character.
cCharacter|nCharacter Designates the character that is inserted between each character in cString. The default value is a space, Chr(32).
Returns
The processed cString is returned.
Description
Expand() can be used to justify text output, although the text is stored normally. This saves memory capacity with text constants or in databases.
Notes
■ Expansion only takes place when the cString contains at
least two characters.
■ To fill out a character string at the ends, use the PadLeft()
■ Use the default value and expand with one space:
? Expand("123456") // "1 2 3 4 5 6"
■ Expand with two spaces:
? Expand("123456", 2) // "1 2 3 4 5 6"
■ Expand with a ".":
? Expand("123456", ".") // "1.2.3.4.5.6"
■ Expand with two "."s:
? Expand("123456", 2, ".") // "1..2..3..4..5..6"
Determines the exponent of a floating point number (base 2)
Syntax
Exponent(<nFloatingPointNumber>) → nExponent
Arguments
nFloatingPointNumber Designates any decimal number.
Returns
Exponent() returns the exponent of the nFloatingPointNumber number in base 2.
Description
CA-Clipper stores all numbers in a floating point format (called "double" in C). Exponent() only returns exponents in this format, and they are always expressed in base 2.
Notes
■ The expression Exponent(0) returns a value of 0. However, the
expression 20 returns a value of 1. In this case, the mantissa must also equal 0 (see Mantissa()).
Examples
■ The following calculation produces the original number:
^2 Exponent(nValue) * Mantissa(nValue)= nValue
? Exponent(0) // Result: 0
? Exponent(Infinity()) // Result: 1023
? Exponent(100) // Result: 6
■ The sign for nValue will not be considered:
? Exponent(-100) // Result: 6
? Exponent(-1.01) // Result: 0
? Exponent(-2.01) // Result: 1
■ Values in the range of -1 < nValue < +1, yield negative
exponents regardless of the sign:
? Exponent(0.01) // Result: -7
? Exponent(-0.01) // Result: -7
Fact() returns the factorial of the specified value.
Description
Fact() computes the factorial of a value in the range of 0 to 21. Since results for factorials over 21 are too large, the function returns -1 to indicate an error.
Examples
Show some factorials:
? Fact(1) // Result: 1
? Fact(5) // Result: 120
? Fact(21) // Result: 51090942171709440000
? Fact(25) // Result: -1 (Value too large !)
? Fact(0) // Function returns 1
Determines the number of decimal places in a field
Syntax
FieldDeci(<nField>) → nDecimalPlaces
Arguments
nField Designates for which numeric data field to determine the number of decimal places.
Returns
When a field number is valid, FieldDeci() returns the number of decimal places in a numeric data field.
Description
It is important to know how many decimal places are in a data field so you can limit the input of significant digits in the corresponding number. FieldDeci() determines the number of decimal places available. This allows you to tailor inputs to the database without changing the program.
Notes
■ If you have an invalid field number, the function returns a
value of 0.
Examples
Convert the second field to a string with the correct number of decimal
places:
@ 0, 60 SAY "Price: " + Str(cField2, 8, FieldDeci(2))
Determines the field number for a specific field in a database file
Syntax
FieldNum(<cFieldName>) → nFieldNumber
Arguments
cFieldName Designates to the field name.
Returns
FieldNum() returns the number of the data field.
Description
FieldNum() is the exact opposite of the CA-Clipper Field() function. Use this function when you need a data field number instead of the data field name. FieldNum() determines if a symbol name pertains to a data field or a memory variable (see Examples).
Notes
■ If a data field with the name cFieldName is not available,
the function returns a value of 0.
Examples
Is it a field or a variable?
IF FieldNum("cName") > 0.
REPLACE cName WITH Upper(cName).
ELSE.
cName := Upper(cName).
ENDIF
nField Designates the number of the field to evaluate.
Returns
FieldSize() returns a numeric value that corresponds to the field length of a valid field number.
Description
Use FieldSize() to determine the length (or size) of data field of desired data types. This determines the window width needed for output to appear without a line break, or the length needed for an input to automatically fit in the database.
Notes
■ If there is an invalid data field number, the function returns
a value of 0.
Examples
Determine the total length of fields 3 to 5:
nLength := 0
FOR I = 3 TO 5
nLength := nLength + FieldSize()
NEXT
nField Designates the data field for which the data type is determined.
Returns
FieldType() returns a single character that designates the data type of the data field (assuming the data field number is valid). FieldType() returns the following characters for the various data field types:
Table 10-1: Coding for Data Field Types
Character Data Type
C Character string
N Numeric
D Date
L Logical
M MEMO
Description
FieldType() operates in a similar fashion to the CA-Clipper Type() function. With Type(), you must always know only the name of the data field. However, FieldType() requires that you only know the data field, not its name. Use the function to confirm data types for data fields when a program is working with different databases that have different field names.
Notes
■ If there are invalid data field numbers, the function returns
a null string.
Examples
Data type for field number 5:
IF FieldType(5) = "C"
? "Field No. 5 is a character field!"
ENDIF
cSourceFile Designates the file that is appended to cTargetFile.
cTargetFile Designates the file to which cSource is appended. Drive and path designation are permitted for both files, wildcards are not.
Returns
FileAppend() returns the number of characters appended on to cTargetFile.
Description
FileAppend() takes fragmented files, split them up on different floppies and reassemble them. This sort of fragmented file could be created with the FileCopy() system described in this chapter. You only need explicit information, such as VOLUME labels, to recognize the different disks. If the target file does not exist, it is created with FileAppend(). If an error occurs while appending to the target file, the file deletes completely to avoid accidental and incorrect results.
Never append data to file if there is no backup copy.
Notes
■ Use SetFCreate(), if FileAppend() creates a new file and an
alternative attribute needs to be specified.
■ Use SETSHARE() to protect a target file from access, if it is
on a network drive.
Examples
Shown below is a simplified program to reassemble a file that is divided
among several disks by a FileCopy() backup.
A catalog contains a list of the disks used during backup in the form of
volume labels and backup file names.
Structure of the DISKLIST catalog:
Table 7-10: DISKLIST File Structure
<table>
Field Name Field Content
VolLabel Back up disk drive and volume label
BackupName Back up file name, incl. drive and path
</table>
The data in DISKLIST is created by a FileCopy() backup:
USE DISKLIST // Saved volume labels
cTargetFile := "C:\TARGET.TXT"
DO WHILE .NOT. Eof()
IF .NOT. Empty(FileSeek(cVolLabel, 8) // Correct disk ?
FileAppend(cBackupName, cTargetFile) // Yes, append data
SKIP
ELSE
? "Please insert the correct disk !"
ENDIF
ENDDO
cFile Designates the file name, including the path and drive designation.
Returns
FileAttr() returns the attributes for the researched entry or the attribute from the FileSeek() buffer (when called without a parameter).
Description
FileAttr() is implemented alone or in conjunction with FileSeek(). If the function is called with the cFile parameter, it returns the attribute of the first entry found. If no acceptable entry is available, a value of 0 is returned.
When called without a parameter, FileAttr() returns the attribute for the most-recent file located with FileSeek(). When used with FileSeek(), you can determine the attribute for file groups (wildcards).
When you call FileAttr() with the cFile parameter, the function internally passes 63 (all attributes) as a mask. When used in conjunction with FileSeek(), you should also designate all 63 as an attribute mask, if all files are to be acknowledged.
Table 7-11: Coding the File Attribute
Value Symb. constants Assigned attribute
0 FA_NORMAL
1 FA_READONLY READ ONLY (Read-only)
2 FA_HIDDEN HIDDEN (Hidden files)
4 FA_SYSTEM SYSTEM (System files)
8 FA_VOLUME VOLUME (Name of a floppy/hard disk)
16 FA_DIRECTORY DIR (Directory)
32 FA_ARCHIVE ARCHIVE (Changes since last backup)
If multiple attributes are implemented for a file, the value of each corresponding attribute is added.
Examples
■ Show the attribute of a specific file:
? FileAttr("C:\TEXT\TEXT.TXT") // 32 ARCHIVE
■ The attribute for an ARCHIVE/HIDDEN file:
? FileAttr("C\HIDE.TXT") // 34 HIDDEN + ARCHIVE
■ Used in conjunction with FileSeek():
cFile := FileSeek("C:\TEXT\TEXT.TXT")
DO WHILE .NOT. EMPTY (cFile)
? cFile, FileAttr() // Name & file attribute
cFile := FileSeek() // Search for next entry
ENDDO
FileCCLose() returns .T., when the the file that was opened with FileCopy() is successfully closed.
Description
FILE COPY CLOSE After you copy on multiple disks, this function should be routinely called. This is to prevent the source file, previously designed with FileCopy(), from remaining open. For example, this may occur if you terminate the copy procedure.
Notes
■ Regardless of the share mode, all other users are not allowed
access. This situation stays this way without needing a file handle.
Examples
Show a back up with FileCopy(). After terminating, close the source
file:
FileCopy(cSource, cTarget, .T.) // Back up mode
DO NEXTDISK // When terminated Terminated =
.T.
DO WHILE FileCOpen() .AND. .NOT. Terminated
FileCCont(cTarget) // Next disk, new name
DO NEXTDISK // Request for disk exchange
ENDDO
IF Terminated
FileCCLose() // Close source file!
ENDIF
cFile Designates the file name for the target file.
Returns
FileCCont() returns the number of bytes copied.
Description
FILE COPY CONTINUE Use this function primarily after a FileCopy(). As much as possible of the remaining data is written to a new disk. If the remaining data still does not fit on the designated target disk, call this function repeatedly until it writes all the remaining data. Each time you call FileCCont(), a new name can be designated for the target file. These files are then numbered consecutively (see Examples).
Notes
■ If a copy procedure on multiple disks terminates for any
Show a back up with FileCopy(). After terminating, close the source
file:
FileCopy(cSource, cTarget, .T.) // Back up mode
DO NEXTDISK // When terminated Terminated = .T.
DO WHILE FileCOpen() .AND. .NOT. Terminated
FileCCont(cTarget) // Next disk, new name
DO NEXTDISK // Request for disk exchange
ENDDO
IF Terminated
FileCCLose() // Close source file!
ENDIF
Determines whether a source file's date and time stamp or the system's date and time stamp, should be used to create or copy a file. Use original or
Syntax
FileCDaTi([<lNewMode>]) → lOldMode
Arguments
lNewMode Designates the new status for FileCDaTi(). When .T. is designated, the target file contains the source file date; when it is .F., the system date. The default is the source file date (.T.).
Returns
If no parameter is designated, FileCDaTi() returns the current setting for FileCDaTi(); otherwise, it returns the previous setting.
Description
FILE COPY DATE TIMEFileCDaTi() determines which date the target file contains with a FileCopy(). When you partition to several disks in backup mode, this concerns all target files. The CA-Clipper Tools default is .T., where the target file contains the date and time of the source file. If you call FileCDaTi() with the parameter designated .F., then the target file contains the system date and time.
■ Query the FileCDaTi() setting:
? FileCDaTi() // The current setting
■ The target file is to contain the system date and time:
? FileCDaTi(.F.) // Returns the previous setting
cSourceFile Designates the source file. Drive and path designations are permitted, but not wildcards.
cTargetFile Designates the target file. Drive and path designations are permitted, but not wildcards.
lMode Designates the backup mode on when designated as .T. The default is no backup mode (.F.).
Returns
FileCopy() returns the number of bytes copied.
Description
This function has additional uses besides allowing you to quickly copy files. When you use the optional lMode parameter, a unique backup mode is switched on. This allows files that are larger than the target disks to be copied. This function writes the maximum possible number of bytes to a disk. FileCOpen() allows you to determine whether all data from the source file has been copied. It then continues with the next disk. The target disks should contain unique labels and be saved to a catalog.
Notes
■ The attribute to be used when newly creating a file can be
specified with SETCREATE().
■ As a minimum, the share mode recommends that you do not write
other program source and target files.
■ This function acknowledges the CSetSafety() setting, and as a
result, cannot overwrite a target file.
Examples
■ Show a simple copy:
? FileCopy("A:\TEXT.TXT", "C:\TEST.TXT") // Bytes copied
■ A back up using FileCopy():
nCounter := 1 // "BIG.001" etc.
cTargetFile := "BIG" + NToC(nCounter, 10, 3, "0")
FileCopy("BIG.DBF", "A:\" + cTargetFile, .T.)
// Back up mode
DO WHILE FileCOpen()
DO NEXTDISK // Request disk change
nCounter := nCounter + 1
cTargetFile := "BIG" + NToC(nCounter, 10, 3, "0")
FileCCont(cTargetFile) // Next disk - new name
ENDDO
RETURN
PROCEDURE NEXTDISK
? "Please insert new diskette in Drive A:!"
WAIT
RETURN
Tests to see if the file is still open in the backup mode
Syntax
FileCOpen() → lOpenFile
Returns
FileCOpen() returns .T. when all data is not copied during a FileCopy() or FileCCont().
Description
FILE COPY OPENFileCOpen() determines whether all data is copied. This concerns the source file, which is specified when the FileCopy() function is called. FileCOpen() returns .T. until all the data in the source file is read, whether by FILECOPY or the follow-on function FileCCont()
Notes
■ If you must abort the copy process, and FileCOpen() continues
Show a back up with FileCopy():
nCounter := 1 // "BIG.001" etc.
cTargetFile := "BIG" + NToC(nCounter, 10, 3, "0")
FileCopy("BIG.DBF", "A:\" + cTargetFile, .T.)
// Back up mode
DO WHILE FileCOpen()
DO NEXTDISK // Request disk change
nCounter := nCounter + 1
cTargetFile := "BIG" + NToC(nCounter, 10, 3, "0")
FileCCont(cTargetFile) // Next disk - new name
ENDDO
FILECCLOSE // For safety
cFileMap Designates a file name, including its path and drive designation.
nFileAttr Designates the file attribute explained in the table below. The default value is 0.
() If you call this function without parameters, it returns the file date from the current FileSeek() buffer.
Returns
FileDate() returns the date of the searched for entry, the date from the FileSeek() buffer (when called without parameters), or an empty date.
Description
You can implement FileDate() alone or in conjunction with FileSeek(). If you use the cFileMap parameter to call this function, it returns the date of the first entry found. If a suitable entry is not present, an empty date is returned.
When called without parameters, FileDate() returns the date of the last file it located with FileSeek(). You could also determine the dates for a file group (wildcards), when used it in conjunction with FileSeek().
The attribute for the desired file can be specified in numeric form:
Table 7-12: Coding the File Attribute
Value Symb. constants Assigned attribute
0 FA_NORMAL
1 FA_READONLY READ ONLY (Read-only)
2 FA_HIDDEN HIDDEN (Hidden files)
4 FA_SYSTEM SYSTEM (System files)
16 FA_DIRECTORY DIR (Directory)
32 FA_ARCHIVE ARCHIVE (Changes since last backup)
To find a file, specify only the SYSTEM, HIDDEN, VOLUME, or DIR attributes. If multiple attributes are implemented simultaneously, the table values are added accordingly. Of course, not all combinations are useful.
Examples
■ Show the date of a particular file:
? FileDate("C:\TEXT\TEXT.TXT") // The date
■ The date of an ARCHIVE/HIDDEN file:
? FileDate("C:\HIDE.TXT", 34) // The date
■ Used in conjunction with FileSeek():
cFile := FileSeek("C:\TEXT\*.TXT")
DO WHILE .NOT. Empty(cFile)
? cFile, FileDate() // Name & date of file
cFile := FileSeek() // Search for next entry
ENDDO
nFileAttr Designates one of the following file attributes. The default value is 32.
Table 7-13: File Attribute Coding
Value Symb. constants Definition
0 FA_NORMAL
1 FA_READONLY Read-only
2 FA_HIDDEN HIDDEN (Concealed files)
4 FA_SYSTEM SYSTEM (System files)
8 FA_VOLUME VOLUME (Name of floppy/hard disk)
32 FA_ARCHIVE ARCHIVE (Changed since last backup)
Returns
FileDelete() returns .T. when at least one or more files are deleted; otherwise, .F. is returned.
Description
Occasionally, you will need to clean up a floppy or a hard disk or delete whole file groups. This function deletes entire file groups with a function call, without using the RUN command.
Notes
Warning! FileDelete() can also delete system files.
■ The default standard attribute is archive (32). Drive and
path designations, and wildcards are permitted.
■ Subdirectories must be deleted with the help of the
cSourceFile Designates the name and the path of the source file.
cTargetFile Designates the name and the path of the target file.
Returns
FileMove() returns a value of 0 when the file can be moved; otherwise, an error code is returned. The codes are defined below:
Table 7-14: FileMove() Error Codes
Code Symb. constants Definition
0 NO_DISK_ERR No errors
-2 ER_FILE_NOT_FOUND File not found
-3 ER_PATH_NOT_FOUND Access path not found
-5 ER_ACCESS_DENIED Access denied (e.g., network)
-17 ER_DIFFERENT_DEVICE Target file not on same drive
Description
If a file is to be copied within a drive and then deleted it from the original position, it is quicker to move the file. FileMove() makes this possible. The directory entries are also changed, which is much quicker than copying and deleting.
Notes
■ You can use drive designators and access paths in
cSourceFile and cTargetFile file names. Wildcards are not permitted.
■ You can only move a file within a drive. If the target
directory already contains a file with the same name as the one from cSourceFile, the move is not completed. In this case, FileMove() returns a value of -5. The only option available in this situation, is to delete the file in the target directory.
Examples
Move a file from "\OLD" to "\NEW":
IF FileMove("\OLD\CUST.DBF", "\NEW\CUST.DBF") = 0
? "The file is now in the \NEW directory"
ENDIF
cFileName Designates the name and path of the screen file.
nOffset Designates from which part of the file offset the screen is to be read. The default is the beginning of file.
Returns
FileScreen() returns the number of bytes read.
Description
FILESCREEEN() is the opposite of ScreenFile(). Use FileScreen() to read and display a screen stored with ScreenFile(). Use the nOffSet parameter to indicate an offset from which the file is to be read. Since the number of bytes written with ScreenFile() is known, you can compute the location within the file of the beginning of the new screen. This allows you to save multiple screens in a single file.
Notes
■ The file read with FileScreen() can also contain end of file
markers. The read procedure does not end prematurely as a result, since the function always reads 4000 bytes.
Examples
■ Read a screen from the beginning of a file:
FileScreen("screen.tst")
■ Read the second screen. Since the offset is specified as
4000, the first screen is skipped:
FileScreen("screen.tst", 4000)
■ Drive and path are permitted:
FileScreen("\screen.tst")
FileScreen("a:screen.tst")
■ Wildcards are not permitted:
FileScreen("screen.*") // Result: 0
cFileMap Designates a file name including its path and drive designation. It may contain wildcards.
nFileAttr Designates the file attribute that corresponds to the ones described in the table on the next page. The default value is 0.
lExact If you designate .T. as the optional parameter, FileSeek() also checks for the exact agreement of the file attributes of the respective file with the value passed by nFileAttr.
() If you call the function without parameters, it serves as a sequential call for a FileSeek() with file specifications, and returns sequential entries as long as these are found.
Returns
FileSeek() returns the name of the first or next entry (when called without parameter) located in the selected directory.
Description
FileSeek() provides the foundation for a variety of functions. As a group, they permit access to desired information about directory entries. Implement the FileSeek() function when you want information about a file group (wildcards). When you call it with the cFileMap parameter, it searches for the first entry in the designated directory. If you call it without parameters, it searches for the next matching entry in the directory. If no more entries are present, it returns a null string. An attribute mask can further define a file group that is being searched for. The desired file attributes are coded as follows:
Table 7-15: Coding the File Attribute
Value Symb. constants Assigned attribute
0 FA_NORMAL
1 FA_READONLY READ ONLY (Read-only)
2 FA_HIDDEN HIDDEN (Hidden files)
4 FA_SYSTEM SYSTEM (System files)
8 FA_VOLUME VOLUME (Name of a floppy/hard disk)
16 FA_DIRECTORY DIR (Directory)
32 FA_ARCHIVE ARCHIVE (Changes since last backup)
If you implement multiple attributes simultaneously, the table values are added accordingly. Of course, not all combinations are useful.
Exact File Attributes
DOS does not make an exact comparison with a designated attribute mask and attributes actually found in a file. Specify only the SYSTEM, HIDDEN, VOLUME, or DIR attributes for an entry to be found. Files with only one other attribute bit set are always returned, regardless of the value specified in the attribute mask. This way, a function call with a mask value of 16 returns not only subdirectories, but all files without a set attribute (e.g., all the ARCHIVE and R/O files).
To avoid this, you can designate .T. as the third parameter. The function itself also reviews the designated attribute mask with the actual file attributes, for an exact agreement. Then, the designation of a 16 mask and .T., only returns subdirectories.
Internal Data Buffer
Every time you use FileSeek() all the data for a directory entry is saved to an internal buffer. Individual information such as size, time, or date is easily accessible. To do this, the FileTime(), FileDate(), etc., functions are called without parameters; otherwise, it requires another call to the disk, instead of taking the data from an internal buffer.
Notes
■ Use the recursive sample function SCANFILES() in the
accompanying Tooldemo.prg file, to produce the most effective programs to work with entire directory structures.
■ Display the date and size of all files with the extension .TXT
in a directory:
cFile := FileSeek("C:\TEXT*.TXT") DO WHILE.NOT. Empty(cFile)
? FileSize() // Size of file in buffer ? FileDate() // Date of file in buffer cFile := FileSeek() // Search for next entry
ENDDO
■ Display system files in the root directory. Attribute: READ
ONLY, HIDDEN, SYSTEM, ARCHIVE → 39, although 6(2 + 4) will suffice as an attribute:
cFile := FileSeek("C:*.*", 39) DO WHILE.NOT. Empty(cFile)
? cFile // File name cFile := FileSeek() // Look for next entry
ENDDO
■ Only query the subdirectory:
cSubDir := FileSeek("C:*.*, 16, .T.) DO WHILE.NOT. Empty(cSubDir)
? cSubDir // Name of the directory cSubDir := FileSeek() // Search for next directory
cFileMap Designates the file name, path, and drive designation.
FileAttr Designates the file attribute that is explained in the table below. The default value is 0.
() If the function is called without parameters, it returns the file size from the current FileSeek() buffer.
Returns
FileSize() returns the designated file's size, the size from the FileSeek() buffer (when called without a parameter), or -1.
Description
Implement FileSize() alone or in conjunction with FileSeek(). If the function is called with the cFileMap parameter, it returns the size of the first entry found. If no matching entry is available, then a value of -1 is returned
When called without parameters, FileSize() returns the size of the most recent file found with FileSeek(). Used in conjunction with FileSeek(), you can also determine the size of file groups (wildcards).
You can designate the attribute for the desired file in numeric form:
Table 7-16: Coding the File Attribute
Value Symb. constants Assigned attribute
0 FA_NORMAL
1 FA_READONLY READ ONLY (Read-only)
2 FA_HIDDEN HIDDEN (Hidden files)
4 FA_SYSTEM SYSTEM (System files)
32 FA_ARCHIVE ARCHIVE (Changes since last backup.)
Specify only the SYSTEM, HIDDEN, VOLUME, or DIR attributes for an entry to be found. If multiple attributes are implemented simul-taneously, the table values are added accordingly. Of course, not all combinations are useful.
Examples
■ Show the size of a particular file:
? FileSize("C:\TEXT\TEXT.TXT") // File size or -1
■ The size of an ARCHIVE/HIDDEN file:
? FileSize("C:\HIDE.TXT", 34") // File size or -1
■ Used in conjunction with FileSeek():
cFile := FileSeek(C:\TEXT.TXT")
DO WHILE .NOT. Empty(cFile)
? cFile, FileSize() // File name and size
cFile := FileSeek() // Search for next entry
ENDDO
Specifies the maximum number of files that can be open at one time
Syntax
FileSMax() → nMaxHandles
Returns
FileSMax() returns the maximum number of files that can be open at once.
Description
The value set for FILES= within the CONFIG.SYS, and the number of available handles, influences the maximum number of files that can be open simultaneously. The maximum number is determined by the smaller of the two values respectively.
Notes
■ The returned value is subtracted from the handles already
occupied by the operating system. This value is usually 5.
■ This function cannot determine if an additional operating
system adaptation (Novell's SHELL.CFG) has been made under a Novell network. These adaptations are only used for the current network drive under Novell.
Examples
How many files can be opened in the system?
? FileSMax() // e.g. 100
cFile Designates the file from which a string is read.
nLength Designates how many characters you want to read from a file (up to a maximum of 65520 bytes). The default is read all characters.
nOffset Designates an offset within the file from which the nLength characters or the rest of the file, are read. The default is from the first character (0).
lCtrl-Z If this parameter is designated as .T., only data up to the first Ctrl-Z is read in. The default is read all data (.F.).
Returns
FileStr() returns the string read in from the designated file.
Description
FileStr() also offers the capability to read files or a portion of them, into a string. This is only possible with a function call, where the file name may contain a drive and path designation. If you implement the lCtrl-Z parameter, you can be sure the function only reads data up to the first Ctrl-Z and ignores whatever might remains in of the file.
In contrast to the CA-Clipper Fxxxx() functions, a disadvantage of FileStr() is a slower access speed, since the file you want to read cannot be held open.
Notes
■ This function reads all available bytes in working memory (up
to 65520). The amount of available free memory is determined by calling Memory(1).
■ As recommended in share mode, no other programs should write
in the net through SETSHARE(2) for the duration of the read.
Examples
■ Read in a file completely:
? FileStr("C:\TEXT\TEST.TXT") // Displays file text
■ Read in everything to the first Ctrl-Z:
cVar := FileStr("C:\TEXT\TEST.TXT", .T.)
■ The file TEST.TXT contains "ABCDEFGHIJ". Four characters,
beginning from position 3, are to be read:
? FileStr("C:\TEXT\TEST.TXT", 4, 3) // "CDEF"
■ Read the maximum that fits into the available working memory:
cVar := FileStr("C:\TEXT\TEST.TXT", Memory(1) *1024 -100)
cFileMap Designates the file name, including the path and drive designation.
nFileAttr Designates the file attribute explained in the table below. The default value is 0.
() If the function is called without parameters, it returns the file time from the current FileSeek() buffer.
Returns
FileTime() returns the clock time for the "searched for" entry, the clock time from the FileSeek() buffer (when called without parameters), or a null string.
Description
Implement FileTime() alone or in conjunction with FileSeek(). If the function is called with the cFileMap parameter, it returns the time of the first entry found. If no matching entry is available, a null string is returned.
When called without parameters, FileTime() returns the clock time of the last file found with FileSeek(). You can also determine the clock time of file groups (wildcards) when the function is used in conjunction with FileSeek().
You can designate the attribute for the desired file in numeric form:
Table 7-17: Coding the File Attribute
Value Symb. constants Assigned attribute
0 FA_NORMAL
1 FA_READONLY READ ONLY (Read-only)
2 FA_HIDDEN HIDDEN (Hidden files)
4 FA_SYSTEM SYSTEM (System files)
16 FA_DIRECTORY (Subdirectory)
32 FA_ARCHIVE ARCHIVE (Changes since last backup)
Only the SYSTEM, HIDDEN, VOLUME, or DIR attributes must be specified for an entry to be found. If multiple attributes are implemented simultaneously, the table values are added accordingly. Of course, not all combinations are useful.
Examples
■ The clock time of a particular file:
? FileTime("C:\TEXT\TEXT.TXT") // File clock time or ""
■ The clock time of an ARCHIVE/HIDDEN file:
? FileTime("C:\HIDE.TXT", 34") // File clock time or ""
■ Used in conjunction with FileSeek():
cFile := FileSeek(C:\TEXT.TXT")
DO WHILE .NOT. Empty(cFile)
? cFile, FileTime() // File name and clock time
cFile := FileSeek() // Search for next entry
ENDDO
Calculates/computes/determines a checksum for a file
Syntax
FILECHECK(<cFile>) → nCheckSum
Arguments
cFile Designates which file name (with path, if required), to check.
Returns
FILECHECK() returns a checksum value for cFile.
Description
FILECHECK() determines if there have been changes or read errors in a file, and then takes note of data backup. This also allows you to protect your hard disk from simple viruses (see Examples).
Notes
■ You must specify the argument. If it is omitted or an
unavailable file is specified, FILECHECK() returns an error code of - 1. You may use a drive and access path, but no wildcards.
Examples
■ Check database for changes:
IF FILECHECK("CUST.DBF") <> Old_ChkSum
? "Warning! Data back-up required."
ENDIF
■ Check COMMAND.COM for changes:
IF FILECHECK("\COMMAND.COM") <> Cmd_ChkSum
? "COMMAND.COM has been changed! Caution, Virus!"
ENDIF
FILESFREE() returns the number of available handles.
Description
This function returns the number of available handles that correspond to the number of files you can open. This enables you to avoid DOS error 4.
Notes
■ Immediately after you start a CA-Clipper application, a value
— smaller than that of FileSMax() — is returned. This happens because the operating system and application itself is already using handles.
Examples
■ Can I still open a file?
IF FILESFREE() > 0 // At least 1 handle free?
USE CUSTOMER // Open a file
ENDIF
■ Be careful when you open multiple indexes at the same time!
IF FILESFREE() > 1 // At least 2 handles free?
USE CUSTOMER INDEX CUSTNR // Open 2 files
ENDIF
cFileName Designates the file name you want to test for validity.
Returns
FILEVALID() returns .T. when the designated name is valid.
Description
FILEVALID() determines if a string contains a valid file name. You could also test the validity of user input in this way. If necessary, path and drive designations must be removed from the string. The tokenizer described in the string chapter is available for this purpose (see Examples).
Examples
The last token in a string with drive and path designations should
contain the file name:
ACCEPT "Target_File " TO cVar
cFileName := TOKEN(cVar, " \:") // Last token
DO WHILE .NOT. FILEVALID(cFileName)
* Error message ...
ACCEPT "Target_File " TO cVar
cFileName := TOKEN(cVar, "\:") // Last token
ENDDO
nFirstNewColumn Designates which column is the first visible column on the left side of a virtual screen.
Returns
If the parameter is passed, the function returns the previous setting. If no parameter is passed, it returns the current setting.
Description
This function is important for use in setting virtual screen size in conjunction with SETMAXROW() and SETMAXCOL(). You can select the first column that you would like to be visible on the left side of the screen. In this way the screen can be moved in any direction.
Notes
■ To simplify programming, values outside of the permissible
range are automatically corrected to the maximum or minimum values (see example).
Examples
The following example sets up a screen with 100 lines and 120 columns.
To help you with screen orientation, the current column number is
displayed at three locations on this virtual screen. The virtual screen
can be moved in any direction using cursor keys and PgUp and PgDn:
SETMAXROW( 99) // screen with 100 lines
SETMAXCOL(119) // and 120 columns
CLEAR
FOR nCount = 0 TO MaxRow() // Build screen
@ nCount, 0 SAY "Line" + NToC(nCount, 10, 4)
@ nCount, MaxCol()/2 -5 SAY "Line" + NToC(nCount, 10, 4)
@ nCount, MaxCol() -10 SAY "Line" + NToC(nCount, 10, 4)
NEXT nCount
@ 99, 00 SAY Center("This is the last line")
nKeyVal := 0
DO WHILE nKeyVal <> 27
nKeyVal := Inkey(0)
DO CASE
CASE nKeyVal = 5
FIRSTROW(FIRSTROW() -1)
CASE nKeyVal = 24
FIRSTROW(FIRSTROW() +1)
CASE nKeyVal = 4
FIRSTCOL(FIRSTCOL() +1)
CASE nKeyVal = 19
FIRSTCOL(FIRSTCOL() -1)
CASE nKeyVal = 18
FIRSTROW(FIRSTROW() -10)
CASE nKeyVal = 3
FIRSTROW(FIRSTROW() +10)
ENDCASE
ENDDO
FIRSTROW(0) // reset
FIRSTCOL(0)
SETMAXCOL(79)
SETMAXROW(24)
CLEAR
nFirstNewLine Designates which line is displayed as the top line on the virtual screen.
Returns
If the parameter is passed, the function returns the previous setting each time. If no parameter is passed, it returns the current setting.
Description
This function is important for use in setting virtual screen size in conjunction with SETMAXROW() and SETMAXCOL(). You can select the first line that you would like to have visible at the top side of the screen. In this way the screen can be moved in any direction.
Notes
■ To simplify programming, values outside of the permissible
range are automatically corrected to the maximum or minimum values (see example).
Examples
The following example sets up a screen with 100 lines and 120 columns.
To help you with screen orientation, the current column number is
displayed at three locations on this virtual screen. The virtual screen
can be moved in any direction using cursor keys and PgUp and PgDn:
SETMAXROW( 99) // screen with 100 lines
SETMAXCOL(119) // and 120 columns
CLEAR
FOR nCount = 0 TO MaxRow() // Build screen
@ nCount, 0 SAY "Line" + NToC(nCount, 10, 4)
@ nCount, MaxCol()/2 -5 SAY "Line" + NToC(nCount, 10, 4)
@ nCount, MaxCol() -10 SAY "Line" + NToC(nCount, 10, 4)
NEXT nCount
@@ 99, 00 SAY Center("This is the last line")
nKeyVal := 0
DO WHILE nKeyVal <> 27
nKeyVal := Inkey(0)
DO CASE
CASE nKeyVal = 5
FIRSTROW(FIRSTROW() -1)
CASE nKeyVal = 24
FIRSTROW(FIRSTROW() +1)
CASE nKeyVal = 4
FIRSTCOL(FIRSTCOL() +1)
CASE nKeyVal = 19
FIRSTCOL(FIRSTCOL() -1)
CASE nKeyVal = 18
FIRSTROW(FIRSTROW() -10)
CASE nKeyVal = 3
FIRSTROW(FIRSTROW() +10)
ENDCASE
ENDDO
FIRSTROW(0) // reset
FIRSTCOL(0)
SETMAXCOL(79)
SETMAXROW(24)
CLEAR
cDrive Designates the drive (A, B, C, etc.) for which you want a type determined. The default is the current disk drive.
Returns
The function returns the exact type of the designated disk drive, coded as follows:
Table 7-18: Coding of Drive Types
Code Definition
0 No floppy drive
1 360-kB drive
2 1.2-MB drive
3 720-kB drive
4 1.44-MB drive
Description
This function gives you a numeric value that specifies exact type and capacity of the selected floppy drive. Whether or not the device is a floppy drive, is determined beforehand by DriveType().
Notes
■ The drive type is determined without actually accessing the
drive. Therefore, a disk does not have to be in the drive.
Examples
Is the current disk drive a floppy and what type?
IF DriveType() = 1 .OR. DriveType() = 2
DO CASE
CASE FLOPPYTYPE() = 0
? "No floppy drive!"
CASE FLOPPYTYPE() = 1
? "360 kB drive"
CASE FLOPPYTYPE() = 2
? "1.2 MB drive"
CASE FLOPPYTYPE() = 3
? "720 kB drive"
CASE FLOPPYTYPE() = 4
? "1.44 MB drive"
ENDCASE
ENDIF
cFileName Designates the name and path of the font file.
nFontArea Designates the number of the specified font area. For EGA, the values 1 to 4 are allowed, or whatever values MAXFONT() permits. For VGA, the values 1 to 8 are allowed, or whatever MAXFONT() permits.
nOffset Designates from what character position the screen adapter font table is overwritten. The default value is 0.
nCounter Designates how many characters to load from the new font. The default value is 256.
lOtherPixelHeight Designates .T. to allow the function to modify the pixel height. This leads to a mode change and character count. Please note that you must designate both nOffset and nCounter to implement this parameter.
Returns
The function returns an error code which corresponds to the explanation below:
Table 6-1: Values returned for FONTLOAD()
Error Code Explanation
0 Font loaded successfully
-2 Impossible in current video mode
-3 Font file not found
-4 The <lOtherPixelHeight> mode is not possible (the Extended
Drivers are not linked in)
Description
FONTLOAD() allows you to load the font definitions from a file into the font area of an EGA or VGA card. Use FONTSELECT() to determine which fonts serve as normal and high density for output.
You may already have some of these fonts on the CA-Clipper Tools disk, and others can be created with the accompanying font editor.
Technical Background
The EGA and VGA cards permit you to modify a portion or all 256 characters of the character generator with software. To do this, a previously created pixel pattern for the character is loaded in the corresponding position in a font area on the screen card. Normally, an EGA card has a maximum of four font areas and a VGA has eight, within which you can redefine all 256 characters. Use MAXFONT() to determine the exact count of font areas.
Building fonts into a program requires unnecessary memory space. Constructing fonts as a string within a program is also awkward. With the GETFONT() and SetFont() functions, you can load a font from a screen card into a string variable, or from such a variable, into a font area on the card. However, FONTLOAD() only allows you to load a font from a file into a particular area of the screen card. In both cases, use ONTSELECT() to activate the loaded font.
On the CA-Clipper Tools sample disk, you will find a font editor to construct new fonts in CA-Clipper source code.
Variable Pixel Height
In principle, EGA and VGA screen adapters provide the opportunity to display fonts with 2 to 32 pixels per character (1 pixel/character only, when there are 200 scan lines). ROM fonts are only available for pixel heights of 8, 14 and 16, which accounts for the great expansion of the EGA 25-/43-line modes and VGA 25-/28-/50-line modes. You must construct individual fonts for all other pixel heights. The CA-Clipper font editor can make this easy.
When FONTLOAD() loads a font, it also computes the pixel height from the font data length. Since a font file always contains all 256 character definitions, there is a formula:
Pixel height = Len(Font-Data)/256
The lOtherPixelHeight parameter determines whether the fonts that do not match the pixel height just set are accepted. This must be explicitly indicated, since the line count and screen mode will change. For this reason, you must always link in the CTUS.LIB Extended Drivers (see Table 6-1, returned value -4).
Notes
■ You cannot use FONTRESET() when a font is loaded for which
there is no associated ROM font (all pixel heights except 8, 14, 16). Prior to a FONTRESET(), switch back to a permissible mode.
■ All previously successful FONTSELECT() settings are discarded
again during FONTLOAD().
■ If an EGA card does not span the entire memory range, then you
can reduce a maximum of four available font areas. MAXFONT() determines the number of available fonts.
Examples
■ Load all 256 characters of an EGA font in area 2:
? FONTLOAD("\FONTS\OLDENG.014", 2) // 0 OK<
FONTSELECT(2)
■ Exchange the fonts for the upper 128 characters in area 3:
? FONTLOAD("\FONTS\OLDENG.EGA", 3, 128, 128) // 0 OK
FONTSELECT(3) // Select
■ Load a 24-pixel font in the last font area:
? FONTLOAD("\FONTS\PC.024", MAXFONT(), .T.)
Resets all font and palette changes to the ROM defaults
Syntax
FONTRESET() → lReset
Returns
FONTRESET() returns .T. when all font and palette settings are reset.
Description
This function resets all the settings implemented with FONTLOAD(), SetFont(), and FONTSELECT(). Settings implemented with EGAPALETTE() or VGAPalette() are also reset. In addition, the border color set with SET COLOR TO is reset.
Table 6-2: Settings affected by FONTRESET()
Settings Functions concerned
All font information FONTLOAD(), FONTSELECT, SetFont()
All palette information. EGAPALETTE(), VGAPalette()
Border attribute CA-Clipper: SET COLOR TO
Notes
■ No ROM fonts exist for screen modes that are not based on 8,
14 or 16 pixels. You cannot implement FONTRESET() in this situation.
Examples
Reset all changes to fonts and palettes:
? FONTRESET() // .T., if ok
cFontstring[@] Designates the font in character string form, within which the characters are rotated or mirrored.
nTurnDirection Designates the rotation axis or rotation direction in numeric form with a value from 1 to 3 (see Description).
nPixelHeight Designates the accompanying pixel height and number of bytes that represent an individual character within a font string. This is only necessary for modes 1 and 3.
nStart (This is for only for mode 1.) Designates from which pixel line (from which byte), the 8 bytes are rotated. Based on nPixelHeight, the bytes before and after this range are deleted (set to 0). The first byte of the character corresponds to the 0 value.
Returns
If CSetRef() is not implemented, FONTROTATE() returns an amended font string.
Description
FONTROTATE() rotates the characters within a font string in different directions. Rotation direction affects the number of characters that can rotate.
Constructing Fonts
If a font is transferred to a string with GETFONT() and the same number of bytes are used for an individual character each time, as specified by the current font height from CharPix(). For example, if a 14-pixel font is installed, then the font string contains 256 groups of 14 bytes. Each of these bytes represents a horizontal pixel line. Since the characters are always 8 pixels wide, one bit always represents this pixel.
Direction of Rotation 1
If a font uses GETFONT() to transfer a string, then a comparable number of bytes are used each time for an individual character, as specified by the current font height in CharPix(). Since only an 8-pixel width is ever available, only 8 bytes are rotated for each character every time. To determine these bytes, you must designate the pixel height nPixelheight and the start of the 8-byte area
nStart . All bytes above and below the rotation are cleared (set to
0). The rotation point is determined by the computation nStart + 4.
Direction of Rotation 2
In this mode, the characters are rotated 180 degrees on the vertical axis (the Y-axis), and thereby mirrored. The nPixelheight and nStart parameters are unnecessary, since only the bits in each byte are mirrored.
Direction of Rotation 3
In this mode, the characters are rotated 180 degrees on the horizontal axis (X-axis), and thereby mirrored in the other direction. You must specify the nPixelheight parameter. The nStart parameter is not needed, since the character is affected through its entire height.
Combinations
Since modes 1 to 3 support all three rotation directions, multiple function calls allow you to combine the rotation operations and create rotated and mirrored characters.
Notes
■ The entire string is always worked on. If you only want to
change a region of characters on the screen, it can be done easily and is regulated by the SetFont() optional parameter, when you write the font back to the screen adapter.
■ If the parameter is passed by reference, use CSetRef() to
suppress the return value and increase the speed.
Examples
In the following example, the screen is first filled with characters and
then rotated. This is particularly useful in the VGA 50-line mode,
since it has an 8 x 8 pixel matrix and none of the characters are cut
off.
All parameters for FONTROTATE() are designated in such a generalized
manner that you can use them for other pixel relationships.
CSetRef(.T.) // Optimize by reference method
nMODE := GETSCRMODE() // Save old mode
VGA50()
FOR I := 0 TO MaxRow() // Build screen
@ I, 0 SAY Center("ABCDEFGHIJKLMNOPQRSTUVWXYZ- 1234567890")
NEXT I
nPixel := CharPix() // Determine font pixel count
cFont := GETFONT() // Load font to variable
nKey := 0
DO WHILE Key <<>> 27
Millisec(100) // Time delay
FONTROTATE(@cFont, 1, nPixel, (nPixel-8)/2)
SetFont(cFont)
nKey := Inkey()
ENDDO
SETSCRMODE(nMODE) // Reset to original mode
RETURN
nFontArea Designates which font area the normal output mode should use.
nIntensiveFontArea Designates which font area the higher- intensity output mode should use. The default is nFontArea.
Returns
FONTSELECT() returns an error code with the following meaning:
Table 6-3: Error code definitions
Code Definition
0 Font loaded successfully
-1 Invalid font area specified
-2 Impossible in current video mode
Description
This function selects the font areas for both normal output and higher- intensity output. Use SET COLOR TO with "+", to bring up to 512 different characters to the screen at the same time. The second font is displayed at a higher intensity. If this is not what you want, you can change the display (not the attribute itself) with EGAPALETTE()/VGAPalette(). The system is preset for both output modes and corresponds to a call of FONTSELECT(1, 1).
Notes
■ After you change the video mode with SETSCRMODE(), the fonts
must be re-selected.
Examples
■ Show font area 1 with normal output and area 4 with high
intensity:
? FONTSELECT(1, 4) // 0 OK
SET COLOR TO W
? "Nantucket" // Output over font 1
SET COLOR TO W+ // Output over font 4
■ Show font area 2 for both output modes:
? FONTSELECT(2)
nFloatingPointNumber Designate any CA-Clipper number.
Returns
FToC() returns an 8-byte character string.
Description
CA-Clipper internal numbers are displayed as 64-bit floating point numbers. FToC() returns these 64 bits as an 8-byte string. In this way, numbers can be locked and/or saved more compactly.
Notes
■ The XToC() function converts floating point numbers in the
same way.
Examples
It is not useful to display the return value on the screen:
NumberString := FToC(274711.335) // 8 byte string
nInstall Designates the installment amount to pay for the period.
nInterestRate Designates the interest rate calculated for the payment period. 1 corresponds to 100%.
nNumberofPayments Designates the number of payments.
Returns
FV() returns the future capital value of the total deposits, plus the interest generated.
Description
FUTURE VALUEFV() returns the capital available after the nNumberofPayments total installments at nInstall payment, at an nInterestRate interest charge for the period.
Examples
What amount would you save, if you pay $150.00 per month for 3 years
into a fund that pays an annual interest rate of 6%?
nRate : 0.06/12 // Monthly interest rate
? FV(150, nRate, 36) // Result: 5900.42
Queries the current attribute for the clearing functions
Syntax
GetClearA() → nClearAttribute
Returns
GetClearA() returns the value of the current standard attribute.
Description
GET CLEAR (A)ttribute This function determines the standard attribute for some CA-Clipper Tools functions with screen output. In this discussion, the attribute is referred to as CLEARA and the character as CLEARB. GetClearA() queries the current standard attribute.
Notes
■ The standard attribute is 7 (white on black), if no other
Queries the default character for the clearing functions
Syntax
GetClearB() → nClearCharacter
Returns
GetClearB() returns the value of the current standard character CLEARB.
Description
GET CLEAR (B)yte This function determines the standard character for some CA-Clipper Tools functions with screen output. In this discussion, the attribute is referred to as CLEARA and the character as CLEARB. GetClearB() queries the current standard character set as CLEARB.
Notes
■ The standard character is Chr(255) when no other character is
nField Designates the number of the GET field for which the screen column is determined. The default is the currently active field.
Returns
GetFldCol() returns the screen column for the first position of the currently active or the specified field. If there is an invalid parameter, a value of -1 is returned.
Description
GET FIELD COLUMN This function determines the first column of an input field. If the nField parameter is not specified, the function returns the column for the currently active field. With an invalid field number or in a situation where there is no active field, a value of -1 is returned.
Examples
■ Display the screen column for the second posted GET:
@ 10, 10 GET....
@ 10, 20 GET....
@ 10, 30 GET.....
? GetFldCol(2) // Result: 20
■ Display the column for the currently active GET field:
READ // Assuming field 1 is active
Within a UDF or KEYTRAP procedure:
? GetFldCol() // Result: 10
nField Designates the number of the GET field for which the screen is determined. The default is the currently active field.
Returns
GetFldRow() returns the screen row for the first position of the currently active or specified field. If there is an invalid parameter a value of -1 is returned.
Description
GET FIELD ROW This function determines the first row of an input field. If the nField parameter is not specified, the function returns the row for the currently active field. When nField is an invalid field number or if there are no active GET fields, a value of -1 is returned.
Examples
■ Display the row for the second posted GET:
@ 10, 10 GET....
@ 11, 20 GET....
@ 12, 30 GET.....
? GetFldRow(2) // Result: 11
READ // Assuming field 1 is active
? GetFldRow() // Result: 10
nField Designates for which number of the GET field to determine the name of the accompanying variable. The default is the currently active field.
Returns
GetFldVar() returns the name for the first position of the currently active or specified field. If there is an invalid parameter, a value of -1 is returned.
Description
GET FIELD VARIABLE This function determines the name of an input field. If the nField parameter is not specified, the function returns the name for the currently active field. With an invalid field number or if there is on active field, a value of -1 is returned
Examples
■ Display the name of the variable associated with the second
posted GET:
@ 10, 10 GET VAR1
@ 10, 20 GET VAR2
@ 10, 30 GET VAR3
? GetFldVar(2) // "VAR2"
■ Display the name for the active field:
READ // Assuming field 1 is active
? GetFldVar() // "VAR1"
■ Within a UDF or KEYTRAP procedure:
? GetFldVar() // "VAR1"
cDefault Designates the content and length of the input field.
nRow Designates the row in which the input occurs. The default is the current cursor position.
nColumn Designates the column in which the input occurs. The default is the current cursor position.
lSAY When you specify .T. and close GetInput(), the actual data input is displayed with the standard color attribute.
cPrompt Designates text to display in front of the input field at the selected coordinates. The default is no prompt text.
Returns
GetInput() returns the input string.
Description
If you call this function, a simple input field is made available. All control keys are interpreted exactly as in a CA-Clipper GET mask. The length and default for the string are specified in the cDefault parameter. This allows you to portray a normal input field with VAR= Space(length). The input field starts at the current cursor position or at the designated row and column. Similar to @ ... SAY...GET, you can also display text just before the input text. The field starting position is moved accordingly.
In the CA-Clipper SET COLOR TO command, the first color you designate stands for screen output; the second for input fields. GetInput() uses these color designators exactly like CA-Clipper. If you designate the lSAY parameter as .T., you can determine (as with a SAY), whether to redisplay the data in its amended form at the point of input. After data input is complete, the data displayed on the screen is the same as the values returned by the function. This is useful when an input breaks off due to an ESC. For example, the data is "the quick brown fox" and you change it to "the slow brown fox". If lSAY is .T. and you press escape, the original data (the quick brown fox) is restored. The affected area also contains the default color attribute.
Notes
■ GetInput() uses the CA-Clipper console input internal routines
and supports the INS display in SCOREBOARD. In addition, the SET ESCAPE, SET BELL, SET INTENSITY, SET DELIMITERS, and SET CONFIRM switches are acknowledged.
■ Key traps may occur within GetInput() when the cursor position
within a field is saved. GetInput() is then called recursively, as long as sufficient stack memory is available.
Examples
■ Input at the current cursor position:
cVar := Space(20) // 20 position input field
cVar := GetInput(cVar) // Retain input attribute
■ Input a 10 space field, row 10, column 20:
cVar := GetInput(Space(10), 10, 20)
■ After input is finished, the actual data input is redisplayed
on the screen. This area contains the standard color attribute. The
input is moved by the text preceding the input field:
SET CONFIRM ON // Close with RETURN
cVAR := "Default text"
GetInput(cVar, 10, 20, .T., "Please input: ")
nKeyValue Designates the original key code so that its current value can be tested for translation or lock out.
Returns
GetKXLat() returns the status of the key designated by nKeyValue. A return value of 0 indicates that there is no translation. A return value of -1 indicates that the key is locked out. And any other return indicates that the designated key is translated into that key value.
With Chr(NumLow(nkeyValue)) + Chr(NumHigh(nkeyValue)) the return value can be converted to the form used in the include file ctscan.ch
Description
GetKXLat() allows you to test to see if a key designated under SetKXLat() has been locked out or translated. nKeyValue is the original key code. The key codes used are described in detail in the SetKXLat() function.
Notes
■ Symbolic constants for key codes can be found in the ctscan.ch
file.
■ You can also use the symbolic constants from the CA-Clipper
Has the "A" key been locked out or translated?
nVar := GetKXLat(KS_A)
IF nVar <> 0
* Undo translation/lock out for "A"
SetKXLat(KS_A) // "A" returns to "A"
ENDIF
GetKXTab() returns a character string that contains all of the previously defined key translations.
Description
A CA-Clipper Tools key table can be as large as the maximum allocatable string. The number of translations corresponds to:
((Memory(1) * 1024)/4),
where the required memory is allocated dynamically. The key code translations can be done through SetKXLat() or SetKXTab().
GetKXTab(), in contrast to GetKXLat(), always returns a table of all defined key code translations as a string. A translation table can then be saved in a variable and reset using SetKXTab().
Examples
Save the entire key table and reinstall it later:
cKXTab := GetKXTab()
DO KEYCHANGE
SetKXTab(cKXTab)
GetPrec() returns the level of precision currently installed for CA-Clipper Tools trigonometric functions. The value corresponds to the number of digits to the right of the decimal in the range of 1 to 16.
Description
GET PRECISIONGetPrec() queries the currently installed precision level for CA-Clipper Tools trigonometric functions. The returned value corresponds to the number of digits to the right of the decimal, that are being worked with. Although the default is 16, you can change this value with SetPrec().
Examples
What precision has been set?
? GetPrec() // e.g. 10
cDefault Designates the length and contents of the input field.
nRow Designates the row in which the input occurs. The default is the current cursor position.
nColumn Designates the column in which the input occurs. The default is the current cursor position.
lSAY When you specify .T. and close GetSecret(), the actual data input is displayed with the default color attribute.
cPrompt Designates the text to display in front of the input field at the selected coordinates.
Returns
GetSecret() returns the input string.
Description
If you call this function, a simple input field is made available. All characters input are displayed as asterisks (*) to hide the actual input. All control keys are interpreted exactly as in a CA-Clipper GET mask.
The length and default for the string are specified in the cDefault parameter. This allows a normal input field to be portrayed with VAR = Space(length). The input field starts at the current cursor position or at the designated row and column.
Similar to @ ... SAY ... GET, you can also display text just before the input field. The field starting position is moved accordingly
In the CA-Clipper SET COLOR TO command, the first color you designate is used for screen output; the second for input fields. GetSecret() uses these color designators exactly like CA- Clipper. If you designate the lSAY parameter as .T., you can determine (as with a SAY), whether the data is redisplayed in its amended form at the point of input. However, GetSecret() only displays asterisks to hide this data. This is useful when input breaks off due to an ESC, because at least the correct number of asterisks is displayed. The affected area also contains the standard color attribute.
Notes
■ GetSecret() uses the CA-Clipper console input internal
routines and supports the INS display in SCOREBOARD. In addition, the SET ESCAPE, SET BELL, SET INTENSITY, SET DELIMITERS, and SET CONFIRM switches are acknowledged.
■ Key traps may occur with GetSecret() when the cursor position
within a field is saved. You can then call GetSecret() recursively, as long as sufficient stack memory is available.
Examples
■ Show the secret field at the current cursor position:
cVar:= Space(20) // 20 position secret field
cVar:= GetSecret(cVar) // Retain input attribute
■ Show the secret a 10-space field, row 10, column 20:
cVar:= GetSecret(Space(10), 10, 20)
■ After input is finished, the actual data input is redisplayed
on the screen. This area contains the standard color attribute. The
input is moved by the text preceding the input field:
SET CONFIRM ON // Close with RETURN
cVar:= "Default text"
GetSecret(cVar, 10, 20, .T., "Please input: ")
GETBOXGROW() returns the value set in SETBOXGROW() for the delay in creating a box.
Description
GETBOXGROW() retrieves the time delay that a box in "grow" mode has when it is opened.
Examples
Here is an example of a box with 10 milliseconds between each growth
step:
SETBOXGROW(10)
WOpen(2, 2, 23, 78) // Sets box coordinates only
WBox() // Generates box with delay
? GETBOXGROW() // Result: 10
GETCURSOR([<lMode>]) → nCursorForm
* This function has been retained for compatibility reasons only.
Its use in development of future applications is not recommended.
For future applications use the SetCursor() function.
Arguments
lMode Sets the cursor form to the overwrite (.F.) or the insert (.T.) mode. The default value (.F.) sets the cursor form to the overwrite mode.
Returns
The returned value designates how many scan lines are used to display the cursor.
Description
GETCURSOR() allows you to save the current cursor form for an input field in a function called with a VALID, before you change it in a UDF. GETCURSOR() then allows you to restore its old form before returning to the GET field.
CA-Clipper Tools stores the form for two cursor displays: one for overwriting and one for inserting. If lMode is .F. or omitted, then the overwrite cursor form is returned. If lMode is .T., then the insert cursor form is returned. (See the note with SetCursor()).
The cursor is broken down into lines on the screen called scan lines. The form and height of the cursor are specified by two instructions that correspond to the first and the last line used for the cursor display. GETCURSOR() returns both numbers combined into one value, according to the following formula:
(Starting Line * 256) + Final Line
The NumHigh() and NumLow() functions let you separate the starting and final lines very easily.
Notes
■ The word "line" here does not mean a screen (output) line, but
the scan or pixel lines from which screen characters are created.
■ This function works independently of the SET CURSOR setting.
Examples
Break down cursor information into a starting line and a final line:
nCursor := GETCURSOR()
? NumHigh(nCursor) // Cursor start line
? NumLow(nCursor) // Cursor final line
GETMODE() returns a character string that represents the active mode. The character string corresponds to the CA-Clipper Tools function call used to switch to that mode.
Description
This function substitutes for a difficult to understand numeric code for the return value of a function. This character string corresponds to the function call used to switch to the current mode. The returned value can be held in a variable, and this function can be called later using the compile and run operator.
Notes
Important! You must declare all function calls for setting a mode which could occur as a return value from this function as EXTERNAL.
Examples
Notice the mode and reset it later:
cVar := GETMODE() // Save current mode
? cVar // For example "CGA80(.T.)"
CGA40(.T.) // Select other mode
? &(cVar) // Reset old mode.
lHiddenPage Designates an optional parameter. If this parameter is .T., the function returns the number of the currently hidden page. If this parameter is .F., the function returns the number of the visible screen page. The default value is .F..
Returns
GETPAGE() returns the number of the currently set screen pages.
Description
GETPAGE() allows you to determine which screen page is currently available. The screen page that is currently available can be switched by using the SETPAGE() function.
Since screen output can be directed to a hidden screen page, you can determine the number of this hidden page by setting the parameter to .T.
Examples
Determine the active screen page:
? GETPAGE() // i.e. 2
GETPBIOS() returns the setting made in SETPBIOS() as a numeric value between 0 and 3.
Description
This function allows you to determine the current setting for rerouting the printer through extended drivers. If the function returns a value of 0, the print output is through DOS. If the value is between 1 and 3, the output is through the BIOS on the corresponding printer.
Examples
Determine the current setting:
? GETPBIOS() // 0 Output via DOS
GETPXLAT() returns the entire print table or returns an empty character string if a print table has not been defined.
Description
GETPXLAT() retrieves the current printer table set by SETPXLAT(). The string returned can be assigned to a variable and restored later. If you use a printer with different font styles, this function allows you to switch print tables as required.
Examples
■ Save the existing table:
cOldTab := GETPXLAT()
■ Install new table:
SETPXLAT(......)
SETPXLAT(......)
SETPXLAT(......)
■ Output to another printer:
SET PRINTER TO LPT2
■ Restore the old table starting at position 0:
SETPXLAT(0, cOldTab)
The function returns the mode number of the currently set video mode.
Description
In contrast to GETMODE(), GETSCRMODE() returns the current video mode as a numeric value. This allows you to query special modes for particular screen adapters and reset them using SETSCRMODE(). The following modes are accommodated by other functions within CA-Clipper Tools:
Table 2-1: Modes and Their Coding
Mode Mode Number
CGA40 Monochrome 0
CGA40 Color 1
CGA80 Monochrome 2
CGA80 Color 3
Monochrome 7
EGA43 (EGA only) 299 (43+256)
VGA28 (VGA only) 284 (28+256)
VGA50 (VGA only) 306 (50+256)
Notes
■ GETSCRMODE() returns the value previously set with
SETSCRMODE() and the current BIOS or CA-Clipper Tools mode. If you switch into a special mode for a particular screen adapter, there is no guarantee that this is the mode number that GETSCRMODE() returns. This is a factor of the unique behavior of the specific screen adapter.
Examples
■ Set the EGA 43-line mode:
EGA43()
■ The current video mode is saved:
nOldMode := GETSCRMODE()
■ The current video mode is restored later:
SETSCRMODE(nOldMode)
Queries screen output that was redirected by SETSCRSTR()
Syntax
GETSCRSTR() → cHiddenCharacterstring
Returns
GETSCRSTR() returns the content of the internal memory area determined by SETSCRSTR().
Description
GETSCRSTR() returns the contents of the internal memory area (determined by SETSCRSTR(.T.)) for hidden screen output . This return value has a length that always corresponds to SCREENSIZE(.T.). You can pass it to a variable and after the mode is switched off, transfer it to the CA- Clipper RestScreen() function. The variable must be passed before the redirected output mode is shut off with SETSCRSTR(.F.). Otherwise, the internal memory area is deallocated and GETSCRSTR() returns a null string.
Notes
■ Since the entire screen output is always redirected
(independent of its actual size), you should always call RestScreen() with the maximum coordinates of 0, 0, MaxRow(), and MaxCol()
Examples
■ Show hidden output, switched back to the physical screen, if
the need should arise:
WSelect(0)
? SETSCRSTR(.T.) // .T., when mode on
@ 10, 10 SAY "XXXXXXX" // Normal screen output
*...
@ 15, 10 SAY "YYYYYYY"
■ Always call the GETSCRSTR() function before SETSCRSTR(.F.)
cVar := GETSCRSTR()
? SETSCRSTR(.F.) // .F. when mode off
RestScreen(0, 0, MaxRow(), MaxCol(), cVar)
GETTAB() returns the currently installed tab locations for CA-Clipper screen output in the form of a character string.
Description
This function gives the tab definitions specified in SETTAB() for CA-Clipper screen output. You can use this function to save the active tab definitions.
GETTIC() returns the number of timer ticks executed since the last SETTIC (.T.).
Description
Use this function in conjunction with SETTIC(). At any given time, it returns the number of completed timer ticks since the timer was set in motion (by calling SETTIC(.T.)).
Examples
An individual UDF is to be measured in ticks. The tick rate counter is
started with the SETTIC(.T.) call, then stopped after execution of the
UDF (by passing .F. to SETTIC()) and the number of completed ticks is
queried:
SETTIC(.T.)
MY_UDF(I)
SETTIC(.F.)
? " Required ticks:", GETTIC()
nColor|cColor Designates a color represented by a number in the range of 0 to 15, or a color code that corresponds to the one in SET COLOR TO.
cRGB May designate as R, G, or B to determine the corresponding palette value.
Returns
GETVGAPAL() returns the red, green, or blue palette value for the designated color. When invalid paramerters are specified, a value of -1 is returned.
Description
On a VGA adapter, each color is a combination of the three values for red, green and blue. Each value can be in the range of 0 to 63, to permit you to install different color palettes.
GETVGAPAL() queries the R, G, and B values for all 16 colors. The individual color can be a number in the range of 0 to 15, or represented as a color code corresponding to the CA-Clipper SET COLOR TO.
Notes
■ This function is implemented in the enclosed Colorpal.prg
program.
Examples
Determines the palette value of red in the color cyan:
GETVGAPAL("BG", "R")
Converts a hexadecimal string into a byte sequence
Syntax
HexToStr(<cHex>) → cBytes
Netware: 2.2 and 3.11
Arguments
cHex Designates a character string of which two characters are recognized as a hexadecimal form of a byte. cHex can contain only the characters "0" to "9" and "A" to "F".
Returns
HexToStr() returns a character string that contains a byte sequence in which each byte corresponds to two characters of its hexadecimal form. The return value is half as long as cHex.
Description
HexToStr() is useful when working with the internet addresses that are required in conjunction with the IPX/SPX functions of Point To Point communication.
Examples
Convert the hexadecimal string into a byte sequence:
? HexToStr('4130') // "A0"
nUnsigned|cHexUnsigned Designates either a numeric value or hexadecimal digit string to convert into a 16-bit or 32-bit signed integer.
32Bit If this optional parameter is designated as .T., the function processes the designated value as a 32-bit unsigned integer. The default value is a 16-bit unsigned integer (.F.).
Returns
IntNeg() returns a signed 16-bit or 32-bit integer.
Description
This function converts unsigned integers into signed integers.
All 16-bit or 32-bit integers are accepted, depending on whether there is a second parameter and the logical value is assigned. For the 16-bit variant, all values for nUnsigned|cHexUnsigned that are less than or equal to +32767 (hex=7FFF), are positive. Values in the range of +32768 (hex=8000) to +65535 (hex=FFFF), have a negative result. When you work with 32-bit values, the positive range goes to 2147483647 (inclusive). All values beyond that are negative.
Notes
■ The function returns a value of 0 for invalid, too large, or
nUnsigned|cHexUnsigned Designates either a numeric value or hexadecimal digit string to convert into a 16-bit or 32-bit unsigned integer.
l32Bit If this optional parameter is designated as .T., the function processes the designated value as a 32-bit signed integer. The default value is a 16-bit signed integer (.F.).
Returns
IntPos() returns an unsigned 16-bit or 32-bit integer.
Description
This function converts signed 16-bit or 32-bit integers into the corresponding unsigned number. Based on the optional parameter and the logical value it is assigned, you can work with 16-bit or 32-bit values.
For the 16-bit variant, all values in the 0 to 32767 range are unchanged. However, all negative values from -1 to -32768 are changed. When the optional parameter is designated as .T., the range of values stretches from -2147483648 to +2147483647.
Notes
■ This function returns a 0 result for invalid paramerters.
Examples
■ Show simple conversions:
? IntPos(-1) // 65535
? IntPos(-2) // 65534
? IntPos(30000) // 30000
? IntPos(60000) // 60000
Warning! When working with 16-bit values IntPos(0) = IntPos(65536):
? IntPos(0) // 0
? IntPos(65536) // 0
■ Show values larger than 65536 in 16-bit mode. For example,
the difference between 90000 and 65536 is 24464:
? IntPos(90000) // 24464
■ However, in 32-bit mode:
? IntPos(90000, .T.) // 90000
? IntPos(-1, .T.) // 4294967295
// (largest 32-bit number)
? IntPos(-60000, .T.) // 4294907296
? IntPos(-90000, .T.) // 4294877296
Inverts the foreground and background of an attribute
Syntax
InvertAttr(<cAttr|nAttr>) → nInvertAttr
Arguments
cAttr|nAttr Designates the attribute to process.
Returns
InvertAttr() returns the value of the inverted attribute.
Description
InvertAttr() returns a value that corresponds to the opposite of an individual screen attribute. This is same as if you were to exchange the foreground color for the background. For example, red characters on a white background, become white characters on a red background.
■ The flashing and high-intensity attributes are not affected.
■ The result is always numeric, regardless of the parameter's
data type.
Examples
■ Invert the attributes at the current cursor position. In
doing so, the attribute is not set:
? INVERATTR(ScreenAttr())
■ You can represent the attribute in a number of different ways.
The returned value is always numeric:
8 // Result: 30
■ An invalid attribute:
? InvertAttr("xx/yy") // Result: 0
nPort|cHexPort Designates a port address from which a byte is read. This value can be a decimal integer or hexadecimal string.
Returns
INBYTE() returns the byte read from the specified port; or a value of - 1, if a parameter error occurs.
Description
CA-Clipper Tools always attempts to offer finished solutions at the highest-possible level for such standared hardware as a serial interface port. However, if you read a highly specialized systems and their ports from CA-Clipper, use INBYTE() or INWORD().
Notes
■ A random return value is produced for a nonexistent port or
one that cannot be read.
Examples
These examples read the first port address of the first serial interface
port. This is only an example, since the CA-Clipper Tools contains
special port functions.
■ With a decimal parameter:
? INBYTE(1016) // 1st Port (COM1)
■ With a hexadecimal parameter:
? INBYTE("3F8") // Also 1st Port (COM1)
The function returns the same key code as Inkey().
Description
This function operates in essentially the same way as Inkey(). It supports the same time delays and returns the same key codes as values. The most significant difference to Inkey() is that all key traps defined using SET KEYKeyTOProcedure are supported. This function saves the programmer time; for example, the programmer does not have to develop extensive CASE constructs after each Inkey().
Notes
■ After the trap procedure ends, the nDelay time is reset.
Examples
SET KEY 28 TO HELP // F1 Key
nVar := INKEYTRAP(10) // 10-second delay
RETURN
PROCEDURE Help(a, b, c) // Parameter c is always
// a null string
("")
* Program code desired
RETURN
Determines the previously active or the currently active input mode
Syntax
INPUTMODE([<lActiveMode>]) → nInputMode
Arguments
lActiveMode Designates an optional parameter. If this parameter is .T., the function returns the currently active mode.
Returns
INPUTMODE() returns a numeric value that indicates the input command for the previously active or the currently active input mode.
Description
INPUTMODE() allows you to determine what type of input command has been interrupted. When called without a parameter or with .F., the function returns the currently active mode or, if no input has occurred, the previously active input mode.
If the function is called with lActiveMode set to .T., then only the currently active input mode or 0 is returned. The following table shows the return values as well as the symbolic constants and their accompanying definitions.
Table 2-2 Coding the Input Mode
Return Symbolic Const. Definition
0 IMODE_NO No input command currently.
1 IMODE_WAIT WAIT
2 IMODE_ACCEPT ACCEPT
3 IMODE_INPUT INPUT
4 IMODE_READ READ
5 IMODE_MEMOEDIT MemoEdit()
6 IMODE_MENU MENU
7 IMODE_INKEY Inkey()
8 IMODE_DEBUG Debugger input
9 IMODE_GETINPUT Input within GetInput()
10 IMODE_GETSECRET Input within GetSecret()
Examples
PROCEDURE HELP(A, B, C)
nArea := Select()
nMode := INPUTMODE()
IF nMode = 5 // Calling from MemoEdit()
SELECT MEMOHELP
ELSE
SELECT HELP
ENDIF
SELECT (nArea)
RETURN
nPort|cHexPort Designates a port address from which a word with a 16-bit value is read. This value can be a decimal integer or hexadecimal string.
Returns
INWORD() returns the word read from the designated port, or a value of - 1 when an error occurs.
Description
CA-Clipper Tools always attempts to offer finished solutions at the highest-possible level for such standard hardware as a serial interface port. However, if you read highly specialized systems and their ports from CA-Clipper, use INBYTE() or INWORD(). INWORD() allows you to read from interfaces that return the data from a port as a 16-bit value.
Notes
■ A returns random value for a nonexistent port or one that
cannot be read.
Examples
Show a read from a 16-bit port:
■ With a decimal parameter:
? INWORD(512) // Read from an additional device
■ With a hexadecimal parameter:
? INWORD("200") // The same port address
Determines the error code of the last IPX/SPX call
Syntax
IPXERROR() → nErrorCode
Netware: 2.2 and 3.11
Returns
IPXERROR() returns the error code of the previous IPX/SPX call by a CA-Clipper Tools function. There is a table containing the error codes in Appendix D.
Description
IPXERROR() allows you to locate the source of an error that occurred during the execution of a CA-Clipper Tools function for IPX/SPX communication (for example IPXOPEN() or SPXESTBCON()). If the IPX/SPX call has been terminated without an error, IPXERROR() returns 0.
IPXERROR() returns an error code that is the direct result of an IPX/SPX call. If the IPX/SPX call initiates the interrupt controlled receiving of a packet, the error code cannot return any information about the success or failure of the receiving process. You can use the PPCRECERR() and PPCSNDERR() functions to determine this information.
Examples
Open the socket. If an error occurs, determine the reason for the
error:
IF OPENSOCK(20000)=0 // Error?
IF IPXERROR()=254
? 'Local socket table full!'
ENDIF
ENDIF
IPXOPEN(<nSourceSocket>,[<nRecBuffer>],
[[<nSendBuffer>],[<cTargetAddr>]],
[<nTargetSocket>],[<nPacket>],[<lHeader>])
→ nHandle
Netware: 2.2 and 3.11
Arguments
nSourceSocket Designates the number of the communication's source socket.
nRecBuffer Designates the selected size of the receiving buffer. If no value is passed for nRecBuffer, no receiving buffer is established. The minimum size of the receiving buffer is nPacket. If the value for nRecBuffer is too small, it is changed automatically by IPXOPEN(). The maximum size of the receiving buffer is 64 KByte.
nSendBuffer Designates the selected size of the sending buffer. If no value is passed for nSendBuffer, no sending buffer is established. The minimum size of the sending buffer is nPacket. If the value for nSendBuffer is too small, it is changed automatically by IPXOPEN(). The maximum size of the sending buffer is 64 KByte.
cTargetAddr Designates the target address for the sending operations. The target address is a 20-character string that represents a 10-character hexadecimal byte sequence. The leading eight characters of cTargetAddr specify the network number of the target. The following 12 characters contain the station ID of the target station (node address). cTargetAddr is mandatory to establish a sending buffer.
nTargetSocket Designates the number of the communication's target socket. The default value is nSourceSocket.
nPacket Designates the packet size in bytes of the data that is sent. The packet size can be between 1 and 546 bytes. Values outside this range are changed automatically. The default value is 546 Bytes.
lHeader Designates whether the data and the header (.T.), or the data (.F.) alone, are transmitted to the receiving buffer.
Returns
If an operation is successful, IPXOPEN() returns a communication handle. The return value contains a numeric value that is greater than 0. You should store the handle in a variable because all further operations that refer to an established buffer require a communication handle. If an error occurs, the function returns 0.
Description
IPXOPEN() allows you to establish a communication buffer for an IPX communication with other workstations in the network. The communication buffer can contain a sending and receiving buffer through which data is processed.
nSourceSocket is the socket address of the process that transmits the data (see the Introduction to this chapter). The socket can be opened with the function OPENSOCK() before the call of IPXOPEN(). If nSourceSocket has not been opened, it is automatically opened by IPXOPEN(). If nSourceSocket is passed with 0, IPXOPEN() opens an available socket.
The parameters nRecBuffer and nSendBuffer determine the size of the receiving and sending buffers. The buffers are automatically designed for one IPX packet. Each buffer can be up to 64 KByte. However, the size of the buffer that is allocated by IPXOPEN() depends on the application and the configuration of the computer used.
The parameter cTargetAddr is mandatory to establish a sending buffer. All following sending operations are addressed to cTargetAddr. Remember that an IPX communication is implemented as a pseudo Point-To- Point communication. Data is received by any station addressed to the current workstation but is sent only to a defined target address. The target address must be passed as a 20- character string (for example, "4921750400001B025A99"), where two characters represent one byte in hexadecimal code.
If the current workstation is logged in to a Netware server, the destination's network address can be determined with NNETADR() , using the user name. However, the target workstation must be logged in. Under Netware Lite, the leading eight characters of cTargetAddr must be passed with 0. A character string consisting of "FFFFFFFFFFFFFFFFFFFF" specifies all stations within an internal network as the target address (broadcast packages).
nTargetSocket allows you to determine the communication's target socket. The default value is nSourceSocket.
nPacket determines the maximum size of the data range of the IPX packets that are sent or received. The maximum value (and the default value) is 564 bytes. The value of nPacket is also valid for sending data.
With lHeader you can determine if the header (30 bytes) of an IPX packet is transmitted to the receiving buffer. The header can contain important information about the received packet. For a description about the header structure, see the Introduction to this chapter.
If the buffer has been established successfully, IPXOPEN() returns an integer value that is greater than 0, called a communication handle. If a value has been passed for nRecBuffer, IPXOPEN() initiates an interrupt controlled receiving mechanism that receives incoming packets in the background and then copies to an receiving buffer. The data can then be read with the PPCREAD() function within a CA-Clipper application. If the receiving buffer is full, incoming data is discarded without notifying the sender. Data should be removed from the receiving buffer and processed as soon as possible. You should either read the contents of the buffer periodically (polling) or supervise the buffer on an event-oriented basis: for example, with the function PPCKEY().
Notes
■ IPX is a protocol that is not based on a connection. There is
no guarantee or verification of a successful delivery to the target workstation. The implementation of specific protocols with the aid of CA-Clipper Tools functions can be necessary. (For your information: Netware usually uses IPX communication, and Netware Lite exclusively uses IPX communication, which is now available under CA-Clipper with the IPXOPEN() function.)
■ Several communication buffers can be established for one
source socket. However, you cannot know when you establish the communication buffers how the data will be distributed to the receiving buffers.
■ Network addresses can be determined under Netware with
"USERLIST /A", and under Netware Lite with "NET ULIST".
Examples
■ Open the 5 KByte IPX receiving buffer for socket 20000:
nHandle=IPXOPEN(20000,5120)
IF nHandle=0
? 'Buffer could not be established!'
ENDIF
■ Open the 2 KByte IPX sending buffer for socket 20000. The
target address is "4921750400001B025A99":
nHandle=IPXOPEN(20000,,2048,"4921750400001B025A99")
■ Open the 1 KByte IPX sending and receiving buffer for socket
20000. The target address is the first workstation where user MIKE
is currently logged in:
nHandle=IPXOPEN(20000,1024,1024,NNETADR("MIKE"))
■ For this example, the current workstation must be logged into
a file server. As NNETADR() is based on Netware-API, this call
cannot be used under Netware Lite.
IsAt() returns .T. value when the program is running on an AT-compatible system.
Description
IsAt() determines if your CA-Clipper application is running on an AT-class system.
Notes
■ The function also returns .T. for systems with an 80386 or
80486 processor.
Examples
Since you can set the hardware clock on an AT (in contrast to an XT),
use IsAt() to determine if SetDate() and SetTime() function properly:
IF IsAt()
? "The internal clock can be changed."
ELSE
? "Time and date will be lost after booting!"
ENDIF
Tests for presence of a CGA card or if one can be emulated
Syntax
IsCGA([<lMode>]) → lCGA
Arguments
lMode When designated as .T., tests to see if a CGA card is available. The default value of .F. tests to see if a CGA adapter can be emulated.
Returns
Depending on the lMode parameter, IsCGA() returns .T. when a CGA card is available, or if a CGA adapter can be emulated.
Description
You can determine two things with this function. When designated as .F. or when called without a parameter, IsCGA() tests it see if a CGA adapter can be emulated. This can be the case with an EGA or VGA card. When designated as .T., the function determines if a CGA card is available.
Notes
■ Use GETMODE() to determine which mode is active.
Examples
Can CGA be emulated?
IF IsCGA()
*...
ENDIF
CGA-Card?
IF IsCGA(.T.)
*...
ENDIF
Determines if an EGA card is present or can be emulated
Syntax
IsEGA([<lMode>]) → lEGA
Important! Contains <lMode>, an additional optional parameter over
and above the original CA-Clipper Tools.
Arguments
lMode When designated as .T., determines if an EGA card is present. The default value of .F. tests to see if an EGA adapter can be emulated.
Returns
In conjunction with the lMode parameter, IsEGA() returns .T. when an EGA card is present or an EGA adapter can be emulated.
Description
This function determines two things. When lMode is designated as .F. or the function is called without a parameter, IsEGA() determines if an EGA adapter can be emulated. This could be the case with a VGA card. When lMode is .T., it determines if an EGA card present.
Determines if a HERCULES card is present or can be emulated
Syntax
IsHercules([<lMode>]) → lHERCULES
Important! Contains <lMode>, an additional optional parameter over
and above the original CA-Clipper Tools.
Arguments
lMode When designated as .T., determines if a HERCULES card is present. The default value .F. tests to see if a Herculess adapter can be emulated.
Returns
In conjunction with the lMode parameter, IsHercules() returns a .T. when a HERCULES card is present or a HERCULES adapter can be emulated.
Description
This function determines two things. When lMode is designated as .F., or the function is called without parameter, IsHercules() determines if a HERCULES adapter can be emulated. This could be the case with a VGA or EGA card. When lMode is .T., it determines if there is a HERCULES card present.
Warning! Although our function implies it, not all EGA and VGA cards can emulate HERCULES. In most cases, a HERCULES emulation on a VGA card is possible , but it cannot be determined with absolute certainty. As long as the text is output under CA-Clipper, working with IsMono() should be sufficient
Examples
Can HERCULES be emulated?
If IsHercules()
* ...
ENDIF
HERCULES card?
IF IsHercules(.T.)
* ...
ENDIF
dDate Designates whether or not the specified date is in a leap year. The default is the system date.
Returns
IsLeap() returns .T. when dDate lies in a leap year; otherwise, it returns .F..
Description
A number of technical financial calculations need to know if a year has 365 or 366 days. IsLeap() determines this.
Notes
■ When parameters are missing, the function automatically uses
the system date. You must adhere to all rules for leap year tests. In the rare occurrence of a century change, the function also returns a correct result.
Examples
Determine if the following dates are in a leap year:
? IsLeap(CToD("01/01/1901")) // .F., No leap year
? IsLeap(CToD("09/30/1988")) // .T., leap year
? IsLeap(CToD("01/01/2000")) // .T., leap year
Determines if an MCGA card is present or can be emulated
Syntax
IsMCGA([<lMode>]) → lMCGA
Arguments
lMode When designated as .T. tests to see if an MCGA card is actually available. The default value of .F. tests to see if a monochrome adapter can be emulated.
Returns
Depending on the lMode parameter, the function returns .T. when a MCGA card is available or if an MCGA adapter can be emulated.
Description
You can determine two things with this function. When designated as .F. or when called without a parameter, IsMCGA() tests to see if a monochrome adapter can be emulated. This can happen with a HERCULES, EGA, or VGA card. When designated as .T., the function determines if a Monochrome card is available.
Determines if a monochrome card is present or can be emulated
Syntax
IsMono([<lMode>]) → lMonochrome
Arguments
lMode When designated as .T., tests to see if a monochrome card is available. The default value of .F. tests to see if a monochrome card can be emulated.
Returns
Depending on the lMode parameter, IsMono() returns .T. when a monochrome card is available, or if a monochrome adapter can be emulated.
Description
This function determines two things. When designated as .F. or when called without a parameter, IsMono() tests to see if a monochrome adapter can be emulated. This can be the case with a HERCULES, EGA, or VGA card. When designated as .T., the function determines if a monochrome card is available.
Determines if a PGA card is present or can be emulated
Syntax
IsPGA([<lMode>]) → lPGA
Arguments
lMode When designated as .T., tests to see if a PGA card is available. The default value of .F. tests to see if a PGA adapter can be emulated.
Returns
Depending upon the lMode parameter, IsPGA() returns .T. when a PGA card is available or if a PGA adapter can be emulated.
Description
This function can determine two things. When designated as. F. or when called without a parameter, IsPGA() tests to see if a PGA adapter can be emulated. This can be the case with an EGA or VGA card. When designated as .T., the function determines if a PGA card is actually available.
Tests to see if the ANSI screen driver is installed
Syntax
ISANSI() → lInstalledDriver
Returns
ISANSI() returns .T. when ANSI.SYS or a comparable driver has been loaded from CONFIG.SYS.
Description
ISANSI() determines if ANSI.SYS or another comparable driver has been loaded from CONFIG.SYS. Some full-page displays require the ANSI driver. If the driver is present, the display is fully operational.
Notes
Warning! You must implement DSETWINDOW(.F.) for ISANSI() to return a correct result.
Examples
If ANSI.SYS is present, output through DOS. This allows a simple
terminal emulation:
IF ISANSI() // ANSI driver present?
com_DosCon(dDate) // Output via DOS
ELSE
*... // Individual ANSI handling
ENDIF
ISDBT() returns .T., if a database has a memo file associated with it.
Description
ISDBT() determines if a database has a memo file associated with it, and allows you to compress that memo file.
Examples
If the database has a memo file, the database is copied to minimize the
memo file:
USE DATA
IF ISDBT()
COPY TO TEMP
CLOSE DATABASES
DeleteFile("DATA.DBF")
DeleteFile("DATA.DBT")
RenameFile("TEMP.DBF", "DATA.DBF")
RenameFile("TEMP.DBT", "DATA.DBT")
ENDIF
Determines if the debugger is available in the application
Syntax
ISDEBUG() → lDebugger
Returns
ISDEBUG() returns a value that signifies if the CA-Clipper debugger is available.
Description
This function determines if the debugger is available in an application. This enables a program to acknowledge this special situation and then conditionally execute or ignore portions of the program.
Notes
■ This is not a CA-Clipper switch. This information is provided
by CA-Clipper Tools.
Examples
Indicate if the debugger is active:
IF ISDEBUG()
? "The debugger is being used!"
ENDIF
ISIPX() returns .T. if IPX support is available. The IPX communication functions of CA-Clipper Tools can be used.
Description
ISIPX() allows you to check to see if IPX support is available. If it is not, an application can be terminated.
Examples
Check to see if IPX support is available. If it is not, terminate the
program:
IF ISIPX()
nHandle=IPXOPEN(20000,2000)
ELSE
? 'IPX support not available, load IPX.COM!'
QUIT
ENDIF
ISNETBIOS() returns .T. if NetBIOS support is available. If the function returns .T., the NetBIOS communication functions of CA-Clipper Tools can be used.
Description
ISNETBIOS() allows you to check to see if NetBIOS support is available. If it is not, an application can be terminated.
Examples
Check to see if NetBIOS support is available. If it is not, terminate
the program:
IF ISNETBIOS()
nHandle=NBDOPEN("STAT1",2000)
ELSE
? 'NetBIOS support not available!'
QUIT
ENDIF
ISSPX() returns .T. if SPX support is available. The SPX communication functions of CA-Clipper Tools can be used.
Description
ISSPX() allows you to check to see if SPX support is available. If it is not, an application can be terminated.
Examples
Check to see if SPX support is available. If it is not, terminate the
program:
IF ISSPX()
nHandle=SPXLISTCON(20000,2000)
ELSE
? 'SPX support not available, load IPX.COM!'
QUIT
ENDIF
cString [@] Designates the string that is processed.
cCharacter|nCharacter Designates the character that is moved from the beginning of the cString to the end. The default value is a space, Chr(32).
Returns
The processed cString is returned.
Description
JustLeft() moves the characters specified in cCharacter|nCharacter from the beginning of a character string to the end. Then the remaining text in the character string is left justified, without affecting the length.
Notes
■ If the cCharacter|nCharacter parameter is not specified,
spaces are automatically moved.
■ The return value for this function can be suppressed by
implementing CSetRef() to save room in working memory.
Examples
■ Move the blanks:
? JustLeft(" 123") // "123 "
■ Move the "." character:
? JustLeft("..123"," ".) // "123.."
cString [@] Designates the string that is processed.
cCharacter|nCharacter Designates the character that is moved from the end of the cString to the beginning. The default value is a space, Chr(32).
Returns
The processed cString is returned.
Description
JustRight() moves the characters specified in cCharacter| nCharacter from the end of a character string to the beginning. Then the remaining text in the character string is right justified, without affecting the length.
Notes
■ If the cCharacter|nCharacter parameter is not specified,
spaces are automatically moved.
■ The return value for this function can be suppressed by
implementing CSetRef() to save room in working memory.
Tests for key shift state status, such as Ctrl and Shift
Syntax
KbdStat() → nKeyStatus
Returns
KbdStat() returns a numeric code that corresponds to the status of certain keys.
Description
This function determines the status of all shift state keys (e.g., Ctrl, Shift or Alt, Scroll-Lock or Num-Lock). The information KDBSTAT() returns depends on the keyboard itself.
Table 13-5: Applies to all Keyboards
Bit Key
1 Right shift currently pressed
2 Left shift currently pressed
3 Ctrl currently pressed (left or right)
4 Alt currently pressed (Alt or Shift-Alt)
5 Scroll-Lock ON/OFF
6 Num-Lock ON/OFF
7 Caps-Lock ON/OFF
8 Insert ON/OFF
Notes
■ Since KbdStat() depends on the type of keyboard, use KBDTYPE()
to determine whether or not the left and right Ctrl or Alt keys are valid return values.
Examples
This example tests the Alt key. You could use it to display an
additional prompt menu when the Alt key is depressed:
IF IsBit(KBSTAT(), 4)
* . . .
ENDIF
lSwitch Designates whether the keyboard is switched on (.T.) or off (.F.).
Returns
KBDDISABLE() always returns a null string.
Description
With the help of this function, the keyboard can be turned on or off. This allows you to prevent any user input for a specific time through program control (even Ctrl-Alt-Del).
Notes
■ Be sure the program reenables the keyboard and does not leave
it locked when the program terminates.
Examples
Switch off the keyboard for 5 seconds:
KBDDISABLE(.F.) // Turn off keyboard
Inkey(5) // Can't be shortened by input!
KBDDISABLE(.T.) // Turn on keyboard
Inserts characters into the BIOS keyboard buffer to emulate keyboard input
Syntax
KBDEMULATE(<cListKeyValue>) → nValue
Arguments
cListKeyValue Designates a keyboard input sequence to emulate. Use a maximum of 15 characters.
Returns
KBDEMULATE() returns the number of key codes it could not place in the BIOS buffer.
Description
KBDEMULATE() emulates keyboard input at a very low level. This function uses the BIOS input buffer to emulate input. This emulated input can then be used by another program. For example, you might stuff the next DOS command prior to the end of the application. Keyboard input for programs that use RUN() to be called is also feasible. The buffer capacity is a maximum of 15 characters. Some of the key codes may vary from keyboard to keyboard, but they still correspond to the values returned by SCANKEY(). Construct the codes as follows:
Chr(ASCII code) + Chr(Scan code)
As a rule, a scan code that is transmitted this way cannot be acknowledged by CA-Clipper or any subsequent program. For example, a DOS command can be passed as a string with spaces at each even position. This emulation of a scan code with a value of 32, would only cause problems when a subsequent program also checks the scan code (see Examples on the next page).
Notes
■ You can find the symbolic constants for key codes in the
■ Problems may arise if you have incompatible hardware/BIOS, or
programs that extend the keyboard buffer.
■ Even though these emulated inputs occur at a low level, the
code translations defined with SetKXLat() still function.
Examples
■ These two programs always call each other reciprocally.
Before returning to DOS, each program wedges the keys necessary to
execute the other program in the BIOS buffer:
Program 1 (PROG1.EXE)
CLEAR
@ 10, 10 SAY "Here is program 1 !"
Inkey(5) // Wait a while...
KBDEMULATE("P R O G 2 " + Chr(13)) // Start PROG2 in DOS
RETURN
Program 2 (PROG2.EXE)
CLEAR
@ 10, 10 SAY "Here is program 2 !"
Inkey(5) // Wait a while...
KBDEMULATE("P R O G 1 " + Chr(13)) // Start PROG1 in DOS
RETURN
■ This program returns to DOS and then re-calls itself. In this
case, the desired extra byte is created with the Expand() function.
The last token in the full path is the EXE name which includes the
file extension. The first token is the file name:
xeName := TOKEN(ExeName(), ":\")
ExeName := TOKEN(ExeName, ".", 1)
KBDEMULATE(Expand(ExeName + Chr(13))) // Expansion with blanks
QUIT
■ The correct way to implement Expand():
* WRONG! No blank before Chr(13)
KBDEMULATE(Expand("TEST") + Chr(13))
* RIGHT! Blank before Chr(13)
KBDEMULATE(Expand("TEST" + Chr(13)))
KBDSPEED(<nDelay>,<nFrequency>) → lAmended
Warning! Use AT keyboards only.
Arguments
nDelay Designates the amount of delay before you begin auto repeat. Possible values are from 0 to 3. The default value is 1.
nFrequency Designates the number of times a character repeats per second. Possible values are from 0 to 31. The default value is 12.
Returns
KBDSPEED() returns .T. when a new repeat rate is set successfully.
Description
KBDSPEED() sets the auto repeat rate for AT keyboards. Both the time delay and repeat rate for auto repeat can be set. The table below provides the values, their corresponding times, and repeat rates:
Table 13-3: Auto Repeat Time Delay
<nDelay> Delay Time
0 250 millisecond
1 500 millisecond
2 750 millisecond
3 1000 millisecond
Table 13-4: Repeat Rate for Depressed Keys
<nFrequency> Repeat Rate
0 30 characters per second
12 10 characters per second
31 2 characters per second
Notes
■ It is best to determine valid values experimentally.
Examples
The quickest setting possible:
IF KBDTYPE() >0 // Only possible for AT's
KBDSPEED(0, 0)
ENDIF
KBDTYPE() returns a value that corresponds to the type of keyboard.
Description
KBDTYPE() determines the type of keyboard in use. This lets you check if the keyboard has F11/F12 keys available (which the CA-Clipper Tools supports). The possible keyboard values are:
Table 13-7: Coding of Keyboard Types
Value Keyboard Type
0 PC keyboard
1 AT keyboard
2 Extended keyboard w/101/102 keys, F11/F12
Notes
■ This function has been thoroughly tested, but there may be
problems with keyboards that are not fully compatible.
Examples
Query the keyboard:
? KBDTYPE() // 2 Extended keyboard
nKeyValue Designates the key code to place in the keyboard buffer.
nTime Designates the time, in seconds, after which the character is placed in the buffer. Negative values correspond to multiples of 1/18.2 seconds.
nCounter Designates the number of times the function occurs before it uninstalls itself. A value of -1 indicates that KeySec() will continue until it is specifically uninstalled. The default value is "Uninstall after the first call" (1).
lMode Designates whether the internal time counter restarts at the beginning (.T.) or not (.F.), after you press a desired key. The default value is "No new start with key stroke" (.F.).
() When called without parameters, the function is completely uninstalled.
Returns
KeySec() returns a value of .T. when installed correctly, so that the desired character will be placed in the keyboard buffer after the specified time.
Description
This function is useful in DEMO programs. If used in conjunction with KEYSEND(), you can simulate any keyboard input with time delays.
Use KeySec() in conjunction with CA-Clipper's SET KEY..TO, for key traps (just like KeyTime()). For example, this makes it possible to automatically write data still in the DOS buffer, to the hard drive at specific intervals during a GET..READ.
As soon as the character is placed in the keyboard buffer nCounter times, KeySec() uninstalls itself.
If the lMode parameter is specified as .T., the elapsed time counter is reset when you press any key.
If you want to specifically uninstall the function from the program, call it without parameters.
Notes
Warning! Always uninstall the function before you leave the program or use the CTUS.LIB Extended Drivers found in CA-Clipper Tools. The function changes interrupt vectors, and if the previous status is not restored before you exit the program, the system will eventually crash.
■ Only one time delay can be active. A new KeySec() deactivates
the previous one.
■ You can use any symbols defined in the CA-Clipper file
INKEY.CH. You can set any other keys described in the CA-Clipper Tools header file ctscan.ch.
Examples
■ Place Chr(7) in the keyboard buffer three times, every 5
seconds:
? KeySec(7, 5, 3) // (.T.)
■ Place Chr(255) in the keyboard buffer every 60 seconds until
an uninstall occurs:
? KeySec(255, 60, -1) // (.T.)
■ As soon as a key is pressed, the internal counter restarts
from the beginning:
? KeySec(13, 60, -1, .T.) // (.T.)
nKeyValue Designates the character to place in the keyboard buffer.
cClocktime Designates the specified time to place the character in the keyboard buffer.
() When called without parameters, the function completely uninstalls.
Returns
KeyTime() returns a .T. to indicate the specified character was placed in the keyboard buffer at the desired time.
Description
Warning! Use on AT-class systems only!
KeyTime() executes a specific program at an indicated time. To do this, the function places the desired key code in the keyboard buffer at the selected clock time. If a procedure is established with SET KEY..TO, CA-Clipper calls the procedure if, or when, you are in a wait state. This allows you to perform specific tasks at a particular time of day such as file backups.
There is also a special variant over and above an exact time designation. You can specify "99" for hours, minutes, or seconds, which modifies the interpretation of this portion of the time designation. A time string of "10:99:00" instructs the function to trigger a key trap every minute between 10:00 and 10:59.
If you want to specifically uninstall the function from the program, call it without specifying parameters.
Notes
Warning! Always uninstall the function before you leave the program or use the CTUS.LIB Extended Drivers found in CA-Clipper Tools. This function changes the interrupt vectors, and if the previous status is not restored before you leave the program, a system crash will eventually occur.
■ Only one time monitor can be active at any given time. A
subsequent call to KeyTime() deactivates the previous one.
■ You can use any symbols defined in the CA-Clipper file
INKEY.CH. You can set any other keys described in the CA-Clipper Tools header file ctscan.ch.
Examples
■ Place key code 7 in the keyboard buffer at 12:30:
? KeyTime(7, "12:30:00") // .T.
■ Place key code 255 in the keyboard buffer at 2:00 PM:
? KeyTime(255, "2") // .T.
■ Place key code 7 in the keyboard buffer at midnight:
? KeyTime(7, "00:00:00") // .T.
■ Set a key trap every second, starting at 11:59 PM:
? KeyTime(7, "11:59:99") // .T.
■ Set a key trap every full hour:
? KeyTime(7, "99:00:00") // .T.
■ Call with an invalid time:
? KeyTime(7, "25:30:00") // .F.
■ Uninstall KeyTime():
? KeyTime() // .F.
The returned string contains the characters from the CA-Clipper keyboard buffer that have already been read and processed by the program.
Description
With KEYREAD() you can read the keys that have already been processed by your application from the keyboard buffer. KEYREAD() offers the possibility of "looking into the past" of the current program execution so you can determine what the user has done up to that point. This gives you the ability to repeat particular actions, perform and undo functions, or build keyboard macros. KEYREAD() can also be very useful in searching for errors.
Notes
■ All the keys processed since the last execution of SET
TYPEAHEAD TO or KEYSEND() are placed in the keyboard buffer. Characters already in the buffer, but not yet read by a CA-Clipper program through an input instruction, are ignored by KEYREAD(). If the keyboard buffer is empty (as at program start, or after executing a KEYSEND() or SET TYPEAHEAD TO), the function returns a null string.
■ In contrast to the Clipper release form the Summer of 1987,
KEYREAD() in CA-Clipper returns the entire BIOS key code as defined in the ctscan.ch include file. If complete key code compatibility is required for an existing application, the ct.ch include file must be included. The ctscan.ch file also contains information regarding new keyboard function behavior.
Examples
cHistory := KEYREAD() // Prior input
IF Right(cHistory, 2) == cSequence
? "You have left MEMOEDIT using Ctrl-END!"
ENDIF
cKeyValue Designates one or more sequences that are placed in the keyboard buffer.
lAdditiveMode Designates an optional parameter. If this parameter is .T., then the key codes passed are added to the contents of the keyboard buffer. If the parmeter is .F. or if no parameter is passed, the contents of the keyboard buffer are overwritten.
Returns
When the string has been placed successfully in the CA-Clipper keyboard buffer, the function returns a value of .T.. If an error occurs, the return value is .F..
Description
KEYSEND() works similarly to the CA-Clipper KEYBOARD command. However, it allows you to use other codes for the characters that are stuffed. Symbolic constants for these key codes can be found in the ctscan.ch include file and in Appendix A. By using this unique coding for characters in the keyboard buffer, KEYSEND() allows you to place keys in the buffer that CA-Clipper's KEYBOARD command does not permit, such as codes smaller than 0 or greater than 255 (e.g. all function keys and most Alt combinations). This unique coding is also helpful for two keys that have the same Inkey() value and cannot be differentiated with the KEYBOARD command.
If you want to place normal characters like letters and numbers in the keyboard buffer, it is better to use the CA-Clipper KEYBOARD command. Using CA-Clipper Tools functions for normal characters provides no real advantage. If, on the other hand, you want to simulate other keyboard input, like function or control keys, then KEYSEND() is best to use because function and control keys can be clearly differentiated.
As with the CA-Clipper KEYBOARD command, the entire contents of the keyboard buffer are cleared as soon as KEYSEND() passes a new character. If lAdditiveMode is .T., the function adds the key codes to the current buffer contents.
Notes
■ Key codes in CA-Clipper Tools have been extended, but the old
codes are still valid (see include file ctscan.ch).
■ The maximum length of the string to be saved is now calculated
as follows:
maximum allocatable memory / 2
Examples
Simulate the function key Alt-F10:
KEYSEND(KS_ALT_F10)
dDate|nMonth Designates either a date or the number of a month. The default is the system date.
Returns
LastDayOM() returns the number of days in the month specified by dDate|nMonth.
Description
To administer due dates and other similar dates, it is useful to know the number of days that remain in a month. Specify either the day's date or month as a parameter, and you get the length of the month in days. If you subtract the number of days until today's date, you are left with the days that remain until month end.
Notes
■ Without the dDate|nMonth parameter, the function
automatically uses the system date. If there is an invalid number of months, LastDayOM() returns 0 as an error code.
Examples
How many days remain before the end of the month?
? "There are " + Str(LastDayOM() - Day(), 2) +;
" days until the end of the month"
Returns the line number of the most-recent key trap
Syntax
LASTKLINE() → nLineNumber
Returns
LASTKLINE() returns a source code line number.
Description
This function notes the program lines where KeyTime(), KeySec(), com_Key(), or com_SKey() placed a key code in the keyboard buffer. With CA-Clipper, key traps only become active when a wait state is triggered. This function differs from the CA-Clipper ProcLine() function because it returns the line number where the respective result occurs, rather than the line of the input command that triggered the trap.
Notes
■ LASTKLINE() returns a value, only if the program compiles
without the compiler switch value of -l (suppress line number information).
■ The function returns a value of 0 when the executed line is in
CA-Clipper Tools, the external function, or -1 option.
Examples
Return the line number of the last key trap:
? "Trap by", LASTKFUNC(), "in line", LASTKLINE()
LASTKPROC() returns the name of the procedure or function (KeyTime(), KeySec(), com_Key(), or com_SKey()) that places a character in the keyboard buffer when executed.
Description
CA-Clipper Tools notices when other procedures or functions encounter an interrupt. LASTKPROC() does not return the procedure name triggered by an input field key trap (as with GET..READ); instead, it returns the procedure name that was interrupted.
Notes
■ This function also returns the names of user-defined functions
(UDFs).
Examples
Return the procedure name that was interrupted:
IF LASTKPROC() = "INPUT"
* Note to user
@ 24, 30 SAY "One moment please!"
ENDIF
Compares character strings using wildcard characters
Syntax
Like(<cString1>,<cString2>) → lEqual
Arguments
cString1 Designates the wildcard string for comparison. All wildcards must be in this character string.
cString2 Designates the string to compare to cString1.
Returns
Like() returns .T. when, after taking wildcards into account, both character strings are equal.
Description
This function allows you to compare two character strings with one another, where the first can contain wildcard characters. This is similar to the way wildcard characters are used in conjunction with DOS commands but not identical. Any single character matches a "?" in the first string (see examples). The "*" within cString1 can be placed anywhere and matches multiple characters. You can also use multiple "*".
Notes
■ You can also use wildcard characters in conjunction with an
array of other string functions by using the SetAtLike() switch, but only for the "?".
Examples
■ This example shows differences from DOS:
Dir XYZ?.DBF // shows XYZ.DBF and XYZ1.DBF
? Like("XYZ?", "XYZ") // .F.
? Like("XYZ?", "XYZ1") // .T.
■ This example shows other combinations:
? Like("*OG.*", "PROG.PRG") // .T.
? Like("*OG.*", "LOG.PRG") // .T.
? Like("*R*T*", "PROTO") // .T.
? Like("*R*T*?", "PROTO") // .F.
? Like("*R*T*?", "PROTO2") // .T.
■ Use wildcards in the first parameter only:
? Like("*PER", "CLIPPER") // .T.
? Like("CLIPPER", "*PER") // .F.
lValue Designates the logical value that is converted. The default value is .F..
Returns
The character returned corresponds to the logical value specified in the parameter.
Description
In contrast to the LToN() function, which converts a logical value into a number, LToC() returns a value for the type character string. This can be particularly helpful with combined index keys.
Examples
■ Without parameters, .F. is assumed:
? LToC() // "F"
■ Return a letter that corresponds to the specified logical
value:
? LToC(.F.) // "F"
? LToC(.T.) // "T"
■ Other functions can return the logical value:
? LToC(Deleted()) // "T" or "F"
lMode When .F. is passed, or when no parameter is specified, the function returns the highest column number of the selected window. When .T. is passed, it returns the highest column number for the entire screen. The default value (.F.) returns the highest column number for the selected window.
Returns
MaxCol() returns the highest column number available within a window or within the physical screen.
Description
MaxCol() is also a CA-Clipper function. Without parameters, or when specifying .F., MaxCol() always returns a value for the selected window. In the absence of CA-Clipper Tools, this value is always Window 0, which is exactly the same size as the entire screen. However, if the extended driver CTUS.LIB and the CA-Clipper Tools window functions are implemented, this value can change. If you want the highest column for the entire screen, regardless of the window selected, you can pass .T. for the optional lMode parameter.
Notes
■ The explanation of this function was taken from the Video
Functions chapter and placed in the Extended Driver chapter. Now all CA-Clipper Tools functions that replace and/or extend CA-Clipper functions when CTUS.LIB is linked in are in the same chapter. The extensions to the CA-Clipper versions of these functions are only of interest when used in conjunction with the other extended driver functions and their accompanying windows.
Examples
Display the highest column number:
WOpen(10, 10, 20, 70) // Open a window
? MaxCol() // Relates to a window
? MaxCol(.T.) // Back to the physical screen
The function returns the maximum line length necessary to display the cString text without automatic line breaks.
Description
MaxLine() looks for the longest line within a character string. This allows you to determine the required width for a window to display text (MEMO fields). In this way the text can be displayed without additional line breaks.
Notes
■ With the exception of the carriage return and the line feed,
this function treats all characters as printable with a width of 1. If the cString text contains tabs, then you must first use the TabExpand() function to expand the tabs to spaces.
Examples
A function, based on the maximum line length, automatically performs a
suitable call of MemoEdit():
FUNCTION SHOWMEMO(cMemo)
LOCAL cMessage, nHeight, nWidth
nHeight := Min(NumLine(cMemo), MaxRow() -1)
nWidth := Min(MaxLine(cMemo), MaxCol() -1)
IF nWidth = 0
cMessage := "The memo field is empty"
ELSE
cMessage := ""
@ 0, 0 TO nHeight +1, nWidth +1 DOUBLE
MemoEdit(cMemo, 1, 1, nHeight, nWidth, .F.)
ENDIF
RETURN(cMessage)
lMode Designates the highest row nmber for the selected window or for the entire screen. When .F. is passed, or when no parameter is specified, the function returns the highest row number of the selected window. When .T. is passed, it returns the highest row number for the entire screen. The default value (.F.) returns the highest row number for the selected window.
Returns
MaxRow() returns the highest row number available within a window or within the physical screen.
Description
MaxRow() is also a CA-Clipper function. Without parameters, or when you specify .F., MaxRow() always returns a value for the selected window. In the absence of CA-Clipper Tools, this value is always Window 0, which is exactly the same size as the entire screen. However, if the extended driver CTUS.LIB and the CA-Clipper Tools window functions are implemented, this value can change. If you want the highest row for the entire screen, regardless of the window selected, you can pass .T. for the optional lMode parameter.
Notes
■ The explanation of this function was taken from the Video
Functions chapter and placed in the Extended Driver chapter. Now all CA-Clipper Tools functions that replace and/or extend CA-Clipper functions when CTUS.LIB is linked in are in the same chapter. The extensions to the CA-Clipper versions of these functions are only of interest when used in conjunction with the other extended driver functions and their accompanying windows.
Examples
Display the highest row number:
WOpen(10, 10, 20, 70) // Open a window
? MaxRow() // Relates to a window
? MaxRow(.T.) // Back to the physical screen
MAXFONT() returns the number of fonts you can load simultaneously within the screen card in use.
Description
Depending upon the screen adapter and its available memory, a various number of screen fonts can be loaded simultaneously. MAXFONT() returns the maximum number of loadable fonts and is very helpful when used in conjunction with FONTLOAD() or SetFont().
Notes
■ As a rule, EGA adapters support four different font areas and
VGA adapters support eight.
Examples
■ Load a font in the highest font area available...
FONTLOAD("ITALIC.016", MAXFONT())
■ ...and then select that font:
FONTSELECT(MAXFONT())
This function returns the number of the maximum available video "pages". A return of 0 means that only one page is available; so, the actual number of available pages is MAXPAGE() +1.
Description
MAXPAGE() allows you to determine the number of screen pages that are available for use on the display adapter. This information can be particularly valuable when you use the SETPAGE() or PAGECOPY() function.
Examples
Find the maximum number of available screen pages:
? MAXPAGE() // Result 3 means 4 pages
dDate Designates the date from which to create a string. The default is the system date.
Returns
MDY() returns a character string in Month DD, YY, or "Month DD, YYYY" format.
Description
MDY() returns the date in a character string that contains the day, name of month, and year. The CA-Clipper SET CENTURY ON/OFF switch determines whether or not the year is displayed in 2 or 4 digits.
If the function is called without a parameter, it automatically uses the current system date.
Notes
■ The returned month name always depends on which CA-Clipper
nations module is in use. A German or French version of CA-Clipper returns the appropriate month names, despite its characteristically American display.
Examples
■ Display system date (1/1/89):
SET CENTURY OFF
? MDY() // January 1, 89
■ Display a different date:
SET CENTURY ON
? MDY(CToD("02/01/89")) // February 1, 1989
Determines size of conventional or extended memory
Syntax
MEMSIZE([<lMode>]) → nMemSize
Arguments
lMode Designates whether you want to determine the size of the conventional memory (.F.) or extended memory (.T.). The default value is conventional memory (.F.).
Returns
MEMSIZE() returns the size (in kBytes) of the designated memory type.
Description
MEMSIZE() determines how much working memory is available on your system. It determines either the size of the conventional memory (0 to 640k) or extended memory (above 1 MB).
Notes
■ This function returns a value determined through the BIOS
(which assumes compatibility).
Examples
■ Show size of conventional memory:
? MEMSIZE() // e.g. 512
? MEMSIZE(.F.)
■ Show size of extended memory:
? MEMSIZE() // e.g. 384
When the switching is successful, MONISWITCH() returns .T.; otherwise, it returns false .F..
Description
Today's IBM standard PC permit the simultaneous use of a monochrome card and CGA, EGA, or VGA color adapters because their screen memory base addresses do not conflict with each other.
You could also use MONISWITCH() to switch back and forth between screens from within a CA-Clipper application. IsColor() determines which screen is currently in use.
CA-Clipper Tools does not just offer the simple capability to switch between two screens. Two totally independent video systems are used internally and all of the accompanying settings that go with them are saved when you switch. In addition, there are two window systems that can display up to 256 windows per screen at one time.
Notes
■ When you first switch, the selected screen is both initialized
and cleared at the same time. All subsequent switches retain all screen information.
Examples
■ The "*" is switched from monochrome and output on the color
screen in a loop:
FOR I = 1 TO 79
?? "*"
MONISWITCH()
NEXT I
■ Since an uneven loop counter was used in the example on the
previous page, the adapter used when you started will not be selected
after execution. Use IsColor() to determine the selected adapter:
? IsColor() // .T., when color screen selected
■ The following example shows how the current value for two
screen adapters is determined. With the double exchange, the current
selection is retained:
? MONISWITCH(MONISWITCH()) // When .T., 2 screen adapters
NBADDGROUP(<cName>) → nNamesum
Netware: 2.2 and 3.11
Arguments
cName Designates the group name that is added to the local name table. The name can be up to 15 characters long and is case sensitive.
Returns
NBADDGROUP() returns the number that has been assigned to the group name. If an error occurs (for example, if the name table is full), the function returns 0.
Description
NBADDGROUP() adds the group name cName to the local name table. If the name has been added successfully, the name can be passed as the source name in the functions NBDOPEN(), NBSCALL(), or NBSLISTCON(). The workstation can receive datagrams addressed to the group cName or react to a connection request addressed to cName.
A group name can be used on any number of workstations. However, if cName is already used as the station name on a station, the call of NBADDGROUP() fails and the function returns 0.
Examples
Add the group name ACCOUNT to the local name table:
IF NBADDGROUP('ACCOUNT')>0
? 'Name has been added successfully!'
ELSE
? 'Name could not be added!'
ENDIF
Adds a NetBIOS station name to the local name table
Syntax
NBADDNAME(<cName>) → nNamenum
Netware: 2.2 and 3.11
Arguments
cName Designates the station name that is added to the local name table. The name can be up to 15 characters long and is case sensitive.
Returns
NBADDNAME() returns the number that has been assigned to the station name. If an error occurs (for example, if the name table is full), the function returns 0.
Description
NBADDNAME() adds the station name cName to the local name table. If the name has been added successfully, the name can be passed as the source name in the functions NBDOPEN(), NBSCALL(), or NBSLISTCON(). The workstation can receive datagrams addressed to the group cName or react to a connection request addressed to cName.
Unlike group names, station names must be unique. If cName is already in use on another station or already defined as a group name, the call of NBADDNAME() fails and the function returns 0.
Examples
Add the station name MIKE to the local name table:
IF NBADDNAME('MIKE')>0
? 'Name has been added successfully!'
ELSE
? 'Name could not be added!'
ENDIF
NBDELNAME(<cName>) →lSuccess
Netware: 2.2 and 3.11
Arguments
cName Designates a station or group name that is deleted from a local name table. The name can be up to 15 characters long and is case sensitive.
Returns
NBDELNAME() returns .T. if cName has been deleted successfully from the local name table. If an error occurs (for example, if the name is not in the name table), the function returns .F..
Description
NBDELNAME() allows you to delete a station or group name from the local name table. For example, all names added to a table within an application can be deleted at the end of the program.
When a name is deleted from a name table, all NetBIOS datagram and NetBIOS session communication buffers for which cName has been passed as source name are closed. Related communication handles are then invalid.
Examples
Delete the NetBIOS name MIKE from the local name table:
IF NBDELNAME('MIKE')
? 'Name has been deleted successfully!'
ELSE
? 'Name could not be deleted!'
ENDIF
Opens the NetBIOS datagram sending and receiving buffer
Syntax
NBDOPEN(<cSourceName>,[<nRecBuffer>],[<nSendBuffer>],
[<cTargetName>],[<nPacket>]) → nHandle
Netware: 2.2 and 3.11
Arguments
cSourceName Designates the NetBIOS name of the communication's transmitting side.
nRecBuffer Designates the selected size of the receiving buffer. If no value is passed for nRecBuffer, no receiving buffer is established. The minimum size of the receiving buffer is nPacket. If the value for nRecBuffer is too small, it is changed automatically by NBDOPEN(). The maximum size of the receiving buffer is 64 KByte.
nSendBuffer Designates the selected size of the send buffer. If no value is passed for nSendBuffer, no sending buffer is established. The minimum size of the sending buffer is nPacket. If the value for nSendBuffer is too small, it is changed automatically by NBDOPEN(). The maximum size of the sending buffer is 64 KByte.
cTargetName Designates a NetBIOS name that specifies the target station(s).
nPacket Designates the packet size of the data that is sent in bytes. The packet size can be between 1 and 512 bytes. Values outside this range are changed automatically. The default value is 512 Bytes.
Returns
If an operation is successful, NBDOPEN() returns a communication handle. The return value contains a numeric value that is greater than 0. You should store the handle in a variable because all further operations that refer to an established buffer require a communication handle. If an error occurs, the function returns 0.
Description
NBDOPEN() allows you to establish a communication buffer for an NetBIOS datagram communication with other workstations in the network. The communication buffer can contain the sending and receiving buffer through which data is processed.
nSourceName is the NetBIOS name of the process that transmits the data (see the Introduction to this chapter). The name can be added to the local name table with the functions NBADDNAME() or NBADDGROUP() before the call of NBDOPEN(). If nSourceName has not been added to the name table, it is added by NBDOPEN() automatically. If the parameter nTargetName is passed, only data that is addressed to cSourceName is received.
The parameters nRecBuffer and nSendBuffer determine the size of the receiving and sending buffer. The buffers are automatically designed for one NetBIOS packet. Each buffer can be up to 64 KByte. However, the size of the buffer that is allocated by NBDOPEN() depends on the application and the configuration of the computer used.
The parameter cTargetName is optional. It controls the type of datagrams that are sent. If cTargetName has been passed, the data that is sent can be received by all workstations on which the name table contains cTargetName (see the Introduction to this chapter). If cTargetName is the name of a station, the data is sent to only one station. If cTargetName contains a group name, the data can be received by any number of stations. If cTargetName has not been passed, NBDOPEN() transmits "broadcast datagrams". Broadcast datagrams do not contain a target address and can be received by all stations that wait for broadcast datagrams.
nPacket determines the maximum size of the data range of the NetBIOS packets that are sent or received. The maximum value (and the default value) is 512 bytes. Smaller packets can be sent without failure, but larger packets are discarded. The value of nPacket is also valid for use in sending data.
Notes
■ The NetBIOS datagram communication is not based on a
connection. There is no guarantee or verification of a successful delivery to the target workstation. The implementation of specific protocols with the aid of CA-Clipper Tools functions can be necessary.
Examples
■ Open the 5 KByte NetBIOS datagram receiving buffer for source
name MICK:
nHandle=NBDOPEN("MICK",5120)
IF nHandle=0
? 'Buffer could not be established!'
ENDIF
■ Open the 2 KByte NetBIOS datagram sending buffer for source
name MICK. The target address is the NetBIOS name KEITH:
nHandle=IPXOPEN("MICK",,2048,"KEITH")
■ Open the 1 KByte NetBIOS sending and receiving buffer. For
the source and target address, see the example above:
nHandle=NBDOPEN(,1024,1024,"KEITH")
Determines the error code of the most recent NetBIOS call
Syntax
NBERROR() → nErrorCode
Netware: 2.2 and 3.11
Returns
NBERROR() returns the error code of the most recent NetBIOS call by a CA-Clipper Tools function. There is a table containing the error codes in Appendix E.
Description
NBERROR() allows you to locate the source of an error that occurred during the execution of a CA-Clipper Tools function for NetBIOS communication (for example, NBDOPEN() or NBSCALL()). If the NetBIOS call was terminated without an error, NBERROR() returns 0.
NBERROR() returns an error code that is the direct result of a NetBIOS call. If the NetBIOS call initiates the interrupt controlled receiving of a packet, the error code cannot return any information about the success or failure of the receiving process. You can use the PPCRECERR() and PPCSNDERR() functions to determine this information.
Examples
Add a NetBIOS name to the name table. If an error occurs, determine the
error source:
IF NBADDNAME('MIKE')=0 // Error?
IF NBERROR()=13
? 'Name already in local name table!'
ENDIF
ENDIF
Reads a NetBIOS name from the name table of a workstation
Syntax
NBNAME(<nPos>,[<cStatName>]) → cName
Netware: 2.2 and 3.11
Arguments
nPos Designates the position in the local name table that is read.
cStatName Designates a station name of the workstation from which the name table is read. The default value specifies the local workstation.
Returns
NBNAME() returns the NetBIOS name on position nPos in the local name table of cStatName. If an error occurs (for example, if nPos is not used or cStatName cannot be found), the function returns an empty string.
Description
Each NetBIOS workstation keeps a local name table with up to 20 NetBIOS names. NBNAME() allows you to determine the names on each position of the table. The names can be determined for the local workstation or for any workstation in the network, if you pass a NetBIOS station name cStatName.
NBNAME() always returns a 15-character string. All NetBIOS names are internally padded with blanks to a length of 15 characters.
Examples
■ Read the name table of the local workstation:
FOR i = 1 TO 20
? NBNAME(i)
NEXT i
■ Read the name table of workstation MIKE:
FOR i = 1 TO 20
? NBNAME(i,"MIKE")
NEXT i
Determines the number of NetBIOS names on a workstation
Syntax
NBNAMECNT([<cStatName>]) → nNames
Netware: 2.2 and 3.11
Arguments
cStatName Designates the station name of the workstation from which the name table is read. The default value is the local workstation.
Returns
NBNAMECNT() returns the number of established NetBIOS names on the station cStatName. If an error occurs (for example, if cStatName has not been found), the function returns -1.
Description
Internally, each NetBIOS workstation keeps a local name table with up to 20 NetBIOS names. NBNAMECNT() allows you to determine the number of names in the table. The number of names can be determined for the local workstation or for any workstation in the network, if you pass a NetBIOS station name cStatName.
Examples
■ Determine the number of NetBIOS names on the local
workstation:
? NBNAMECNT()
■ Determine the number of NetBIOS names on workstation MIKE:
? NBNAMECNT("MIKE")
NBNAMENUM(<cName>) → nNumber
Netware: 2.2 and 3.11
Arguments
cName Designates the NetBIOS name for which the number is determined.
Returns
NBNAMENUM() returns the number of cName. If an error occurs, the function returns -1.
Description
NetBIOS assigns a number to each new station or group name. The name's number can be determined with NBNAMENUM(). If an error occurs (for example, if the name does not exist), the function returns -1.
Examples
Determine the number for the NetBIOS name ACCOUNT:
nNumber=NBNAMENUM('ACCOUNT')
IF nNumber <> -1
? 'Number for ACCOUNT:',nNumber
ELSE
? 'Name does not exist!'
ENDIF
NBNAMESTAT(<nPos>,[<cStatName>]) → nStatus
Netware: 2.2 and 3.11
Arguments
nPos Designates the position in the local name table that is read.
cStatName Designates a station name of the workstation from which the name table is read. The default station is the local workstation.
Returns
NBNAMESTAT() returns a bit mask that contains the status of the specified NetBIOS name. The highest bit (bit 8) indicates if the name is a station name (not set) or a group name (set). The three lower bits (bits 1 to 3) are seen as one unit. Their value returns information about the current state of the specified name. The following table contains a description of the three bits:
Table 31.3: Coding of Bits 1-3 in the NBNAMESTAT() Return Value
Value Binary Definition
0 000 Name registration not finished
4 100 Name registered properly
5 101 Name already deleted, but sessions still to come
6 110 Duplicate name
7 111 Duplicate name, deletion in process
If an error occurs (for example, if cStatName has not been found), the function returns -1.
Description
Internally, each NetBIOS workstation keeps a local name table with up to 20 NetBIOS names. NBNAMESTAT() allows you to determine the status of each name in the table. The status of a name in the name table can be determined for the local workstation or, by passing a NetBIOS station name cStatName, for any workstation in the network.
Examples
■ Check to see if the first NetBIOS name on the local
workstation is a station or group name:
nStat=NBNAMESTAT(1)
IF nStat=-1
? 'Error!'
ELSE
IF IsBit(nStat,8)
? 'Group name'
ELSE
? 'Station name'
ENDIF
ENDIF
■ Check to see if the third NetBIOS name on the local
workstation is registered properly:
IF NumAnd(NBNAMESTAT(3),7)=4
? 'Name registered properly!'
ELSE
? 'Name not properly registered!'
ENDIF
NBRESET([<nMaxSessions>],[<nMaxNCBs>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
nMaxSessions Designates the maximum number of sessions possible after the adapter has been reset. The default value is 0. The value 0 sets the internal default value for the number of sessions (normally 6).
nMaxNCBs Is the maximum number of simultaneously active NCBs (Network Control Blocks) after the adapter has been reset. The default value is 0. The value 0 sets the internal default value for the number of NCBs (normally 12).
Returns
NBRESET() returns .T. if the adapter has been reset successfully.
Description
Important! This function must not be called in networks that base the internal communication on the NetBIOS protocol. The entire network can be brought to a standstill! However, on a Novell workstation, where the NetBIOS emulator (NETBIOS.EXE) is loaded, the function NBRESET() can be called without any problems.
When an adapter is reset, the local name table is deleted and all active sessions are terminated. At the same time, the maximum number of sessions and the maximum number of NCBs (Network Control Blocks) can be redefined. CA-Clipper Tools functions for the NetBIOS communication require two NCBs for each session communication buffer, and one NCB each for the datagram communication buffer, and the sending and receiving buffers.
Examples
Reset the NetBIOS adapter in a Novell network:
IF NNetwork()
NBRESET()
ENDIF
Opens a NetBIOS session sending and receiving buffer and attempts a connection setup
Syntax
NBSCALL(<cSourceName>,[<nRecBuffer>],[<nSendBuffer>],
<cTargetName>,[<nPacket>],[<nRecTimeout>],
[<nSendTimeout>]) → nHandle
Netware: 2.2 and 3.11
Arguments
cSourceName Designates the NetBIOS name of the communication's transmitting side.
nRecBuffer Designates the selected size of the receiving buffer. If no value is passed for nRecBuffer, no receiving buffer is established. The minimum size of the receiving buffer is nPacket. If the value for nRecBuffer is too small, it is changed automatically by NBSCALL(). The maximum size of the receiving buffer is 64 KByte.
nSendBuffer Designates the selected size of the sending buffer. If no value is passed for nSendBuffer, no sending buffer is established. The minimum size of the sending buffer is nPacket. If the value for nSendBuffer is too small, it is changed automatically by NBSCALL(). The maximum size of the sending buffer is 64 KByte.
cTargetName Designates a NetBIOS name that specifies the target station.
nPacket Designates the packet size of the data that is sent in bytes. The default value is 512 Bytes.
nRecTimeout Designates the timeout for the following receiving operations in 1/2 seconds. The default value (0) designates no timeout.
nSendTimeout Designates the timeout for the following sending operations in 1/2 seconds. The default value (0) designates no timeout.
Returns
If an operation is successful, NBSCALL() returns a communication handle. The return value contains a numeric value that is greater than 0. You should store the handle in a variable because all further operations that refer to an established buffer require a communication handle. If an error occurs, the function returns 0.
Description
NBSCALL() allows you to establish a communication buffer for a NetBIOS session communication with other workstations in the network. The communication buffer can contain the sending and receiving buffer through which the interrupt controlled sending and receiving of data is processed.
nSourceName is the NetBIOS name of the process that transmits the data (see the Introduction to this chapter). The name can be added to the local name table with the functions NBADDNAME() or NBADDGROUP() before the call of NBSCALL(). If nSourceName has not been added to the name table, it is added by NBSCALL() automatically.
The parameters nRecBuffer and nSendBuffer determine the size of receiving and sending buffers. The buffers are automatically designed for one NetBIOS packet. Each buffer can be up to 64 KByte. However, the size of the buffer that is allocated by NBSCALL() depends on the application and the configuration of the computer used.
The parameter cTargetName is mandatory. The session is set up with the station specified by cTargetName.
nPacket determines the maximum size of the data range of the NetBIOS packets that are sent or received. The maximum value (and the default value) is 512 bytes. Smaller packets can be sent without failure. However, larger packets are discarded. The value of nPacket is also valid for use in sending data.
The seconds for the timeout are not determined individually for each sending and receiving operation. The timeout is set when the session is opened by passing the parameters nRecTimeout and nSendTimeout. The parameters can contain numeric values that specify the timeout in steps of 1/2 second.
If all parameters have been passed correctly and the buffers have been established successfully, NBSCALL() attempts to set up a session between the current workstation and the target station. However, the target station must expect the connection setup. If a CA-Clipper application is running on the target station, the function NBSLISTCON() must have been called. If no acknowledgment is returned by the target station within the specified timeout, NBSCALL() releases the reserved buffers and returns 0.
After a successful connection setup NBSCALL() returns a communication handle that is greater than 0. If a value has been passed for nRecBuffer, NBSCALL() initiates an interrupt controlled receiving mechanism that receives incoming packets in the background and then copies them to a receiving buffer. The data can then be read with the PPCREAD() function within a CA-Clipper application. If the receiving buffer is full, incoming data is discarded without notifying the sender. Data should be removed from the receiving buffer and processed as soon as possible. You should either read the contents of the buffer periodically (polling) or supervise the buffer on an event-oriented basis: for example, with the function PPCKEY().
Notes
■ Unlike a NetBIOS datagram communication, a NetBIOS session
communication is connection-oriented. A connection is established between two stations. As long as no error occurs, a successful delivery of sent packets is guaranteed.
Examples
■ Attempt to set up a NetBIOS session connection to workstation
MIKE. If the setup is successful, a 5000 byte receiving buffer and a
1000 byte sending buffer are established. The source name on the
local workstation is KEITH:
nHandle=NBSCALL("MICK",5000,1000,"MIKE")
IF nHandle=0
? 'Failure!'
ENDIF
■ The destination side can wait for the connection with the
following call:
nHandle:=NBSLISTCON("MIKE",2000,2000)
Determines the target name of a NetBIOS communication session
Syntax
NBSCONTARG(<nHandle>) → cNetBIOSName
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication buffer.
Returns
NBSCONTARG() returns the destination's NetBIOS name. If nHandle does not specify a NetBIOS session communication buffer or the NetBIOS session connection is not active, the function returns an empty string.
Description
NBSCONTARG() allows you to determine the destination's NetBIOS name after a call of NBSLISTCON(). For example, if no target name has been passed for NBSLISTCON(), the function can establish a connection to any requesting station. The name of this station can be queried with NBSCONTARG().
Examples
Wait for a NetBIOS session connection in the background. After the
connection has been set up, display the destination's NetBIOS name:
nHandle=NBSLISTCON("MIKE",1000,1000)
WHILE .NOT. PPCCONACT(nHandle)
ENDDO
? 'Connection set up with ',NBSCONTARG(nHandle)
Opens the NetBIOS session sending and receiving buffer and waits for connection in the background
Syntax
NBSLISTCON(<cSourceName>,[<nRecBuffer>],
[<nSendBuffer>],[<cTargetName>],[<nPacket>],
[<nRecTimeout>],[<nSendTimeout>]) → nHandle
Netware: 2.2 and 3.11
Arguments
cSourceName Designates the NetBIOS name of the communication's transmitting side.
nRecBuffer Designates the selected size of the receiving buffer. If no value is passed for nRecBuffer, no receiving buffer is established. The minimum size of the receiving buffer is nPacket. If the value for nRecBuffer is too small, it is changed automatically by NBSLISTCON(). The maximum size of the receiving buffer is 64 KByte.
nSendBuffer Designates the selected size of the sending buffer. If no value is passed for nSendBuffer, no sending buffer is established. The minimum size of the sending buffer is nPacket. If the value for nSendBuffer is too small, it is changed automatically by NBSLISTCON(). The maximum size of the sending buffer is 64 KByte.
cTargetName Designates a NetBIOS name that specifies the target station. If a value is passed for cTargetName, NBSLISTCON() waits for a connection request for this station. The default value does not specify a target name.
nPacket Designates the packet size of the data that is sent in bytes. The default value is 512 Bytes.
nRecTimeout Designates the timeout for the following receiving operations in 1/2 seconds. The default value (0) designates no timeout.
nSendTimeout Designates the timeout for the following sending operations in 1/2 seconds. The default value (0) designates no timeout.
Returns
If an operation is successful, NBSLISTCON() returns a communication handle. The return value contains a numeric value that is greater than 0. You should store the handle in a variable because all further operations that refer to an established buffer require a communication handle. If an error occurs, the function returns 0.
Description
NBSLISTCON() establishes a communication buffer for an NetBIOS session communication with other workstations in the network, and then waits for a connection setup through any other station. The communication buffer can contain sending and receiving buffers through which the interrupt controlled sending and receiving of data is processed.
nSourceName is the NetBIOS name of the process that transmits the data (see the Introduction to this chapter). The name can be added to the local name table with the functions NBADDNAME() or NBADDGROUP() before the call of NBSLISTCON(). If nSourceName has not been added to the name table, it is added by NBSLISTCON() automatically.
The parameters nRecBuffer and nSendBuffer specify the size of the receiving and sending buffers. The buffers are automatically designed for one NetBIOS packet. Each buffer can be up to 64 KByte in size. However, the size of the buffer that is allocated by NBSLISTCON() depends on the application and the configuration of the computer used.
The parameter cTargetName is optional. When a value is passed for cTargetName, NBSLISTCON() waits for a connection request for cTargetName. Without cTargetName, NBSLISTCON() reacts to any connection request.
nPacket determines the maximum size of the data range of the NetBIOS packets to be sent or received. The maximum and default value is 512 bytes. Smaller packets can be sent without failure. However, larger packets are discarded. The value of nPacket is also valid for use in sending data.
The seconds for the timeout are not determined individually for each sending and receiving operation. The timeout is set when the session is opened by passing the parameters nRecTimeout and nSendTimeout. The parameters can contain numeric values that specify the timeout in steps of 1/2 second.
If all parameters have been passed correctly and the buffers have been established successfully, NBSLISTCON() returns a communication handle. A communication handle, however, does not indicate that a NetBIOS session has already been set up. After NBSLISTCON() has been executed, a handler waits for a connection request in the background. The communication handler, returned by NBSLISTCON(), cannot be used for sending and receiving before a connection has been established. The current connection status after a call of NBSLISTCON() can be queried with PPCCONACT(). It is also possible to trigger a key trap with PPCKEY().
Notes
■ Unlike a NetBIOS datagram communication, a NetBIOS session
communication is connection-oriented. A connection is established between two stations. As long as no error occurs, a successful delivery of sent packets is guaranteed.
Examples
■ Wait for the setup of a NetBIOS session:
nHandle=NBSLISTCON("MICK",1000)
WHILE .NOT. PPCCONACT(nHandle)
ENDDO
■ After a NetBIOS session has been set up successfully, send key
code 255 to the keyboard buffer:
#include "ctppc.ch"
nHandle=NBSLISTCON("MICK",5000,1000)
PPCKEY(nHandle,255,PPC_CONESTB)
cLocalDevice Designates the name for the local device, for which an existing redirection in the network is released.
Returns
NetCancel() returns .T. when a redirection existed for the designated device and it was released.
Description
NETWORK CANCEL REDIRECTION With NetCancel(), an existing redirection for a local device can be released. You call the function by simply specifying the device name, d: or LPTn:.
If the return value is .F., the device did not exist or was not previously redirected.
Notes
WARNING! Make sure that no drive on which files are still open is rendered invalid when you use NetCancel(). This situation leads to problems, and under certain circumstances, to data loss.
Examples
Make all redirected printer devices local
nCounter := 0
cLocalName := NETLOCNAME(nCounter)
DO WHILE .NOT. Empty(cLocalName)
IF cLocalName $"LPT1:LPT2:LPT3:PRN:" // Is device a printer?
NetCancel(cLocalName)
ENDIF
nCounter := nCounter +1
cLocalName := NETLOCNAME(nCounter)
ENDDO
Determines whether a drive is local or resident on the server
Syntax
NetDisk(<cDrive>) → lServerDrive
Arguments
cDrive Designates the drive that is tested in a range from A to Z.
Returns
NetDisk() returns .T. when the specified drive is a network drive.
Description
NETWORK DISK This function allows you to determine if a drive in the range of A: to Z: is local or remote. Remote means that a drive is actually resident on a file server and that the local device address has been redirected through DOS.
Notes
■ Since this is DOS information, this function works correctly
with those networks that support DOS.
Examples
Test all drives to determine if they are local or resident on the
server:
FOR I = Asc("A") TO Asc("Z")
? NetDisk(Chr(I))
NEXT I
Determines whether the current printer is a local or network printer
Syntax
NetPrinter() → lServerPrinter
Returns
NetPrinter() returns .T. when the printer installed using the CA-Clipper SET PRINTER TOLPTn command has been redirected onto a network server.
Description
NETWORK PRINTER This function allows you to determine if the printer installed using the CA-Clipper SET PRINTER TOLPTn command is local or resides on a network server.
Notes
■ This function cannot be used in a Novell network, because
there the redirection occurs on a deeper level (INT 17h). However, you can use the NNETCAPACT() function in a Novell Network.
Examples
Determine whether LPT1 and LPT2 are local or remote:
SET PRINTER TO LPT1
? NetPrinter() // .F., local printer
SET PRINTER TO LPT2
? NetPrinter() // .T., network printer
cLocalDevice Designates the name of the local device (LPTn:, PRN:, or d:).
cServerDevice Designates the complete path for the server (\Servername
cPassword Can designate a password when it is required by the server.
Returns
NetRedir() returns .T. when the specified local device has been redirected to the selected server device.
Description
NETWORK REDIRECTION Under PC LAN/MS-NET, server devices can be redirected to local devices using the NET USElocalremote command. Exactly the same thing can be accomplished using the NetRedir() function from within an application. The function returns .T. when the redirection has been carried out. A return of .F. could occur for several reasons:
■ The designated drive is not accepted. Either this drive is
already physically available or LASTDRIVE in CONFIG.SYS has to be set higher.
■ The device is not available on the server. Use NET SHARE on
the selected server to review all the devices available there.
■ The password is incorrect. Check the password that the server
has designated for the device.
■ Too many devices have already been allocated. In this
instance you must change some of the flags with the NET START command (see PC LAN/MS-NET manual).
Notes
■ The redirections accomplished here are not listed when you use
NET USE.
Examples
■ Create a new drive H:
? NetRedir("H:", "\\SERVER\DRIVEC") // .T. if OK
■ In this example, the server device asks for a password:
? NetRedir("H:", "\\SERVER\DRIVEC", "SECRET") // .T. if OK
■ Allocate a server printer to LPT2:
? NetRedir("LPT2:", "\\SERVER\PRINTER") // .T. if OK
Determines the name of a server device for a local device
Syntax
NetRmtname(<nDevice>) → cServerDevice
Arguments
nDevice Designates the location within the DOS redirection table.
Returns
NetRmtname() returns the local name for the designated location in the DOS redirection table (nDevice), or a null string if no name is available.
Description
NETWORK REMOTE NAME Under PC LAN/MS-NET server devices can be redirected to local devices using the NET USElocalremote command. DOS logs these redirections in its redirection table. In this way, NetRmtname() allows you to determine all the local devices that have been redirected to a server device.
Notes
■ Using NETLOCNAME() allows you to determine the name of the
corresponding local device.
Examples
Determine all the devices used by the server:
nCounter := 0
cDeviceName := NetRmtname(nCounter)
DO WHILE .NOT. Empty(cDeviceName)
? cDeviceName // Display server device
nCounter := nCounter +1
cDeviceName := NetRmtname(nCounter)
ENDDO
Network() returns .T. when a PC LAN/MS-NET or a Novell network is available.
Description
With Network(), you can determine whether or not an IBM PC LAN/MS-NET or Novell network is available and active. Using NNetwork() allows you to further differentiate to see if you are dealing with a Novell network.
Examples
Test to see if one of the two networks is available:
IF Network()
* ...
ENDIF
nDevice Designates the location within the DOS redirection table.
Returns
NETLOCNAME() returns the local name for the designated location in the DOS redirection table (nDevice), or a null string if no name is available.
Description
NETWORK LOCAL NAME Under PC LAN/MS-NET, server devices can be redirected to local devices using the NET USElocalremote command. DOS logs these redirections in its redirection table. In this way, NETLOCNAME() allows you to determine all the local devices that have been redirected to a server device.
Notes
■ Using NetRmtname() allows you to determine the name of the
corresponding server device.
Examples
Determine all the local devices that have been redirected to a server
device:
nCounter := 0
cLocalName := NETLOCNAME(nCounter)
DO WHILE .NOT. Empty(cLocalName)
? cLocalName // Display local device
nCounter := nCounter +1
cLocalName := NETLOCNAME(nCounter)
ENDDO
Determines whether or not a Novell network is active
Syntax
NNetwork() → lNovellNetActive
Netware: 2.2 and 3.11
Returns
NNetwork() returns .T. when you are working in a Novell network.
Description
NOVELL NETWORK With NNetwork(), you can determine if you are working with a Novell network. If so, the NNETVER() function can determine the related version.
Notes
■ This function only tests to see if a Novell shell (requestor)
has been loaded.
Examples
Determine if there a Novell network, version => 2.0/ELS I that is
active:
IF NNetwork()
IF NNETVER() >= "2.0"
NNETCAPBEG(1) // Start capture
ENDIF
ENDIF
NNETACCDIS(<cUser>,[<lLock>],[<cServer>|<nConId>),
→ lLocked
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of the user for whom an access account lock is set or checked.
lLock Allows locking (.T.) or releasing (.F.) of the access account of cUser.
cServer Designates the name of the file server where cUser is established. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETACCDIS() returns .T. when the access account of cUser is currently disabled. cUser is not able to log in. If the parameter lLock has been passed and the return value does not match lLock, the user of the NNETACCDIS() function did not have the rights requested for the modification (see the description).
Description
NOVELL NET ACCOUNT DISABLED With NNETACCDIS(), the access account lock for cUser can be set or queried. To determine the status of the account, do not pass a value for the parameter lLock. To set the status of the account, pass .T. or .F. for lLock. However, to lock or release an access account lock, supervisor rights on the related file server are necessary. With cServer or nConId, the status of any user on any attached server can be queried. NNETATTACH() and NNETLOGIN() return the server connection ID.
Examples
■ Determine the access account status for user MIKE:
? NNETACCDIS('MIKE') // for example .T.
■ Disable the account for user MIKE:
NNETACCDIS('MIKE',.T.)
■ Release the account lock for user MIKE:
NNETACCDIS('MIKE',.F.)
NNETADDGRP(<cGroup>,<cUser>|<aUser>,
[,<cServer>|<nConId>) → nNumber
Netware: 2.2 and 3.11
Arguments
cGroup Designates the name of the group to which cUser|aUser is added.
cUser Designates the name of the user that is added to cGroup.
aUser Designates a number of elements of the type string. Each element is the name of a user that is added to cGroup.
cServer Designates the name of the file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETADDGRP() returns the number of users successfully added to cGroup. If no user could be added, the function returns 0.
Description
NOVELL NET ADD USER TO GROUP With NNETADDGRP(), one or more users can be added to an existing group. To add one user, the login name of the user must be passed as the single argument, cUser. More users can be added by passing the array, aUser, that contains the user names as elements. As a member of a group, users automatically inherit the group privileges. By passing cServer or nConId, the operation can be executed on any connected file server. The connection ID of a file server can be determined with the functions NNETATTACH() or NNETLOGIN().
Supervisior rights are necessary to add a user to a group.
Notes
■ NNETADDGRP() is a high level function based on the low level
functions for bindery access. The CA-Clipper source code can be found on the product disks.
Examples
■ Add user MIKE to the TECH group:
IF NNETADDGRP('TECH','MIKE')>0
? 'User added successfully!'
ELSE
? 'No user added!'
ENDIF
■ Add users PAUL, JIM, and STEPHEN to the group TOOLS:
NNETADDGRP('TOOLS',{'PAUL','JIM','STEPHEN'})
NNETADDQOP(<cQueue>,<cUser>|<aUser>,[<cServer>|
<nConId>) → nNumber
Netware: 2.2 and 3.11
Arguments
cQueue Designates a print queue on the default server or on cServer|nConId.
cUser Designates the name of a user that is added as an operator of cQueue.
aUser Designates a number of elements of the type string. Each element contains the name of a user that is added as an operator of cQueue.
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETADDQOP() returns the number of users that have been added successfully as operators of cQueue. A value of 0 indicates that no operator has been added.
Description
NOVELL NET ADD QUEUE OPERATORNNETADDQOP() allows you to add one or more users as operators of a print queue. To add one user, the login name of the user must be passed in cUser. To add more users, an array containing all user names can be passed in aUser. With the parameters cServer or nConId, the operation can be performed on any attached server. The connection ID of a server can be determined with NNETATTACH() or NNETLOGIN().
Supervisor rights are required on the related file server to add a user as a queue operator.
Notes
■ NNETADDQOP() is a high level function based on the low level
functions of the bindery access. The CA-Clipper source code can be found on the product disks.
Examples
■ Add user MICK as an operator of the queue LINEPRINTER:
IF NNETADDQOP('LINEPRINTER','MICK')>0
? 'User added successfully!'
ELSE
? 'Error!'
ENDIF
■ Add users PETER, MIKE, and JIM as operators of the queue
LINEPRINTER:
NNETADDQOP('LINEPRINTER',{'PETER','MIKE','JIM'})
NNETADDQSV(<cQueue>,<cPServer>|<aPServer>,[<cServer>|
<nConId>) → nNumber
Netware: 2.2 and 3.11
Arguments
cQueue Designates a print queue on the default server or on cServer|nConId.
cPServer Designates the name of a print server that is added as the server for cQueue.
aPServer Designates a number of elements of the type string. Each element contains the name of a print server that is added as the server for cQueue.
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETADDQSV() returns the number of print servers that have been added successfully as servers of cQueue. A value of 0 indicates that no server has been added.
Description
NOVELL NET ADD QUEUE SERVERNNETADDQSV() allows you to add one or more print servers as servers of a print queue. To add one server, the name of the server must be passed in cPServer. To add more servers, an array containing all print server names can be passed in aPServer. With the parameters cServer or nConId, the operation can be performed on any attached server. The connection ID of a server can be determined with NNETATTACH() or NNETLOGIN().
Supervisor rights are required on the related file server to add a print server as the server for a queue.
Notes
■ NNETADDQSV() is a high level function based on the low level
functions of the bindery access. The CA-Clipper source code can be found on the product disks.
Examples
■ Add the print server PSERVERTOOLS1 as the server for the queue
LINEPRINTER:
IF NNETADDQSV('LINEPRINTER','PSERVERTOOLS1')>0
? 'Print server added successfully!'
ELSE
? 'Error!'
ENDIF
■ Add the print servers PSERVERTOOLS1 and PSERVERDEV1 as servers
for the queue LINEPRINTER:
NNETADDQSV('LINEPRINTER',{'PSERVERTOOLS1','PSERVERDEV1'})
NNETADDQUS(<cQueue>,<cUser>|<aUser>,[<cServer>|
<nConId>) → nNumber
Netware: 2.2 and 3.11
Arguments
cQueue Designates a print queue on the default server or on cServer|nConId.
cUser Designates the name of a user that is added as a user of cQueue.
aUser Designates a number of elements of the type string. Each element contains the name of a user that is added as a user of cQueue.
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETADDQUS() returns the number of users that have been added successfully as users of cQueue. A value of 0 indicates that no user has been added.
Description
NOVELL NET ADD QUEUE USERNNETADDQUS() allows you to add one or more users as users of a print queue. To add one user, the login name of the user must be passed in cUser. To add more users, an array containing all user names can be passed in aUser. With the parameters cServer or nConId, the operation can be performed on any attached server. The connection ID of a server can be determined with NNETATTACH() or NNETLOGIN().
Supervisor rights are required on the related file server to add a user as a queue operator.
Notes
■ NNETADDQUS() is a high level function based on the low level
functions of the bindery access. The CA-Clipper source code can be found on the product disks.
Examples
■ Add user MICK as a user of the queue LINEPRINTER:
IF NNETADDQUS('LINEPRINTER','MICK')>0
? 'User added successfully!'
ELSE
? 'Error!'
ENDIF
■ Add users PETER, MIKE, and JIM as users of the queue
LINEPRINTER:
NNETADDQUS('LINEPRINTER',{'PETER','MIKE','JIM'})
NNETADDSET(<cObjName>,[<nType>],<cPropName>,<cMember>,
[<cMemberType>],[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cObjName Designates the name of the bindery object that is processed.
nType Designates a numeric value that indicates the type of cObjName. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use with the bindery functions of CA-Clipper Tools. The default value indicates the object type OBJ_USER.
cPropName Designates the name of the set property of cObjName.
cMember Designates the name of the bindery object that is stored in the property cPropName of the bindery object cObjName.
cMemberType Designates a numeric value that indicates the type of cMember. The default value indicates the object type OBJ_USER.
cServer Designates the name of the file server that contains the bindery that is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETADDSET() returns .T. if the bindery object has been added successfully. If an error occurs, the Novell error code can be queried with the NNETERROR() function.
Description
Important! NNETADDSET() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET ADD BINDERY OBJECT TO SET Internally, Novell Netware differentiates between two possible property types: item and set property. The function NNETADDSET() allows the storage of information to a set property. Set properties contain a list of references to other bindery objects. For example, the GROUP_MEMBERS property contains a list of users that are members of a user group.
The parameters cObjName and nType describe the object that is processed. cPropName is the name of the property. The property must have been created before (for example, with the NNETCRTPRP() function). cMember and cMemberType specify the bindery object that is added to cPropName. By passing the parameters cServer or nConId, it is possible to access the bindery of any connected file server. The connection ID of a server can be determined with the functions NNETATTACH() or NNETLOGIN().
Prerequisites for a successful call of NNETADDSET() are sufficient bindery and property access rights. The necessary property access rights depend on the property security of the property that is manipulated. For efficiency reasons, user defined object types must be passed in the high-low format.
Examples
■ Add user MIKE to the MARKET group :
#include "ctnnet.ch"
IF NNETADDSET('MARKET',OBJ_GROUP,'GROUP_MEMBERS','MIKE')
? 'User added successfully!'
ELSE
? 'No user added!'
ENDIF
■ To add a user to a group, it is also necessary to add the
group to two user properties. Use NNETADDGRP() when adding a user to
a group.
NNETADR([<cUser>],[<nNumber>],[<cServer>|<nConId>])
→ cNetAddress
Netware: 2.2 and 3.11
Arguments
cUser Designates the login name of the user whose internal netaddress is determined. The default value is the internal netaddress of the current workstation.
nNumber Designates the connection of cUser. The default value is 1.
cServer Designates the name of the file server on which cUser is logged in. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETADR() returns the internal netaddress of cUser in the form of a 20- character hexadecimal string. The returned string represents a 10-byte sequence, where each byte consists of two hexadecimal characters. The leading eight characters of cNetAddress (four byte) specify the network number of cUser. The remaining 12 characters (six byte) contain the station ID of cUser (number of the network adapter, Node Address).
If an error occurs (no user is logged in with the name cUser), NNETADR() returns an empty string.
Description
NOVELL NET ADDRESSNNETADR() allows you to determine the internal netaddress of the workstation, where cUser is currently logged in. For example, this address can be used to establish a Point-To-Point connection with cUser.
Netware does not limit the number of workstations where a user can be simultaneously logged in. The currently active connections can be passed with the optional parameter nNumber. The default return value of NNETADR() contains the internal netaddress of the first connection. By passing nNumber, additional addresses can be determined.
Notes
■ nNumber does not specify the connection ID of cServer.
This parameter simply counts the connections of cUser.
Examples
■ Determine the internal netaddress of the first connection of
user MIKE:
? NNETADR('MIKE') // z.B. "4921750400001B025A99"
■ Determine the internal netaddresses of all connections of user
MIKE:
nNumber=1
cAdr=""
WHILE .T.
cAdr=NNETADR('MIKE',nNumber)
IF Empty(cAdr)
EXIT
ENDIF
? cAdr
nNumber=nNumber+1
ENDDO
Determines or sets the expiration date of an access account
Syntax
NNETAEXPD(<cUser>,[<dDate>],[<cServer>|<nConId>)
→ dExpiration
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of the user.
dDate Designates the new expiration date for the access account of cUser.
cServer Designates the name of the file server where cUser is established. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETAEXPD() returns the valid expiration date for the access account of cUser. If dDate has been passed and the returned date does not match dDate, the user of the NNETAEXPD() did not have the requested rights for the modification (see the description).
Description
NOVELL NET ACCOUNT EXPIRATION DATENNETAEXPD() allows you to query and set the expiration date for the access account of cUser. Any attempt by cUser to log in after the account expires disables the account. To query the expiration date, do not pass a date for dDate. If a value is passed for dDate, NNETAEXPD() tries to modify the expiration date. However, supervisor rights on cServer are required to set a new expiration date. An expiration date can be removed by passing an empty date. With the parameters cServer or nConId, the expiration date of users on any file server can be queried or set. The connection ID of a file server can be determined with the functions NNETATTACH() or NNETLOGIN().
Examples
■ Determine the expiration date for user MIKE:
? NNETAEXPD('MIKE') // z.B. 03/19/92
■ Set the new expiration date for the account of user MIKE:
NNETAEXPD('MIKE',CToD('06/01/92'))
■ Remove the expiration date for the account of user MIKE:
NNETAEXPD("MIKE",CToD(""))
NNETATTACH(<cServer>) → nConId
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the server that is attached.
Returns
If the server has been attached successfully, NNETATTACH() returns a numeric value between 1 and 8. This value specifies the connection ID. The workstation uses the connection ID to address the server.
If an error occurs, NNETATTACH() returns 0. The error code can be queried with the function NNETERROR().
Description
NOVELL NET ATTACH A workstation can be attached to up to eight file servers. This logical connection between workstation and file server is necessary to access network services and resources. NNETATTACH() allows you to establish a connection without a login of the user on cServer.
If the server has been attached successfully, NNETATTACH() returns a value between 1 and 8. The return value can be stored in a variable and can be used later to identify a file server. Alternatively, a file server can also be identified by using the server name.
Using the NNETLOGIN() function to log in a user on a file server does not require the call of NNETATTACH(). NNETLOGIN() attaches the file server automatically if necessary.
Notes
■ The names of the attached file servers can be determined by
using the function NNETFSLIST() or the Novell utility SLIST.
Examples
Attach the file server NANGERTOOLS2:
nConId=NNETATTACH("NANGERTOOLS2")
NNETBANNER([<cBannerName>]) → cName
Netware: 2.2 and 3.11
Arguments
cBannerName Designates an optional parameter that must be passed to set a new banner name for the current capture processes.
Returns
NNETBANNER() returns the banner name that is set.
Description
NOVELL NET BANNERNNETBANNER() allows you to set or determine the current banner name. To query the banner name, the function can be called without the parameter. To set a new banner name, the name must be passed in cBannerName. The banner name is the same for all current capture processes (capture for different interfaces).
Examples
■ Determine the current banner name:
? NNETBANNER()
■ Set the banner name to MICK:
NNETBANNER('MICK')
NNETBINACC([<cServer>|<nConId>]) → nRights
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server for which the bindery security access level is determined. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETBINACC() returns the bindery security access level of the currently logged in user. nRights can be a numeric value between 0 and 3.
Description
NOVELL NET BINDERY ACCESS LEVEL All bindery objects and their properties have security levels for read and write access. For example, the security code can be defined when a new bindery object is created with the NNETCRTOBJ() function. The access to an object or a property is possible only if the user's access right is equivalent to or higher than the security level defined for the operation. With NNETBINACC(), you can determine the security access level. The function returns a numeric value between 0 and 3.
Table 18.1: Security Access Levels
Value Definition
0 User has not logged in to the file server
1 User has logged in to the file server
2 User has logged in to the file server with password
3 User has logged in to the file server as supervisor
With the parameters cServer or nConId, the security access level can be determined for any attached file server. The connection ID of a file server can be determined with the functions NNETATTACH() or NNETLOGIN().
Examples
Determine the bindery security access level; if the return value is 3
(supervisor), delete a user:
#include "ctnnet.ch"
IF NNETBINACC()=3
NNETDELOBJ('GUEST',OBJ_USER)
ENDIF
NNETBINCL([<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server where the bindery is closed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETBINCL() returns .T. if the bindery has been closed successfully.
Description
Important! NNETBINCL() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET BINDERY CLOSE Under Netware, the bindery is physically organized as two files, NET$BIND.SYS and NET$BVAL.SYS. These files are hidden files in the SYS:SYSTEM directory. During network operation these files are exclusively open and cannot be accessed directly. For example, to archive the bindery files, the bindery must be closed. The bindery can be closed with the NETBINCL() function, but supervisor rights are required.
With the parameters cServer or nConId, the bindery can be closed on any attached file server. The connection ID of a file server can be determined with the functions NNETATTACH() or NNETLOGIN().
Important! While the bindery is closed, much of the network is not functional. The bindery should not be closed if another user is logged in. The time that the bindery is closed should be kept to a minimum.
Examples
In the following example, drive K: is mapped to the SYS:SYSTEM directory
of the current file server. If the bindery has been closed
successfully, the bindery files are copied to a local drive with the
FileCopy() function. After the FileCopy(), the bindery is reopened with
the NNETBINOP() function:
IF NNETBINCL()
FileCopy('K:NET$BIND.SYS','C:\NET$BIND.SYS')
FileCopy('K:NET$BVAL.SYS','C:\NET$BVAL.SYS')
NNETBINOP()
ELSE
? 'Bindery could not be closed!'
ENDIF
NNETBINOP([<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server where the bindery is opened. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETBINOP() returns .T. if the bindery has been opened successfully.
Description
Important! NNETBINOP() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET BINDERY OPENNNETBINOP() reopens the bindery after it has been closed with NNETBINCL(). Supervisor rights are required.
With the parameters cServer or nConId, the bindery can be opened on any attached file server. The connection ID of a file server can be determined with the functions NNETATTACH() or NNETLOGIN().
Notes
■ It is not necessary to open the bindery explicitly before an
access. The bindery files are kept open automatically.
Determines or queries the receiving mode for broadcast messages
Syntax
NNETBRDCST([<nMode>]) → nPrevMode
Netware: 2.2 and 3.11
Arguments
nMode Designates the new mode for receiving broadcast messages. Values from 0 to 3 are accepted.
Table 24.1: Broadcast Receiving Modes
Value Sym. Con. Definition
0 BRD_RECALL Receive all messages automatically
1 BRD_RECSERVER Receive server messages only, discard other
messages
2 BRD_STORESERV Store one server message on the server, discard
other messages
3 BRD_STOREALL Store any message on the server
Returns
NNETBRDCST() returns a numeric value between 0 and 3. The value represents the broadcast mode at the moment of the call of NNETBRDCST(), before a new mode is set (see the argument). With NNETBRDCST(), you can save the previous mode and set a new mode. A return value of -1 indicates an error.
Description
NOVELL NET BROADCAST MODE With NNETBRDCST(), you can set the mode for receiving broadcast messages. Broadcast messages can be sent by a file server (system messages or the shutdown of a server) or by any workstation within the network (user messages set up with the Novell SEND utility or a NNETSND()). When a message is received, the network shell usually interrupts the running application, displays the message in line 24 of the screen and waits for a user input (CtrlEnter). This behavior can be modified by using the function NNETBRDCST(). Four different receiving modes are available (see the argument). Modes 0 and 1 allow the interruption of an application; however, mode 1 ignores user messages. Modes 2 and 3 suppress the display of messages on the screen during an application. The file server has a message buffer available for each connected workstation. As soon as the buffer is full, additional messages are ignored. Messages can be read with the function NNETGETMSG().
Alternatively, the broadcast system of CA-Clipper Tools can be activated (see NNETMSGOPN()). This system allows the interrupt controlled receiving of broadcast messages in the background. Messages can be processed within an application, and the computer is not interrupted by incoming messages.
Examples
Suppress incoming messages at program start, and reset to the previous
mode after the end of the application:
// Program start
#include "ctnnet.ch"
nOldMsg=NNETBRDCST(BRD_STOREALL)
....
// End of program
NNETBRDCST(nOldMsg)
RETURN
Determines if the capture mode is active for an LPT device
Syntax
NNETCAPACT(<nPrinter>) → lActive
Netware : 2.2 and 3.11
Arguments
nPrinter Designates the LPT device that is examined to determine if the capture mode is active. LPT1(1) to LPT3(3) are allowed.
Returns
NNETCAPACT() returns .T. when the capture mode for the designated LPT device is active.
Description
NOVELL NETWORK CAPTURE ACTIVE With NNETCAPACT(), you can determine if the capture mode is active for the designated LPT device and if the printer output has been redirected accordingly. If the function returns .T., the print output is on the network server in the allocated queue.
Examples
Determine the capture mode status for LPT1:
NNETCAPBEG(1) // Start capture mode
? NNETCAPACT(1) // .T.
NNETCAPEND(1) // End capture mode
? NNETCAPACT(1) // .F.
NNETCAPBEG(<nPrinter>) → lActivate
Netware: 2.2 and 3.11
Arguments
nPrinter Designates the LPT device for which the capture mode is activated. LPT1(1) to LPT3(3) are possible.
Returns
NNETCAPBEG() returns .T. when the capture mode for the designated LPT device can be activated.
Description
NOVELL NETWORK CAPTURE BEGIN With NNETCAPBEG(), the capture mode for a particular LPT device can be activated directly from within a CA-Clipper application. Optimal control of print output within a Novell network is possible in conjunction with other NNETCAPXXX() functions.
All print output parameters (flags) can be selected using the NNETCAPSSF() function. These parameters must be set before every BEGIN CAPTURE command. In this way, the auto form feed, the banner page, and other settings can be carried out from within the CA-Clipper program.
By contrast, the print queue can be selected using the NNETSETQ() function, where another server had been previously selected using NNETSETSRV().
Examples
Activate the capture mode for LPT2:
SET PRINTER TO LPT2
? NNETCAPBEG(2) // .T., when active
SET PRINT ON
? "That is a test 234"
SET PRINT OFF
NNETCAPEND(2) // End capture mode
Deactivates the capture mode and aborts the print job
Syntax
NNETCAPCAN(<nPrinter>) → lAbort
Netware: 2.2 and 3.11
Arguments
nPrinter Designates the LPT device for which the network print output is aborted. LPT1(1) to LPT3(3) are possible.
Returns
NNETCAPCAN() returns .T. when an existing network print output has been aborted.
Description
NOVELL NETWORK CAPTURE CANCEL Using NNETCAPCAN(), you can deactivate an existing capture mode and abort the print job in progress. Only output not yet "in service" is aborted. If the capture mode is not active, the function returns .F..
Notes
■ If a timeout is selected using NNETCAPSSF(), it is possible
that the print job in progress is already "in service".
Examples
Activate the capture mode for LPT3. Then either abort or pause the
print job:
SET PRINTER TO LPT3
? NNETCAPBEG(3) // .T., if active
SET DEVICE TO PRINT
@ 10, 10 SAY "This is a test 234"
SET DEVICE TO SCREEN
EJECT
Key := Inkey(0)
IF Key = 27 // ESC do not print
NNETCAPCAN(3)
ENDIF
NNETCAPEND(<nPrinter>) → lTerminate
Netware: 2.2 and 3.11
Arguments
nPrinter Designates the LPT device for which the capture mode is terminated. LPT1(1) to LPT3(3) are possible.
Returns
NNETCAPEND() returns .T. when an existing capture mode for the designated LPT device has been terminated.
Description
NOVELL NETWORK CAPTURE END This function can terminate an active capture mode. Subsequent print output occurs on the local printer. Print jobs still open are terminated and transferred to "service".
Notes
■ If you want to abort the output for the last print job "in
Activate the capture mode for LPT1, and turn it off after the ensuing
print output:
SET PRINTER TO LPT1
? NNETCAPBEG(1) // .T. when active
SET DEVICE TO PRINT
@ 10, 10 SAY "This is a test 234"
SET DEVICE TO SCREEN
EJECT
NNETCAPEND(1) // Terminate LPT1 capture
NNETCAPFLU(<nPrinter>) → lTransfer
Netware: 2.2 and 3.11
Arguments
nPrinter Designates the LPT device for which an active print job is closed and transferred to "service". LPT1(1) to LPT3(3) are possible.
Returns
NNETCAPFLU() returns .T. when the print job has been transferred to "service".
Description
NOVELL NETWORK CAPTURE FLUSH In CA-Clipper, print output occurs in the network when the application has been exited or the device has been closed. To close the current print job and dispatch that job, you can set a timeout with the NNETCAPSSF() or use the NNETCAPFLU() function.
If a timeout does not provide you with an acceptable solution, you can close a previously occurring print job using the NNETCAPFLU() function under Novell; the print job is transferred to "service". Internally, this function corresponds to the END CAPTURE or START CAPTURE commands. Subsequent print output can occur in the network without calling NNETCAPBEG() again.
Examples
Activate the capture mode for LPT1, and then stop it after the print
output occurs:
SET PRINTER TO LPT1
? NNETCAPBEG(1) // .T. if active
SET DEVICE TO PRINT
? "This is a test 234"
SET DEVICE TO SCREEN
EJECT
NNETCAPFLU(1) // Terminate print job.
Determines the job number of the most recently opened capture job
Syntax
NNETCAPJOB([<nPrinterNo>]) → nJob
Netware: 2.2 and 3.11
Arguments
nPrinterNo Designates the LPT device for which the job number is determined. LPT1 (1) to LPT3 (3) are possible. The default value is 1.
Returns
NNETCAPJOB() returns the job number of the last opened capture job for nPrinterNo. If an error occurs, the function returns 0.
Description
NOVELL NET CAPTURE JOB To maintain the jobs within a queue, Netware internally uses job numbers. The job number is a 16-bit integer. This number has nothing to do with the logical position of a job within a queue; for example, the first job within a queue is not automatically job number 1. The job number is assigned to a print job by the Queue Management Services (QMS) and cannot be foreseen. It is only used to identify a job unambiguously.
After a job has been created, the job number determined with NNETCAPJOB() can be used to access and manipulate specific jobs with the NNETJXXX() functions. However, the start of a capture process with NNETCAPBEG() does not immediately create a job. Therefore, a call of the function NNETCAPJOB() immediately after a call of NNETCAPBEG() returns the number of a job that was called earlier. A new job is not created before the first output via the LPT device. After the first output you can determine the number of the current job using NNETCAPJOB().
Examples
■ Determine the job number of the last opened capture job on
LPT2:
? NNETCAPJOB(2)
■ Start the capture mode for LPT1, send output to the queue
LINEPRINTER, and set the job description to "! CONFIDENTIAL !":
NNETCAPSSF(1)
NNETCAPBEG(1)
NNETSETQ(1,'LINEPRINTER')
SET PRINTER ON
? 'Hello' // A new job is created!
NNETJDESC('LINEPRINTER',NNETCAPJOB(1),'! CONFIDENTIAL !')
NNETCAPFLU(1)
NNETCAPSSF(<nPrinter>,[<lPageFeed>,<lBanner>,
<nServerPrinterNr>,<nTimeout>,<nTab>,<nCopies>,
<nForm>]) → lAmended
Netware: 2.2 and 3.11
Arguments
nPrinter Designates the number of the LPT device for which the flags are set. LPT1(1) to LPT3(3) are possible.
lPageFeed Designates whether the form feed at the end of a print job is suppressed (.T.) or transmitted (.F.). The default value is .F..
lBanner Designates whether a banner page is transmitted (.T.) or not (.F.). The default value is .F..
nServerPrinterNr Designates the server printer number between 0 and 4. The default value for the server printer is 0.
nTimeout Designates if a timeout is used and which one. When you input 0, print jobs are not "sent off" after a particular time span. However, you can specify a time delay in seconds. The default value (0) specifies no timeout.
nTab Designates which tabs are used, if any. If this parameter is a 0, there are no tabs. You can designate tab values between 1 and 18. The default value (0) specifies no tabs.
nCopies Designates the number of copies of the print job that the server creates. Values between 1 and 255 are valid. The default value (1) creates one copy.
nForm Designates the form definition that the server uses during printing. Values between 0 and 255 are valid. The default value specifies that no form definition is used.
Returns
NNETCAPSSF() returns .T. when the flags for the capture system have been changed to the designated values.
Description
NOVELL NETWORK CAPTURE SET SPECIFIC FLAGS This function allows you to make settings for the Novell capture mode. These setting are normally done in conjunction with the CAPTURE command in the DOS environment or through the PRINTCON for the print job. All capture mode settings must be complete before you initiate a START CAPTURE command, or there is no effect.
Notes
■ If this function has not yet been called during the course of
an application, the values preset by Novell or those selected in the last capture mode apply.
■ A precise description of the flags can be found in the Novell
Command Utilities Handbook under the Capture Commands heading.
Examples
■ Configure a print job. Specify LPT1; suppress the form feed,
and the "banner page"; and specify server printer 1:
? NNETCAPSSF(1, .T., .F., 1) // .T. when set
■ Specify LPT2, with form feed and banner page, server printer
0, a 5-second timeout, a tab width of 8, and two print copies:
NNETCAPSSF(2, .F., .T., 0, 5, 8, 2)
NNETCCNSRV([<lLoggedIn>]) → nServer
Netware: 2.2 and 3.11
Arguments
lLoggedIn Designates whether the number of all attached servers (.F.) or if the number of servers with logged in users (.T.) is determined. The default value (.F.) counts all servers.
Returns
NNETCCNSRV() returns the number of attached servers.
Description
NOVELL NET COUNT CONNECTED SERVERS With the function NNETCCNSRV() you can determine the number of attached servers without having to specify the server names (NNETFSLST()). Alternatively, you can determine the number of servers, where the user is currently logged in.
Examples
Server1 is attached. A user then logs into another server. The
information about the attached servers is determined by using
NNETCCNSRV():
NNETATTACH('SERVER1')
NNETLOGIN('PAUL','190366','SERVER2')
? NNETCCNSRV() // Returns: 2
? NNETCCNSRV(.T.) // Returns: 1
NNETCLRCON(<nConnect>,[<cServer>|<nConId>])
→ lSuccess
Netware: 2.2 and 3.11
Arguments
nConnect Designates the connection number that is cleared.
cServer Designates the name of the file server that is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETCLRCON() returns .T. if nConnect has been cleared successfully. If an error occurs, the function returns .F..
Description
NOVELL NET CLEAR CONNECTION When a workstation is first attached to a server, the Netware file server returns a connection number (connection ID) to the workstation. The file server keeps the connection ID even after a logout and is assigned to the related workstation at the next connection setup. However, the connection ID is changed, if all connection numbers are used. In this case, the connection ID can be assigned to another workstation. NNETCLRCON() allows you to clear used connection numbers.
Important! If the connection nConnect is currently active, it is interrupted immediately. This can lead to data loss on the related workstation, as all drive mappings become invalid and the writing of data to the server is no longer possible.
Supervisor rights on the related file server are required to clear a connection.
Notes
■ This function should be used very carefully as data loss is
possible if nConnect is currently active.
Examples
Determine the connection ID of the user MICK, and clear the connection
(ATTENTION: MICK will be logged out):
NNETCLRCON(NNETSTANUM('MICK'))
NNETCOPRIV() returns .T. when the station or the logged-in user has privileges for the use of the file server console.
Description
NOVELL NET CONSOLE PRIVILEGES This function allows you to determine if the user that is logged-in on the station being used has rights for the use of the file server console. These rights are a prerequisite for particular network operations and also for certain CA-Clipper Tools functions. One example of a network function that requires specific rights is NNETPURGE()
Notes
■ Console privileges are already contained within supervisor
rights.
Examples
Test to see if you have rights to the file server console:
? NNETCOPRIV() // .T. if console privileges exist
NNETCOPY(<cSourceFile>,<cTargetFile>,[<nBytes>])
→ nCopiedBytes
Netware: 2.2 and 3.11
Arguments
cSourceFile Designates the name of the file that is copied. This parameter can contain the drive and path designation but must be resident on a network drive.
cTargetFile Designates the name of the target file that is created. This parameter can contain the drive and path designation but must be resident on a network drive.
nBytes Designates the number of bytes that are copied. The default value designates the entire file.
Returns
NNETCOPY() returns the number of bytes copied. If a copy did not occur, the function returns -1.
Description
NOVELL NET COPY This function was planned specifically for copying files within a Novell file server. The copy speed is very high because the file content is copied within the server and is not transmitted over the network. In this way the function corresponds to the Novell NCOPY utility program.
Notes
■ If the size of the file that is copied is already known,
(through FileSeek()/FileSize()), you should pass that size as the third parameter. The function then does not have to determine the size of the source file and the copy speed is quicker.
■ Notice that the source and target file must be resident on
network drives on the same file server. You cannot copy to or from hard disks or floppies, or copy between different servers. FileCopy() must be used for all other file copying.
■ Distinctions can be made based on the source of the error
through ERRORCODE() (source file not found; target file cannot be created) or through NNETERROR() (different file servers).
Examples
■ Drive J: is mapped on a Novell server. Copy a file, giving
the source and target path:
NNETCOPY("J:\SUPPORT\TEST.EXE", "J:\USER\TEST2.EXE")
■ FileCopy() is a simple method of copying a file every time.
If you cannot copy with NNETCOPY(), use FileCopy():
IF FILE(cFileName)
IF NNETCOPY(cFileName, cTargetFile) = -1
FileCopy(cFileName, cTargetFile)
ENDIF
IF ERRORCODE(.T.) = 0
? "File copied successfully!"
ENDIF
ENDIF
Modifies or sets the password for a bindery object
Syntax
NNETCPASS(<cName>,[<nType>],<cOldPass>,<cNewPass>,
[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cName Designates the name of the bindery object that is processed.
nType Designates a numeric value that indicates the type of cName. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use with the bindery functions of CA-Clipper Tools. The default value indicates OBJ_USER.
cOldPass Designates the old password for cName.
cNewPass Designates the new password that is set for cName.
cServer Designates the name of the file server that contains the bindery that is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETCPASS() returns .T. if the new password has been set successfully. If an error occurs, the Novell error code can be queried with the NNETERROR() function.
Description
NOVELL NET CHANGE BINDERY OBJECT PASSWORD With NNETCPASS(), the password of a bindery object can be modified. Usually the function is used to change the password of a user. The parameters cName and nType specify the object that is processed. If the user does not have supervisor rights, the old password must be passed to prove the rights to set a new password. If no password exists for cName, an empty string ("") must be passed for cOldPass. cNewPass is the new password that is set. A user with supervisor rights can pass the parameter cOldPass as an empty string.
With the parameters cServer or nConId, the bindery of any attached file server can be accessed. The connection ID of a file server can be determined with NNETATTACH() or NNETLOGIN().
Supervisor rights for the bindery are required to modify passwords. For efficiency reasons, user defined object types must be passed in the high- low format.
Notes
■ The password of a bindery object does not affect the access
possibilities to the object. The password is only required when the object logs into the file server.
■ When a password is first set, the object is required to have
"password" property. If necessary, the "password" property must be created with NNETCRTPRP().
Examples
Change the password for user PAUL from LINDA to SILVIA:
IF NNETCPASS('PAUL',,'LINDA','SILVIA')
? 'Password changed!'
ELSE
? 'Password not changed!'
ENDIF
NNETCRTGRP(<cName>,[<cFullName>],[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cName Designates the name of the new group.
cFullName Designates the full name of cName.
cServer Designates the name of the file server where the new group is created. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETCRTGRP() returns .T. if the group has been created successfully.
Description
NOVELL NET CREATE GROUPNNETCRTGRP() allows you to create a new user group. With the parameter cFullName, a full name can be assigned to the group. With the parameters cServer or nConId ,a new group can be created on any attached file server. The connection ID of the server can be determined with NNETATTACH() or NNETLOGIN().
The group's access rights can be set with the function NNETTRUST().
Supervisior rights are required to establish a new group.
Notes
■ NNETCRTGRP() is a high level-function based on the low level
functions for bindery access. The CA-Clipper source code can be found on the product disks.
Examples
Create the group DEV with full name DEVELOPMENT:
IF NNETCRTGRP('DEV','DEVELOPMENT')
? 'Group created successfully!'
ELSE
? 'Group could not be created!'
ENDIF
NNETCRTOBJ(<cName>,[<nType>],[<nDynamic>],[<nSafe>],
[<cServer>|<nConId>) → lSuccess
Netware: 2.2 and 3.11
Arguments
cName Designates the name of the new bindery object. Under Netware, object names can be up to 47 characters long.
nType Designates a numeric value that indicates the type of cName. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use with the bindery functions of CA-Clipper Tools. The default value indicates the object type OBJ_USER.
nDynamic Designates whether the bindery object is static (0) or dynamic (1). The default value is static (0).
nSafe Designates the value for the object security. The value specifies the rights required to find (read) or to modify (write) the object in the bindery. The settings are defined in a bit-coded mask. The low-ordered bits control the read access; the high-ordered bits control the write access to the bindery object.
Table 18.2: Values for Object Security
Value Hex Bin Definition
0 0 0000 Access allowed to all users
1 1 0001 Access allowed to users who have logged in to the
file server
2 2 0010 Access allowed to users who have logged in to the
file server with password
3 3 0011 Access allowed to users who have logged in to the
file server as the supervisor or as a user who has
supervisor equivalence
4 4 0100 Access only allowed to the Netware operating system
The default value for nSafe is 49 (31h). The mask defines write access for supervisors and equivalents, and read access for all logged in users.
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETCRTOBJ() returns .T. if the new object has been created successfully. If an error occurs, the Novell error code can be queried with the NNETERROR() function.
Description
Important! NNETCRTOBJ() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET CREATE BINDERY OBJECTNNETCRTOBJ() allows you to create a new bindery object. Supervisor rights are required. For efficiency reasons, user defined object types must be passed in high-low format.
For the definition of the security mask, the four bits for the write access must be followed by the four bits for the read access. The resulting eight-bit string must be passed as decimal value for nSafe.
Examples
■ Create a static object of the type group under the name DEV:
#include "ctnnet.ch"
IF NNETCRTOBJ('DEV',OBJ_GROUP)
? 'Group created successfully!'
ELSE
? 'Group could not be created!'
ENDIF
■ To create groups, use the NNETCRTGRP function in CA-Clipper
Tools.
NNETCRTPRP(<cObjName>,[<nObjType>],<cPropName>
[<nFlag>],[<nSafe>],[<cServer>|<nConId>])
→ lSuccess
Netware: 2.2 and 3.11
Arguments
cObjName Designates the name of the object for which a new property is created.
nObjType Designates a numeric value that indicates the object type. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use with the bindery functions of CA-Clipper Tools. The default value indicates the object type OBJ_USER.
cPropName Designates the name of the new property. The name can be up to 15 characters long.
nFlag Designates the value for the property flag. With the property flag, two property characteristics can be set. With bit 1 you can determine if the property is static (bit 1 = 0) or dynamic (bit 1=1). Bit 2 specifies an item (bit 2 = 0) or a set (bit 2 = 1) property. The following table contains possible values for nFlag:
Table 18.3: Possible property flags
Value Sym. Con. Definition
0 PRP_ITEM Static item property
1 Dynamic item property
2 PRP_SET Static set property
3 Dynamic set property
Symbolic constants can be found in the header file CTNNET.CH. The default value for nFlag is 0.
nSafe Designates the value for the property security. For more information, see the description of the function NNETCRTOBJ(). The default value is 49 (31h).
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETCRTPRP() returns .T. if the new property cPropName has been created successfully. If an error occurs, the Novell error code can be queried with the NNETERROR() function.
Description
Important! NNETCRTPRP() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET CREATE PROPERTYNNETCRTPRP() allows you to create a new property for a bindery object. Sufficient bindery and object access rights are required. The necessary object access rights depend on the object security of the object that is manipulated. For efficiency reasons, user defined object types must be passed in the high-low format.
Examples
■ The property GROUP_MEMBERS is added to the group DEV. This
property is defined by Novell and must be created as set property:
#include "ctnnet.ch"
IF NNETCRTPRP('DEV',OBJ_GROUP,'GROUP_MEMBERS',PRP_SET)
? 'Property created successfully!'
ELSE
? 'Property could not be created!'
ENDIF
■ To add a group, use the NNETADDGRP() function in CA-Clipper
Tools.
NNETCRTQ(<cQueue>,[<cQueuePath>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the queue that is created.
cQueuePath Designates the directory where the new queue is created.
Returns
NNETCRTQ() returns .T. if the new queue (cQueue) has been created successfully. If an error occurs, the Novell error code can be queried with the NNETERROR() function.
Description
NOVELL NET CREATE QUEUE
NNETCRTQ() allows you to create a new print queue on a file server. In addition to the name of the queue (cQueue), you can specify the directory (cQueuePath) where the new queue is created. If no directory is passed, the queue directory is established in the SYS:SYSTEM directory of the default server. Supervisor rights are required to create a new print queue.
Examples
■ Create the queue LINEPRINTER on the default server:
IF NNETCRTQ('LINEPRINTER')
? 'Queue created successfully!'
ELSE
? 'Queue could not be created!'
ENDIF
■ Create the queue LINEPRINTER on the file server DEV:
NNETCRTQ('LINEPRINTER','DEV/SYS:SYSTEM')
NNETCRTUSR(<cName>,[<cPass>],[<cFullName>],[<lSuper>],
[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cName Designates the login name of the new user.
cPass Designates the password for cName.
cFullName Designates the full name for cName.
lSuper Designates whether the new user is granted supervisor rights (.T.) or not (.F.). The default value (.F.) indicates that the new user is not granted supervisor rights.
cServer Designates the name of the file server where the new user is created. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETCRTUSR() returns .T. if the user has been added successfully.
Description
NOVELL NET CREATE USERNNETCRTUSR() allows you to create a new user and to define the basic characteristics for the user. If NNETCRTUSR() is called only with the parameter cName, a user of the type guest is created. The guest user can log into the file server without a password. If cPass is passed, the password is required to log into the file server. The password can also be defined later with the NNETCPASS() function. With the argument cFullName, the full name of the new user can be set. Supervisor rights can be granted to the new user by passing the lSuper with (.T.). The default value for lSuper (.F.) does not grant supervisor rights. Additional rights can be assigned to the user by adding the user to a group (NNETADDGRP()) or by explicitly setting trustee rights. With the parameters cServer or nConId, a new user can be added on any attached file server. The connection ID of a server can be determined with NNETATTACH() or NNETLOGIN().
Supervisor rights are required to create a new user.
Notes
■ NNETCRTUSR() is a high level function based on the low level
functions of the bindery access. The CA-Clipper source code can be found on the product disks.
Examples
■ Create user PAUL with password 190366 and the full name PAUL
SMITH Give the new user supervisor rights:
IF NNETCRTUSR('PAUL','190366','Paul Smith',.T.)
? 'User created successfully!'
ELSE
? 'User could not be created!'
ENDIF
■ Create a new user, and then set the password to HELLO:
IF NNETCRTUSR('TEST')
NNETCPASS('TEST',,'','HELLO')
ENDIF
Determines the number of visible file servers in a network
Syntax
NNETCVSSRV([<cMask>]) → nServer
Netware: 2.2 and 3.11
Arguments
cMask Designates a search mask that can contain the wildcards "?" and "*". The default value ("*") indicates that all file servers are taken into account.
Returns
NNETCVSSRV() returns the number of visible file servers that match the search mask, cMask. Without argument, the function returns the number of all servers within a network.
Description
NOVELL NET COUNT VISIBLE SERVERS With NNETCVSSRV() you can determine the number of all visible file servers in a network without having to specify the server names (NNETFSLST()). For example, you can determine if all file servers in a WAN are available or if some file servers are currently unavailable.
Examples
Determine the number of all visible file servers:
? NNETCVSSRV() // Returns: 6
NNETDELFAK([<cDrive>]) → NIL
Netware: 2.2 and 3.11
Arguments
cDrive Designates a drive (A to .Z) or a search drive that has been mapped to a network directory as a fake root. When called without the parameter, NNETDELFAK() uses the default drive.
Description
NOVELL NET DELETE FAKE ROOT MAPPINGNNETDELFAK() deletes an existing fake root mapping for Drive. The function does not affect the drive mapping. After the fake root mapping has been deleted, you can also access parent directories of the fake root on cDrive.
Notes
■ Fake roots require Novell shell version 3.01 or higher.
Examples
Map drive M: as a fake root, then delete the fake root mapping and
change to the parent directory of the fake root:
NNETMAP('M','SYS:PAUL',.T.)
NNETDELFAK('M')
DirChange('M:..')
NNETDELOBJ(<cName>,[<nType>],[<cServer>|<nConId>])
→ lSuccess
Netware: 2.2 and 3.11
Arguments
cName Designates the name of the bindery object that is deleted.
nType Designates a numeric value that indicates the type of cName. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use with the bindery functions of CA-Clipper Tools. The default value indicates the object type OBJ_USER.
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETDELTOBJ() returns .T. if the object cName has been deleted successfully. If an error occurs, the Novell error code can be queried with the NNETERROR() function.
Description
Important! NNETDELOBJ() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET DELETE BINDERY OBJECTNNETDELOBJ() allows you to delete bindery objects. Users and user groups can be deleted. With the parameters cServer or nConId, the bindery of any attached server can be accessed. The connection ID of a server can be determined with NNETATTACH() or NNETLOGIN().
Supervisor rights are required to delete a bindery object. For efficiency reasons, user defined object types must be passed in the high- low format.
Notes
■ CA-Clipper Tools has no high level function available to
delete users or user groups. Use NNETDELOBJ().
Examples
■ Delete user GUEST:
IF NNETDELOBJ('GUEST')
? 'User has been deleted successfully!'
ELSE
? 'User could not be deleted!'
ENDIF
■ Delete group DEV:
#include "ctnnet.ch"
IF NNETDELOBJ('DEV',OBJ_GROUP)
? 'Group has been deleted successfully!'
ELSE
? 'Group could not be deleted!'
ENDIF
NNETDELPRP(<cObjName>,[<nObjType>],<cPropName>,
[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cObjName Designates the name of the bindery object that is processed.
nObjType Designates a numeric value that indicates the object type. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use with the bindery functions of CA-Clipper Tools. The default value indicates the object type OBJ_USER.
cPropName Designates the name of the property that is deleted. The name can contain the wildcards "?" and "*". In this case, all properties matching the search mask are deleted.
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETDELPRP() returns .T. if the property cPropName has been deleted successfully. If an error occurs, the Novell error code can be queried with the NNETERROR() function.
Description
Important! NNETDELPRP() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET DELETE PROPERTYNNETDELPRP() allows you to delete properties of a bindery object. Sufficient bindery and object access rights are required. The necessary object access rights depend on the object security of the object that is manipulated. For efficiency reasons, user defined object types must be passed in the high-low format.
Examples
■ Delete property IDENTIFICATION of the user MICK:
IF NNETDELPRP('MICK',,'IDENTIFICATION')
? 'Property has been deleted successfully!'
ELSE
? 'Property could not be deleted!'
ENDIF
■ The property IDENTIFICATION of a user object contains a user's
full name. In the example above, this information is deleted. Other
information, such as the user name (login name) or the password is
not affected.
NNETDELQ(<cQueue>,[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is deleted.
cServer Designates the name of the file server where cQueue is established. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETDELQ() returns .T. if the queue (cQueue) has been deleted successfully. If an error occurs, the Novell error code can be queried with the NNETERROR() function.
Description
NOVELL NET DELETE QUEUENNETDELQ() allows you to delete an entire queue. After a queue has been deleted with NNETDELQ(), all jobs of cQueue are canceled, all job files are deleted, and all queue directories are removed. Supervisor rights are required to delete a queue.
Examples
Delete the queue LINEPRINTER on the default server:
IF NNETDELQ('LINEPRINTER')
? 'Queue has been deleted successfully!'
ELSE
? 'Queue could not be deleted!'
ENDIF
NNETDELSET(<cName>,[<nType>],<cProperty>,<cMember>,
[<cMemberType>],[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cName Designates the name of the bindery object that is processed.
nType Designates a numeric value that indicates the type of cName. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use with the bindery functions of CA-Clipper Tools. The default value indicates the object type OBJ_USER.
cProperty Designates the name of a set property of cName.
cMember Designates the name of the bindery object that is deleted from cProperty of the bindery object cName.
cMemberType Designates a numeric value that specifies the type of cMember. The default value is OBJ_USER.
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETDELSET() returns .T. if the operation has been completed successfully. If an error occurs, the Novell error code can be queried with the NNETERROR() function.
Description
Important! NNETDELSET() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET DELETE BINDERY OBJECT FROM SET Internally, Novell Netware has defined two different property types: item and set properties. NNETDELSET() allows you to delete information from a set property. A set property contains a list of references to other bindery objects. An example is the GROUP_MEMBERS property that contains a list of users who are members of a user group.
The parameters cName and cType identify the object, and cProperty is the name of the property. cMember and cMemberType define the bindery object that is deleted from cProperty. With the parameters cServer or nConId, the bindery of any attached server can be accessed. The connection ID of a server can be determined with NNETATTACH() or NNETLOGIN().
To delete information from a property, sufficient bindery and property access rights are required. The necessary property access rights depend on the property security of the property that is manipulated. For efficiency reasons, user defined object types must be passed in the high- low format.
Notes
■ NNETDELSET() deletes only the reference to the bindery object
cMember from cProperty. The object itself is not affected or deleted.
Examples
■ Delete user MIKE from the MARKET group:
#include "ctnnet.ch"
IF NNETDELSET('MARKET',OBJ_GROUP,'GROUP_MEMBERS','MIKE')
? 'User has been deleted from group!'
ELSE
? 'User could not be deleted!'
ENDIF
■ To delete a user from a group, it is also necessary to delete
the group from two user properties. Use the function NNETREMGRP() to
remove a user from a group.
Determines the number of free directory entries in a volume
Syntax
NNETDIRFRE(<nVolume>) → nFreeDirectoryEntries
Netware: 2.2 and 3.11
Arguments
nVolume Designates the selected volume number of the related default file server. This value can be from 0 to 31.
Returns
NNETDIRFRE() returns the number of directory entries still free on the volume specified in nVolume.
Description
NOVELL NET DIRECTORY FREE This function allows you to determine how many directory entries are still available for each volume on the default file server. This allows you to determine if new files can be created on the related volume. The number of directory entries in the Novell network software installation program can be increased if necessary.
Notes
■ This function requires that the station have console
privileges.
Examples
Determine if directory entries are still available for all volumes:
FOR I = 0 TO NNETVOLNUM()
? NNETDIRFRE(I) // Avail. entries, each volume
NEXT I
Determines the extended information about subdirectories
Syntax
NNETDIRS([<cPath>],[<nAttr>|<cAttr>],[<l386>]) → aDir
Netware: 2.2 and 3.11
Arguments
cPath Designates the directory for which the subdirectories are read. The parameter contains a search mask for the directories that are read. Within the search mask, the wildcard characters "?" and "*" can be used. A file identifier is not permitted. The search mask is ignored if the function is called on a Netware 2.x server, but this parameter must be passed.
nAttr Designates the file attributes in numeric form, according to the table in the description . The default value is 16.
cAttr Designates the file attributes in the form of a character string, according to the table in the description. The default value is "D".
l386 Designates whether NNETDIRS() also returns extended information that is only available on Netware 3.x servers. The parameter must be designated .T.. The default value ( .F.) does not return extended information.
Returns
NNETDIRS() returns an array with subarrays (two-dimensional array). Each subarray contains information about each directory entry that is found. The structure of the subarrays is described in the following table.
Table 23.1: NNETDIRS() Subarray Structure
Position Metasymbol CTNNET.CH Definition
1 cName ND_NAME Directory name
2 dCrDate ND_CREADATE Creation date
3 cCrTime ND_CREATIME Creation time
4 nRights ND_RIGHTS Maximum (2.x) / Inherited (3.x) Rights
5 cOwner ND_OWNER Owner
If l386 has been designated .T., the returned array contains the following extension:
NOVELL NET DIRECTORIESNNETDIRS() returns extended information about the subdirectories of file server directories. On Netware 3.x servers, the subdirectories can be determined by a search mask in cPath. You can also determine the default file attribute. The attribute can be passed in the form of a numeric value or a character string:
Table 23.3: File Attribute Coding for NNETDIRS()
Value Symbol Definition
1 R Read Only
2 H Hidden directories
4 S System directories
16 D Subdirectories (always set by NNETDIRS())
32 A Archive bit set
To specify an attribute, numeric values must be added or the related symbols must be added to a character string.
A call of NNETDIRS() for a Netware 2.x file server also requires a search mask in cPath; however, the mask is ignored. Under Netware 2.x, the function returns all subdirectories that correspond to the passed attributes.
Examples
■ Read the subdirectories of L:\, and display the directory
names:
#include "ctnnet.ch"
aDirs=NNETDIRS('L:\*')
FOR i=1 TO Len(aDirs)
? aDirs[i,ND_NAME]
NEXT i
■ Read the subdirectories of NANGERTOOLS1/VOL1:DATA, including
the hidden system directories:
aDirs=NNETDIRS('NANGERTOOLS1/VOL1:DATA/*','SH')
■ Read the subdirectories of L:\ with extended 3.x information.
Display the directory name and the date of the last update:
#include "ctnnet.ch"
aDirs=NNETDIRS('L:\*',,.T.)
FOR i=1 TO Len(aDirs)
? aDirs[i,ND_NAME],aDirs[i,ND_UPDDATE])
NEXT i
NNETDISLOG([<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server that is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETDISLOG() returns .T., if the file server has been successfully disabled for logins. If an error occurs (for example, insufficient access rights), the function returns .F..
Description
NOVELL NET DISABLE LOGINNNETDISLOG() allows you to disable a file server for further logins of new users. For example, you should use this function if you want to execute a data backup. Console rights are required to disable a file server for logins with NNETDISLOG().
Examples
Disable the default server for further logins:
IF NNETDISLOG()
? 'Server disabled for logins!'
ELSE
? 'Error!
ENDIF
NNETDISTTS([<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETDISTTS() returns .T. if the TTS of the specified file server has been turned off successfully. If an error occurs (for example, insufficient rights), the function returns .F..
Description
NOVELL NET DISABLE TRANSACTION TRACKING SYSTEMNNETDISTTS() allows you to temporarily turn off the TTS on a file server. Console rights are required to turn off the TTS with NNETDISTTS().
Examples
Turn off the TTS on the default server:
IF NNETDISTTS()
? 'TTS turned off successfully!'
ELSE
? 'Error!
ENDIF
NNETDOWN([<lMode>],[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
lMode Designates whether the file server is shut down only if the current workstation is the only logged in station (.F.) or if the server is shut down for all logged in stations (.T.). The default value is .F..
cServer Designates the name of the file server that is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETDOWN() returns .T. if the down process has been established. If an error occurs, the function returns .F..
Description
NOVELL NET DOWNNNETDOWN() allows you to shut down a file server.
Important! If the parameter lMode is designated .T., all logged in stations are logged out immediately. Data that is still in the buffer cannot be saved.
This function requires supervisor rights on the related file server.
Examples
■ Attempt to shut down the default file server:
IF NNETDOWN()
? 'Successful!'
ELSE
? 'Error'
ENDIF
■ Wait until the server can be shut down safely:
WHILE .NOT. NNETDOWN()
ENDDO
Determines the server disk capacity occupied by a user
Syntax
NNETDSKUSE([<cUser>],[<nVol>|<cVol>],[<cServer>|
<nConId>]) → nKByte
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of the user whose disk capacity is determined. The default value designates the logged in user.
nVol Designates the volume number. Under Novell, volume numbers start with 0. This parameter is only important if the specified file server runs under Netware 3.x.
cVol Designates the volume name. A server name is not allowed. This parameter is only important if the specified file server runs under Netware 3.x.
cServer Designates the name of the file server where the used disk capacity is determined. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETDSKUSE() returns the disk capacity in kByte on the specified file server or volume occupied by cUser.
Description
NOVELL NET DISK SPACE IN USENNETDSKUSE() allows you to determine the disk capacity on a file server occupied by a user. Under Netware 2.x and Netware 3.x, the function returns the total of the used disk capacity over all volumes on the specified file server when it is called without the parameter nVol|cVol. Under Netware 3.x, it is possible to determine the capacity for a specific volume by passing the volume number nVol or the volume name cVol. With the parameters cServer or nConId, the occupied capacity on any attached file server can be determined. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Examples
Determine the total occupied disk capacity for user MIKE under Netware
3.x for all volumes. Also determine the total occupied disk capacity
for user MIKE for any Netware version:
IF NNETVER()>'2'
FOR i = 0 TO NNETVOLNUM()
? NNETVOLNAM(i),NNETDSKUSE('MIKE',i)
NEXT i
? '======================'
ENDIF
? 'Total: ',NNETDSKUSE('MIKE')
NNETENLOG([<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server that is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETENLOG() returns .T. if the file server has been successfully enabled for logins. If an error occurs (for example, insufficient access rights), the function returns .F..
Description
NOVELL NET ENABLE LOGINSNNETENLOG() allows you to enable a file server for logins if it has been previously disabled with NNETDISLOG(). Console rights are required to enable a file server for logins with NNETENLOG().
NNETENTTS([<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETENTTS() returns .T. if the TTS has been activated successfully. If an error occurs (for example, insufficient rights), the function returns .F..
Description
NOVELL NET ENABLE TRANSACTION TRACKING SYSTEMNNETENTTS() allows you to activate the TTS on the file server if it has been turned off with NNETDISTTS(). Console rights are required to activate the TTS.
Examples
Activate the TTS on file server TOOLS1:
NNETENTTS('TOOLS1')
Returns the error most recently encountered by a Novell function
Syntax
NNETERROR() → nErrorCode
Netware: 2.2 and 3.11
Returns
NNETERROR() returns the error that occurred most recently on the network as a numeric value.
Description
NOVELL NET ERROR This function returns the code for the error that occurred most recently in conjunction with NNETXXX() functions. However, this error did not necessarily occur in the function most recently called. All the possible error codes are in Appendix C.
Examples
Determine the last error that occurred:
? NNETERROR() // e.g. 254
NNETEXTATT(<cFile>,[<nAttr>]) → nNewAttr
Netware: 2.2 and 3.11
Arguments
cFile Designates the file for which the extended file attributes are set or queried. cFile can contain a path specification.
nAttr Designates an optional parameter that must be passed to set the new extended file attributes of cFile . The value for nAttr can be calculated according to the table in the description.
Returns
NNETEXTATT() returns a numeric value that contains the extended file attributes of cFile. These numeric values correspond to the table in the description. If an error occurs, the function returns -1.
Description
NOVELL NET EXTENDED ATTRIBUTES Besides the DOS file attributes, Netware supports additional extended file attributes. NNETEXTATT() allows you to set or query these attributes. The coding of the extended file attributes can be seen in the following table:
Table 23.4: Coding of Extended File Attributes
Bit Value CTNNET.CH Definition
5 16 EXA_TTS Transaction attribute
6 32 EXA_INDEX Index attribute
7 64 EXA_READAU Read audit attribute
8 128 EXA_WRITAU Write audit attribute
To specify more attributes, the numeric values must be added.
Notes
■ Currently, read and write audit attributes (protocol of read
and write access) are not supported by Netware.
Examples
■ Check to see if the transaction attribute is set for
CLIENT.DBF:
IF IsBit(NNETEXTATT('CLIENT.DBF'),5)
? 'CLIENT.DBF is flagged transactional!'
ELSE
? 'TTS not possible for CLIENT.DBF!'
ENDIF
■ Set the transaction attribute for CLIENT.DBF:
#include "ctnnet.ch"
NNETEXTATT('CLIENT.DBF',EXA_TTS)
Determines the relative directory depth under a fake root
Syntax
NNETFAKDEP([<cDrive>]) → nDepth
Netware: 2.2 and 3.11
Arguments
cDrive Designates a drive (A to .Z) or a search drive (S1 to .S16) that has been mapped to a network directory as fake root. When called the parameter, the function uses the default drive.
Returns
NNETFAKDEP() returns the relative depth under the fake root directory. If the specified drive has not been mapped as fake root, NNETFAKDEP() returns -1. If cDrive does not exist, the return value is -2.
Description
NOVELL NET FAKE DEPTH If a network drive has been mapped as a so-called fake root, it becomes the apparent root of the allocated drive. After a directory change, NNETFAKDEP() returns the number of directories under the fake root. Depth 0 is assigned to the root directory. Additionally, NNETFAKDEP() allows you to determine if a drive has been mapped as a fake root (return value => 0) or a normal drive (return value < 0).
Notes
■ Fake roots require shell version 3.01 or higher.
Examples
Map drive M: as a fake root, then change the directory, and query the
relative directory depth:
NNETMAP('M','SYS:PAUL',.T.)
DirChange('M:\DATA')
? NNETFAKDEP('M') // Returns: 1
cPath Designates the directory for which the subdirectories are read. The parameter contains a search mask for the directories that are read. Within the search mask, the wildcard characters "?" and "*" can be used.
nAttr Designates the file attributes in numeric form, according to the following table. The default (0) designates normal files.
cAttr Designates the file attributes in form of a character string, according to the following table . The default value ("") designates normal files.
l386 Designates whether NNETFILES() also returns extended information that is only available on Netware 3.x servers. The parameter must be designated .T.. The default value (.F.) does not return extended information.
Returns
NNETFILES() returns an array with subarrays (two-dimensional array). Each subarray contains information about each directory entry that is found. The structure of the subarrays are described in the following table.
Table 23.5: NNETFILES() Subarray Structure
Position Metasymbol CTNNET.CH Definition
1 cName NF_NAME Directory name
2 nSize NF_SIZE File size
3 cUpdDate NF_UPDDATE Date of last update
4 cUpdTime NF_UPDTIME Time of last update
5 dCrDate NF_CREADATE Creation date
6 nAttr NF_ATTR File attributes
7 nExtAttr NF_EXTATTR Extended file attributes
8 cOwner NF_OWNER Owner
If l386 has been designated .T., the returned array contains the following extension:
NOVELL NET FILESNNETFILES() returns extended information about files on file servers. The files can be specified by a search mask in cPath and by determining the file attribute. The attribute can be passed in the form of a numeric value or a character string:
Table 23.7: Coding of File Attributes for NNETFILES()
Value Symbol Definition
1 R Read Only
2 H Hidden directories
4 S System directories
32 A Archive bit set
To specify an attribute, numeric values must be added or the related symbols must be added to a character string.
Examples
■ Read the files in L:\, and display the file names:
#include "ctnnet.ch"
aFiles=NNETFILES('L:\*.*')
FOR i=1 TO Len(aFiles)
? aFiles[i,NF_NAME]
NEXT i
■ Read the files in NANGERTOOLS1/VOL1:DATA, including the hidden
files and the system files:
aFiles=NNETFILES('NANGERTOOLS1/VOL1:DATA/*.*','SH')
■ Read the files in L:\ with extended 3.x information, and
display he file names and the date of the last archive:
#include "ctnnet.ch"
aFiles=NNETFILES('L:\*.*',,.T.)
FOR i=1 TO Len(aFiles)
? aFiles[i,NF_NAME],aFiles[i,NF_ARCDATE])
NEXT i
Determines the names of all visible file servers within a network
Syntax
NNETFSLST([<cMask>]) → aServerList
Netware: 2.2 and 3.11
Arguments
cMask Designates a search mask that can contain the wildcard characters "?" and "*". The default value ("*") indicates that all server names are returned.
Returns
NNETFSLST() returns a one-dimensional array. Each array element contains one server name.
Description
NOVELL NET FILE SERVER LISTNNETFSLST() returns the names of all visible file servers, whether the server is attached or not. With this function you can determine if you can address a specific file server before you call NNETATTACH() or NNETLOGIN().
Notes
■ Unlike NNETSLIST(), which returns the names of the attached
servers (maximum of eight), NNETFSLST() returns the names of all servers within a network.
Examples
■ Display the names of all the file servers in a network:
aServer=NNETFSLST()
FOR i = 1 TO Len(aServer)
? aServer[i]
NEXT i
■ Select a file server with AChoice(), and then log in a user:
aServer=NNETFSLST()
IF (nSelect:=AChoice(5,5,8,45,aServer))>0
NNETLOGIN("PAUL","190366",aServer[nSelect])
ENDIF
NNETGETMSG([<cServer>|<nConId>]) → cMessage
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server for which the message buffer is read. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETGETMSG() returns a character string that contains the broadcast message of the specified file server. If there is no message in the broadcast buffer, the function returns a null string.
Description
NOVELL NET GET BROADCAST MESSAGE If the receiving of broadcast messages is suppressed (for example, with the Novell utility CASTOFF or the function NNETBRDCST()), the file server stores the first message in a buffer. This buffer can be read with NNETBRDCST(). Reading the server buffer causes its deletion. With the parameters cServer or nConId, the buffer of any attached server can be read. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Examples
Read the broadcast buffer of the default server, and display the
message:
cMsg=NNETGETMSG()
IF .NOT. Empty(cMsg)
? cMsg
ENDIF
NNETGROUPS([<cServer>|<nConId>],[<cMask>])
→ aGroupList
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server for which the user groups are determined. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer. If no file server is specified, the function uses the default server.
cMask Designates a search mask that can contain the wildcard characters "?" and "*". The default value ("*") designates that all user groups are determined.
Returns
NNETGROUPS() returns a one-dimensional array. Each array element contains the name of a user group.
Description
NOVELL NET GROUPSNNETGROUPS() allows you to determine all the user groups established on a file server. The file server can be specified either by its name or its connection ID. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
To achieve results with this function, the requesting user must be logged in on the related file server. If the requesting user is not logged in on the related file server, the function returns an empty array.
Examples
Display all user groups on the file server NANGERTOOLS2:
AEval(NNETGROUPS('NANGERTOOLS2'),{|x|QOut(x)})
NNETGRPMEM(<cUser>,<cGroup>,[<cServer>|<nConId>])
→ lMember
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of the user.
cGroup Designates the name of the group that is searched for cUser.
cServer Designates the name of the file server on which the user and group definition is searched. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer. If no server has been specified, the function uses the default server.
Returns
NNETGRPMEM() returns .T. if the user cUser is a member of the group cGroup. If cUser is not a member of cGroup, the function returns .F..
Description
NOVELL NET GROUP MEMBER To improve organization and simplify user access to file server resources, user groups can be created under Novell Netware. Each user can be a member of one or more groups. With the function NNETGRPMEM(), you can determine if a user is a member of a specific group. For example, the branch in an application can be made dependent on the membership of the logged in user to a specific group.
The file server can be specified either by its name or its connection ID. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
This function requires that the requesting user be logged in on the related file server.
Examples
Log the user into another file server if the user is a member of the
group DEV:
IF NNETGRPMEM(cUser,"DEV")
NNETLOGIN(cUser,cPassword,"NANGERDEV")
ENDIF
Returns the information string of the Netware in use
Syntax
NNETINFO() → cInfo
Netware: 2.2 and 3.11
Returns
NNETINFO() returns an information string to the Novell network software in use on the default file server. The return has a maximum of 512 characters.
Description
NOVELL NET INFO This function can call an information string contained in Novell network software. This information always relates to the default file server. For example, the character string contains specifications regarding the company that sold the software being used. This can be of particular interest for OEM users.
Examples
Display the information string:
? NNETINFO() // String of up to 512 characters
NNETINGRPS(<cUser>[,<cServer>|<nConId>]) → aGroupList
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of the user whose group membership is determined.
cServer Designates the name of the file server on which cUser is established. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer. If no file server is specified, the function uses the default file server.
Returns
NNETINGRPS() returns a one-dimensional array. Each array element contains the name of a user group.
Description
NOVELL NET IN GROUPS To improve organization and simplify user access to file server resources, you can create user groups under the Novell Netware. Each user can be a member of one or more groups. With the function NNETINGRPS(), you can determine all the user groups to which a user belongs.
The file server can be specified either by its name or its connection ID. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
To achieve results with this function, the requesting user must be logged in on the related file server. If the requesting user is not logged in on the related file server, the function returns an empty array.
Examples
Display all the user groups to which user KEITH on file server STONES
belongs:
aList:=NNETINGRPS('KEITH','STONES')
FOR i = 1 TO Len(aList)
? aList[i]
NEXT i
Determines if a bindery object belongs to a set property
Syntax
NNETINSET(<cObjName>,[<nType>],<cPropName>,<cMember>,
[<cMemberType>],[<cServer>|<nConId>]) → lMember
Netware: 2.2 and 3.11
Arguments
cObjName Designates the name of the bindery object that is processed.
nType Designates a numeric value that indicates the type of cName. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use with the bindery functions of CA-Clipper Tools. The default value indicates the object type OBJ_USER. When you work with numeric values, you must take into account that, for efficiency reasons, NNETRDITM() expects the object type as an integer in the high-low format.
cPropName Designates the name of a set property of cObjName.
cMember Designates the name of the bindery object for which the membership in cPropName of cObjName is checked.
cMemberType Designates a numeric value that indicates the type of cMember. The default value indicates the object type OBJ_USER.
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETINSET() returns .T. if cMember belongs to the set property (cPropName) of the bindery object (cObjName). If < cMember> does not belong to the set property (cPropName) the function returns .F..
Description
NOVELL NET OBJECT IN SET Internally, Novell Netware has defined two different property types: item and set properties. A set property contains a list of references to other bindery objects. An example is the GROUP_MEMBERS property that contains a list of users that are members of a user group. With the function NNETINSET(), you can check to see if a bindery object, specified with the parameters cMember and cMemberType, belongs to the set property (cPropName of the bindery object (cObjName and cType). With the parameters cServer or nConId, the bindery of any attached server can be accessed. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Examples
Check to see if user MIKE has supervisor rights:
#include "ctnnet.ch"
IF NNETINSET('MIKE',OBJ_USER,'SECURITY_EQUALS','SUPERVISOR',OBJ_USER)
? 'User has supervisor rights!'
ELSE
? 'User has no supervisor rights!'
ENDIF
Returns the number of objects currently logged into the network
Syntax
NNETINUSE() → nStations
Netware: 2.2 and 3.11
Returns
NNETINUSE() returns the number of stations currently in use on the default file server.
Description
NOVELL NET IN USE With NNETINUSE() you can determine the number of stations that are currently in use on the default file server. For example, you could provide an overview of network capacity.
Notes
■ The returned value does not agree with the users that are
displayed in USERLIST or CONNECTION INFORMATION within FCONSOLE. You will always have at least one more channel that is open than there are users in the network. The returned value for Netware, versions 2.1 or later, agree with STATISTIC → SUMMARY → CONNECTIONS IN USE under FCONSOLE.
Examples
Determine the stations in use on the default file server:
? NNETINUSE() // e.g. 7
Checks for the availability of the Transaction Tracking System (TTS)
Syntax
NNETISTTS([<lMode>],[<cServer>|<nConId>]) → lAvailable
Netware: 2.2 and 3.11
Arguments
lMode Designates the test mode of NNETISTTS(). If .F. is passed, NNETISTTS() checks for the general availability of the TTS. The default value is .F.. If .T. is passed, NNETISTTS() checks to see if an available TTS is activated or not.
cServer Designates the name of the file server that is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETISTTS() returns .T. if the TTS is available (lMode=.F.) or activated (lMode=.T.).
Description
NOVELL NET IS TRANSACTION TRACKING SYSTEMNNETISTTS() allows applications using the TTS to check to see if the TTS is available or currently activated.
Examples
■ Check for the availability of the TTS on the default server:
IF NNETISTTS()
? 'TTS available!'
ELSE
? 'TTS not available!'
ENDIF
■ Check to see if the TTS is currently activated:
IF NNETISTTS(.T.)
? 'TTS activated!'
ELSE
? 'TTS not activated!'
ENDIF
NNETJBAN(<cQueue>,<nJob>,[<lNewTitle>],[<cServer>|
<nConId>]) → lTitle
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
lNewTitle Designates whether a banner page for nJob is printed (.T.) or not (.F.).
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJBAN() returns .T. if a banner page is printed.
Description
NOVELL NET JOB BANNER PAGE Under Netware, a banner page can be printed before each print job to show the user name. However, if a banner page is not necessary, it can be suppressed by passing the parameter lNewTitle with .F..
The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
Examples
■ Determine if a banner page is printed for the first job in the
queue LINEPRINTER:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJBAN('LINEPRINTER', nJob)
■ Suppress the banner page for the first job in the queue
LINEPRINTER:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJBAN('LINEPRINTER', nJob, .F.)
Sets or determines the file names in the banner text of a job
Syntax
NNETJBFILE(<cQueue>,<nJob>,[<cNewName>],[<cServer>|
<nConId>]) → cName
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cNewName Designates a new file name that is set for the banner text. The file name can be up to 12 characters long.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJBFILE() returns the file name that is printed on the banner page of nJob.
Description
NOVELL NET JOB BANNER FILE The banner page of a job contains the user name of the job owner and the name of the printed file. NNETJBFILE() allows you to set or to determine the file name. The default name is LST:.
Examples
■ Determine the file name to be printed on the banner page of
the first job in the queue LINEPRINTER:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJBFILE('LINEPRINTER', nJob)
■ Set the file name to be printed on the banner page of the
first job in the queue LINEPRINTER to STONES.TXT:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJBFILE('LINEPRINTER', nJob, 'STONES.TXT')
NNETJBNAME(<cQueue>,<nJob>,[<cNewName>],[<cServer>|
<nConId>]) → cName
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cNewName Designates a new banner name that is set for nJob. The banner name can be up to 12 characters long.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJBNAME() returns the user name that is printed on the banner page of nJob.
Description
NOVELL NET JOB BANNER NAME
The banner page of a job contains the user name of the job owner and the name of the printed file. NNETJBNAME() allows you to set or to determine the user name.
The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
Examples
■ Determine the user name that is printed on the banner page of
the first job in the queue LINEPRINTER:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJBNAME('LINEPRINTER', nJob)
■ Set the user name that is printed on the banner page of the
first job in the queue LINEPRINTER to MICK:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJBNAME('LINEPRINTER', nJob, 'MICK')
NNETJCNT(<cQueue>,[<cServer>|<nConId>]) → nJobs
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJCNT() returns the number of jobs that are currently in a print queue. If an error occurs (for example, non existing print queue), the function returns -1.
Description
NOVELL NET JOB COUNTNNETJCNT() allows you to determine when it is safe to modify certain characteristics of a queue (for example, the connection to a print server). You should wait until the queue is empty to modify certain characteristics of the queue. NNETJCNT() can be used to count the jobs in a number of queues. With NNETSETQ() you can then assign a job to the queue with the lowest number of jobs.
Notes
■ This function requires that the requesting user have access to
the queue as a user or an operator.
Examples
Determine the number of jobs in the queue LINEPRINTER:
? 'Jobs:',NNETJCNT('LINEPRINTER')
NNETJCOPY(<cQueue>,<nJob>,[<nNewCopies>],[<cServer>|
<nConId>]) → nCopies
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
nNewCopies Designates the new number of copies for nJob.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJCOPY() returns the number of copies of nJob that are printed. If an error occurs, the function returns -1.
Description
NOVELL NET JOB COPIES The queue management allows you to print out more than one copy of a print job. With NNETJCOPY(), you can set or determine the number of copies of nJob. To query the number of copies, do not pass a value for nNewCopies.
The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
Examples
■ Determine the number of copies for the first job in the queue
LINEPRINTER:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJCOPY('LINEPRINTER', nJob)
■ Set the number of copies for the first job in the queue
LINEPRINTER to 5:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJCOPY('LINEPRINTER', nJob, 5)
Sets or determines the number of characters per line for a job
Syntax
NNETJCPL(<cQueue>,<nJob>,[<nNewChar>],[<cServer>|
<nConId>]) → nChar
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cNewChar Designates the new number of characters per line for nJob.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJCPL() returns the number of characters per line for nJob. If an error occurs, the function returns -1.
Description
NOVELL NET CHARACTERS PER LINE With NNETJCPL(), you can set or determine the number of characters per line for nJob. To query the number of copies, do not pass a value for nNewChar. A new number of characters can be set by passing the selected number. The number of characters is simply informative; this information is not evaluated by Netware.
The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
Examples
■ Determine the number of characters for the first job in the
queue LINEPRINTER:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJCPL('LINEPRINTER', nJob)
■ Set the number of characters for the first job in the queue
LINEPRINTER to 72:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJCPL('LINEPRINTER', nJob, 72)
NNETJDEL(<cQueue>,<nJob>,[<cServer>|<nConId>])
→ lSuccess
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is deleted from cQueue.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJDEL() returns .T. if the job has been deleted successfully. If an error occurs, the function returns .F. An error can occur if cQueue does not exist or the requesting user does not have the required access rights.
Description
NOVELL NET JOB DELETENNETJDEL() allows you to delete a job from a queue. The job that is deleted is specified by its job number. The job number has nothing to do with the logical position of a job within a queue. The job number can be determined with NNETCAPJOB() or NNETJLIST(). A job that is already in process is canceled immediately by a call of NNETJDEL().
Notes
■ The user of a queue can delete a job only if the user
submitted it to the queue. The queue operator can remove any job.
Examples
Delete the second job from the queue LINEPRINTER:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),3,2))
IF NNETJDEL('LINEPRINTER',nJob)
? 'Job has been deleted successfully!'
ELSE
? 'Job could not be deleted!'
ENDIF
NNETJDESC(<cQueue>,<nJob>,[<cDescription>],
[<cServer>|<nConId>]) → cDescription
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cDescription Designates the new job description for nJob. The job description can be up to 49 characters long.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJDESC() returns the job description of nJob in cQueue. If an error occurs (for example, if cQueue does not exist), the function returns an empty string.
Description
NOVELL NET JOB DESCRIPTIONNNETJDESC() allows you to read or to modify the description of each job in a queue. The description can be up to 49 characters long and is printed on the banner page. By passing the parameter cDescription, you can overwrite the default description "LPTnCatch". The operation has been successful if the returned character string is identical to the parameter cDescription.
The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue. The job number can be determined with NNETCAPJOB() or NNETJLIST().
Notes
■ The reading of a job description requires that the requesting
user has access to the queue as a user or an operator. The right to modify a job description is reserved for the user who has created the job and for the queue operator.
■ A job that is already in progress cannot be modified.
Examples
■ Query the job description for the first job in the queue
LINEPRINTER:
nJob=Bin2I(Left(NNETJLIST('LINEPRINTER'),2))
? NNETJDESC('LINEPRINTER',nJob)
■ Start the capture mode for LPT1, send output to the queue
LINEPRINTER, and set the description of the resulting job to
"!CONFIDENTIAL!":
NNETCAPSSF(1)
NNETCAPBEG(1)
NNETSETQ(1,'LINEPRINTER')
SET PRINTER ON
? 'Hello'
NNETJDESC('LINEPRINTER',NNETCAPJOB(1),'!CONFIDENTIAL!')
NNETCAPFLU(1)
■ The new job is always created at the first output (? "Hello"),
not by calling NNETCAPBEG(). Therefore, NNETJDESC() must be called
after the first output. If NNETJDESC() is not called after the first
output, NNETCAPJOB() returns the number of the previous capture job
and the wrong description is modified.
NNETJEDATE(<cQueue>,<nJob>,[<cServer>|<nConId>])
→ dDate
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJEDATE() returns the date when nJob was placed in cQueue. If an error occurs (for example, if cQueue does not exist), the function returns an empty date.
Description
NOVELL NET JOB ENTRY DATE The Queue Management System (QMS) provides each new job with a date and time stamp. With NNETJEDATE(), you can determine the entry date of nJob in cQueue. The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue. The job number can be determined with NNETCAPJOB() or NNETJLIST().
Notes
■ This function requires that the requesting user have access to
the queue as a user or an operator.
Examples
Determine the entry date of the first job in the queue LINEPRINTER:
nJob=Bin2I(Left(NNETJLIST('LINEPRINTER'),2))
? NNETJEDATE('LINEPRINTER',nJob)
NNETJETIME(<cQueue>,<nJob>,[<cServer>|<nConId>])
→ cTime
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJETIME() returns the time when nJob was placed in cQueue as a string in the form ("HH:MM:SS"). If an error occurs (for example, if cQueue does not exist), the function returns an empty string (" : : ").
Description
NOVELL NET JOB ENTRY TIME The Queue Management System (QMS) provides each new job with a date and time stamp. With NNETJETIME(), you can determine the entry time of nJob in cQueue. The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue. The job number can be determined with NNETCAPJOB() or NNETJLIST().
Notes
■ This function requires that the requesting user have access to
the queue as a user or an operator.
Examples
Determine the entry time of the first job in the queue LINEPRINTER:
nJob=Bin2I(Left(NNETJLIST('LINEPRINTER'),2))
? NNETJETIME('LINEPRINTER',nJob)
NNETJFILE(<cQueue>,<nJob>,[<cServer>|<nConId>])
→ cFile
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJFILE() returns the name of the job file of the job nJob in cQueue. If an error occurs (for example, if cQueue does not exist), the function returns an empty string.
Description
NOVELL NET JOB FILE Netware stores the contents of a job in a separate file. The queue itself only contains references to these files. With NNETJFILE(), you can determine the size of the job files. The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue. The job number can be determined with NNETCAPJOB() or NNETJLIST().
NNETJFILE() only returns file names and file identification. The file name is assigned to a job by the Queue Management System (QMS) when the job is created and cannot be modified. The job file directory can be determined with NNETQDIR().
Notes
■ This function requires that the requesting user have access to
the queue as a user or an operator.
Examples
Determine the job file name of the second job in the queue LINEPRINTER:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),3,2))
? 'File name:', NNETJFILE('LINEPRINTER',nJob)
NNETJFLAGS(<cQueue>,<nJob>,[<nNewFlags>],[<cServer>|
<nConId>]) → nFlags
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
nNewFlags Designates an optional parameter that contains a bit- coded value to change the control flags of nJob in cQueue. The definition of the bits can be seen in table below. To set multiple bits, the decimal values of the attributes must be added.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJFLAGS() returns a numeric value that contains the job flags. The flags correspond to a bit position within this value.
Table 25.1: Coding of Job Control Flags
Bit Value Definition
4 8 Service autostart flag
5 16 Service restart flag. When this flag is set, a job
that is canceled by a job server remains in the queue.
Otherwise, the job is deleted from the queue.
6 32 Entry open flag. This bit indicates that a job has not
been released by a user and therefore is not ready for
servicing.
7 64 User hold flag. The job remains in the queue without
being serviced until the user or the queue operator
clears this flag.
8 128 Operator hold flag. The job remains in the queue
without being serviced until a queue operator clears
this flag.
If an error occurs (for example, if cQueue does not exist), the function returns -1.
Description
NOVELL NET JOB FLAGS Job control flags can provide important information about nJob. The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue. The job number can be determined with NNETCAPJOB() or NNETJLIST().
With NNETJFLAGS() you can determine if a job is ready for processing or if the user has not yet closed the job (entry open flag). You can see if a job is in waiting state (user or operator hold flag). By passing nNewFlags, one or more flags can be set or deleted. For example, a job can be set into a waiting state with the user hold flag.
Notes
■ The reading of the job control flags requires that the
requesting user has access to cQueue as a user or a queue operator.
■ Netware does not prevent a user who has created a job from
changing the operator hold flag. Therefore, it does not make sense to differentiate between a user and an operator hold flag when using NNETJFLAGS(). A difference between these two flags can arise in an application specific interpretation, like the one that is implemented in the Novell utility PCONSOLE.
■ A job that is already in progress cannot be modified.
Examples
■ Check to see if job 1 in the queue LINEPRINTER has already
been closed by the user::
nJob=Bin2I(Left(NNETJLIST('LINEPRINTER'),2))
IF IsBit(NNETJFLAGS('LINEPRINTER',nJob),6)
? 'Job closed!'
ELSE
? 'Job not ready!'
ENDIF
■ Start the capture mode for LPT1, send output in the queue
LINEPRINTER, and set the user hold flag:
NNETCAPSSF(1)
NNETCAPBEG(1)
NNETSETQ(1,'LINEPRINTER')
SET PRINTER ON
? 'Hello'
nJob=NNETCAPJOB(1)
nOldFlags=NNETJFLAGS('LINEPRINTER',nJob)
nNewFlags=NumAnd(nOldFlags,64)
NNETJFLAGS('LINEPRINTER',nJob,nNewFlags)
NNETCAPFLU(1)
■ The new job is always created at the first output (? "Hello"),
not by calling NNETCAPBEG(). Therefore, NNETJFLAGS() must be called
after the first output. If NNETJFLAGS() is not called after the
first output, NNETCAPJOB() returns the number of the previous capture
job and the job control flags are modified for the wrong job.
NNETJFORM(<cQueue>,<nJob>,[<cNewName>],[<cServer>|
<nConId>]) → cName
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cNewName Designates an optional parameter that contains a new form name that is set for nJob. The form name can be up to 15 characters long.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJFORM() returns the name of the form required for nJob.
Description
NOVELL NET JOB FORM Before a job is serviced, the print server checks to see if the form mounted in the printer matches the form specified in nJob. If the form in the printer differs from the specified form, the print server waits for a form change. NNETJFORM() allows you to set or determine the form name for nJob. To query the form name, do not pass a value for cNewName. A new form can be set with this parameter. However, the function does not check to see if cNewName exists.
Examples
■ Determine the form name for the first job in the queue
LINEPRINTER:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJFORM('LINEPRINTER', nJob)
■ Set the form name for the first job in the queue LINEPRINTER
to INVOICE:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJFORM('LINEPRINTER', nJob, 'INVOICE')
NNETJLIST(<cQueue>,[<cServer>|<nConId>]) → cJobNum
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJLIST() returns a string in form of a byte sequence that contains the job numbers of the jobs in cQueue. Two bytes correspond to one job number. If an error occurs (for example, if cQueue does not exist), the function returns an empty string.
Description
NOVELL NET JOB LIST Netware internally uses job numbers in form of 16-bit integers for the administration of jobs within a queue. The job number has nothing to do with the logical position of a job within a queue; for example, the first job in a queue is not automatically job number 1. The job number is assigned to a job by the Queue Management System (QMS) when the job is placed in the queue. Job numbers are used only to identify a job unambiguously.
You must know the job number to work with the functions (NNETJXXX()). NNETJLIST() returns the job numbers in a queue as a string where two bytes contain one job number. With the functions SubStr() and Bin2I(), you can extract each job number (see the example). The sequence of the job numbers in the string corresponds to the logical job sequence. The first two bytes represent the job with the highest priority in the queue.
Notes
■ This function requires that the requesting user have access to
the queue as a user or an operator.
Examples
Determine and output the job numbers for the queue LINEPRINTER:
cJobs=NNETJLIST('LINEPRINTER')
FOR i= 0 TO Len(cJobs)/2-1
? Bin2I(SubStr(cJobs,2*i+1,2))
NEXT i
Sets or determines the number of lines per page for a job
Syntax
NNETJLPP(<cQueue>,<nJob>,[<nNewLines>],[<cServer>|
<nConId>]) → nLines
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cNewLines Designates the new number of lines per page that are set for nJob.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJLPP() returns the number of lines per page for nJob. If an error occurs, the function returns -1.
Description
NOVELL NET LINES PER PAGE With NNETJLPP(), you can set or determine the number of lines per page for nJob. To query the number of lines, do not pass a value for nNewChar. A new number of characters can be set by passing the selected number. The number of lines is simply informative; this information is not evaluated by Netware.
The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
Examples
■ Determine the number of lines per page for the first job in
the queue LINEPRINTER:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJLPP('LINEPRINTER', nJob)
■ Set the number of lines to 62 per page for the first job in
the queue LINEPRINTER:
nJob = Bin2I(Left(NNETJLIST('LINEPRINTER'), 2))
? NNETJLPP('LINEPRINTER', nJob, 62)
NNETJOWNER(<cQueue>,<nJob>,[<cServer>|<nConId>])
→ cUser
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJOWNER() returns the login name of the user who has placed nJob in cQueue. If an error occurs (for example, if cQueue does not exist), the function returns an empty string.
Description
NOVELL NET JOB OWNER Internally, the Queue Management System (QMS) saves the login name (the object ID) of the user who has created the job. NNETJOWNER() allows you to query this information. The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
Notes
■ This function requires that the requesting user have access to
the queue as a user or an operator.
Examples
Determine the creator of the third job in the queue LINEPRINTER:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),5,2))
? NNETJOWNER('LINEPRINTER',nJob)
NNETJPOINT(<cQueue>,<nJob>,[<lNewMode>],[<cServer>|
<nConId>]) → lMode
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
lNewMode Designates an optional parameter that specifies if nJob is serviced by a print server when the job file has not been closed correctly. If the parameter is designated .T., the QMS submits nJob to a print server. If the parameter is set to .F., QMS discards the nJob when the job file has not been closed correctly.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
The return value of NNETJPOINT() indicates whether a job is printed (.T.) or discarded (.F.) when the job file has not been closed correctly.
Description
NOVELL NET JOB PRINT ON INTERRUPTNNETJPOINT() allows you to determine whether or not a job is printed when the job file has not been closed correctly. To query the current setting for nJob, do not pass a value for lNewMode.
The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
Examples
■ Determine if the first job in the queue LINEPRINTER is printed
when the job file has not been closed correctly:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),5,2))
? NNETJPOINT('LINEPRINTER', nJob)
■ Determine that the first job in the queue LINEPRINTER is
printed when the job file has not been closed correctly:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),5,2))
? NNETJPOINT('LINEPRINTER', nJob, .T.)
Determines or changes the position of a job in a queue
Syntax
NNETJPOS(<cQueue>,<nJob>,[<nNewPos>],[<cServer>|
<nConId>]) → nPos
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
nNewPos Designates an optional parameter that contains the new position of nJob in the logical sequence of cQueue.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJPOS() returns the new position of nJob in the logical sequence of cQueue. If an error occurs (for example, if cQueue does not exist), the function returns -1.
Description
NOVELL NET JOB POSITION Within a queue, the jobs are organized as a waiting line. Generally, the jobs are put into a queue in the sequence of their creation. With NNETJPOS(), you can determine the position of a job within a queue. The job with position 1 is serviced first. The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
NNETJPOS() allows a queue operator to change the position of nJob in cQueue by passing the parameter nNewPos.
Notes
■ To determine a job position, the requesting user must have
access to the queue as a user or a queue operator. The modification of a job position is reserved for queue operators.
Examples
■ Determine the position of the last created capture job via
LPT1 in the queue LINEPRINTER:
? NNETJPOS('LINEPRINTER',NNETCAPJOB(1))
■ Change the priority of the job:
IF NNETJPOS('LINEPRINTER',NNETCAPJOB(1),1)<>1
? 'No queue operator rights!'
ENDIF
NNETJSDATE(<cQueue>,<nJob>,[<dNew>],[<cServer>|
<nConId>]) → dDate
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
dNew Designates a new job start date that is set for nJob.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJSDATE() returns the earliest date for nJob in cQueue. The function returns an empty date if the job start date has not been set or if an error occurs (for example, if cQueue does not exist).
Description
NOVELL NET JOB START DATE The Queue Management System (QMS) allows you to provide each job with a retention period. A job is not serviced before that date (job start date). With NNETJSDATE(), you can query or set the job start date of nJob in cQueue. The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
NNETJSDATE() returns the job start date. An empty date indicates that no date has been set. In this case, the job is serviced as soon as a print server is available. ( An empty date can also indicate an error. A differentiation is possible with the NNETERROR() function.)
A new job start date can be set by passing a date with the dNew parameter. If dNew contains an empty date, a previously set job start date is removed. If you reset a job start date, the job start time is removed automatically.
To avoid an incorrect interpretation by the QMS of a time that has not been initialized, always set a job start time with the job start date.
Notes
■ To determine a job start date, the requesting user must have
access to the queue as a user or an operator. The modification of a job start date is reserved for the user who created the job or for queue operators.
■ A job that is already in progress cannot be modified.
Examples
■ Query the job start date for the first job in the queue
LINEPRINTER:
nJob=Bin2I(Left(NNETJLIST('LINEPRINTER'),2))
? NNETJSDATE('LINEPRINTER',nJob)
■ Create the capture job, set the job start date for the
following day, and set the job start time for 10 PM:
NNETCAPSSF(1)
NNETCAPBEG(1)
NNETSETQ(1,'LINEPRINTER')
SET PRINTER ON
? 'Hello'
nJob=NNETCAPJOB(1)
NNETJSDATE('LINEPRINTER',nJob,Date()+1)
NNETJSTIME('LINEPRINTER',nJob,'22:00:00')
NNETCAPFLU(1)
■ The new job is always created at the first output (? "Hello"),
not by calling NNETCAPBEG() Therefore, NNETJSDATE() must be called
after the first output. If NNETJSDATE() is not called after the
first output, NNETCAPJOB() returns the number the previous capture
job and the job start date is modified for the wrong job.
■ Remove the retention period for the first job in the queue
LINEPRINTER (date and time):
nJob=Bin2I(Left(NNETJLIST('LINEPRINTER'),2))
? NNETJSDATE('LINEPRINTER',nJob,CToD(''))
NNETJSIZE(<cQueue>,<nJob>,[<cServer>|<nConId>])
→ nBytes
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJSIZE() returns the size of the job file assigned to nJob in bytes. If an error occurs (for example, if cQueue does not exist), the function returns -1.
Description
NOVELL NET JOB SIZE Netware stores the contents of a job in a separate file. The queue itself only contains references to these files. With NNETJSIZE(), you can determine the size of the job files. If the job is not completed at the function call, NNETJSIZE() returns the temporary size. The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue. The job number can be determined with NNETCAPJOB() or NNETJLIST().
Notes
■ This function requires that the requesting user have access to
the queue as a user or an operator.
Examples
Determine the size of the first job in the queue LINEPRINTER:
nJob=Bin2I(Left(NNETJLIST('LINEPRINTER'),2))
? 'Size:', NNETJSIZE('LINEPRINTER',nJob)
Sets or determines the target or the processing print server
Syntax
NNETJSRV(<cQueue>,<nJob>,[<cNewPServer>],[<cServer>|
<nConId>]) → cPServer
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cNewPServer Designates an optional parameter that contains a new target print server that is set for nJob. If nJob is already in service on another print server, this parameter is meaningless.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
If nJob is not yet in service, NNETJSRV() returns the name of the new target print server. If an error occurs or if no specific printer is set, the function returns an empty string. With NNETERROR(), you can determine if an error occurred.
If nJob is already in service, NNETJSRV() returns the name of the processing print server.
Description
NOVELL NET JOB SERVER The Queue Management System (QMS) allows you to set a target server for each print job. If more than one print server has access to cQueue, you can define a specific print server for nJob. To allow any print server to process nJob, an empty string must be passed for cNewPServer. You can query the current target print server by calling NNETJSRV() without a value for cNewPServer.
The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
Examples
■ Query the target or the processing server for the first job in
the queue LINEPRINTER:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),5,2))
? NNETJSRV('LINEPRINTER', nJob)
■ Set the target server for the first job in the queue
LINEPRINTER to PSERVER:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),5,2))
? NNETJPOINT('LINEPRINTER', nJob, 'PSERVER')
■ Reset the target server for the first job in the queue
LINEPRINTER:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),5,2))
? NNETJSRV('LINEPRINTER', '')
■ Wait until the first job in the queue LINEPRINTER is serviced,
and then display the name of the processing server:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),5,2))
DO WHILE .NOT. NNETJWORK('LINEPRINTER', nJob)
ENDDO
? NNETJSRV('LINEPRINTER', nJob)
NNETJSTIME(<cQueue>,<nJob>,[<cNew>],[<cServer>|
<nConId>]) → cTime
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cNew Designates a new job start time for nJob. The time must be passed as a string in the form ("HH:MM:SS").
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJSTIME() returns the earliest time for nJob in cQueue as a string in the form ("HH:MM:SS"). The function returns an empty string (" : : ") if the job start time has not been set or if an error occurs (for example, if cQueue does not exist).
Description
NOVELL NET JOB START DATE The Queue Management System (QMS) allows you to provide each job with a retention period. A job is not serviced before the specified time (job start time). With NNETJSTIME(), you can query or set the job start time of nJob in cQueue. The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
NNETJSTIME() returns the job start time. An empty string indicates that no time has been set. In this case, the job is serviced as soon as a print server is available. ( An empty string can also indicate an error. A differentiation is possible with the NNETERROR() function.)
A new job start time can be set by passing a time with the dNew parameter. If dNew contains an empty time string (" : : "), a previously set job start date is removed. If you reset a job start time, the job start date is removed automatically.
To avoid an incorrect interpretation by the QMS of a date that has not been initialized, always set a job start date with the job start time.
Notes
■ To determine a job start time, the requesting user must have
access to the queue as a user or an operator. The modification of a job start time is reserved for the user who created the job or for queue operators.
■ A job that is already in progress cannot be modified.
Examples
■ Query the job start time for the first job in the queue
LINEPRINTER:
nJob=Bin2I(Left(NNETJLIST('LINEPRINTER'),2))
? NNETJSTIME('LINEPRINTER',nJob)
■ Create the capture job, set the job start date for the
following day, and set the job start time for 10 PM:
NNETCAPSSF(1)
NNETCAPBEG(1)
NNETSETQ(1,'LINEPRINTER')
SET PRINTER ON
? 'Hello'
nJob=NNETCAPJOB(1)
NNETJSDATE('LINEPRINTER',nJob,Date()+1)
NNETJSTIME('LINEPRINTER',nJob,'22:00:00')
NNETCAPFLU(1)
■ The new job is always created at the first output (? "Hello"),
not by calling NNETCAPBEG(). Therefore, NNETJSTIME() must be called
after the first output. If NNETJSTIME() is not called after the
first output, NNETCAPJOB() returns the number of the previous capture
job and the job start date is modified for the wrong job.
■ Remove the retention period for the first job in the queue
LINEPRINTER (date and time):
nJob=Bin2I(Left(NNETJLIST('LINEPRINTER'),2))
? NNETJSDATE('LINEPRINTER',nJob,(' : : '))
Checks to see if the form feed at the end of a job is suppressed
Syntax
NNETJSUPFF(<cQueue>,<nJob>,[<lNewMode>],[<cServer>|
<nConId>]) → lMode
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
lNewMode Designates an optional parameter. The value .T. causes the print server to ignore form feeds (Chr(12)) in nJob.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
The return value of NNETJSUPFF() indicates if a form feed at the end of nJob is suppressed (.T.) or not (.F.).
Description
NOVELL NET JOB SUPPRESS FORM FEEDS Netware automatically creates a form feed at the end of each print job. With NNETJSUPFF(), a form feed can be suppressed by designating lNewMode with .T.. To query the current setting, do not pass a value for lNewMode.
The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
Examples
■ Check to see if a form feed is created for the first job in
the queue LINEPRINTER:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),5,2))
? NNETJSUPFF('LINEPRINTER', nJob)
■ Suppress the form feed for the first job in the queue
LINEPRINTER:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),5,2))
? NNETJSUPFF('LINEPRINTER', nJob, .T.)
NNETJTABS(<cQueue>,<nJob>,<nNewTabs>,[<cServer>|
<nConId>]) → nTabs
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
nNewTabs Designates an optional parameter that contains the number of spaces to which the tabs are expanded. The value 0 indicates that the tabs are not expanded.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJTABS() returns the number of spaces to which the tabs (Chr(9)) are expanded. The value 0 indicates that the tabs have not been expanded. If an error occurs, the function returns -1.
The return value makes only sense if nJob is a text job.
Description
The Queue Management System (QMS) differentiates between text and binary jobs. In text jobs, QMS is able to replace tabs (Chr(9)) with spaces. The number of spaces per tab can be queried or set with NNETJTABS().
The required job is specified by its job number. The job number has nothing to do with the logical position of a job within a queue; for example, the job with the highest priority in a queue is not automatically job number 1. The job number must be determined with NNETCAPJOB() or NNETJLIST().
Examples
■ Determine the number of spaces per tab created for the first
job in the queue LINEPRINTER:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),5,2))
IF NNETJTXT('LINEPRINTER', nJob)
? NNETJTABS('LINEPRINTER', nJob)
ELSE
? 'No text job'
ENDIF
■ Create five spaces per tab in the first job of the queue
LINEPRINTER:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),5,2))
IF NNETJTXT('LINEPRINTER', nJob)
? NNETJTABS('LINEPRINTER', nJob, 5)
ELSE
? 'No text job'
ENDIF
Determines if the contents of a job file are interpreted as text or a binary byte sequence
Syntax
NNETJTXT(<cQueue>,<nJob>,[<lNewMode>],[<cServer>|
<nConId>]) → lMode
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
lNewMode Designates an optional parameter that indicates if nJob contains text (.T.) or binary data (.F.).
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJTXT() returns .T. if nJob is a text job. The value .F. indicates a binary job or an error. By calling the function NNETERROR(), you can determine if the return value .F. is the result of an error.
Description
NOVELL NET JOB TEXT The Queue Management System (QMS) differentiates between text and binary jobs. NNETJTXT() allows you to query or set the mode for nJob.
Examples
■ Determine the mode for the second job in the queue
LINEPRINTER:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),3,2))
IF NNETJTXT('LINEPRINTER', nJob)
? 'Text job'
ELSE
? 'Binary job'
ENDIF
■ Define the second job of the queue LINEPRINTER as a text job:
nJob=Bin2I(SubStr(NNETJLIST('LINEPRINTER'),3,2))
NNETJTXT('LINEPRINTER', nJob, .T.)
Checks to see if a job is currently in service on a print server
Syntax
NNETJWORK(<cQueue>,<nJob>,[<cServer>|<nConId>])
→ lProcess
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
nJob Designates the job number of the job that is processed in cQueue.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETJWORK() returns .T. if nJob is currently in service. If a job is not yet in service or if an error occurs, the function returns .F.. With NNETERROR() you can determine if the return value .F. results from an error.
Description
NOVELL NET JOB WORKNNETJWORK() allows you to determine whether or not a job is in service. If a job is already in service, its attributes cannot be modified.
Examples
Check to see if the first job in the queue LINEPRINTER is already in
service:
nJob=Bin2I(Left(NNETJLIST('LINEPRINTER'),2))
IF NNETJWORK('LINEPRINTER', nJob)
? 'Job in service'
ENDIF
Determines the users that are currently logged in on a file server
Syntax
NNETLGUSER([<cServer>|<nConId>]) → aUserListe
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server for which the logged in users are determined. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer. If no file server is specified, the function uses the default server.
Returns
NNETLGUSER() returns a one-dimensional array. Each array element contains a user name.
Description
NOVELL NET LOGGED USERNNETLGUSER() allows you to determine all the users currently logged in on the specified file server. The file server can be specified by its name or its connection ID. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
The function NNETLGUSER() requires that the requesting user be logged in on the related file server. If the requesting user is not logged in on the related file server, the function returns an empty array.
All users on a file server can be determined with the function NNETUSERS().
Examples
Display a list of the users currently logged in on file server
NANGERTOOLS2:
aList:=NNETLGUSER('NANGERTOOLS2')
FOR i = 1 TO Len(aList)
? aList[i]
NEXT i
NNETLOGGED() returns .T. when the related station is logged in on the default file server.
Description
NOVELL NET LOGGED IN This function allows you to determine if the related station is logged into the network. This is important information since LOGIN is a prerequisite to having any rights within a network.
Examples
Determine if this station on the default server is logged in:
? NNETLOGGED() // .T., when logged in
NNETLOGIN(<cName>,<cPassword>,[<cServer>|<nConId>])
→ nConId
Netware: 2.2 and 3.11
Arguments
cName Designates the name of the user that is logged in.
cPassword Designates the corresponding password. If no password is required, an empty string must be passed.
cServer Designates the name of the file server on which the user is logged in.
nConId Designates the connection ID of the workstation on cServer. A connection ID can be passed only if the file server is attached to the workstation.
Returns
If a user has been logged in successfully, NNETLOGIN() returns a value between 1 and 8. This value represents the connection ID that can be used to address the file server on the workstation. If an error occurs, the function returns 0.
Description
NNETLOGIN() allows you to log in a user on a file server within an application. The file server must not be attached when you call this function. When NNETLOGIN() is first called, it automatically attaches the workstation to cServer. If no server is specified, the function tries to log in the user on the default server.
If a user at the requesting workstation is already logged in on the related file server, this user is logged out automatically. The log out is performed even if the name of the logged in user is identical to the user name passed with NNETLOGIN(). If the attempt to log in is unsuccessful (for example, because of an incorrect password), the previous log in is canceled. Any drives mapped to the related file server are deleted and are not restored even if the log in is successful.
Important! Before you attempt to log in on file servers where a user is already logged in on the current workstation, make sure that all files on the volumes of the related file server are closed correctly.
A return value that is greater than 0 indicates that the log in has been successful. The value can be stored in a variable and used later to identify the required file server. Alternatively, the identification of the server is possible with the server name.
Notes
■ The password is case sensitive.
■ If the log in is unsuccessful (for example, because of an
invalid password or user name), the server remains attached.
■ The function does not execute a login script. To get a login
script, the function must be called.
Examples
■ Log in Paul on server NANGERTOOLS2:
IF (nConId:= NNETLOGIN('PAUL','190366','NANGERTOOLS2'))>0
? 'Login successful!'
ELSE
? 'Login failed!'
ENDIF
■ Log in on an attached server:
IF (nConId:=NNETATTACH('NANGERTOOLS2'))>0
NNETLOGIN('PAUL','190366',nConId)
ENDIF
NNETLOGOUT(<cServer>|<nConId>|<lAll>,[<lConnect>])
→ lSuccess
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server on which a user is logged out.
nConId Designates the connection ID of your workstation on cServer.
lAll Allows a log out from all file servers if designated .T..
lAttach Designates whether or not the file server remains attached. If a user logs out on a file server, the workstation and the server are detached. If the parameter lAttach is designated .T., the workstation remains attached to cServer.
Returns
NNETLOGOUT() returns .T. if the log out has been successful. If an error occurs (for example if the server name or the connection ID are invalid), the function returns .F..
Description
NOVELL NET LOGOUTNNETLOGOUT() allows you to log out a user on one or all file servers.
To log out on a server, the server can be specified either by its name or its connection ID. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN(). To log out a user on all servers, the parameter lAll must be designated .T..
Usually if you log out on a file server, the workstation connection is terminated (detached). However ,if you want to remain attached to the related file server, you can pass the parameter lAttach with .T..
To be able to perform a successful log in, at least one file server must be attached. Therefore, when you use the function NNETLOGOUT(), the default server always remains attached and is independent of the parameter lAttach.
NNETLOGOUT() can also be used to terminate a connection between a workstation and a file server (detach) when no user is logged in.
Important! When you call NNETLOGOUT(), all drive mappings for the specified server or all servers are terminated. Files on related server volumes cannot be accessed, which can lead to data loss. Before you use NNETLOGOUT(), make sure that all files on the network drives have been closed properly.
Notes
■ The server name cServer must be passed in uppercase letters.
Examples
■ Close all databases, and then log out on all file servers:
CLOSE DATABASES
NNETLOGOUT(.T.)
■ After you call NNETLOGOUT(), the default server is still
attached.
■ Log out on server NANGERTOOLS2:
NNETLOGOUT('NANGERTOOLS2')
NNETMAP([<cDrive>],[<cPath>],[<lFake>],[<lTemp>]
[<lInsert>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cDrive Designates the drive that is mapped or unmapped. Valid identifiers are "A" to "Z" and "S1" to "S16" (search drives). When called without this parameter, the function uses the current drive.
cPath Designates the path on a server volume that is assigned to cDrive. This parameter must be passed if a drive is mapped. When called without cPath, NNETMAP() deletes a mapping for cDrive.
lFake Designates whether cPath is created as fake root (.T.) or not (.F.). The default value (.F.) designates that cPath is not a fake root..
lTemp Designates whether the mapping is permanent (.F.) or temporary (.T.). The default value is .F..
lInsert Designates whether the mapped search drive (S1 to S16) replaces an existing search drive (.F.) or is inserted on the position before the old entry (.T.). This parameter is only important if cDrive is a search drive. The default value is .F..
Returns
NNETMAP() returns .T. if the operation has been successful.
Description
NOVELL NET MAPNNETMAP() allows you to map or unmap drives and search drives within an application. If NNETMAP() is called with only the cDrive parameter, the mapping for the drive is deleted.
To map a drive, NNETMAP() must be called with the arguments cDrive and cPath. The path can contain a local drive designator, path, server name, volume name, and already mapped drives as well as search drives. The default mapping is permanent which means that the mapping continues after the application that created the mapping terminates. If the mapping is terminated with the application, the parameter lTemp must be set to .T..
The directory cPath becomes the root of cDrive if the parameter lFake is set to .T..
NNETMAP() allows you to create search drives. Up to 16 search drives, "S1" to "S16" can be addressed. If a search drive is created (Sn, n=1..16), NNETMAP() determines the first available drive designator with a descending search that starts with "Z". If no designator is available, NNETMAP() cannot perform the allocation and returns .F.. If a designator is available, cPath is mapped to the drive designator and the drive is set on position n in the path environment variable. The previous entry in the path variable is replaced. If lInsert is set to .T., the drive designator is placed before position n in the path list. To delete the mapping for a search drive, cDrive can be passed either with the search drive (S1 to S16) or the drive designator. The drive designator is removed from the path variable.
Notes
■ Fake roots require Novell shell version 3.01 or higher. If
version 3.01 or higher is not available, the attempt to map a fake root fails (cFake=.T.) and NNETMAP() returns .F..
■ You cannot add a new search drive if the path environment
variable already contains 16 entries.
■ Do not create temporary search drives because the drive
mapping is canceled in the program; the invalid drive designator is not removed from the path variable.
Examples
■ Map drive L: to directory PUBLIC on server NANGERTOOLS2,
volume SYS:
? NNETMAP('L','NANGERTOOLS2/SYS:PUBLIC')
■ Map directory ABC to the next available drive designator,
starting from drive L:
? NNETMAP(NNETNXTFRE(),'L:ABC')
■ Create directory SYS:DATA as a permanent search drive on the
current server, and insert the search drive on position 5 in the path
variable. The directory becomes the root for the new drive:
? NNETMAP('S5','SYS:DATA',.T.,,.T.)
■ Terminate the mapping for drive K:
NNETMAP('K')
■ If K: was a search drive, it is removed from the PATH
variable.
NNETMAPINF([<cDrive>],[<lExpand>]) → cPath
Netware: 2.2 and 3.11
Arguments
cDrive Designates the drive for which the mapping is determined. Without this parameter, NNETMAPINF() returns the mapping for the default drive. Values from "A" to "Z" for a normal drive and "S1" to "S16" for a search drive are possible.
lExpand Designates how the search drives are handled. When called without this parameter, or when the parameter is .F., the function returns the drive that corresponds to a search drive designator, followed by a colon and a period. When called with lExpand equal to .T., NNETMAPINF() returns the network path assigned to the drive designator. The default value is .F..
Returns
NNETMAPINF() returns the path that has been mapped to cDrive with the function NNETMAP(). For normal network drives, the return value contains the server name, the volume name, and the directory. For search drives, the return value depends on the parameter lExpand. If this parameter is set to .F., the function returns the drive, followed by a colon and a period. If this parameter is set to .T., the complete network path is returned. If cDrive contains a local drive, NNETMAPINF() returns the drive designator, followed by a colon. An empty string is returned if the designated drive does not exist.
Description
NOVELL NET MAP INFORMATION In a Novell environment, NNETMAPINF() allows you to differentiate between local, network, or unassigned drive designators. For a network drive, the function returns the server name, the volume name, and the path allocated to cDrive. For a search drive, you can determine the drive designator.
Examples
■ Determine the mapping for drive C:
? NNETMAPINF('C') // C: is a local hard disk
■ Determine the mapping for drive J:
? NNETMAPINF('J') // Login directory
NANGERTOOLS2/SYS:LOGIN
■ Determine the mapping for search drive S13:
? NNETMAPINF('S13') // Returns: Z:.
■ Determine the mapping for search drive S13 as a complete path:
? NNETMAPINF('S13',.T.)
NNANGERTOOLS2/SYS:PUBLIC
NNETMAPMOD([<cDrive>]) → nMode
Netware: 2.2 and 3.11
Arguments
cDrive Designates the drive (A to Z, S1 to S16) for which the mapping mode is determined. Without this parameter, NNETMAPMOD() uses the default drive.
Returns
NNETMAPMOD returns a numeric value that contains the mapping mode for cDrive.
Description
NOVELL NET MAP MODENNETMAPMOD() allows you to determine the mapping mode for a specified drive. For example, you can determine if a drive is allocated to a network directory, if the mapping is temporary or permanent, or if a local drive is "masked". For valid return values, see the following table:
Table 22.1: NNETMAPMOD() return values
Value Hex Bin Definition
0 0 00000000 Drive unknown
1 1 00000001 Drive mapped permanently
2 2 00000010 Drive mapped temporarily
128 8 010000000 Local drive
129 8 110000001 Drive mapped permanently, initially local drive
130 8 210000010 Drive mapped temporarily, initially local drive
Examples
■ Determine the mapping mode for drive Y:
? NNETMAPMOD('Y') // Returns: 0
Drive Y: is currently unavailable.
■ Determine the mapping mode for drive J:
? NNETMAPMOD('J') // Returns: 1
Drive J: has been mapped permanently.
Sets or determines the maximum number of connections
Syntax
NNETMAXCON(<cUser>,[<nNumber>],[<cServer>|<nConId>)
→ nMaxConn
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of the user for whom the maximum number of connections is set or determined.
nNumber Designates the new maximum number of connections for cUser.
cServer Designates the name of the file server where cUser is established. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETMAXCON() returns the maximum number of connections for cUser. If the function was called with a value for nNumber and the return value does not match nNumber, the requesting user did not have the rights to modify the number of connections.
Description
NOVELL NET MAXIMUM CONNECTIONSNNETMAXCON() allows you to query or set the maximum number of connections for cUser (the number of workstations where a user can be logged in). To determine the maximum number of connections, do not pass a value for nNumber. If nNumber contains a numeric value, NNETMAXCON() tries to set the maximum number of connections to nNumber. Supervisor rights are required on the related file server to modify the number of connections. With nNumber equal to 0, an existing limit for the number of connections can be removed.
With cServer or nConId, the number of connections for users on any attached file servers can be modified. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Examples
■ Determine the maximum number of connections for user MIKE:
? NNETMAXCON('MIKE') // For example 2
■ Set the new number of connections for user MIKE:
NNETMAXCON('MIKE',5)
■ Remove the limit for user MIKE:
NNETMAXCON("MIKE",0)
Sets or queries the maximum and inherited rights for a directory
Syntax
NNETMAXRGH([<cPath>],[<nRights>|<cRights>]) → nRights
Netware: 2.2 and 3.11
Arguments
cPath Designates a directory or a file (only Netware 3.x) of which the maximum (Netware 2.x) or the inherited (Netware 3.x) rights are set or queried. If no value is passed for cPath, the maximum or inherited rights for the current directory are determined.
cRights Designates a character string that contains the rights for the new directory in form of symbols (maximum rights under Netware 2.x, inherited rights under Netware 3.x). If no value is passed for cRights or nRights, the rights for cPath are not modified.
nRights Designates a numeric value that contains a bit mask for the determination of the rights for the new directory (maximum rights under Netware 2.x, inherited rights under Netware 3.x). If no value is passed for cRights or nRights, the rights for cPath are not modified.
Returns
NNETMAXRGH() returns the maximum rights (Netware 2.x) or the inherited rights (Netware 3.x) for cPath.
Description
NOVELL NET MAXIMUM RIGHTS Under Netware 2.x, NNETMAXRGH() allows you to set or query the maximum rights for a directory. The maximum rights are the rights a user can be granted for a directory. The maximum rights cannot be exceeded even if additional trustee rights are defined for a user. To query the rights, do not pass a value for cRights|nRights.
Rights can be set by passing a character string whereby each character indicates an attribute (cRights), or by passing a numeric value that results from a bitwise OR operation of the binary significance of the attributes (nRights). The maximum rights are coded as follows:
Table 23.8: Rights Coding under Netware 2.x
Bit Definition Description
1 READ Read files
2 WRITE Write files
3 OPEN Open files
4 CREATE Create new files
5 DELETE Delete files
6 PARENTAL Create new directories
7 SEARCH Search files in directories
8 MODIFY Modify files or attributes
The symbols for cRights correspond to the first letter of each keyword under "Definition" in the above table. Individual rights of the return value can be checked with IsBit().
Under Netware 3.x, NNETMAXRGH() allows you to set or query the inherited rights for a directory as well as for individual files. The inherited rights determine which trustee rights a directory or a file inherits from a parent directory, as long as a user has not been explicitly granted trustee rights for the directory or file.
Under Netware 3.x, the rights are coded as follows:
Table 23.9: Rights Coding under Netware 3.x
Bit Definition Description
1 READ Read files
2 WRITE Write to files
3 RESERVED
4 CREATE Create new files
5 ERASE Delete files
6 ACCESS CONTROL Trustee rights can be modified
7 FILE SCAN Search files in directories
8 MODIFY Modify files or attributes
9 SUPERVISORY All rights / can grant rights
The first letter of each keyword under "Definition" represents the symbol for cRights.
Notes
■ For detailed information about rights and security, see the
Novell documentation.
Examples
■ Query the rights for the directory L:DATA:
nRights=NNETMAXRGH('L:DATA')
IF NNETVER('L:')<'3'
? 'Maximum rights:',nRights
ELSE
? 'Inherited rights:',nRights
ENDIF
■ Set the rights for the directory VOL1:DATA/APRIL:
IF NNETVER()<'3'
NNETMAXRGH('VOL1:DATA/APRIL','RWOCDPSM')
ELSE
NNETMAXRGH('VOL1:DATA/APRIL','RWCEFM')
ENDIF
NNETMKDIR(<cPath>,<cRights>|<nRights>) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPath Designates a directory on a server volume. The path can contain a server name.
cRights Designates a character string that contains the rights for the new directory in form of symbols ( maximum rights under Netware 2.x, inherited rights under Netware 3.x).
nRights Designates a numeric value that contains a bit map to determine the rights for the new directory ( maximum rights under Netware 2.x, inherited rights under Netware 3.x).
Returns
NNETMKDIR() returns .T. if the new directory has been created successfully.
Description
NOVELL NET MAKE DIRECTORYNNETMKDIR() allows you to create a new directory on any server volume. The volume must not be mapped to a drive. cPath is the path designation for the new directory. With the parameters cRights or nRights, rights can be assigned for the new directory. The rights can be passed as a string where each character represents an attribute, or as a numeric value that results from a bit wise OR operation of the binary significance of the attributes.
The possible rights are interpreted differently under Novell 2.x and 3.x.
The following table contains the rights under Netware 2.x:
Table 23.10: Rights Coding under Netware 2.x
Bit Definition Description
1 READ Read files
2 WRITE Write to files
3 OPEN Open files
4 CREATE Create new files
5 DELETE Delete files
6 PARENTAL Create new directories
7 SEARCH Search files in directories
8 MODIFY Modify files or attributes
The first letter of each keyword under "Definition" represents the symbol for cRights. Under Novell 2.x, the rights necessary to create a directory are the maximum rights a user can get for a directory. Even if additional trustee rights are granted to a user, the maximum rights cannot be overwritten.
The following table contains the possible rights under Netware 3.x:
Table 23.11: Rights Coding under Netware 3.x
Bit Definition Description
1 READ Read files
2 WRITE Write to files
3 RESERVED
4 CREATE Create new files
5 ERASE Delete files
6 ACCESS CONTROL Trustee rights can be modified
7 FILE SCAN Search files in directories
8 MODIFY Modify files or attributes
9 SUPERVISORY All rights / can grant rights
The first letter of each keyword under "Definition" represents the symbol for cRights. Under Novell 3.x, the rights that are granted when a user creates the directory specify which trustee rights are inherited from the parent directory, as long as the user has not been granted trustee rights for the directory.
Notes
■ For detailed information about rights and security, see the
Novell documentation.
Examples
Create the directory VOL1:DATA/APRIL on the default server:
IF NNETVER()<'3'
NNETMKDIR('VOL1:DATA/APRIL','RWOCDPSM')
ELSE
NNETMKDIR('VOL1:DATA/APRIL','RWCEFM')
ENDIF
Reads the message buffer and uninstalls the broadcast system
Syntax
NNETMSGCLO() → lClosed
Netware: 2.2 and 3.11
Returns
NNETMSGCLO() returns .T. if an installed broadcast system has been uninstalled successfully.
Description
NOVELL NET MESSAGE BUFFER CLOSE A call of NNETMSGCLO() discards all messages in the broadcast buffer and uninstalls the broadcast system. After a call of NNETMSGCLO(), future messages are displayed in line 24 of the screen and must be confirmed by pressing CtrlReturn.
Examples
Read all the messages and close the buffer:
FOR i = 1 TO NNETMSGCNT()
? NNETMSGRD()
NEXT i
NNETMSGCLO()
Determines the number of messages in the broadcast buffer
Syntax
NNETMSGCNT() → nNumber
Netware: 2.2 and 3.11
Returns
NNETMSGCNT() returns the number of messages in the broadcast buffer. If the broadcast buffer is empty, the function returns 0.
Description
NOVELL NET MESSAGE COUNTNNETMSGCNT() allows you to determine the number of messages in the broadcast buffer. If the broadcast buffer is empty, or if the broadcast system is not installed, the function returns 0.
Examples
Read and display all the messages from the broadcast buffer:
FOR i = 1 TO NNETMSGCNT()
? NNETMSGRD()
NEXT i
Defines the key code for incoming broadcast messages
Syntax
NNETMSGKEY([<nKeyValue>]) → lActive
Netware: 2.2 and 3.11
Arguments
nKeyValue Specifies the key code that is placed in the keyboard buffer by the broadcast system when a message is received. All values from the CA-Clipper KEYBOARD command are valid. When called without this parameter, the function resets a previously set key code.
Returns
NNETMSGKEY() returns (.T.) if a key code for the broadcast system has been set successfully.
Description
NOVELL NET MESSAGE KEYNNETMSGKEY() allows you to react to incoming messages within a wait state (READ, WAIT, AChoice() or MemoEdit()). For example, a refresh can be triggered within an input mask, as soon as a defined message arrives.
Initializes the interrupt-controlled broadcast system
Syntax
NNETMSGOPN([<nNumber>]) → lStatus
Netware: 2.2 and 3.11
Arguments
nNumber Designates the maximum number of broadcast messages that are accepted by the receiving buffer. Values from 1 to 1000 are allowed. Values outside of this range are corrected automatically. The default value for nNumber is 1.
Returns
NNETMSGOPEN() returns .T. if the broadcast system has been initialized successfully. If an error occurs (for example, insufficient fixed heap memory to create the buffer), the function returns .F..
Description
NOVELL NET MESSAGE BUFFER OPEN Netware allows you to send broadcast messages between workstations. For example, broadcast messages can be created with the Novell utility SEND or with the CA-Clipper Tools function NNETSND(). The broadcast system is also used by Netware servers to send system messages. Incoming messages are displayed on line 24 of the screen; these messages block the system until they are confirmed with CtrlReturn. These incoming messages can be suppressed with CASTOFF or with the CA-Clipper Tools function NNETBRDCST(). In contrast, NNETMSGOPN(), in conjunction with the NNETSND() functions, allows communication between applications.
NNETMSGOPN() opens a buffer that can accept up to nNumber broadcast messages and installs an interrupt handler. After the message system has been installed, incoming messages are no longer displayed on the screen; these messages are stored in the internal message buffer. The messages can then be read from the buffer in the sequence of their arrival with NNETMSGRD().
The broadcast system can simulate a key code when a message is received. If the receiving buffer is full, no additional messages are accepted. Do not suppress the receiving of messages when using the broadcast system! Messages are already suppressed on the file server instead of the workstation.
Notes
Important! NNETMSGOPN() works with the interrupt system. Before you leave your CA-Clipper application, NNETMSGOPN() must be uninstalled with the function NNETMSGCLO(). Changed interrupt vectors can, sooner or later, lead to a system crash. When working with the extended drivers module, interrupt vectors are reset automatically.
■ It is not possible to use the message system with former
versions of the Novell shell. The latest version is available free of charge from Novell through CompuServe.
Examples
Install the broadcast system with a buffer for up to 10 messages:
IF NNETMSGOPN(10)
? 'Broadcast system installed successfully!'
ELSE
? 'Installation failed!'
ENDIF
NNETMSGRD([<lNotDelete>]) → cMessage
Netware: 2.2 and 3.11
Arguments
lNotDelete Designates an optional parameter that allows you to read a message from the buffer without changing the contents of the buffer. If lNotDelete is designated .T., the message remains in the buffer. If lNotDelete is designated .F., the message is deleted from buffer.
Returns
NNETMSGRD() returns a character string that contains the message that has been received previously in the background.
Description
NOVELL NET MESSAGE READ NNETMSGRD() allows you to read messages from the broadcast buffer after the buffer has been opened with NNETMSGOPN(). NNETMSGRD() always returns the oldest message. If the buffer is empty or if the broadcast system is not installed, NNETMSGRD() returns an empty string.
Examples
Read a message from the broadcast buffer, and emulate the Novell
standard behavior:
#include "inkey.ch"
IF .NOT. Empty(cMsg:=NNETMSGRD())
@ 24,0 SAY cMsg
WHILE Inkey()!=K_CTRL_RETURN
ENDDO
ENDIF
NNETMSGSIZ() returns the number of broadcast messages the broadcast buffer can accept.
Description
NOVELL NET MESSAGE BUFFER SIZENNETMSGSIZ() allows you to determine the size of the broadcast buffer. If the broadcast system is not installed, the function returns 0.
Examples
Calculate the number of messages that the broadcast buffer can accept:
? NNETMSGSIZ()-NNETMSGCNT()
Determines the user name for an internal netaddress
Syntax
NNETNAME(<cInterNetAdr>,[<cServer>|<nConId>]) → cUser
Netware: 2.2 and 3.11
Arguments
cInterNetAdr Designates a 20-character string containing a 10- character hexadecimal byte sequence. Two characters represent one byte in hexadecimal form. The leading eight characters of cInterNetAdr (four byte) indicate the network number of cUser. The remaining 12 characters (six byte) contain the station ID of cUser (number of the network adapter, Node Address).
cServer Designates the name of the file server that is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETNAME() returns the name of the user that is logged in with the internet address, cInterNetAdr. The function returns an empty string if the user cannot be determined.
Description
NOVELL NET NAMENNETNAME() allows you to determine the name of a user with an internal netaddress and can be used in conjunction with the SPX functions of the Point to Point communication. Functions like SPXCONTARG() always return the communication's destination as an internet address. If both the current station and the station specified by cInterNetAdr are logged in on cServer, NNETNAME() allows you to determine the user name of a passed internet address.
Examples
Determine the destination's user name of an SPX session:
? NNETNAME(SPXCONTARG(nHandle))
Determines the number of print servers that service a print queue
Syntax
NNETNQSRVS(<cQueue>,[<lAll>],[<cServer>|<nConId>])
→ nNumber
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is accessed.
lAll Designates whether all print servers that have access to cQueue (.T.) or only the print servers that are currently logged in at cQueue (.F.) are counted. The default value is .F..
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETNQSRVS() returns the number of print servers currently logged in at cQueue (lAll = .F.) or the number of print servers that have access to cQueue (lAll = .T.). If an error occurs (for example, if the cQueue does not exist), the function returns -1.
Description
NOVELL NET NUMBER OF QUEUE SERVERSNNETNQSRVS() allows you to determine if any print server has access to a specified queue, if a print server is currently logged in at a queue, or if the queue is "dead".
Notes
■ This function requires that the requesting user have access to
the queue as a user or an operator.
Examples
Set the queue LINEPRINT to LPT1 for the capture mode if it is serviced
by at least one print server:
IF NNETNQSRVS('LINEPRINT')>0
NNETSETQ(1,'LINEPRINT')
ELSE
? 'Queue is currently not serviced !'
ENDIF
Determines the number of members of a set property
Syntax
NNETNUMMEM(<cObjName>,[<nType>],<cPropName>,
[<cServer>|<nConId>]) → nNumber
Netware: 2.2 and 3.11
Arguments
cObjName Designates the name of the bindery object that is processed.
nType Designates the object type of cObjName. The header file CTNNET.CH contains symbolic constants for a number of object types. When you work with numeric values, take into account that, for efficiency reasons, the function NNETNUMMEM() expects the object type in the high-low format. The default value indicates the object type OBJ_USER.
cPropName Designates the name of the property for which the members are counted. cPropName must describe a set property.
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETNUMMEM() returns the number of members of the property cPropName of cObjName. If an error occurs, the function returns -1.
Description
NOVELL NET COUNT MEMBERS Internally, Novell Netware defines two possible property types: item and set properties. Unlike an item property that accepts any kind of data, the set property contains references to other bindery objects. These bindery objects are the members of the set property. This function allows you to determine the total of members of a set property without having to specify all the members explicitly.
The object type nType must be passed in the high-low format (see the Introduction to this chapter). For the object types, use the symbolic constants of the header file CTNNET.CH. With the parameters cServer or nConId, the bindery of any attached server can be accessed. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Examples
Determine the number of members of the group EVERYONE:
#include "ctnnet.ch"
? NNETNUMMEM('EVERYONE',OBJ_GROUP,'GROUP_MEMBERS')
NNETNXTFRE([<lRevers>]) → cDrive
Netware: 2.2 and 3.11
Arguments
lRevers Designates whether the search is performed in ascending order, starting from drive designator "A", or in descending order, starting from drive designator "Z". The default value (.F.) designates that the search is performed in ascending order.
Returns
NNETNXTFRE() returns the designator of the determined drive. If no further drive designator is available, the function returns an empty string ("").
Description
NOVELL NET NEXT FREENNETNXTFRE() is used mainly in conjunction with the function NNETMAP(). NNETNEXTFRE() allows you to determine the next available drive designator before a drive mapping. For example, you can avoid deleting existing mappings.
Examples
■ Determine the next available drive designator, starting from
"A":
? NNETNXTFRE() // Returns: K
■ Determine the next available drive designator, starting from
"Z":
? NNETNXTFRE(.T.) // Returns: Y
Determines the object ID with the object name and the object type
Syntax
NNETOBJID(<cObjName>,<nObjType>,<cServer>|<nConId>])
→ nObjId
Netware: 2.2 and 3.11
Arguments
cObjName Designates the name of the object for which the ID is determined.
nObjType Designates a numeric value that specifies the object type. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use in conjunction with the bindery functions of CA-Clipper Tools.
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETOBJID() returns the object ID of the bindery object that is specified by cObjName and nObjType on cServer. For efficiency reasons, the object ID is returned in the high-low format. If an error occurs, the function returns -1.
Description
NOVELL NET OBJECT ID Each object in the bindery of a file server is identified by its object ID. NNETOBJID() allows you to determine the ID with the object name and the object type. For efficiency reasons, numeric values for nObjType must be passed in the high-low format.
Examples
Determine the subdirectories of a print queue:
#include "ctnnet.ch"
nId=NNETOBJID('PRINTQ_0',OBJ_PRINTQUEUE)
? 'Queue directory:'+HexToStr(L2Bin(nId))+'.QDR'
NNETOBJNAM(<NId>, [<cServer>|<nConId>]) → cObjName
Netware: 2.2 and 3.11
Arguments
NId Designates a bindery object ID. For efficiency reasons, the ID must be passed in the high-low format (see the Introduction to this chapter).
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NETOBJNAM() returns the name of the bindery object, specified by NId. If an error occurs, the function returns a null string.
Description
NOVELL NET OBJECT NAME Within a file server, each bindery object is given a unique object ID with a length of four bytes. With NNETOBJNAM(), you can determine the name of the related bindery object. NNETOBJNAM() can be used in conjunction with functions that return an object ID in the high-low format (for example, NNETRDSET()).
Examples
Read the property SECURITY_EQUALS of user MIKE, and return the object
names of the members (the SECURITY_EQUALS property contains a list of
objects to which an object is security-equivalent):
#include "ctnnet.ch"
aIn=NNETRDSET('MIKE',OBJ_USER,'SECURITY_EQUALS')
FOR i=1 TO Len(aIn)
? NNETOBJNAM(aIn[i])
NEXT i
NNETOBJSEC(<cObjName>,<nObjType>,<nSafe>,
[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cObjName Designates the name of the object for which the security is modified.
nObjType Designates a numeric value that specifies the object type. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use in conjunction with the bindery functions of CA-Clipper Tools.
nSafe Designates the new value for the object security. This value specifies the rights required to find (read) or to modify (write) the object in the bindery. The settings are defined with a bit-coded mask. The low-ordered bits control the read access; the high-ordered bits control the write access to the bindery object.
Table 18.4: Values for Object Security
Value Hex Bin Definition
0 0 0000 Access allowed to all users
1 1 0001 Access allowed to users who have logged in to the
file server
2 2 0010 Access allowed to users who have logged in to the
file server with password
3 3 0011 Access allowed to users who have logged in to the
file server as the supervisor or as a user who has
supervisor equivalence
4 4 0100 Access only allowed to the network operating system
cServer Designates the name of the file server that is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETOBJSEC() returns .T. if the new security value (nSafe) has been set successfully.
Description
Important! NNETOBJSEC() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET OBJECT SECURITYNNETOBJSEC() allows you to modify the security of existing bindery objects. For efficiency reasons numeric values for nObjType must be passed in the high-low format. This function requires supervisor rights.
Examples
Set the security of the user object MICK to 51 (hex 33):
IF NNETOBJSEC('MICK',OBJ_USER,51)
? 'Security modified successfully!'
ELSE
? 'Error!'
ENDIF
NNETOBJTYP(<NId>, [<cServer>|<nConId>]) → nObjType
Netware: 2.2 and 3.11
Arguments
NId Designates a bindery object ID. For efficiency reasons, the ID must be passed in the high-low format (see the Introduction to this chapter).
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NETOBJTYP() returns the type of the bindery object, specified by NId in the high-low format. If an error occurs, the function returns 0.
Description
NOVELL NET OBJECT TYPE Within a file server, each bindery object is given a unique object ID with a length of four bytes. With NNETOBJTYP(), you can determine the type of the related bindery object. NNETOBJTYP() can be used in conjunction with functions that return an object ID in the high-low format (for example, NNETRDSET()).
Examples
Read the property SECURITY_EQUALS of user MIKE, and return the object
names and types of the members (the SECURITY_EQUALS property contains a
list of objects to which an object is security-equivalent):
#include "ctnnet.ch"
aIn=NNETRDSET('MIKE',OBJ_USER,'SECURITY_EQUALS')
FOR i=1 TO Len(aIn)
? NNETOBJNAM(aIn[i])
?? IF(NNETOBJTYP(aIn[i])=OBJ_USER,'User','Group')
NEXT i
Determines all of the stations where a user is logged in
Syntax
NNETOCNUMS([<cUser>]) → cStationList
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of an object of the type user. The default value specifies the logged in user.
Returns
NNETOCNUMS() returns a character string where each byte represents a station number.
Description
NOVELL NET OPEN CONNECTION NUMBERS With the help of this function you can determine on how many stations, and on which stations, an object of the type user is logged into the network. This always relates to the default file server.
The station numbers are returned as a character string; each byte represents a station number. This character string works very well with CA-Clipper Tools string functions, such as CharSort(), CharRem(), etc..
If no user name is specified, the function returns the numbers for all stations that are logged in under the same name as the station being used. This corresponds to a call of NNETOCNUMS(NNETWHOAMI()).
Notes
■ Console privileges are required to determine the station
number of another user.
Examples
Determine the station numbers where JIM is logged in:
cVar := NNETOCNUMS("JIM")
FOR I = 1 TO Len(cVar)
? Asc(SubStr(cVar, I, 1)) // Station numbers
NEXT I
NNETPDEV([<cServer>,<nConId>]) → aDevices
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server for which the device definition is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPDEV() returns a one-dimensional array that contains the names of the defined devices.
Description
NOVELL NET PRINT DEVICES Netware allows you to manage printer and form information in a database (NET$PRN.DAT). NNETPDEV() allows you to access this database and use the information in your application. The function returns an array that contains the names of the defined devices.
Examples
Determine and display the defined devices:
aDevices = NNETPDEV()
FOR i = 1 TO Len(aDevices)
? aDevices[i]
NEXT i
NNETPEXPD(<cUser>,[<dDate>],[<cServer>|<nConId>)
→ dExpiration
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of the user whose password is set or determined.
dDate Designates the new expiration date for the password of cUser.
cServer Designates the name of the file server to which cUser has access. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPEXPD() returns the current expiration date of the password for cUser. If dDate has been passed and the return value does not match dDate, the requesting user did not have the rights required for the modification.
Description
NOVELL NET PASSWORD EXPIRATION DATENNETPEXPD() allows you to query or set the expiration date of the password of cUser. To determine the expiration date, do not pass a date for dDate. If dDate contains a date, NNETPEXPD() tries to set a new expiration date. Supervisor rights are required on the related file server to modify the expiration date. An existing expiration date can be removed with an empty date. With cServer or nConId, the password expiration date of users on any attached file servers can be modified. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Examples
■ Determine the password expiration date for user MIKE:
? NNETPEXPD('MIKE') // z.B. 03/19/92
■ Set the new password expiration date for user MIKE:
NNETPEXPD('MIKE',CToD('06/01/92'))
■ Remove the password expiration date for user MIKE:
NNETPEXPD("MIKE",CToD(""))
Sets or determines the password expiration interval
Syntax
NNETPEXPI(<cUser>,[<nDays>],[<cServer>|<nConId>)
→ nExpiration
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of user whose password expiration interval is set or determined.
nDays Designates the new password expiration interval of cUser.
cServer Designates the name of the file server to which cUser has access. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPEXPI() returns the current expiration interval of the password for cUser. If nDays has been passed and the return value does not match nDays, the requesting user did not have the rights required for the modification.
Description
NOVELL NET PASSWORD EXPIRATION INTERVALLNNETPEXPI() allows you to query or set the expiration interval of the password of cUser. To determine the expiration interval, do not pass a value for nDays. If nDays contains a numeric value, NNETPEXPI() tries to set this value as new expiration interval. Supervisor rights are required on the related file server to modify the expiration interval. An existing expiration interval can be removed if you set nDays equal to 0. With cServer or nConId, the password expiration interval of users on any attached file servers can be modified. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Examples
■ Determine the password expiration interval for user MIKE:
? NNETPEXPI('MIKE') // For example 40
■ Set the new password expiration interval for user MIKE:
NNETPEXPI('MIKE',50)
■ Remove the password expiration interval for user MIKE:
NNETPEXPI("MIKE",0)
NNETPFLEN(<cForm>,[<cServer>|<nConId>]) → nLength
Netware: 2.2 and 3.11
Arguments
cForm Designates the name of the form for which the page length is determined.
cServer Designates the name of the file server for which the form's definitions are used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPFLEN() returns the number of lines per page for cForm. If an error occurs (for example, if cForm is not found), the function returns -1.
Description
NOVELL NET PRINT FORM LENGTH Netware allows you to manage printer and form information in a database (NET$PRN.DAT). The CA-Clipper Tools functions allow you to access this database and use the information in your application. With NNETPFLEN(), you can determine the number of lines per page for cForm. The number of lines has an informative character only and is not evaluated by Netware.
Examples
Query the page length for the form INVOICE:
? NNETPFLEN('INVOICE')
NNETPFNUM(<cForm>,[<cServer>|<nConId>]) → nNumber
Netware: 2.2 and 3.11
Arguments
cForm Designates the name of the form for which the number is determined.
cServer Designates the name of the file server for which the formÆs definitions are used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPFNUM() returns the number of cForm in the definition file. A return value of -1 indicates an error.
Description
NOVELL NET PRINT FORM NUMBER Netware allows you to manage printer and form information in a database (NET$PRN.DAT). A name and a unique number are assigned to each form. NNETPFNUM() allows you to determine the form number of cForm.
Examples
Determine the number for the form INVOICE:
? NNETPFNUM('INVOICE')
NNETPFORMS([<cServer>,<nConId>]) → aForms
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server for which the formÆs definitions are used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPFORMS() returns a one-dimensional array that contains the names of the defined forms.
Description
NOVELL NET PRINT FORMS Netware allows you to manage printer and form information in a database (NET$PRN.DAT). NNETPFORMS() allows you to access this database and use the information in your application. The function returns an array that contains the names of the defined forms.
Examples
Determine and define the defined forms:
aForms = NNETPFORMS()
FOR i = 1 TO Len(aForms)
? aForms[i]
NEXT i
Determines the control sequences of a function definition
Syntax
NNETPFUNCO(<cDevice>,<cFunc>,[<cServer>,<nConId>])
→ cControl
Netware: 2.2 and 3.11
Arguments
cDevice Designates the name of the device that is processed.
cFunc Designates the name of a function that is established for cDevice.
cServer Designates the name of the file server for which the device definitions are used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPFUNCO() returns the control sequence defined in NET$PRN.DAT for the function cFunc of cDevice.
Description
NOVELL NET PRINT FUNCTION CODES Netware allows you to manage printer and form information in a database (NET$PRN.DAT). For each device, functions are defined to put the device into specific modes. With NNETPFUNCO(), you can determine the control sequence for cFunc of cDevice. This allows you to link the printer control to the Netware printer management within your application.
Examples
Determine the control sequence for the reset function of the device
HPLJ, and send it to the printer:
PrintSend(NNETPFUNCO('HPLJ', 'RESET'))
NNETPFUNCS(<cDevice>,[<cServer>,<nConId>]) → aFuncs
Netware: 2.2 and 3.11
Arguments
cDevice Designates the name for the device for which the functions are determined.
cServer Designates the name of the file server for which the device definitions are used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPFUNCS() returns a one-dimensional array that contains the names of the functions defined for cDevice.
Description
NOVELL NET PRINT FUNCTIONS Netware allows you to manage printer and form information in a database (NET$PRN.DAT). For each device, functions are defined to put the device into specific modes. NNETPFUNCS() returns a list of functions defined for cDevice. This allows you to link the printer control to the Netware printer management within your application.
Examples
Determine and display the functions for device HPLJ:
aFuncs = NNETPFUNCS('HPLJ')
FOR i = 1 TO Len(aFuncs)
? aFuncs[i]
NEXT i
NNETPFWDTH(<cForm>,[<cServer>|<nConId>]) → nLength
Netware: 2.2 and 3.11
Arguments
cForm Designates the name of the form for which the form width (characters per line) is determined.
cServer Designates the name of the file server for which the form definitions are to be used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPFWDTH() returns the number of characters per line for cForm. If an error occurs (for example, if cForm is not found), the function returns -1.
Description
NOVELL NET PRINT FORM WIDTH Netware allows you to manage printer and form information in a database (NET$PRN.DAT). The CA-Clipper Tools functions allow you to access this database and use the information in your application. With NNETPFWDTH(), you can determine the number of characters per line for cForm. The number of lines has an informative character only and is not evaluated by Netware.
Examples
Query the number of characters for the form INVOICE:
? NNETPFWDTH('INVOICE')
NNETPJADD(<cJob>,[<cUser>],[<cServer>|<nConId>])
→ lSuccess
Netware: 2.2 and 3.11
Arguments
cJob Designates the print job definition that is added.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJADD() returns .T. if the print job definition has been added successfully.
Description
NOVELL NET PRINT JOB ADD NNETPJADD() allows you to add a new print job definition (cJob) for cUser. The new job definition is created with default values that can be modified by calling other NNETPJXXX() functions. To achieve results with NNETPJADD(), a print job file for cUser must exist (PRINTCON.DAT). cJob must be unique, and the job file must have less than 37 entries. If cUser is not the current user, access rights for the mail directory of the user are required.
Examples
Add a new print job definition for the current user under the name
MYJOB:
IF NNETPJADD('MYJOB')
? 'Job definition has been added successfully'
ELSE
? 'Error'
ENDIF
NNETPJBAN([<cJob>],[<lNewTitle>],[<cUser>],[<cServer>|
<nConId>]) → lBanner
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
lNewTitle Designates whether a banner page for nJob is printed (.T.) or not (.F.).
cServer Designates the name of the file server on which the queue Queue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJBAN() returns .T. if the job definition includes printing a banner page.
Description
NOVELL NET PRINT JOB BANNER A banner page can be printed under Netware before each print job to show the user name. NNETPJBAN() allows you to determine if a banner page is printed. The printing of a banner page can be suppressed by passing the parameter lNewTitle with .F.. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine if the job definition MYJOB includes printing a
banner page:
? NNETPJBAN('MYJOB')
■ Suppress the printing of a banner page for the job MYJOB:
? NNETPJBAN('MYJOB', .F.)
NNETPJBNAM([<cJob>],[<cNewName>],[<cUser>],[<cServer>|
<nConId>]) → cName
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates a default job.
cNewName Designates a new banner name that is set for cJob. The banner name can be up to 12 characters long.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJBNAM() returns the user name that is printed on the banner page of cJob.
Description
NOVELL NET PRINT JOB BANNER NAME The banner page of a job contains the user name of the job owner and the name of the printed file. NNETPJBNAM() allows you to set or determine the name of the printed file. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the file name for the banner page in the job
definition MYJOB:
? NNETPJBNAM('MYJOB')
■ Set the file name for the banner page in the job definition
MYJOB to LST:
? NNETPJBAN('MYJOB', 'LST')
NNETPJCAP([<cJob>],[<lNewCap>],[<cUser>],[<cServer>|
<nConId>]) → lCaptureMode
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
lNewCap Designates an optional parameter that allows you to set a new capture mode for cJob. When this parameter is .T., the function activates the auto end capture mode.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJCAP() returns .T. if the auto end capture mode has been activated.
Description
NOVELL NET PRINT JOB CAPTURE MODE Under Netware, two capture modes are possible. If the auto end capture mode is activated, open print jobs are closed automatically when the application has been terminated or the printer device has been closed. If the auto end capture mode is not activated, open jobs are closed when the timeout value is exceeded, or the ENDCAP utility or the CA-Clipper Tools NNETCAPEND() function are called. NNETPJCAP() allows you to query or set the capture mode in a print job definition. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the capture mode in the job definition MYJOB:
IF NNETPJCAP('MYJOB')
? 'Auto end capture activated'
ELSE
? 'Auto end capture mode not active'
ENDIF
■ Activate the auto end capture mode in the job definition
MYJOB:
? NNETPJCAP('MYJOB', .T.)
NNETPJCAPF([<cJob>],[<cUser>],[<cServer>|<nConId>])
→ lSuccess
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJCAPF() returns .T. if the capture mode has been started successfully.
Description
NOVELL NET PRINT JOB CAPTURE FLAGSNNETPJCAPF() allows you to start a capture process with the settings of a print job definition (cJob). A call of NNETPJCAPF() corresponds to a call of the Novell utility CAPTURE, with or without the /j=cJob option. If cUser is not the current user, access rights for the mail system of the user are required.
Notes
■ NNETPJCAPF() starts a capture process. A following call of
■ Start a capture process with the settings of the default job
definition:
IF NNETPJCAPF()
? 'Capture has been started successfully'
ELSE
? 'Error'
ENDIF
■ Start a capture process with the settings of the job
definition MYJOB:
IF NNETPJCAPF('MYJOB')
? 'Capture has been started successfully'
ELSE
? 'Error'
ENDIF
NNETPJCNT([<cUser>],[<cServer>|<nConId>]) → nNumber
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJCNT() returns the number of print job definitions in the job definition file (PRINTCON.DAT) of cUser. If an error occurs, the function returns -1.
Description
NOVELL NET PRINT JOB COUNT A job definition file (PRINTCON.DAT) can contain up to 37 entries. NNETPJCNT() allows you to determine the current number of job definitions. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
Determine the number of print job definitions for the current user:
? NNETPJCNT()
Sets or queries the number of copies for a print job
Syntax
NNETPJCOPY([<cJob>],[<nNewCopies>],[<cUser>],
[<cServer>|<nConId>]) → nCopies
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
nNewCopies Designates the new number of copies for cJob. The maximum number of copies is 255.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJCOPY() returns the number of copies of cJob that are printed. If an error occurs, the function returns -1.
Description
NNETPJCOPY() allows you to set or query the number of copies within a print job definition. To query the number of copies, do not pass a value for nNewCopies. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the number of copies in print job definition MYJOB:
? NNETPJCOPY('MYJOB')
■ Set the number of copies in print job definition MYJOB to 3:
? NNETPJCOPY('MYJOB', 3)
NNETPJCRT([<cUser>],[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJCRT() returns .T. if the print job file has been created successfully.
Description
NOVELL NET PRINT JOB (DEFINITION FILE) CREATENNETPJCRT() allows you to create an empty job definition file (PRINTCON.DAT) for the current user or any other user. Job definitions can be added to this file by calling NNETPJADD(). If cUser is not the current user, access rights for the mail system of the user are required.
Notes
Important! If a print job file for cUser already exists, all job entries are lost when you call NNETPJCRT().
Examples
Create a new job definition file for the current user:
cDef = 'SYS:MAIL/+RemLeft(NNETUSERID(), '0')+'PRINTCON.DAT'
IF !FILE(cDef)
NNETPJCRT()
ENDIF
NNETPJDEF([<cNewDefault>],[<cUser>],[<cServer>|
<nConId>]) → cDefault
Netware: 2.2 and 3.11
Arguments
nNewDefault Designates an optional parameter that sets a new print job definition. The definition must already exist.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJDEF() returns the name of the default job definition for cUser.
Description
In general, all NNETPJXXX() functions that refer to a print job definition access the default job definition. NNETPJDEF() allows you to set or query the name of the default job definition. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the name of the default job definition for the
current user:
? NNETPJDEF()
■ Set MYJOB as the default job definition for the current user:
? NNETPJDEF('MYJOB')
NNETPJDEL(<cJob>,[<cUser>],[<cServer>|<nConId>])
→ lSuccess
Netware: 2.2 and 3.11
Arguments
cJob Designates the name of the print job definition.
cUser Designates the name of the user whose print job definition file (PRINTCON.DAT) is accessed. The default value accesses the current user.
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJDEL() returns .T. if the print job definition cJob has been deleted successfully. If an error occurs, the function returns .F..
Description
NOVELL NET PRINT JOB DELETENNETPJDEL() allows you to delete the print job definition (cJob) of the current user or any other user (if the print job definition file can be accessed for that user). The default job cannot be deleted.
Examples
Delete the print job HPLJ of the current user:
IF NNETPJDEL('HPLJ')
? 'Job definition deleted successfully!'
ELSE
? 'Error'
ENDIF
NNETPJDEV([<cJob>],[<cNewDevice>],[<cUser>],
[<cServer>|<nConId>]) → cDevice
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
nNewDevice Designates a new device name for cJob. The device name must have an entry in the printer definition file (NET$PRN.DAT) on cServer.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJDEV() returns the device name in the job definition cJob.
Description
NOVELL NET PRINT JOB DEVICE A print job definition can contain the name of a device. This name can be set or queried by calling NNETPJDEV(). Do not pass a value for cNewDevice to query the device name. A device name can be set by specifying cNewDevice. To reset a device name (set to none), the parameter cNewDevice must contain an empty string (""). If cUser is not the current user, access rights for the mail system of the user are required.
Notes
■ Setting a new device name resets the current device mode. The
■ Determine the device name in the job definition MYJOB:
? NNETPJDEV('MYJOB')
■ Set the device name in the job definition MYJOB to HPLJ:
? NNETPJDEV('MYJOB', 'HPLJ')
■ Reset the device name in the job definition MYJOB to NONE:
? NNETPJDEV('MYJOB', '')
NNETPJFORM([<cJob>],[<cNewForm>],[<cUser>],[<cServer>|
<nConId>]) → cForm
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
nNewForm Designates a new form name for cJob. The form name must have an entry in the printer definition file (NET$PRN.DAT) on cServer.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJFORM() returns the form name in the job definition cJob.
Description
NOVELL NET PRINT JOB FORM A print job definition can contain the name of a form. This name can be set or queried by calling NNETPJFORM(). Do not pass a value for cNewForm to query the form name. A form name can be set by specifying cNewForm. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the form name in the job definition MYJOB:
? NNETPJFORM('MYJOB')
■ Set the form name in the job definition MYJOB to INVOICE:
? NNETPJFORM('MYJOB', 'INVOICE')
NNETPJFSRV([<cJob>],[<cNewServer>],[<cUser>],
[<cServer>|<nConId>]) → cFileServer
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
nNewServer Designates a new file server name for cJob. The file server must be available in the internal network.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJFSRV() returns the name of the file server in the job definition cJob.
Description
NOVELL NET PRINT JOB FILE SERVER A print job definition must contain the name of a file server to find the print queue when the job is activated. The file server name can be set or queried by calling NNETPJFSRV(). Do not pass a value for cNewServer to query the server name. A server name can be set by specifying cNewServer. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the file server name in the job definition MYJOB:
? NNETPJFSRV('MYJOB')
■ Set the server name in the job definition MYJOB to SERVER1:
? NNETPJFSRV('MYJOB', 'SERVER1')
NNETPJLIST([<cUser>],[<cServer>|<nConId>]) → aJobs
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJLIST() returns a one-dimensional array that contains the names of the print job definitions for cUser.
Description
NOVELL NET PRINT JOB LISTNNETPJLIST() returns a list of all existing job definitions for cUser. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
Determine and display the job definitions for the current user:
aJobs = NNETPJLIST()
FOR i = 1 TO Len(aJobs)
? aJobs[i]
NEXT i
NNETPJLPT([<cJob>],[<nNewLPT>],[<cUser>],[<cServer>|
<nConId>]) → nLPT
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
nNewLPT Designates a new LPT device for cJob. Values from 1 to 3 (LPT1 to LPT3) are valid.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJLPT() returns the LPT device. A return value of -1 indicates an error.
Description
NOVELL NET PRINT JOB LPT A local parallel interface, referred to the definition, must be specified for each print job definition. The LPT device of a print job definition can be set or queried by calling NNETPJLPT(). Do not pass a value for cNewLPT to query the LPT device. A new LPT device can be set by designating a value for cNewLPT between 1 and 3 for LPT1 to LPT3. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the LPT device in the job definition MYJOB:
? NNETPJLPT('MYJOB')
■ Set the LPT device in the job definition MYJOB to 2:
? NNETPJLPT('MYJOB', 2)
NNETPJMODE([<cJob>],[<cNewMode>],[<cUser>],[<cServer>|
<nConId>]) → cMode
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
nNewMode Designates a new device mode for cJob. The device mode must have an entry in the printer definition file (NET$PRN.DAT) on cServer.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJMODE() returns the device mode in the job definition cJob.
Description
NOVELL NET PRINT JOB MODE A print job definition can contain the name of a device and a corresponding device mode. The device mode can be set or queried by calling NNETPJMODE(). Do not pass a value for cNewMode. A device mode can be set to query the device mode by specifying cNewMode. To reset a device mode (set to none), the parameter cNewMode must contain an empty string (""). If cUser is not the current user, access rights for the mail system of the user are required.
Notes
■ The device mode is validated only when it is set. If the
device has been modified with NNETPJDEV(), the returned device mode can be invalid.
Examples
■ Determine the device mode in the job definition MYJOB:
? NNETPJMODE('MYJOB')
■ Set the device mode in the job definition MYJOB to PLAIN:
? NNETPJMODE('MYJOB', 'PLAIN')
■ Reset the device name and the device mode in the job
definition MYJOB to NONE:
? NNETPJDEV('MYJOB', '')
? NNETPJMODE('MYJOB', '')
NNETPJNOTY([<cJob>],[<lNewMessage>],[<cUser>],
[<cServer>|<nConId>]) → lMessage
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
nNewMessage Designates a new notify mode that is set for cJob.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJNOTY() returns the notify mode in the job definition cJob. A return of .T. indicates that the user is notified after a job has been printed.
Description
NOVELL NET PRINT JOB NOTIFY Netware allows a user to receive a broadcast message after a job has been printed. This option can be specified within a job definition. NNETPJNOTY() allows you to set or query the option. Do not pass a value for cNewMessage to query the notify option. When cNewMessage is set to .T., the user is notified after a job has been printed. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the notify mode for the default job:
IF NNETPJNOTY()
? 'Notify mode activated'
ELSE
? 'Notify mode not active'
ENDIF
■ Activate the notify mode for default job:
? NNETPJNOTY(, .T.)
Sets or queries the target print server for a print job
Syntax
NNETPJPSRV([<cJob>],[<cNewServer>],[<cUser>],
[<cServer>|<nConId>]) → cPrintServer
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
nNewServer Designates a new print server name for cJob. The print server must be in the print server list of the currently defined queue.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJPSRV() returns the name of the print server in the job definition cJob.
Description
NOVELL NET PRINT JOB PRINT SERVER A print job definition can contain the name of a print server. This setting is not supported by the Novell capture services. However, you can use the information in conjunction with the CA-Clipper Tools functions for job manipulation to set a specified print server as the target for a print job (NNETJSRV()).
The print server name can be set or queried by calling NNETPJPSRV(). Do not pass a value for cNewServer to query the server name. A server name can be set by specifying cNewServer. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the print server name in the job definition MYJOB:
? NNETPJPSRV('MYJOB')
■ Set the print server name in the job definition MYJOB to
PSERVER:
? NNETPJPSRV('MYJOB', 'PSERVER')
■ Create the print job, and set the print server of the job
definition MYJOB as the target server:
NNETPJCAPF('MYJOB')
SET PRINTER ON
? 'Hello' // A new job is created
NNETJSRV('LINEPRINTER', NNETCAPJOB(1), NNETPJPSRV('MYJOB'))
? NNETCAPFLU(1)
NNETPJQ([<cJob>],[<cNewQueue>],[<cUser>],[<cServer>|
<nConId>]) → cQueue
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
nNewQueue Designates a new queue that is set for cJob. The queue must exist on the file server currently defined in cJob.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJQ() returns the name of the print queue in the job definition cJob.
Description
NOVELL NET PRINT JOB QUEUE A print job definition must contain the name of the print queue that is set as the target queue when the definition is activated. The queue name can be set or queried by calling NNETPJQ(). Do not pass a value for cNewQueue to query the queue name. A new queue can be set by specifying cNewQueue. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the queue in the job definition MYJOB:
? NNETPJPQ('MYJOB')
■ Set the queue in the job definition MYJOB to LINEPRINTER:
? NNETPJQ('MYJOB', 'LINEPRINTER')
Sets or queries the form feed mode after a print job
Syntax
NNETPJSUPF([<cJob>],[<lNewPage>],[<cUser>],[<cServer>|
<nConId>]) → lPageMode
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
lNewPage Designates a new form feed mode for cJob.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJSUPF() returns the form feed mode for cJob. A return of .F. indicates that a form feed is performed after a job has been printed.
Description
NOVELL NET SUPPRESS FORM FEED Netware automatically creates a form feed at the end of each print job. NNETPJSUPF() allows you to set a form feed or determine if a form feed is defined in the job definition. A form feed can be suppressed by designating lNewPage with .T.. Do not pass a value for lNewPage to query the current setting. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the form feed mode for the default job:
IF NNETPJSUPF()
? 'Form feed suppressed'
ELSE
? 'Form feed activated'
ENDIF
■ Deactivate the form feed for the default job:
? NNETPJSUPF(, .T.)
NNETPJTABS([<cJob>],[<nNewTab>],[<cUser>],[<cServer>|
<nConId>]) → nTab
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
nNewTabs Designates an optional parameter that contains the number of spaces to which the tabs are expanded. The value 0 designates that the tabs are not expanded.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJTABS() returns the number of spaces to which the tabs (Chr(9)) are expanded. The value 0 indicates that the tabs have not been expanded. If an error occurs, the function returns -1.
The return value has a meaning only if the text mode is set in cJob.
Description
NOVELL NET PRINT JOB TABS In text jobs, the print server is able to replace tabs (Chr(9)) with spaces. The number of spaces per tab can be queried or set with NNETPJTABS(). Do not pass a value for nNewTabs to query the number of spaces.
Examples
■ Determine the number of spaces that are set as a tab
replacement in the default job:
NNETPJTABS()
■ Set the number of spaces per tab to 4 in the default job:
? NNETPJTABS(, 4)
Sets or queries the text or binary mode for a print job
Syntax
NNETPJTXT([<cJob>],[<lNewText>],[<cUser>],[<cServer>|
<nConId>]) → lText
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
lNewMode Designates an optional parameter that indicates whether text (.T.) or binary (.F.) jobs are created after the definition cJob has been activated.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
The return value of NNETPJTXT() specifies the data type in the job definition cJob. A return value of .F. indicates binary data, and a return value of .T. indicates text data.
Description
NOVELL NET PRINT JOB TEXT The Queue Management System (QMS) differentiates between text and binary jobs. NNETJTXT() allows you to query or set the mode for a job definition cJob.
Examples
■ Determine the mode for the default job:
IF NNETPJTXT()
? 'Text mode'
ELSE
? 'Binary mode'
ENDIF
■ Set the text mode for the default job:
? NNETPJTXT(, .T.)
NNETPJUSR([<cJob>],[<cNewName>],[<cUser>],[<cServer>|
<nConId>]) → cName
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
cNewName Designates an optional parameter that allows you to set a new user name for cJob. The name can be up to 12 characters long.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NOVELL NET PRINT JOB USERNNETPJUSR() returns the user name for the banner page in the job definition file cJob.
Description
NOVELL NET PRINT JOB USER (NAME) The banner page of a job contains the user name of the job owner and the name of the printed file. NNETPJUSR() allows you to set or determine the user. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the user name for the banner page in the job
definition MYJOB:
? NNETPJUSR('MYJOB')
■ Set the user name for the banner page in the job definition
MYJOB to MICK:
? NNETPJBAN('MYJOB', 'MICK')
NNETPJWAIT([<cJob>],[<nNewTimeout>],[<cUser>],
[<cServer>|<nConId>]) → nTimeout
Netware: 2.2 and 3.11
Arguments
cJob Designates the selected print job definition. The default value designates the default job.
nNewTimeout Designates an optional parameter that allows you to set a timeout in seconds for cJob. A value of 0 indicates a timeout that does not end.
cUser Designates the name of the user whose print job definition is processed. The default value designates the current user.
cServer Designates the name of the file server on which the operation is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPJWAIT() returns the timeout in seconds. The value 0 indicates a timeout that does not end. If an error occurs, the function returns -1.
Description
NOVELL NET PRINT JOB WAIT The timeout in a job definition specifies after how many seconds without data output a job is automatically closed. NNETPJWAIT() allows you to set or query the timeout. Do not pass a value for nNewTimeout to query the number of seconds. If cUser is not the current user, access rights for the mail system of the user are required.
Examples
■ Determine the timeout in the job definition MYJOB:
? NNETPJWAIT('MYJOB')
■ Set the timeout in the job definition MYJOB to 20 seconds:
? NNETPJWAIT('MYJOB', 20)
NNETPMODES(<cDevice>,[<cServer>,<nConId>]) → aModes
Netware: 2.2 and 3.11
Arguments
cDevice Designates the name of the device for which the modes are determined.
cServer Designates the name of the file server for which the device definitions are used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPMODES() returns a one-dimensional array that contains the names of the modes defined for cDevice.
Description
NOVELL NET PRINT MODES Netware allows you to manage printer and form information in a database (NET$PRN.DAT). For each device you can define modes that contain functions for cDevice. NNETPMODES() returns a list of modes defined for cDevice.
Examples
Determine and display the modes for device HPLJ:
aModes = NNETPMODES('HPLJ')
FOR i = 1 TO Len(aModes)
? aModes[i]
NEXT[i]
NNETPMODFU(<cDevice>,<cModus>,[<cServer>,<nConId>])
→ aFuncs
Netware: 2.2 and 3.11
Arguments
cDevice Designates the name of the device that is processed.
cMode Designates the name of a mode established for cDevice.
cServer Designates the name of the file server for which the device definitions are used. Your workstation must be attached to cServer.
nConId Designates connection ID of your workstation on cServer.
Returns
NNETPMODFU() returns a one-dimensional array that contains the names of the functions for cMode of cDevice.
Description
NOVELL NET PRINT MODE FUNCTIONS Netware allows you to manage printer and form information in a database (NET$PRN.DAT). For each device you can define modes that contain a number of functions for cDevice. NNETPMODFU() returns a list of the functions for cMode .
Examples
Determine and display the functions of the plain mode for device HPLJ:
aFuncs = NNETPMODFU('HPLJ', 'PLAIN')
FOR i = 1 TO Len(aFuncs)
? aFuncs[i]
NEXT[i]
NNETPRPSEC(<cObjName>,<nObjType>,<cProp>,<nSafe>,
[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cObjName Designates the name of the object.
nObjType Designates a numeric value that specifies the object type. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use in conjunction with the bindery functions of CA-Clipper Tools.
cProp Designates the property for which the security is modified.
nSafe Designates the new value for the property security. This value specifies the rights required to find (read) or to modify (write) the property. The settings are defined with a bit-coded mask. The low- ordered bits control the read access to the bindery object; the high- ordered bits control the write access to the bindery object.
Table 18.5: Values for Property Security
Value Hex Bin Definition
0 0 0000 Access allowed to all users
1 1 0001 Access allowed to users who have logged in to the
file server
2 2 0010 Access allowed to users who have logged in to the
file server with password
3 3 0011 Access allowed to users who have logged in to the
file server as the supervisor or as a user who has
supervisor equivalence
4 4 0100 Access only allowed to the network operating system
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPRPSEC() returns .T. if the new security value (nSafe) has been set successfully.
Description
Important! NNETPRPSEC() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET PROPERTY SECURITYNNETPRPSEC() allows you to modify the security of existing properties. For efficiency reasons numeric values for nObjType must be passed in the high-low format. This function requires supervisor rights.
Examples
Set the security of the property IDENTIFICATION of the user object MICK
to 51 (hex 33):
IF NNETOBJPRP('MICK',OBJ_USER,'IDENTIFICATION',51)
? 'Security modified successfully!'
ELSE
? 'Error!'
ENDIF
NNETPSACC(<cPServer>,[<cServer>|<nConId>]) → nAccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSACC() returns the access rights to cPServer.
Table 27.1: Access Rights
Value Definition
-1 Error
0 Restricted access
1 Print server user
2 Print server operator
Description
NOVELL NET PRINT SERVER ACCESSNNETPSACC() allows you to determine the operations that the current user can execute on cPServer. While simple operations (like status query) can be done by any user, critical operations (like print server controlling and configuration) require operator rights.
Examples
Determine the access rights to print server PSERVER1:
? NNETPSACC('PSERVER1')
NNETPSADDQ(<cPServer>,<nPrinter>,<cQueue>,[<nPrior>],
[<cServer>|<nConId>) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cQueue Designates the name of the print queue that is added.
nPrior Designates the priority for cQueue. The highest priority is 1, which is also the default value.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSADDQ() returns .T. if cQueue has been added successfully to nPrinter. If an error occurs (for example, insufficient rights), the function returns .F..
Description
NOVELL NET PRINT SERVER ADD QUEUE (TO PRINTER) NNETPSADDQ() allows you to add a print queue to a print server printer (nPrinter). This function requires operator rights and access rights for cPServer and cQueue.
Examples
Add the print queue TOOLSQ_1 to print server printer 0 on print server
PSERVER:
IF NNETPSADDQ('PSERVER',0,'TOOLSQ_1')
? 'Queue TOOLSQ_1 has been added!'
ELSE
? 'Error!'
ENDIF
Aborts the print job that is currently being printed
Syntax
NNETPSAJOB(<cPServer>,<nPrinter>,[<nJobMode>],[<cServer>|
<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
nJobMode Designates the mode of the job that is aborted according to the following table:
Table 27.2: Job Modes
Value CTPS.CH Definition
1 PSJ_RET2Q Return job to queue
2 PSJ_THROWAWAY Discard job
The default value for nJobMode is 1. To return the job to the queue, you must set the service restart flag (see NNETJFLAGS()).
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSAJOB() returns .T. if the current job of nPrinter on cPServer has been aborted.
Description
NOVELL NET PRINT SERVER ABORT JOBNNETPSAJOB() allows you to abort a print job currently being printed. You can determine if the job is returned to the queue (nJobMode=1) or discarded (nJobMode=2).
Examples
Abort and discard the job of printer 0 on print server PSERVER:
#include "ctps.ch"
NNETPSAJOB('PSERVER',0,PS_THROWAWAY)
Defines an object that is notified for the print server printer
Syntax
NNETPSANO(<cPServer>,<nPrinter>,<cObjName>,[<nObjType>],
[<nFirst>],[<nNext>],[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cObjName Designates the name of the bindery object (for example, a user) that is defined as the object that is notified for nPrinter on cPServer.
nObjType Designates a numeric value that indicates the type of cObjName. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use with the bindery functions of CA-Clipper Tools. The default value designates the object type OBJ_USER.
nFirst Designates a time value in seconds that specifies the waiting period between when a problem occurs and the first message. The default value is 30 seconds.
nNext Designates a time value in seconds that specifies the length of the time interval between two messages. The default value is 60 seconds.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSANO() returns .T. if cObjName has been added as the object that is notified for nPrinter on cPServer. If an error occurs (for example, no operator rights), the function returns .F..
Description
NOVELL NET PRINT SERVER ADD NOTIFY OBJECTNNETPSANO() allows you to define objects (normally users) that are notified if printer problems occur (printer offline, no paper) for a print server printer. This function requires operator rights for cPServer. For efficiency reasons, numeric values for nObjType must be passed in the high-low format.
Examples
Add user MICK as the object that is notified for printer 0 on PSERVER:
IF NNETPSANO('PSERVER',0,'MICK')
? 'User MICK added successfully!'
ELSE
? 'Error!'
ENDIF
Determines the available remote printers of a print server
Syntax
NNETPSARP(<cPServer>,[<cServer>|<nConId>]) → aRemote
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSARP() returns an array with subarrays (two-dimensional array). Each subarray contains information about an available remote printer. For the structure of the subarrays, see the following table:
Table 27.3: NNETPSARP() Subarray Structure
Position Metasymbol CTPS.CH Definition
1 cName ARP_NAME Printer name
2 nNumber ARP_NUM Printer number (0..15)
3 nTyp ARP_TYPE printer type
If an error occurs, the function returns an empty array.
For the printer type, the following values are possible:
Table 27.4: Printer Types
Value CTPS.CH Definition
7 PSP_REMLPT1 Remote printer on LPT1:
8 PSP_REMLPT2 Remote printer on LPT2:
9 PSP_REMLPT3 Remote printer on LPT3:
10 PSP_REMCOM1 Remote printer on COM1:
11 PSP_REMCOM2 Remote printer on COM2:
12 PSP_REMCOM3 Remote printer on COM3:
13 PSP_REMCOM4 Remote printer on COM4:
Description
NOVELL NET AVAILABLE REMOTE PRINTERS Netware print servers can serve printers connected to a workstation (remote printers). NNETPSARP() allows you to determine which remote printers of a print server are available. The sample program RPRINTER.PRG demonstrates how to use NNETPSARP() for the emulation of a remote printer.
Examples
Display the list of available remote printers for print server PSERVER:
#include "ctnet.ch"
aRemote=NNETPSARP('PSERVER')
FOR i=1 TO Len(aRemote)
? aRemote[i,ARP_NAME],aRemote[i,ARP_TYPE]
NEXT i
NNETPSCAND(<cPServer>,[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSCAND() returns .T. if a running down request of cPServer has been canceled successfully.
Description
NOVELL NET PRINT SERVER CANCEL DOWN (REQUEST) If a print server receives a down request, it can continue to process active jobs. Within this time period, the down request can be canceled with NNETPSCAND(). This function requires operator rights for cPServer.
Examples
Cancel the down request for the print server PSERVER:
// Start down request
NNETPSDOWN('PSERVER')
IF .NOT. NNETPSCAND('PSERVER')
? 'Down request cannot be canceled!'
ENDIF
NNETPSCHGQ(<cPServer>,<nPrinter>,<cQueue>,[<nPrior>],
[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cQueue Designates the queue for which the priority is changed.
nPrior Designates the new priority for cQueue. The highest priority is 1, which is also the default value.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSCHGQ() returns .T. if the priority has been changed successfully.
Description
NOVELL NET PRINT SERVER CHANGE QUEUE (PRIORITY) Jobs within a queue are serviced by a print server according to the queue priorities. NNETPSCHGQ() allows you to change the priority of a queue (cQueue) for a print server (nPrinter). This function requires operator rights for cPServer.
Examples
Set the priority of QUEUE1 for printer 0 on PSERVER to 3 (low priority):
IF NNETPSCHGQ('PSERVER',0,'QUEUE1',3)
? 'Priority changed successfully!'
ELSE
? 'Error!'
ENDIF
Changes the settings for the object that is notified
Syntax
NNETPSCNO(<cPServer>,<nPrinter>,<cObjName>,[<nObjType>],
[<nFirst>],[<nNext>],[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cObjName Designates the name of the bindery object (for example, a user) that is defined as the object to notify for nPrinter on cPServer.
nObjType Designates a numeric value that indicates the type of cObjName. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use with the bindery functions of CA-Clipper Tools. The default value designates the object type OBJ_USER.
nFirst Designates a time value in seconds that specifies the waiting period between when a problem occurs and the first message. The default value designates no modification.
nNext Designates a time value in seconds that specifies the length of the interval between two messages. The default value designates no modification.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSCNO() returns .T. if the values for nFirst and nNext have been changed as requested. If an error occurs (for example, no operator rights), the function returns .F..
Description
NOVELL NET PRINT SERVER CHANGE NOTIFY (OBJECT) NNETPSCNO() allows you to change the waiting period for the first message after a problem has occurred (nFirst) and the time period between the following messages (nNext). This function requires operator rights for cPServer. For efficiency reasons, numeric values for nObjType must be passed in the high-low format.
Examples
Set the waiting period for the first message to 10 seconds, and set the
time interval between the following messages to 30 seconds:
IF NNETPSCNO('PSERVER',0,'MICK',,10,30)
? 'Values changed successfully!'
ELSE
? 'Error!'
ENDIF
NNETPSDELQ(<cPServer>,<cQueue>,[<lImmediate>],
[<nJobMode>],[<cServer>|<nConId>) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cQueue Designates the name of the print queue that is deleted from nPrinter.
lImmediate Designates if the operation is executed immediately (.T.) or if active jobs are completed (.F.). The default value is .F..
nJobMode Designates the mode of the job that will be active, according to the following table. This parameter is only taken into account if lImmediate is designated .T..
Table 27.5: Job Modes
Value CTPS.CH Definition
1 PSJ_RET2Q Return job to queue
2 PSJ_THROWAWAY Discard job
The default value for nJobMode is 1. To return the job to the queue, you must set its service restart flag (see NNETJFLAGS()).
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSDELQ() returns .T. if the queue has been deleted successfully.
Description
NOVELL NET PRINT SERVER DELETE QUEUE (FROM PRINTER) NNETPSDELQ() allows you to delete a queue from a print server printer (nPrinter). This function requires operator rights for cPServer.
Examples
Delete the print queue TOOLSQ_1 from print server printer 0 on print
server PSERVER:
IF NNETPSDELQ('PSERVER',0,'TOOLSQ_1')
? 'Queue TOOLSQ_1 deleted!'
ELSE
? 'Error!'
ENDIF
Deletes an object that is notified for a print server printer
Syntax
NNETPSDNO(<cPServer>,<NPrinter>,<cOBjName>,[<nObjType>],
[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cObjName Designates the name of the bindery object (for example, a user) that is deleted from the list of notified objects.
nObjType Designates a numeric value that indicates the type of cObjName. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use with the bindery functions of CA-Clipper Tools. The default value designates the object type OBJ_USER.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSDNO() returns .T. if cObjName has been deleted from the list of notified objects for nPrinter on cPServer. If an error occurs (for example, no operator rights), the function returns .F..
Description
NOVELL NET PRINT SERVER NOTIFY OBJECTNNETPSDNO() allows you to delete a notified object from the list of notified objects for nPrinter on cPServer. This function requires operator rights for cPServer. For efficiency reasons, numeric values for nObjType must be passed in the high-low format.
Examples
Delete user MICK from the list of notified objects for printer 0 on
PSERVER:
IF NNETPSDNO('PSERVER',0,'MICK')
? 'User MICK deleted successfully!'
ELSE
? 'Error!'
ENDIF
NNETPSDOWN(<cPServer>,[<lImmediate>],[<nJobMode>],
[<cServer>|<nConId>) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
lImmediate Designates if the operation is executed immediately (.T.) or if active jobs are completed (.F.). The default value is .F..
nJobMode Designates the mode of the job that will be active, according to the following table. This parameter is only taken into account if lImmediate is designated .T..
Table 27.6: Job Modes
Value CTPS.CH Definition
1 PSJ_RET2Q Return job to queue
2 PSJ_THROWAWAY Discard job
The default value for nJobMode is 1. To return the job to the queue, you must set its service restart flag (see NNETJFLAGS()).
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETDOWN() returns .T. if the operation has been executed successfully.
Description
NOVELL NET PRINT SERVER DOWNNNETDOWN() allows you to initialize a down request for cPServer. With lImmediate you can specify if the down request is executed immediately (.T.) or if active jobs are completed first (.F.). During this time period the down request can be canceled with NNETPSCAND(). This function requires operator rights for cPServer.
Notes
■ A print server shut down with NNETDOWN() cannot be rebooted
from an application!
Examples
Start the controlled shut down of PSERVER:
? NNETPSDOWN('PSERVER')
Determines the error code of the most recent print server call
Syntax
NNETPSERR() → nErrorCode
Netware: 2.2 and 3.11
Returns
NNETPSERR() returns the error code of the most recent print server function call by a CA-Clipper Tools function (NNETPSXXX() functions). There is an error code table in Appendix F.
Description
NOVELL NET PRINT SERVER ERROR CA-Clipper Tools functions for print server control (NNETPSXXX()) do not use Netware API calls, but communicate directly with the print server. Therefore, the error code of the print server functions cannot be queried with the NetError() function. NNETPSERR() allows you to determine the error code of the most recent print server call. If a print server call has been executed successfully, the function returns 0.
Examples
Delete QUEUE1 from printer 0 on PSERVER. If the call is unsuccessful,
determine the reason:
IF .NOT. NNETPSDELQ('PSERVER',0,'QUEUE1')
IF NNETPSERR()=782
? 'Insufficient rights...'
ENDIF
ENDIF
Initializes a form feed on the print server printer
Syntax
NNETPSFF(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSFF() returns .T. if the function has been executed successfully.
Description
NOVELL NET PRINT SERVER FORM FEED NNETPSFF() allows you to initialize a form feed even if no job is currently being serviced by nPrinter. This function requires operator rights cPServer.
Examples
Initialize the form feed on printer 0 on PSERVER:
NNETPSFF('PSERVER',0)
Determines the number of bytes already printed for an active job
Syntax
NNETPSJBYT(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ nBytes
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSJBYT() returns the number of bytes already printed within the current copy. If an error occurs, the function returns -1.
Description
NOVELL NET PRINT SERVER JOB BYTESNNETPSJBYT() allows you to determine the processing state of the current job for nPrinter on cPServer.
Examples
Determine the number of bytes printed for the current job of printer 0
on PSERVER:
IF (nBytes:=NNETPSJBYT('PSERVER',0))>=0
? nBytes,' bytes printed.'
ELSE
? 'No job active or other error!'
ENDIF
NNETPSJDSC(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ cDescription
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSJDSC() returns the job description of the active job of nPrinter. If an error occurs (for example, no job active), the function returns an empty string.
Description
NOVELL NET PRINT SERVER JOB DESCRIPTIONNNETPSJDSC() allows you to determine the description of the active job of nPrinter on cPServer. The job is already active, so the description cannot be modified.
Examples
Determine the description of the active job of printer 0 on PSERVER:
? NNETPSJDSC('PSERVER',0))
NNETPSJFRM(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ nForm
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSJFRM() returns the number of the form used for the active job of nPrinter. If an error occurs (for example, no job active), the function returns -1.
Description
NOVELL NET PRINT SERVER JOB FORM The job is already active, so the form number cannot be modified.
Examples
Determine the form number of the active job of printer 0 on PSERVER:
IF (nForm:=NNETPSJFRM('PSERVER',0))>=0
? 'Form:',nForm
ELSE
? 'No job active or other error!'
ENDIF
NNETPSJDSC(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ cFileServer
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can therefore depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSJFS() returns the file server of the active job of nPrinter. If an error occurs (for example, no active job), the function returns an empty string.
Description
NOVELL NET PRINT SERVER JOB FILE SERVERNNETPSJFS() allows you to determine the file server for the active job of nPrinter on cPServer.
Examples
Determine the file server for the active job of printer 0 on PSERVER:
? NNETPSJFS('PSERVER',0))
NNETPSJNO(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ nJob
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSJNO() returns the job number of the active job of nPrinter. If an error occurs (for example, no active job), the function returns -1.
Description
NOVELL NET PRINT SERVER JOB NUMBER Internally, Netware uses job numbers to manage jobs within a queue. The job number of an active job of nPrinter can be determined with NNETPSJNO(). The job number and queue name can be used to determine additional job information using the NNETJXXX() functions.
Examples
■ Determine the job number of the active job of printer 0 on
PSERVER:
IF (nJob:=NNETPSJNO('PSERVER',0))>=0
? 'Job number:',nJob
ELSE
? 'No job active or other error!'
ENDIF
■ Determine the owner of the active job:
nJob=NNETPSJNO('PSERVER',0)
cQueue=NNETPSJQ('PSERVER',0)
? 'Owner: ',NNETJOWNER(cQueue,nJob)
Determines the number of copies printed for the active job
Syntax
NNETPSJPCO(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ nCopies
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSJPCO() returns the number of copies of the active job that have already printed on nPrinter. If an error occurs (for example, no active job), the function returns -1.
Description
NOVELL NET PRINT SERVER JOB PRINTED COPIESNNETPSJPCO() allows you to determine the processing state of the active job of nPrinter on cPServer.
Examples
Determine the number of printed copies for the active job of printer 0
on PSERVER:
IF (nCopies:=NNETPSJPCO('PSERVER',0))>=0
? nCopies,' copies printed.'
ELSE
? 'No job active or other error!'
ENDIF
NNETPSJQ(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ cQueue
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSJQ() returns the queue of the active job of nPrinter. If an error occurs (for example, no active job), the function returns an empty string.
Description
NOVELL NET PRINT SERVER JOB QUEUENNETPSJQ() allows you to determine the print queue of the active job of nPrinter on cPServer.
Examples
Determine the queue of the active job of printer 0 on PSERVER:
? NNETPSJQ('PSERVER',0))
NNETPSJSIZ(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ nBytes
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSJSIZ() returns the size of the active job of nPrinter on cPServer in bytes. If an error occurs (for example, no active job), the function returns -1.
Description
NOVELL NET PRINT SERVER JOB SIZENNETPSJSIZ() allows you to determine the size of an active job. In conjunction with NNETPSJBYT(), a relative value of characters already printed or characters to be printed can be calculated.
Examples
Determine the size of the active job of printer 0 on PSERVER:
IF (nBytes:=NNETPSJSIZ('PSERVER',0))>=0
? nBytes,' bytes.'
ELSE
? 'No job active or other error!'
ENDIF
Determines the total number of copies for an active job
Syntax
NNETPSJTCO(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ nCopies
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can therefore depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSJTCO() returns the total number of copies of the active job that are printed on nPrinter. If an error occurs (for example, no active job), the function returns -1.
Description
NOVELL NET PRINT SERVER JOB TOTAL COPIESNNETPSJTCO() allows you to determine the total number of copies for an active job. In conjunction with NNETPSJPCO(), a relative value of copies already printed or copies to be printed can be calculated.
Examples
Determine the total number of copies of the active job of printer 0 on
PSERVER:
IF (nCopies:=NNETPSJTCO('PSERVER',0))>=0
? nCopies,' copies.'
ELSE
? 'No job active or other error!'
ENDIF
NNETPSJTXT(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ lText
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSJTXT() returns .T. if the active job of nPrinter on cPServer is a text job. A return of .F. indicates a binary job.
Description
NOVELL NET PRINT SERVER JOB TEXTNNETPSJTXT() allows you to determine whether the active job of nPrinter on cPServer is a text or binary job.
Examples
Determine the job type of the active job of printer 0 on PSERVER:
IF NNETPSJTXT('PSERVER',0)
? 'Text job!'
ELSEIF NNETPSERR()=0
? 'Binary job!'
ELSE
? 'Error!'
ENDIF
NNETPSLIN(<cPServer>,<cPassword>,<cServer1>,[<cServer2>|
<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is logged in on cServer1.
cPassword Designates the password defined for cPServer on cServer1.
cServer1 Designates the file server on which cPServer is logged in.
cServer2 Designates the name of the file server used to access cPServer. The print server checks login information on cServer2. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer2.
nConId Designates the connection ID of your workstation on cServer2.
Returns
NNETPSLIN() returns .T. if the function has been executed successfully.
Description
NOVELL NET PRINT SERVER LOGIN To service a queue on a file server, a print server must be logged in on the file server. NNETPSLIN() allows you to log in a print server on a file server (cServer1) after it has been started. For a print server login, a password can be queried and then passed for cPassword. An empty string ("") for cPassword must be passed if no password has been specified for cPServer on cServer1.
Examples
Log in the print server PSERVER on file server TOOLS1 (with password
SECRET):
IF NNETPSLIN('PSERVER','SECRET','TOOLS1')
? 'Log in successful!'
ELSE
? 'Error!'
ENDIF
NNETPSLOUT(<cPServer>,<cServer1>,[<lImmediate>]
[<lJobMode>],[<cServer2>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is logged out from cServer1.
cServer1 Designates the file server from which cPServer is logged out.
lImmediate Designates if the operation is executed immediately (.T.) or if active jobs are completed (.F.). The default value is .F..
nJobMode Designates the mode of the job that will be active, according to the following table. This parameter is only taken into account if lImmediate is designated .T..
Table 27.7: Job Modes
Value CTPS.CH Definition
1 PSJ_RET2Q Return job to queue
2 PSJ_THROWAWAY Discard job
The default value for nJobMode is 1. To return the job to the queue, you must set its service restart flag (see NNETJFLAGS()).
cServer2 Designates the name of the file server used to access cPServer. The print server checks login information on cServer2. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer2.
nConId Designates the connection ID of your workstation on cServer2.
Returns
NNETPSLOUT() returns .T. if the function has been executed successfully.
Description
NOVELL NET PRINT SERVER LOGOUTNNETPSLOUT() performs a logout of cPServer from cServer1. After a successful logout, print queues on cServer1 are no longer serviced by cPServer. NNETPSLOUT() requires operator rights on cPServer.
Examples
Log out the print server PSERVER from file server TOOLS1 (make sure that
the active jobs are completed):
IF NNETPSLIN('PSERVER','TOOLS1')
? 'Logout successful!'
ELSE
? 'Error!'
ENDIF
Marks the top of the page on the print server printer
Syntax
NNETPSMTOF(<cPServer>,<nPrinter>,<cChar>|<nChar>
[<cServer>|<nConId>) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cChar Designates the character used to mark the top of page.
nChar Designates the ASCII code of cChar.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSMTOF() returns .T. if the function has been executed successfully.
Description
NOVELL NET PRINT SERVER MARK TOP OF FORMNNETPSMTOF() allows you to mark the top of the page if no job is currently being processed by nPrinter. The character to mark the top of the page can be passed as a character string (cChar) or a character code (nChar). On the print server, one line that contains the passed character is printed. NNETPSMTOF() requires operator rights on cPServer.
Examples
Mark the top of page on printer 0 of PSERVER with one line containing
"=" characters:
NNETPSMTOF('PSERVER',0,"=")
NNETPSNMOD(<cPServer>,[<cServer>|<nConId>]) → nModes
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSNMOD() returns the number of queue service modes supported by cPServer. If an error occurs, the function returns -1.
Description
NOVELL NET PRINT SERVER NUMBER OF MODESNNETPSNMOD() allows you to determine the number of queue service modes supported by cPServer. The four standard modes are: change forms as requested, minimize form changes within a queue, avoid form changes, and minimize form change between queues.
Examples
Determine the number of queue service modes for print server PSERVER:
? NNETPSNMOD('PSERVER')
Determines the list of notified objects for the print server printer
Syntax
NNETPSNOTL(<cPServer>,<nPrinter>,[<cServer>|<nConId>)
→ aNoti
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSNOTL() returns an array with subarrays (two-dimensional array). Each subarray contains information about a file entry found. For the structure of the subarrays, see the following table:
Table 27.8: NNETPSNOTL() Subarray Structure
Position Metasymbol CTPS.CH Definition
1 cServer NL_SERVER File server
2 nObjName NL_NAME Object name
3 nType NL_TYPE Object type
4 nFirst NL_FIRST Time to the first message
5 nNext NL_NEXT Time between messages
If an error occurs, the function returns an empty array.
Description
NOVELL NET PRINT SERVER NOTIFY LIST For each print server printer, objects (normally users) that are notified if printer problems occur (printer offline, no paper) can be defined. NNETPSNOTL() allows you to determine a list of the objects defined for nPrinter.
Examples
Determine the notified objects for printer 0 on print server PSERVER,
and display the file server and the names of the objects found:
#include "ctnet.ch"
aObjs=NNETPSNOTL('PSERVER',0)
FOR i=1 TO Len(aObjs)
? aObjs[i,NL_SERVER],aObjs[i,NL_NAME]
NEXT i
NNETPSNPRN(<cPServer>,[<cServer>|<nConId>]) → nPrinter
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSNPRN() returns the number of printers defined for cPServer. If an error occurs, the function returns -1.
Description
NOVELL NET PRINT SERVER NUMBER OF PRINTERSNNETPSNPRN() returns the number of printers defined for cPServer. The value returned includes printers that are directly connected and remote.
Examples
Determine the number of printers on print server PSERVER:
? NNETPSNMOD('PSERVER')
Sets or determines the form for the print server printer
Syntax
NNETPSPFRM(<cPServer>,<nPrinter>,[<nNewForm>],[<cServer>|
<nConId>]) → nForm
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
nNewForm Designates an optional parameter that must be passed to set a new form.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSPFRM() returns the form number of nPrinter on cPServer. If an error occurs, the function returns -1.
Description
NOVELL NET PRINT SERVER PRINTER FORMNNETPSPFRM() allows you to set or determine the current form of nPrinter on cPServer. The form number can be queried by users and operators; however, operator rights are required to set a new form number on cPServer.
Examples
■ Determine the current form number of printer 0 on print server
PSERVER:
IF (nForm:=NNETPSPFRM('PSERVER',0))>=0
? 'Form:',nForm
ELSE
? 'Error!'
ENDIF
■ Set the form number for printer 0 on print server PSERVER to
1:
IF NNETPSPFRM('PSERVER',0,1)>=0
? 'Form number set successfully!'
ELSE
? 'Error!'
ENDIF
Checks to see if the print server printer is processing a job
Syntax
NNETPSPJOB(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ lJob
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSPJOB() returns .T. if nPrinter on cPServer is currently processing a job.
Description
NOVELL NET PRINT SERVER PRINTER (HAS) JOB ? NNETPSPJOB() checks to see if a print server printer is currently processing a job. This allows you to determine whether or not the printer is directly available.
Examples
Determine if printer 0 on print server printer PSERVER is currently
processing a job:
IF NNETPSPJOB('PSERVER',0)
? 'Printer is busy!'
ELSEIF NNETPSERR()=0
? 'Printer available!'
ELSE
? 'Error!'
ENDIF
NNETPSPMOD(<cPServer>,<nPrinter>,<nMode>,[<cServer>|
<nConId>]) → nMode
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
nMode Designates an optional parameter that must be passed to set a new queue service mode for nPrinter. For possible queue service modes see the description.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSPMOD() returns the queue service mode of nPrinter on cPServer. For possible service modes see the description. If an error occurs, the function returns -1.
Description
NOVELL NET PRINT SERVER PRINTER MODE For print server printers, various service modes regarding the form change are possible. The following table shows the four standard queue service modes:
Table 27.9: Queue Service Modes
Value CTPS.CH Definition
1 QSM_NEED Change forms as requested
2 QSM_MINQ Minimize form change within a queue
4 QSM_NEVER Avoid form change
8 QSM_MINACROSS Minimize form change between queues
Examples
■ Determine the current queue service mode of printer 0 on print
server PSERVER:
IF (nMode:=NNETPSPMOD('PSERVER',0))>=0
? 'Queue service mode:',nMode
ELSE
? 'Error!'
ENDIF
■ Set the queue service mode for printer 0 on print server
PSERVER to QSM_MINQ:
#include "ctnet.ch"
IF NNETPSPMOD('PSERVER',0,QSM_MINQ)>=0
? 'Queue service mode set successfully!'
ELSE
? 'Error!'
ENDIF
NNETPSPNAM(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ cName
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can therefore depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSPNAM() returns the name of nPrinter on cPServer. If an error occurs, the function returns an empty string.
Description
NOVELL NET PRINT SERVER PRINTER NAME In a print server, configuration names can be assigned to print server printers. NNETPSPNAM() allows you to determine the name for a print server printer (nPrinter).
Examples
Determine the name of printer 0 on print server PSERVER:
? NNETPSPNAM('PSERVER',0)
Determines the cause of an error for print server printer
Syntax
NNETPSPROB(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ nProblem
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSPROB() returns a numeric value that specifies the cause of an error on nPrinter on cPServer.
Table 27.10: Return Values of NNETPSPROB()
Value CTPS.CH Definition
-1 Call error
0 PPROB_NONE No problem
1 PPROB_OFFLINE Printer is offline
2 PPROB_NOPAPER Paper out
Description
NOVELL NET PRINT SERVER PRINTER PROBLEM With the aid of NNETPSPROB() applications can check to see if nPrinter on cPServer is ready. For example, this allows you to display an error message before a print job is started.
Examples
Determine the cause of an error for printer 0 on print server PSERVER:
#include "ctps.ch"
nProb=NNETPSPROB('PSERVER',0)
DO CASE
CASE nProb=PPROB_NONE
? 'Ready!'
CASE nProb=PPORB_OFFLINE
? 'Printer offline!'
CASE nProb=PPROB_NOPAPER
? 'No paper!'
OTHERWISE
? 'Error!'
ENDCASE
Determines the list of printers that service a queue
Syntax
NNETPSPSQ(<cPServer>,<cQueue>,[<cServer1>],[<cServer2>|
<nConId>]) → cPrinter
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
cQueue Designates a print queue.
cServer1 Designates the file server of cQueue. The default value designates the default server.
cServer2 Designates the name of the file server used to access cPServer. The print server checks login information on cServer2. Therefore, the access rights can therefore depend on the specified file server. Your workstation must be attached to cServer2.
nConId Designates the connection ID of your workstation on cServer2.
Returns
NNETPSPSQ() returns a character string. Each character (byte) indicates the number of a print server printer.
Description
NOVELL NET PRINT SERVER PRINTERS SERVICING QUEUENNETPSPSQ() determines the numbers of all the printers on cPServer that service cQueue on cServer1. The list of printers is returned as a character string in which each character specifies a printer number.
Examples
Display a list that contains the printer number and printer name of all
the printers on PSERVER that service QUEUE1 on the default server:
cPrinters=NNETPSPSQ('PSERVER','QUEUE1')
FOR i=1 TO Len(cPrinters)
nNum:=Asc(SubStr(cPrinters,i,1)
? nNum,NNETPSPNAM('PSERVER',nNum)
NEXT i
NNETPSPSTA(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ nStatus
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can therefore depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSPSTA() returns a numeric value that specifies the current status of nPrinter on cPServer.
Table 27.11: Return Values of NNETPSPPSTA()
Value CTPS.CH Definition
-1 Call error
0 PST_WAIT_JOB Printer waiting for job
1 PST_WAIT_FORM Printer waiting for form
2 PST_PRINT Printer is processing job
3 PST_PAUSED Printer on hold
4 PST_STOPPED Printer stopped
5 PST_MARK Printer marking top of form
6 PST_GO_DOWN Printer ready for deinitialization
7 PST_NOT_CON Remote printer not connected
8 PST_PRIVATE Remote printer in private mode
Description
NOVELL NET PRINT SERVER PRINTER STATUS With the aid of NNETPSPSTA(), applications can determine the status of nPrinter on cPServer.
Examples
Determine the status of printer 0 on print server PSERVER:
#include "ctps.ch"
nStat=NNETPSPSTA('PSERVER',0)
DO CASE
CASE nStat=PST_WAIT_JOB
? 'Printer waiting for job!'
CASE nStat=PST_WAIT_FORM
? 'Printer waiting for form!'
CASE nStat=PST_PRINT
? 'Printer is processing job!'
CASE nStat=PST_PAUSED
? 'Printer on hold!'
CASE nStat=PST_STOPPED
? 'Printer stopped!'
CASE nStat=PST_MARK
? 'Printer is marking top of form!'
CASE nStat=PST_GO_DOWN
? 'Printer ready for deinitialization!'
CASE nStat=PST_NOT_CON
? 'Remote printer not connected!'
CASE nStat=PST_PRIVATE
? 'Remote printer in private mode!'
OTHERWISE
? 'Error!'
ENDCASE
Determines the queues that are serviced by a print server printer
Syntax
NNETPSQL(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ aQueues
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can therefore depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSQL() returns an array with subarrays (two-dimensional array). Each subarray contains information about a serviced queue. For the structure of the subarrays, see the following table:
Table 27.12: NNETPSQL() Subarray Structure
Position Metasymbol CTPS.CH Definition
1 cServer QL_SERVER File server
2 cQName QL_NAME Queue name
3 nPrior QL_PRIOR Queue priority
If an error occurs, the function returns an empty array.
Description
NOVELL NET PRINT SERVER QUEUE LISTNNETPSQL() returns a list of all print queues that are serviced by nPrinter on cPServer. The array also contains the name of queue's file server because a print server can access several file servers.
Examples
Determine the print queues for printer 0 on print server PSERVER, and
display the queue's file server and name:
#include "ctnet.ch"
aQs=NNETPSQL('PSERVER',0)
FOR i=1 TO Len(aQs)
? aQs[i,QL_SERVER],aQs[i,QL_NAME]
NEXT i
Requests a remote printerÆs configuration information
Syntax
NNETPSRRP(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ aInfo
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSQL() returns a one-dimensional array that contains configuration information about the passed printer. The elements of the array are defined in the table that follows.
Table 27.13: NNETPSRRP() Array Structure
Position Metasymbol CTPS.CH Definition
1 nType RRP_TYPE Printer type
2 lInt RRP_INT Use interrupts
3 nIRQ RRP_IRQ IRQ number
4 nBuf RRP_BUF Rec. number of 512 byte buffers
5 lXon RRP_XON Use Xon/XOff protocol
6 nBaud RRP_BAUD Baud rate
7 nData RRP_DATA Data bits
8 nStop RRP_STOP Stop bits
9 nParity RRP_PARITY Parity
10 nSocket RRP_SOCKET Socket number for communication
with print server
For a list of possible remote printers, see the function NNETPSARP(). The elements RRP_XON, RRP_BAUD, RRP_DATA, RRP_STOP, and RRP_PARITY are useful only if the remote printer is configured as serial printer. The baud rate, stop bits, and parity are coded as numeric values: 0=300 baud, 1=600 baud, 2=1200 baud, 3=2400 baud, 4=4800 baud, 5=9600 baud; 0=0 stop bits, 1=1,5 stop bits, 2=1 stop bit; parity: 0=no, 1=even, 2=odd.
If an error occurs, the function returns an empty array.
Description
NOVELL NET PRINT SERVER REQUEST REMOTE PRINTER Netware print servers are able to service printers that are connected to a workstation (remote printers). NNETPSRRP() allows you to request a remote printer from a print server to emulate a remote printer from within a CA-Clipper application (see the sample program RPRINTER.PRG).
For the emulation of a remote printer, the most important information within the return value is the socket number (RRP_SOCKET). For the following setup of an SPX session, this socket number must be passed as target socket.
Examples
You can find a detailed example for the description of NNETPSRRP() on
the CA-Clipper Tools disks under RPRINTER.PRG.
NNETPSSRM(<cPServer>,<nPrinter>,<lMode>,[<cServer>|
<nConId>) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
lMode Designates the remote mode for nPrinter on cPServer. If lMode is designated .F., the function selects the shared mode. If lMode is designated .T., the function selects the private mode.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSSRM() returns .T. if the function has been executed successfully.
Description
NOVELL NET PRINT SERVER REMOTE MODE Netware print servers are able to service printers that are connected to a workstation (remote printers). A remote printer can operate in the shared or the private mode. The default mode is the shared mode. In the shared mode, the remote printer operates like a network printer that is directly connected to the print server. In the private mode, the remote printer is used locally and cannot be used by the print server. NNETPSRM() allows you to select the mode of a remote printer.
Examples
Set printer 8 on print server PSERVER to the private mode:
IF NNETPSRM('PSERVER',8,.T.)
? 'Printer 8 set to private mode!'
ELSE
? 'Error!'
ENDIF
NNETPSSRVL(<cPServer>,[<cServer>|<nConId>]) → cServer
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSSRVL() returns a one-dimensional array. The elements contain the names of the file servers on which cPServer is currently logged in.
Description
NOVELL NET PRINT SERVER SERVER LISTNNETPSSRVL() allows you to determine all file servers on which cPServer is currently logged in. cPServer must be logged in on a file server to access print queues on the file server.
Examples
Display a list of all the file servers on which PSERVER is logged in:
aSrv=NNETPSSRVL('PSERVER')
FOR i=1 TO Len(aSrv)
? aSrv[i]
NEXT i
NNETPSSTAT(<cPServer>,[<cServer>|<nConId>]) → nStatus
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSSTAT() returns the status of cPServer:
Table 27.14: Return Values of NNETPSSTAT()
Value CTPS.CH Definition
-1 Call error
0 PSTAT_RUNNING Normal operation mode
1 PSTAT_GO_DOWN Deinitialization phase
2 PSTAT_DOWN Deinitialized
Description
NOVELL NET PRINT SERVER STATUSNNETPSSTAT() allows you to determine if cPServer is running in the normal operation mode or if its availability is going to end.
Examples
Determine and display the status of print server PSERVER:
#include "ctps.ch"
nStatus=NNETPSSTAT('PSERVER')
DO CASE
CASE nStatus=PSTAT_RUNNING
? 'Normal operation mode!'
CASE nStatus=PSTAT_GO_DOWN
? 'Deinitialization phase!'
CASE nStatus=PSTAT_DOWN
? 'Deinitialized!'
OTHERWISE
? 'Error!'
ENDCASE
NNETPSTART(<cPServer>,<nPrinter>,[<cServer>|<nConId>])
→ lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSTART() returns .T. if the function has been executed successfully.
Description
NOVELL NET PRINT SERVER (PRINTER) STARTNNETPSTART() can reactivate nPrinter on cPServer if nPrinter has been stopped by the Novell utility PCONSOLE or by NNETPSTOP(). This function requires operator rights for cPServer.
Examples
Stop and reactivate printer 0 on print server PSERVER:
lSuccess=.T.
lSuccess=lSuccess .AND. NNETPSTOP('PSERVER',0)
lSuccess=lSuccess .AND. NNETPSTART('PSERVER',0)
IF lSuccess
? 'Printer stopped and reactivated!'
ELSE
? 'Error!'
ENDIF
NNETPSTART(<cPServer>,<nPrinter>,[<nMode>],[<cServer>|
<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
nPrinter Designates the number of the printer on cPServer. Values between 0 and 15 are possible.
nMode Designates the currently active job mode.
Table 27.15: Job Modes
Value CTPS.CH Definition
0 PSJ_HOLD Stop job
1 PSJ_RET2Q Return job to queue
2 PSJ_THROWAWAY Discard job
The default value for nMode is 0, the stop job mode.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSTOP returns .T. if the function has been completed successfully.
Description
NOVELL NET PRINT SERVER (PRINTER) STOPNNETPSTOP() allows you to stop nPrinter on cPServer. In this state no additional print server outputs are processed on nPrinter. By passing a value for nMode, you can specify what happens to a job that is currently being processed. NNETPSTOP() requires operator rights for cPServer.
Examples
Stop printer 0 on print server PSERVER:
IF NNETPSTOP('PSERVER',0)
? 'Printer 0 stopped!'
ELSE
? 'Error'
ENDIF
NNETPSTYPE(<cPServer>,[<cServer>|<nConId>]) → nType
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSTYPE() returns the type of cPServer:
Table 27.16: Return Values of NNETPSTYPE()
Value CTPS.CH Definition
-1 Call error
1 PSTYP_DOS Dedicated DOS print server
2 PSTYP_NLM Netware loadable module
3 PSTYP_FSVAP VAP on file server
4 PSTYP_BRGVAP VAP on bridge
Description
NOVELL NET PRINT SERVER TYPE Netware print servers are available for various platforms. A print server can operate on a dedicated DOS station as an NLM on a Netware 3.x file server, as a VAP on a Netware 2.x file server, or as a VAP on a bridge. NNETPSTYPE() allows you to determine the type of cPServer.
Examples
Determine and display the type of print server PSERVER:
#include "ctps.ch"
nType=NNETPSTYPE('PSERVER')
DO CASE
CASE nType=PSTYP_DOS
? 'Dedicated DOS'
CASE nType=PSTYP_NLM
? 'Netware loadable module'
CASE nType=PSTYP_FSVAP
? 'File server VAP'
CASE nType=PSTYP_BRGVAP
? 'Bridge VAP'
OTHERWISE
? 'Error!'
ENDCASE
NNETPSVER(<cPServer>,[<cServer>|<nConId>]) → cVersion
Netware: 2.2 and 3.11
Arguments
cPServer Designates the name of the print server that is accessed.
cServer Designates the name of the file server used to access cPServer. The print server checks login information on cServer. Therefore, the access rights can depend on the specified file server. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPSVER() returns a character strings that contains the version of the print server in the form "Main_version.Sub_version.Revision_number". If an error occurs, the function returns an empty string.
Description
NOVELL NET PRINT SERVER VERSIONNNETPSVER() allows you to determine the version of a print server.
Examples
Determine the version of print server PSERVER:
? NNETPSVER('PSERVER') // For example "1.2.1"
Removes the files that are marked for deletion from the server
Syntax
NNETPURGE(<cFile>,[<lAll>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cFile Designates the file that is deleted, but depends on the Netware version that is used.
Under Netware 3.x, cFile designates the file that is deleted. The file name can contain a path, but the path must be unique. Wildcard characters are not allowed.
Under Netware 2.x, the operating system permits a definite purging of files only for the entire file server. If NNETPURGE() determines that the server is running under Netware 2.x after a server change is implied by cFile, the file specification in cFile is no longer taken into account. All the files on the related server that are marked for deletion are purged.
lAll Designates the files that are deleted. lAll is only taken into account if the function is called on a Netware 2.x server. If the parameter is designated .F., all the marked files of the current user are deleted. If the parameter is designated .T., all the files of the related file server that are marked for deletion are deleted. The default value is .F..
Returns
NNETPURGE() returns .T. if the function has been completed successfully.
Description
NOVELL NET PURGENNETPURGE() allows you to physically delete all the files that are marked for deletion on a server disk. (These files can no longer be restored with the Novell utility SALVAGE). The function is supported differently by Netware 2.x and 3.x. Under Netware 3.x, files can be purged individually. Under Netware 2.x, all the files of the current user (lAll=.F.) or all the files that are marked for deletion (lAll=.T.) are removed. Console operator rights are required to purge all the files that are marked for deletion. You should query the Netware version with NNETVER() before calling NNETPURGE() to avoid a purging of all files marked for deletion.
Notes
■ For compatibility reasons the previous version of the
NNETPURGE() function is still supported (NNETPURGE() → lSuccessful). A call in this form is only valid for Netware 2.x servers. With console operator rights, NNETPURGE() purges of all of the files that are marked for deletion.
Examples
■ Delete and purge the file CONFID.DBF:
NNETMAP('L','FSERVER386/SYS:DATA')
ERASE L:CONFID.DBF
IF NNETVER('FSERVER386') > '2'
NNETPURGE('L:CONFID.DBF')
ENDIF
■ Purge all the files that are marked for deletion for the
current user on FSERVER286 (2.x server):
NNETPURGE('FSERVER286/SYS:')
The definition of the volume SYS: is necessary to identify FSERVER286
as server name. If FSERVER286 contains more volumes, all the volumes
are purged.
NNETPWGRCE(<cUser>,[<nNumber>],[<lMode>],[<cServer>|
<nConId>) → nNumber
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of the user whose number of grace logins is set or determined.
nNumber Designates the new number of grace logins for cUser. The number of remaining grace logins or the maximum number of grace logins is set depending on the parameter lMode.
lMode Designates if the number of remaining grace logins (.F.) or the maximum number of grace logins (.T.) is set. The default value is .F..
cServer Designates the name of the file server to which cUser has access. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPWGRCE() returns the currently valid number of grace logins for cUser. Dependent on the parameter lMode, the return value contains the number of remaining grace logins (lMode=.F.) or the maximum number of grace logins (lMode=.T.). If a value has been passed for nNumber and the return value does not match nNumber, the requesting user did not have the rights for the modification.
Description
NOVELL NET PASSWORD GRACE LOGINSNNETPWGRCE() indicates the number times a user can log in with an expired password. With each login under an expired password, Netware reduces the number of remaining logins by 1. However, the maximum number of grace logins remains unchanged.
NNETPWGRCE() allows you to set or determine the number of remaining grace logins or the maximum number of grace logins for cUser. If the parameter lMode is not passed or is passed with .F., NNETPWGRCE() returns the number of remaining grace logins. If the lMode paramter is passed with .T., the maximum number of grace logins can be set or determined. To query the number of grace logins, do not pass a value for nNumber. If nNumber contains a numeric value, NNETPWGRCE() tries to set this value as new number of grace logins. Supervisor rights on the related file server are required to modify the number of grace logins. With the parameters cServer or nConId, the number of grace logins for users on any attached file server can be changed. The connection ID of a file server is returned by NNETATTACH() or NNETLOGIN().
Examples
■ Determine the number of remaining grace logins for user MIKE:
? NNETPWGRCE('MIKE') // For example 4
■ Determine the maximum number of grace logins for user MIKE:
? NNETPWGRCE('MIKE',,.T.) // For example 6
■ Set the new maximum number of grace logins for user MIKE:
NNETPWLEN('MIKE',8,.T.)
NNETPWLEN(<cUser>,[<nNumber>],[<cServer>|<nConId>)
→ nPassLen
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of the user whose minimum password length is set or determined.
nNumber Designates the new minimum password length for cUser.
cServer Designates the name of the file server to which cUser has access. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETPWLEN() returns the currently valid minimum password length for cUser. If a value has been passed for nNumber and the return value does not match nNumber, the requesting user did not have the rights for the modification.
Description
NOVELL NET PASSWORD LENGTHNNETPWLEN() allows you to set or determine the minimum password length for cUser. To query the minimum password length, do not pass a value for nNumber. If nNumber contains a numeric value, NNETPWLEN() tries to set this value as new minimum password length. Supervisor rights on the related file server are required to modify the password length. With nNumber equal to 0, a previously set password length can be removed. In this case, a password for cUser is not required.
With the parameters cServer or nConId, the password length for users on any attached file server can be changed. The connection ID of a file server is returned by NNETATTACH() or NNETLOGIN().
Examples
■ Determine the minimum password length for user MIKE:
? NNETPWLEN('MIKE') // For example 5
■ Set the new minimum password length for user MIKE:
NNETPWLEN('MIKE',8)
■ Remove the limit of the password length for user MIKE:
NNETPWLEN("MIKE",0)
NNETQDIR(<cQueue>,[<cServer>|<nConId>]) → cDir
Netware: 2.2 and 3.11
Arguments
cQueue Designates the queue for which the directory is determined.
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETQDIR() returns the directory of the job files of cQueue. If an error occurs, the function returns an empty string.
Description
NOVELL NET QUEUE DIRECTORY Netware stores the contents of a job in a separate file. The queue only contains references to these files. NNETQDIR() allows you to determine the directory of the job files. By default, the job directory is a subdirectory of SYS:SYSTEM. The name of the subdirectory consists of the queue ID and the extension .QDR.
Notes
■ NNETQDIR() is a high level function based on the low level
functions of the bindery access. The CA-Clipper source code can be found on the product disks.
Examples
Display the directory for the print queue QUEUE1:
? NNETQDIR('QUEUE1')
Determines the list of print servers that service a print queue
Syntax
NNETQSRVS(<cQueue>,[<lAll>],[<cServer>|<nConId>])
→ aPrintServer
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue for which the print servers are determined.
lAll Designates whether the names of all the print servers that have access to cQueue (.T.) or only the names of the print servers that are currently logged in at cQueue (.F.) are determined. The default value is .F..
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETQSRVS() returns an array that contains the names of print servers currently logged in at cQueue (lAll = .F.) or the number of print servers that have access to cQueue (lAll = .T.). If an error occurs (for example, if cQueue does not exist), the function returns an empty array.
Description
NOVELL NET QUEUE SERVERSNNETQSRVS() allows you to determine the names of print servers that are currently logged in cQueue or have access to cQueue. This information can be used to access one or more print servers with the print server functions of CA-Clipper Tools.
Notes
■ This function requires that the requesting user have access to
the queue as a user or an operator.
Examples
Display a list of print servers that have access to the queue LINEPRINT
and a list of print servers currently logged in at the queue LINEPRINT:
aPServer=NNETQSRVS('LINEPRINT',.T.)
? 'Access to LINEPRINT have:'
FOR i = 1 TO Len(aPServer)
? aPServer[i]
NEXT i
aPServer=NNETQSRVS('LINEPRINT')
? 'Currently logged in are:'
FOR i = 1 TO Len(aPServer)
? aPServer[i]
NEXT i
NNETQSTAT(<cQueue>,[<nStatus>],[<cServer>|<nConId>])
→ nStatus
Netware: 2.2 and 3.11
Arguments
cQueue Designates the name of the print queue that is processed.
nStatus Designates an optional parameter that sets the queue status. nStatus must be passed as a bit-coded value according to table 25.3. To change more attributes, the decimal values of the required definitions must be added.
cServer Designates the name of the file server on which cQueue is processed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETQSTAT() returns a bit-coded value which describes the queue status. The following table contains the definitions of the bits:
Table 25.3: Queue Status Coding
Bit Value Definition
2 2 No new jobs can be added to queue.
3 4 Currently, no further print servers can be logged in
at queue currently.
5 16 No jobs are being serviced in queue currently
If an error occurs (for example, if cQueue does not exist), the function returns -1.
Description
NOVELL NET QUEUE STATUSNNETQSTAT() allows you not only to query, but also to set a new queue status. For example, this can be used to stop the print output for a queue temporarily. To change the queue status, the requesting user must have access to the queue as an operator.
Notes
■ This function requires that the requesting user have access to
the queue as a user or an operator.
Examples
■ Check to see if jobs can be added to the queue LINEPRINTER:
IF IsBit(NNETQSTAT('LINEPRINTER'),2)
? 'No new jobs can be added!'
ELSE
? 'New jobs can be added!'
ENDIF
■ Prevent the servicing of jobs in the queue LINEPRINTER:
NNETQSTAT('LINEPRINTER',16)
NNETRDITM(<cObjName>,<nType>,<cProperty>,[<nSeg>],
[<lMode>],[<cServer>|<nConId>]) → cPropValue
Netware: 2.2 and 3.11
Arguments
cObjName Designates the name of the bindery object that is processed.
nType Designates the object type of cObjName. The header file CTNNET.CH contains symbolic constants for a number of object types. When you work with numeric values, take into account that, for efficiency reasons, NNETRDITM() expects the object type in the high-low format.
cPropName Designates the name of the property that is processed. cPropName must describe an item property.
nSeg Designates the number of the segment that is read. The smallest possible number, as well as the default value, is 1.
lMode Designates whether the contents of the property are interpreted as text (lMode = .F.) or as binary byte sequence (lMode = .T.). The default value is .F.. If text, NNETRDITM() returns the characters up to the first occurrence of a terminator 0. In binary mode, all 128 bytes of the required property segment are returned.
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETRDITM() returns the contents of the specified property segment in the form of a character string. In text mode, the returned string contains all characters up to the first occurrence of a terminator 0. In binary mode, the string always contains 128 characters. If an error occurs, the function returns an empty string.
Description
NOVELL NET READ ITEM PROPERTY Internally, Novell Netware defines two property types: item and set property. With NNETRDITM(), you can read the contents of an item property. Item properties can contain any type of data. The information within an item property is organized in segments that have a constant length of 128 bytes. NNETRDITM() allows you to read single segments (nSeg) of a property (cPropName) of a bindery object, specified by cObjName and nType. The organization of the information within a segment depends on the property. With lMode you can specify if segment contains text or a binary sequence (see the arguments). An example for text mode is the property IDENTIFICATION. The IDENTIFICATION property contains a bindery object's full name as a zero-terminated ASCII character string. An example for the binary mode is the property LOGIN_CONTROL. The property LOGIN_CONTROL contains binary-coded information about a user's access limits. To avoid incorrect results when working with binary-coded information, the parameter lMode must be designated .T..
To read all property segments, call NNETRDITM() with an incrementing value for nSeg until NNETRDITM() returns an empty string and NNETERROR() returns 236.
With the parameters cServer or nConId, the bindery of any attached file server can be accessed. The connection ID of a file server is returned by NNETATTACH() or NNETLOGIN().
The function NNETRDITM() requires sufficient bindery and property access rights. The necessary property access rights depend on the property security of the property that is read.
Examples
■ Determine the full name of user MIKE:
#include "ctnnet.ch"
? NNETRDITM('MIKE',OBJ_USER,'IDENTIFICATION')
■ Determine the date of the last login of user MIKE:
#include "ctnnet.ch"
cBuf=NNETRDITM('MIKE',OBJ_USER,'LOGIN_CONTROL',1,.T.)
IF !Empty(cBuf)
dLast= SToD('19'+NToC(Asc(SubStr(cBuf,57,1)),,2,'0');
+NToC(Asc(SubStr(cBuf,58,1)),,2,'0');
+NToC(Asc(SubStr(cBuf,59,1)),,2,'0'))
? dLast
ENDIF
NNETRDSET(<cObjName>,<nType>,<cPropName>,
[<cServer|<nConId>]) → aObjList
Netware: 2.2 and 3.11
Arguments
cObjName Designates the name of the bindery objects that are processed.
nType Designates the object type of cObjName. The header file CTNNET.CH contains symbolic constants for a number of object types. When working with numeric values, take into account that, for efficiency reasons, the function NNETRDSET() expects the object type in the high- low format.
cPropName Designates the name of the property that is processed. cPropName must describe a set property.
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETRDSET() returns a one-dimensional array that contains the object ID's of the bindery objects in cPropName as numeric values.
Description
NOVELL NET READ SET PROPERTY Internally, Novell Netware defines two property types: item and set property. With NNETRDSET(), the contents of a set property can be read. Set properties contain a list of object ID's. An object ID has a length of four bytes and identifies a bindery object. An example is the property GROUP_MEMBERS, which contains a list of users that are members of a group.
NNNETRDSET() returns an array with the object ID's of the members of the set property cPropName. With the functions NNETOBJNAM() and NNETOBJTYP(), object name and object type for the object ID can be determined.
The function NNETRDSET() requires sufficient bindery and property access rights. The necessary property access rights depend on the property security of the property that is read.
Notes
■ For efficiency reasons, NNETRDSET() returns the object IDs in
the high-low format (see the Introduction to this chapter).
Examples
The SECURITY_EQUALS property contains a list of objects to which an
object is security-equivalent. This property is usually attached to
user and user group objects. Read the property SECURITY_EQUALS of user
MIKE, and display the object names and object types of the members:
#include "ctnnet.ch"
aIn=NNETRDSET('MIKE',OBJ_USER,'SECURITY_EQUALS')
FOR i=1 TO Len(aIn)
? NNETOBJNAM(aIn[i])
?? IF(NNETOBJTYP(aIn[i])=OBJ_USER,'User','Group')
NEXT i
NNETREMGRP(<cGroup>,<cUser>|<aUser>,[<cServer>|
<nConId>) → nNumber
Netware: 2.2 and 3.11
Arguments
cGroup Designates the name of the group from which the user is removed.
cUser Designates the name of the user that is removed from cGroup.
aUser Designates a one-dimensional array of the type string. Each element contains the name of a user to be removed from cGroup.
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETREMGRP() returns the number of users successfully removed from cGroup. A return value of 0 indicates that no user has been removed.
Description
NOVELL NET REMOVE USER FROM GROUPNNETREMGRP() allows you to remove one or more users from a group. To remove one user, the user's login name must be passed as the single argument cUser. More users can be removed by passing the array, aUser. Each element of the array, aUser, contains a user name. As soon as a user has been removed from a group, the user loses all the rights that have been granted as a member of the group. With the parameters cServer or nConId, users on any attached file servers can be removed. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Supervisor rights are required on the related file server to remove a user from a group.
Notes
■ NNETREMGRP() only removes the user from Group. The user is
not deleted.
■ NNETCRTUSR() is a high level function based on the low level
functions of the bindery access. The CA-Clipper source code can be found on the product disks.
Examples
■ Remove user MIKE from the TECH group:
IF NNETREMGRP('TECH','MIKE')>0
? 'User removed successfully!'
ELSE
? 'User cannot not be removed!'
ENDIF
■ Remove users JIM, STEPHEN and ED from the TOOLS group:
NNETREMGRP('TOOLS',{'JIM','STEPHEN','ED'})
NNETREMQOP(<cQueue>,<cOperator>|<aOperators>,
[<cServer>| <nConId>]) → nNumber
Netware: 2.2 and 3.11
Arguments
cQueue Designates a print queue on the default server or on cServer|nConId.
cOperator Designates the name of a user that is removed from the operator list of cQueue.
aOperators Designates a number of elements of the type string. Each element designates the name of a user that is removed from the operator list of cQueue.
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETREMQOP() returns the number of operators that are successfully removed from the operator list of cQueue. The value 0 indicates that no operator has been deleted.
Description
NOVELL NET REMOVE QUEUE OPERATORNNETREMQOP() allows you to remove one or more users from the operator list of a print queue. To remove one operator, the user name must be passed in cOperator. By passing an array containing the user names as elements (aOperators), more operators can be deleted. With the parameters cServer or nConId, the operator list of any attached server can be modified. The connection ID of a server can be determined with NNETATTACH() or NNETLOGIN().
Supervisor rights of the requesting user on the related file server are required to remove users from an operator list.
Notes
■ NNETREMQOP() is a high level function based on the low level
functions of the bindery access. The CA-Clipper source code can be found on the product disks.
Examples
■ Remove user MICK from the operator list of the queue
LINEPRINTER:
IF NNETREMQOP('LINEPRINTER','MICK')>0
? 'Operator removed successfully!'
ELSE
? 'Error!'
ENDIF
■ Remove JIM, PETER, and MIKE from the operator list of the
queue LINEPRINTER:
NNETREMQOP('LINEPRINTER',{'JIM','PETER','MIKE'})
NNETREMQSV(<cQueue>,<cPServer>|<aPServer>,[<cServer>|
<nConId>]) → nNumber
Netware: 2.2 and 3.11
Arguments
cQueue Designates a print queue on the default server or on cServer|nConId.
cPServer Designates the name of a print server that is removed from the server list of cQueue.
aPServer Designates a number of elements of the type strings. Each element designates the name of a print server that is removed from the server list of cQueue.
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETREMQSV() returns the number of print servers that have been removed successfully from the server list of cQueue. The value 0 indicates that no print server has been deleted.
Description
NOVELL NET REMOVE QUEUE SERVERNNETREMQSV() allows you to remove one or more print servers from the server list of a print queue. To remove one print server, the server name must be passed in cPServer. By passing an array containing the server names as elements (aPServer), more print servers can be deleted. With the parameters cServer or nConId, the server list of any attached server can be modified. The connection ID of a server can be determined with NNETATTACH() or NNETLOGIN().
Supervisor rights of the requesting user on the related file server are required to remove print servers from a server list.
Notes
■ NNETREMQSV() is a high level function based on the low level
functions of the bindery access. The CA-Clipper source code can be found on the product disks.
Examples
■ Remove the print server PSERVER from the server list of the
queue LINEPRINTER:
IF NNETREMQSV('LINEPRINTER','PSERVER')>0
? 'Print server removed successfully!'
ELSE
? 'Error!'
ENDIF
■ Remove the print servers PSERVERTOOLS1 and PSERVERDEV1 from
the server list of the queue LINEPRINTER:
NNETREMQOP('LINEPRINTER',{'PSERVERTOOLS1','PSERVERDEV1'})
NNETREMQUS(<cQueue>,<cUser>|<aUser>,[<cServer>|
<nConId>]) → nNumber
Netware: 2.2 and 3.11
Arguments
cQueue Designates a print queue on the default server or on cServer|nConId.
cUser Designates the login name of a user that is removed from the user list of cQueue.
aUser Designates a number of elements of the type string. Each element designates the name of a user that is removed from the user list of cQueue.
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETREMQUS() returns the number of users that have been removed successfully from the user list of cQueue. The value 0 indicates that no user has been deleted.
Description
NOVELL NET REMOVE QUEUE USERNNETREMQUS() allows you to remove one or more users from the user list of a print queue. To remove one user, the user name must be passed in cUser. By passing an array containing the user names as elements (aUser), more users can be deleted. With the parameters cServer or nConId, the user list of any attached server can be modified. The connection ID of a server can be determined with NNETATTACH() or NNETLOGIN().
Supervisor rights of the requesting user on the related file server are required to remove users from an user list.
Notes
■ NNETREMQUS() is a high level function based on the low level
functions of the bindery access. The CA-Clipper source code can be found on the product disks.
Examples
■ Remove user MICK from the user list of the queue LINEPRINTER:
IF NNETREMQUS('LINEPRINTER','MICK')>0
? 'User removed successfully!'
ELSE
? 'Error!'
ENDIF
■ Remove the users JIM, PETER, and MIKE from the user list of
the queue LINEPRINTER:
NNETREMQUS('LINEPRINTER',{'JIM','PETER','MIKE'})
NNETRENDIR(<cPath>,<cNewDir>) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPath Designates an existing directory on a server volume. The path can contain a server name.
cNewDir Designates the new name for the directory specified by cPath. This character string can contain a maximum of an eight- character name, a period, and a three-character extension.
Returns
NNETRENDIR() returns .T. if the directory has been renamed successfully.
Description
NOVELL NET RENAME DIRECTORYNNETRENDIR() allows you to rename an existing directory (cPath) on any server volume. The volume must not be mapped to a drive. Under Netware 2.x, the rights MODIFY and PARANTEL are required to rename a directory. Under Netware 3.x, the right MODIFY for the parent directory of cPath is required to rename a directory.
Notes
■ The default directories on volume SYS: (LOGIN, PUBLIC, MAIL,
SYSTEM) cannot be renamed.
Examples
Rename the directory ACCOUNT/VOL1:DATEN/ACT to
ACCOUNT/VOL1:DATEN/BACKUP:
IF NNETRENDIR('ACCOUNT/VOL1:DATEN/ACT','BACKUP')
? 'Directory has been renamed successfully!'
ELSE
? 'Failure during rename!'
ENDIF
NNETRENOBJ(<cOldName>,[<nType>],<cNewName>,
[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cOldName Designates the name of the bindery object that is renamed.
nType Designates a numeric value that specifies the type of cOldName. The header file CTNNET.CH contains symbolic constants of the object type defined by Novell for use in conjunction with the bindery functions of CA-Clipper Tools. The default value indicates the object type OBJ_USER.
cNewName Designates the new name for the bindery object.
cServer Designates the name of the file server of which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETRENOBJ() returns .T. if the bindery object has been renamed successfully. If an error occurs, the error code can be queried with NNETERROR().
Description
Important! NNETRENOBJ() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET RENAME BINDERY OBJECTNNETRENOBJ() allows you to rename bindery objects. For example, this function can be used to change the login name of a user. With the parameters cServer or nConId, the bindery object of any attached server can be accessed. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
To rename an object, the requesting user must have supervisor rights on the related file server. NNETRENOBJ() expects the object type in the high-low sequence for efficiency reasons.
Notes
■ NNETRENOBJ() must be used to rename users or user groups, as
no other high level function is available in CA-Clipper Tools.
Examples
■ Rename user JIM to JAMES and evaluate the return values:
IF NNETRENOBJ('JIM',,'JAMES')
? 'User has been renamed successfully!'
ELSE
? 'Failure during rename!'
ENDIF
■ Rename the group DEV to TECH:
#include "ctnnet.ch"
NNETRENOBJ('DEV',OBJ_GROUP,'TECH')
Returns the rights mask, dependent on the Netware version
Syntax
NNETRGHMSK([<cServer>|<nConId>]) → cRightsMask
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server for which the rights mask is determined. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETRGHMSK() returns a string that contains the rights symbols in a descending order of their bit significance.
Description
NOVELL NET RIGHTS MASK The possible rights and their definitions are interpreted differently under Novell 2.x and 3.x. NNETRGHMSK() returns a character string that contains the symbols of the rights, dependent on the Netware version. The possible rights can be seen in the following tables. The first letter of each keyword under "Definition" represents the symbol used by NNETRGHMSK().
The following table contains the rights under Netware 2.x:
Table 23.12: Rights Coding under Netware 2.x
Bit Definition Description
1 READ Read files
2 WRITE Write to files
3 OPEN Open files
4 CREATE Create new files
5 DELETE Delete files
6 PARENTAL Create new directories
7 SEARCH Search files in directories
8 MODIFY Modify files or attributes
The following table contains the possible rights under Netware 3.x:
Table 23.13: Rights Coding under Netware 3.x
Bit Definition Description
1 READ Read files
2 WRITE Write to files
3 RESERVED
4 CREATE Create new files
5 ERASE Delete files
6 ACCESS CONTROL Trustee rights can be modified
7 FILE SCAN Search files in directories
8 MODIFY Modify files or attributes
9 SUPERVISORY All rights / can grant rights
The return value of NNETRGHMSK() can be used in the function BitToC().
Notes
■ NNETRGHTMSK() returns a constant that depends on the Netware
version on the file server used. The function does not return information about the access rights of the currently logged in user.
Examples
In the following example, file server TEST286 runs under Netware 2.15
and file server WORK386 runs under Netware 3.11:
? NNETRGHMSK('TEST286') // Returns: MSPDCOWR
? NNETRGHMSK('WORK386') // Returns: SMFAEC WR
Tests for access rights to a Novell file server directory
Syntax
NNETRIGHTS(<cPath>) → nBitMap
Netware: 2.2 and 3.11
Arguments
cPath Designates the complete path, including the drive designation for the directory that is tested.
Returns
NNETRIGHTS() returns a value between 0 and 255 that corresponds to a bit map for the related directory rights. A right is present when the designated bit is set at 1.
Table 23.14: Access Right Coding
Bit Definition Description
1 READ Read from files
2 WRITE Write to files
3 OPEN Open files
4 CREATE Create new files
5 DELETE Delete files
6 PARENTAL Create subdirectories
7 SEARCH Search for files in directories
8 MODIFY Change file names or attributes
Beginning with NETWARE386 version 3.0, the numeric range for the access rights coding has been extended from 1 bit up to 9 bits. Additionally, the meaning of the individual bits has been changed according to the following table.
Table 23.15: Access Right Coding
Bit Definition Description
1 READ Read from files
2 WRITE Write to files
3 RESERVED
4 CREATE Create new files
5 ERASE Delete files
6 ACCESS CONTROL Trustee rights can be changed
7 FILE SCAN Search for files in directories
8 MODIFY Change file names or attributes
9 SUPERVISORY All rights / can assign access rights
With an invalid parameter, the function returns 0 (which equates to no rights).
Description
This function determines the access rights to a directory of a Novell file server. The parameter must always relate the complete path to the root directory and must include the drive designation. The construction of this type of absolute path can be done with the aid of functions like DirName(), DiskName(), and TrueName().
You can determine if a Novell network is active and if a drive is resident on a file server with the NetDisk() and NNetwork() functions.
Notes
■ This function always returns a value of 511 for a local drive
and displays full rights to the designated directory.
Examples
■ Display the rights to the CA-Clipper directory on drive J:
? NNETRIGHTS("J:\CLIPPER") // Returns numeric
// value
■ Test for a particular right:
? IsBit(NNETRIGHTS("J:\CLIPPER"), 6) // Allowed to create
// a directory
■ Display the rights in the current directory:
? NNETRIGHTS(DiskName() + ":" + DirName())
■ Rights depend on the version:
cDrive := "J:"
IF NNETVER(cDrive) < "3.00"
? BitToC(NNETRIGHTS(cDrive+"\CLIPPER"), "MSPDCOWR", .T.)
ELSE
? BitToC(NNETRIGHTS(cDrive+"\CLIPPER"), "SMFAEC WR", .T.)
ENDIF
NNETRMDIR(<cPath>) → lSuccess
Netware: 2.2 and 3.11
Arguments
cPath Designates an existing directory on a server volume. The path can contain a server name.
Returns
NNETRMDIR() returns .T. if the directory has been removed successfully.
Description
NOVELL NET REMOVE DIRECTORYNNETRMDIR() allows you to remove an existing directory (cPath) from a server volume. The volume must not be mapped to a drive. Under Netware 2.x, the rights DELETE and PARANTEL are required to remove a directory. Under Netware 3.x, the right ERASE for the parent directory of cPath is required to remove a directory. A directory can be removed only if it is empty and it is not currently mapped on another workstation.
Notes
■ The default directories on volume SYS: (LOGIN, PUBLIC, MAIL,
SYSTEM) cannot be removed.
Examples
Remove the directory VOL1:DATEN from file server ACCOUNT:
IF NNETRMDIR('ACCOUNT/VOL1:DATEN')
? 'Directory has been removed successfully!'
ELSE
? 'Directory could not be removed!'
ENDIF
Determines the list of recoverable files (Netware 3.x only)
Syntax
NNETSALLST([<cPath>]) → aFiles
Netware: 2.2 and 3.11
Arguments
cPath Designates the directory on a server volume in which the recoverable files are searched. The default value designates the current directory on the current drive.
Returns
NNETPSQL() returns an array with subarray (two-dimensional array). Each subarray contains information about a recoverable file. For the subarray structure, see the following table:
Table 23.16: NNETSALLST() Subarray Structure
Position Metasymbol CTNNET.CH Definition
1 cName SAL_NAME File name
2 cSize SAL_SIZE File size
3 dDate SAL_DATE Salvage date
4 cTime SAL_TIME Salvage time
5 cDeletor SAL_DELETOR Deletor
If an error occurs, the function returns an empty array.
Description
NOVELL NET SALVAGE LIST Files on a server volume that are deleted within DOS or within an application are logically marked for deletion and can be recovered with the Novell utility SALVAGE or the CA-Clipper Tools function NNETSALVAG(). NNETSALLST() returns a list of all files in the directory cPath that can be recovered. This service is only available under Netware 3.x.
Examples
■ Determine the list of recoverable files in L:\DATA. Display
the name of the files and the name of the user that deleted these
files:
#include "ctnnet.ch"
aFiles=NNETSALLST('L:\DATA')
FOR i=1 TO Len(aFiles)
? aFiles[i,SAL_NAME],aFiles[i,SAL_DELETOR]
NEXT i
■ Purge all recoverable files in L:\DATA:
#include "ctnnet.ch"
aFiles=NNETSALLST('L:\DATA')
FOR i=1 TO Len(aFiles)
NNETPURGE('L:\DATA\'+aFiles[i,SAL_NAME])
NEXT i
NNETSALVAG(<cOldFile>,[<cNewFile>]) → cFile
Netware: 2.2 and 3.11
Arguments
cOldFile Designates the file that is marked for deletion, but depends on the Netware version used.
Under Netware 3.x, cFile designates the file that is recovered. The file name can contain a path, but the path must be unique. Wildcard characters are not allowed.
Under Netware 2.x, the operating system only permits files to be salvaged sequentially for the entire volume. If NNETSALVAG() determines that the server is running under Netware 2.x after a server change is implied by cOldFile, only the volume definition from the remaining part of cOldFile is taken into account. The first recoverable file is salvaged.
cNewFile Designates the name under which cOldFile is recovered. This parameter is only taken into account if the function is called on a Netware 3.x server. cNewFile can only contain a file name (an eight- character name, and a three-character extension).
Returns
NNETSALVAG() returns the name of the file that is recovered. If an error occurs, the function returns an empty string.
Description
NOVELL NET SALVAGE Files on a server volume that are deleted within DOS or within an application are logically marked for deletion. These files can be recovered with the function NNETSALVAG(). The function is supported differently under Netware 2.x and 3.x. Under Netware 3.x, files can be salvaged individually. Under Netware 2.x, only the first recoverable file of the current user on the related volume is salvaged. Files cannot be recovered individually under Netware 2.x.
Examples
■ Salvage the file CLIENT.DBF on a Netware 3.x server:
NNETMAP('L','FSERVER386/SYS:DATA')
NNETSALVAG('L:CLIENT.DBF')
■ Salvage all recoverable files in the directory L:\DATA:
#include "ctnnet.ch"
aFiles=NNETSALLST('L:\DATA')
FOR i=1 TO Len(aFiles)
NNETSALVAG('L:\DATA\'+aFiles[i,SAL_NAME])
NEXT i
■ Salvage all the files of the current user on volume SYS: of a
Netware 2.x server:
WHILE .T.
IF Empty(cFile:=NNETSALVAG('FSERVER286/SYS:'))
EXIT
ENDIF
? cFile
ENDDO
NNETSCNBIN(<cObjMask>,[@]<nType>,[@]<NId>,
[@<nObjFlag>],[@<nObjSafe>],[@<lObjProp>],
[<cServer>|<nConId>]) → cObjName
Netware: 2.2 and 3.11
Arguments
cObjMask Designates a search mask that is satisfied by the bindery objects that are searched. cObjMask can contain the wildcard characters "*" and "?" according to DOS regulations. The default value is "*".
nType Designates the object type that is searched. The header file CTNNET.CH contains symbolic constants for a number of object types. When you work with numeric values, NNETSCNBIN() expects the object type in the high-low format for efficiency reasons. If nType is passed by reference, the variable contains the type of the object found after the function has been completed successfully.
NId Contains the object ID (high-low format) of the last object found. To start the search with the first object, NId must be designated -1. If NId is passed by reference, the variable contains the ID of the object found after the function has been completed successfully.
nObjFlag Designates whether the object found is static (0) or dynamic (1). This parameter must be passed by reference. In this case, the variable contains the object flag after the function has been completed successfully
nObjSafe Designates the object security as an eight-bit number. The four high-order bits control the security level for the object's write access; the four low-order bits control the object's read access. This parameter must be passed by reference. In this case, the variable contains the object security after the function has been completed successfully. A table for access levels can be found with the NNETCRTOBJ() function.
lObjProp Designates whether the object has property (.T.) or not (.F.). This parameter must be passed by reference.
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETSCNBIN() returns the name of the binary object that is found. If no object has been found, the function returns a null string. If the parameters nType, NId, nObjFlag, nObjSafe, and/or lObjProp are passed by reference, NNETSCNBIN() returns the object type, the object ID, the object flag, the object security, and a flag for property existence (see the arguments).
Description
Important! NNETSCNBIN() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET SCAN BINDERYNNETSCNBIN() allows you to scan the bindery of a file server for objects that satisfy a specified search mask (cObjMask) and a defined type (nType). To find the first object that matches the passed criterion, the parameter NId must be designated -1. For a successive search, the object ID must be passed by reference to use the ID of the object that is found at the next function call. To find objects of any type, the parameter nType must contain -1 or the symbolic constant OBJ_WILD. With the parameters cServer or nConId, the bindery of any attached file server can be accessed. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Notes
■ The object type and the object ID are expected in the high-low
format (see the Introduction to this chapter).
Examples
List the names and types of all bindery objects on the default server:
#include "ctnnet.ch"
nId:=-1 // Start with the 1st object
WHILE .T.
nType=OBJ_WILD // all objects
IF Empty(cName:=NNETSCNBIN('*',@type,@ID))
EXIT
ENDIF
? cName,nType
ENDDO
NNETSCNPRP(<cObjName>,<nType>,<cPropMask>,[@]<nSeq>,
[@<nFlag>],[@<nSafe>],[@<lValue>],
[<cServer>| <nConId>]) → cPropName
Netware: 2.2 and 3.11
Arguments
cObjName Designates the name of the bindery object that is processed.
nType Designates the object type of cObjName. The header file CTNNET.CH contains the symbolic constants for a number of object types. When you work with numeric values, NNETSCNPRP() expects the object type in the high-low format for efficiency reasons.
cPropMask Designates a search mask that is satisfied by the properties that are searched. cPropMask can contain the wildcard characters "*" and "?".
nSeq Designates the sequence number (high-low format) of the last property that was found. To start the search with the first property, nSeq must be designated -1. If nSeq is passed by reference, the variable contains the sequence number of the property found after the function has been completed successfully.
nFlag Designates the property flag after the function has been completed successfully. This parameter must be passed by reference. The following table contains the possible values for nFlag:
Table 18.6: Possible property flags
Value Sym. Con. Definition
0 PRP_ITEM Static item property
1 Dynamic item property
2 PRP_SET Static set property
3 Dynamic set property
nSafe Designates the property security after the function has been completed successfully. This parameter must be passed by reference. The property security is an eight-bit number. The four high- order bits control the security level for the property's write access; the four low-order bits control the property's read access. A table for access levels can be found with the NNETCRTOBJ() function.
lValue Designates a logical value that indicates if the property has any values (.T.) or not (.F.). This parameter must be passed by reference.
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETSCNPRP() returns the name of the property that is found. If no property is found, the function returns an empty string. If the parameters nSeq, nFlag, and/or nSafe are passed by reference, NNETSCNPRP() returns the sequence number, the property flag, property security, and a flag for value existence (see the arguments).
Description
Important! NNETSCNPRP() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET SCAN PROPERTYNNETSCNPRP() allows you to scan a bindery object (cObjName and nType) for properties that satisfy a specified search mask (cPropMask). To find the first property that matches the passed criterion, the parameter nSeq must be designated -1. For a successive search, the sequence number must be passed by reference in order to use the sequence number of the found property at the next function call. With the parameters cServer or nConId, the bindery of any attached file server can be accessed. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Notes
■ The object type and sequence number are expected and/or
returned in the high-low format (see the Introduction to this chapter).
Examples
List all the properties of the bindery object SUPERVISOR:
#include "ctnnet.ch"
nSeq:=-1 // Start with 1st property
WHILE .T.
cName=NNETSCNPRP('SUPERVISOR',OBJ_USER,'*', @nSeq, ;
@nFlag,@nSafe,@lValue)
IF Empty(cName)
EXIT
ENDIF
? cName,nSeq,nFlag,nSafe,lValue
ENDDO
NOVELL NETSERVER DATE This function allows you to query the current default file server date. This date is then available in the corresponding date format under CA-Clipper. This allows all applications to synchronize their dates within a Novell network.
Examples
■ Query the default server date:
? NNETSDATE() // e.g. 04/01/91
■ Pass the date with an AT to the CMOS-RAM:
SetDate(NNETSDATE(), IsAt())
Determines the index of a search drive in the path variable
Syntax
NNETSEARCH([<cDrive>]) → nSearchDrive
Netware: 2.2 and 3.11
Arguments
cDrive Designates the drive (A to Z) for which the index in the path variable is determined. Without this parameter, the function uses the default drive.
Returns
NNETSEARCH() returns a numeric value that indicates the position of cDrive in the form "cDrive:.", in the path variable. The return value is between 0 and 16. If cDrive is not a search drive, the function returns 0.
Description
NOVELL NET SEARCHNNETSEARCH() determines if the specified drive is a search drive and returns the drive's position in the path environment variable. NNETSEARCH() assumes that the path variable contains search drives in the form "X:.", where "X" can be any drive designator from "A" to "Z". If cDrive is not a search drive, NNETSEARCH() returns 0.
Examples
Determine the search drive position for drive Z:
? NNETSEARCH('Z') // Returns: 13
NNETSEMCLO(<nHandle>,[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
nHandle Designates the semaphore handle that is returned by NNETSEMOPN() when the semaphore is opened.
cServer Designates the name of the file server on which nHandle has been created. Your workstation must be attached to cServer.
nConId Designates the connection ID for your workstation on cServer.
Returns
NNETSEMCLO() returns .T. if the semaphore specified by nHandle has been closed successfully. If an error occurs (for example, if the handle is invalid), the function returns .F..
Description
NOVELL NET SEMAPHOR CLOSENNETSEMCLO() allows you to close a semaphore that is no longer needed. The semaphore is specified by a handle. If the closing workstation is the only workstation using the semaphore, the related file server removes the semaphore from its semaphore table.
Examples
Open and close semaphore:
nHandle=NNETSEMOPN("superacc")
NNETSEMCLO(nHandle)
Determines the number of stations that have opened a particular semaphore
Syntax
NNETSEMOPC(<nHandle>,[<cServer>|<nConId>]) → nNumber
Netware: 2.2 and 3.11
Arguments
nHandle Designates the semaphore handle that is returned by NNETSEMOPN() when the semaphore is opened.
cServer Designates the name of the file server on which nHandle has been created. Your workstation must be attached to cServer.
nConId Designates the connection ID for your workstation on cServer.
Returns
NNETSEMOPC() returns the number of stations that have opened the semaphore specified by nHandle. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
NOVELL NET SEMAPHOR OPEN COUNTNNETSEMOPC() allows you to determine the number of stations currently accessing a specific semaphore. The semaphore is specified by a handle. The file server manages two values for each semaphore. This function determines the number of stations that have opened nHandle. This information has nothing to do with the semaphore's value.
Examples
■ Open semaphore TEST and determine the number of stations that
have also opened this semaphore:
nHandle=NNETSEMOPN("test")
? "Number of stations:", NNETSEMOPC(nHandle)
■ The evaluation of the return value of NNETSEMOPC() in an "if"
statement allows you to limit the access to a semaphore's resource.
NNETSEMOPN(<cName>,[<nValue>],[<cServer>|<nConId>]),
→ nHandle
Netware: 2.2 and 3.11
Arguments
cName Designates the name of the semaphore that is opened.
nValue Designates a start value between -128 and 127 for the semaphore cName. The default value is 1. The file server accepts the assignment only if cName is created by the function call.
nHandle Designates the semaphore handle that has been returned by NNETSEMOPN() when the semaphore is opened.
cServer Designates the name of the file server on which cName is created. Your workstation must be attached to cServer.
nConId Designates the connection ID for your workstation on cServer.
Returns
NNETSEMOPN() returns the handle of the semaphore that has been opened. The handle is used by the file server to manage the semaphores. If an error occurs, the function returns 0.
Description
NOVELL NET SEMAPHOR OPENNNETSEMOPN() allows you to open an existing semaphore or to create a new semaphore. If the specified semaphore does not exist on the file server, the semaphore is created and entered into the file server's semaphore table. The new semaphore can be assigned a start value by passing nValue.
The function returns the handle used by the file server for the semaphore cName. Handles are used to save variables because they are needed as identification characteristics for other operations. Once a semaphore has been opened successfully, it is exclusively addressed with the handle returned by NNETSEMOPN().
Examples
■ Create semaphore SUPERACC, and check to see if the semaphore
has been opened successfully with the handle:
nHandle=NNETSEMOPN("superacc")
IF nHandle=0
? 'Error during opening the semaphore!'
ENDIF
■ Create semaphore TEST and assign a start value of 3, if it
does not already exist:
nHandle=NNETSEMOPN("test",3)
NNETSEMSGN(<nHandle>,[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
nHandle Designates the semaphore handle that is returned by NNETSEMOPN() when the semaphore is opened.
cServer Designates the name of the file server on which nHandle has been created. Your workstation must be attached to cServer.
nConId Designates the connection ID for your workstation on cServer.
Returns
NNETSEMSGN() returns .T. if the semaphore has been incremented successfully. If an error occurs (for example, if the handle is invalid), the function returns .F..
Description
NOVELL NET SEMAPHOR SIGNAL With NNETSEMSGN(), a station signal is completed using a semaphore's nHandle resource. The semaphore is specified by a handle. Another station waiting for the semaphore can access the semaphore if NNETSEMSGN() has been executed successfully.
Examples
Open, lock, and release the semaphor:
nHandle=NNETSEMOPN('Test')
IF NNETSEMWAI(nHandle)
// Execute action
...
// Release semaphore
NNETSEMSGN(nHandle)
ENDIF
NNETSEMVAL(<nHandle>,[<cServer>|<nConId>]) → nValue
Netware: 2.2 and 3.11
Arguments
nHandle Designates the semaphore handle that is returned by NNETSEMOPN() when the semaphore is opened.
cServer Designates the name of the file server on which nHandle has been created. Your workstation must be attached to cServer.
nConId Designates the connection ID for your workstation on cServer.
Returns
NNETSEMVAL() returns the current value of the semaphore nHandle. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
NOVELL NET SEMAPHOR VALUENNETSEMVAL() allows you to determine the current value of a semaphore. The semaphore is specified by a handle. The file server manages two values for each semaphore. This function determines the semaphore's value. This information has nothing to do with the number of stations that have opened nHandle.
Examples
Open semaphore TEST, and determine its current value:
nHandle=NNETSEMOPN("test")
? 'Value:',NNETSEMVAL(nHandle)
NNETSEMWAI(<nHandle>,[<nTimeout>],
[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
nHandle Designates the semaphore handle that is returned by NNETSEMOPN() when the semaphore is opened.
nTimeout Designates a time period in 1/18 seconds that NNETSEMWAI() must wait if the semaphore nHandle cannot be locked successfully. The default value is 0.5 seconds (9).
cServer Designates the name of the file server on which nHandle has been created. Your workstation must be attached to cServer.
nConId Designates the connection ID for your workstation on cServer.
Returns
NNETSEMWAI() returns .T. if the semaphore has been locked successfully (the semaphore's value is greater than 0). If the semaphore has not been locked successfully (the semaphoreÆs value is equal to 0), the function returns .F..
Description
NOVELL NET SEMAPHOR WAITNNETSEMWAI() tries to lock a semaphore. The semaphore is specified by a handle. NNETSEMWAI() decrements the value of the semaphore nHandle by 1. A semaphore is locked if the value is greater than or equal to 0 after it decrements.. In this case, NNETSEMWAI() returns .T.. If the value is negative, NNETSEMWAI() waits for a specific time period. If the value does not become positive within the specified time period, NNETSEMWAI() resets the value to its start value and returns .F.. The time period is calculated by multiplying nTimeout with 1/18 seconds.
Examples
Open the semaphore, and then try to lock the semaphore:
nHandle=NNETSEMOPN('TEST')
IF NNETSEMWAI(nHandle)
? 'Semaphore locked successfully!'
ELSE
? 'Semaphor could not be locked!'
ENDIF
NNETSERNO([<cServer>|<nConId>]) → cSerNo
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETSERNO() returns a 12-character string that contains the serial number of the Netware on cServer.
Description
NOVELL NET SERIAL NUMBERNNETSERNO() allows you to determine the Netware serial number. The number can be used to limit the usage of an application to a specific network.
Notes
■ Certain subversions of Netware prohibit the query of the
serial number. In this case, NNETSERNO() returns an empty string.
Examples
Display the Netware serial number of the default server:
? NNETSERNO()
NNETSETQ(<nPrinter>,<cPrintQueue>) → lLoggedIn
Netware: 2.2 and 3.11
Arguments
nPrinter Designates to which LPT device a new print queue is redirected. LPT1(1) to LPT3(3) are valid.
cPrintQueue Designates the name of the print queue on the default server where the future print output is created.
Returns
NNETSETQ() returns .T. when the designated print queue has been found and redirected.
Description
NOVELL NET SET QUEUE You can use NNETSETQ() to determine which print queue of the default server generates the future print output. If the queue is on another server, then you must switch over using NNETSETSRV(). All other settings required for printing can be done using the NNETCAPSSF() function.
Notes
■ The currently logged in user must have rights to use the
designated queue.
Examples
Redirect the queue USER:
? NNETSETQ("USER") // .T., when successful
NNETSETSRV(<cServerName>) → lLoggedIn
Netware: 2.2 and 3.11
Arguments
cServerName Designates the name of the server that is redirected as the default server.
Returns
NNETSETSRV() returns .T. when the designated name has been found in the attached server table and designated as the default server.
Description
NOVELL NET SET SERVER With NNETSETSRV(), it is possible to designate an attached server as the default server. Then all NNETXXXXXX() functions except NNETSLIST() (list of the attached servers) and NNETSTAID() (station ID) relate to this server specifically.
Examples
Switch from CA1 server to CA2 server:
? NNETSNAME() // "CA1"
? NNETSETSRV("CA2") // .T., if OK.
Determines the System Fault Tolerance (SFT) level of the Netware in use
Syntax
NNETSFTLVL() → nSFTLevel
Netware: 2.2 and 3.11
Returns
NNETSFTLVL() returns the System Fault Tolerance (SFT) level of the Netware version on the default file server.
Description
NOVELL NET SYSTEM FAULT TOLERANCE LEVEL This function allows you to determine if a System Fault Tolerant version of Netware is available on the server, and on what level it is working.
NNETSLIST() returns the names of all the attached servers.
Description
NOVELL NET SERVER LIST This function allows you to determine the names of all the servers attached through the station. The character string that is returned contains all the server names separated by a CR/LF. Each of the servers that are returned can be redirected as the default server using NNETSETSRV().
Examples
Determine the names of all attached servers:
cSList := NNETSLIST()
TokenInit(@cSList, Chr(10)+Chr(13))
DO WHILE .NOT. TokenEnd()
cServer := TokenNext(cSList)
? cServer
ENDDO
NNETSNAME() returns the name of the default file server.
Description
NOVELL NET SERVER NAME This function allows you to determine the name of the default file server. The returned character string can be up to 48 characters long. The NNETSETSRV() function allows you to set another attached file server as the default file server.
Examples
Determine the name of the default file server:
? NNETSNAME() // e.g. "CA"
NNETSNDALL(<cMessage>,[<lNoSender>],
[<cServer>|<nConId>]) → nNumber
Netware: 2.2 and 3.11
Arguments
cMessage Designates the message that is sent to all users. The message can be up to 55 characters long (including information about the sender) and can only contain characters that have an ASCII value between 32 and 127.
lNoSender Designates an optional parameter that allows you to suppress the sender information (from ...) when designated as (.T.). When this parameter is designated as .F., the sender information is generated automatically.
cServer Designates the name of the file server through which the message is sent. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETSNDALL() returns the number of stations to which the message has been sent successfully. The function returns 0 if no users are logged in.
Description
NOVELL NET SEND GROUPNNETSNDGRP() allows you to send a message (cMessage) of up to 55 characters to all users (cName) that are currently logged into a file server. The message is sent to all workstations where a user is logged in and the message receipt is not disabled (castoff). The message is displayed in line 24 of the screen and must be confirmed with CtrlReturn.
The message system of CA-Clipper Tools (NNETMSGOPN()) allows the interrupt-controlled receipt of messages in the background. The incoming messages can be processed within the application, and the computer is not interrupted in critical moments.
If the parameter lNoSender is set to .F. or no parameter is set, the message contains information about the sender. This information consists of the word "from", the name of the sender, and the connection ID. By passing lNoSender with .T., the sender information can be suppressed. With the parameters cServer or nConId, the message can be sent on any attached file server. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Examples
Send a message to all users on the default server:
nNumber= NNETSNDALL('Backup in 5 minutes!')
? 'Message has been sent to '+NToC(nNumber)+' station(s)!'
NNETSNDCON(<cMessage>,[<lNoSender>],
[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cMessage Designates the message that is sent to the server console. The message can be up to 60 characters long (including information about the sender) and can only contain characters that have an ASCII value between 32 and 127.
lNoSender Designates an optional parameter that allows you to suppress the sender information (from ...) when designated (.T.). When this parameter is designated .F., the sender information is generated automatically. The default value is .F..
cServer Designates the name of the file server to which the message is sent. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETSNDCON() returns .T. if the message has been sent successfully. If an error occurs, the function returns .F..
Description
NOVELL NET SEND CONSOLENNETSNDCON() allows you to send a message (cMessage) of up to 60 characters to the console of a file server. The message is displayed by the file server on a connected screen. If the parameter lNoSender is set to .F. or if no parameter is set, the message contains information about the sender. The information consists of the word "from", the name of the sender, and the connection ID. By passing lNoSender with .T., the sender information can be suppressed.
With the parameters cServer or nConId, the message can be sent to any attached file server. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Examples
■ Send a message to the default server:
IF NNETSNDCON('Start of the accounting system')
? 'Message sent successfully!'
ELSE
? 'Message could not be sent'
ENDIF
■ Send a message to server MAIL under the wrong sender:
NNETSNDCON('From Mick[99] : Hi, guys!',.T.,'MAIL')
NNETSNDGRP(<cName>,<cMessage>,[<lNoSender>],
[<cServer>|<nConId>]) → nNumber
Netware: 2.2 and 3.11
Arguments
cName Designates the name of the group that has members to which the message is sent.
cMessage Designates the message that is sent to the members of cName. The message can be up to 55 characters long (including information about the sender) and can contain only characters that have an ASCII value between 32 and 127.
lNoSender Designates an optional parameter that allows you to suppress the sender information (from ...) when designated as (.T.). When this parameter is designated .F., the sender information is generated automatically. The default value is .F..
cServer Designates the name of the file server through which the message is sent. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETSNDGRP() returns the number of workstations to which the message cMessage was successfully sent. The function returns 0 if no member of cName is currently logged in or ready to receive messages..
Description
NOVELL NET SEND GROUPNNETSNDGRP() allows you to send a message of up to 55 characters to all the users of a group. The function can be compared with the Novell utility SEND. The group cName must exist either on the default server or on the server specified by cServer|nConId because the sending of messages is processed through a file server. The message is sent to all workstations on which a member of cName is logged in and the message receipt is not disabled (castoff). The message is displayed on line 24 of the screen and must be confirmed with CtrlReturn. The message system of CA-Clipper Tools (NNETMSGOPN()) allows the interrupt controlled receipt of messages in the background. The incoming messages can be processed within the application and the computer is not interrupted in critical moments.
If the parameter lNoSender is set to .F. or if no parameter is set, the message contains information about the sender. This information consists of the word "from", the name of the sender, and the connection ID. By passing lNoSender with .T., the sender inforation can be suppressed. With the parameters cServer or nConId, the message can be sent on any attached file server. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Examples
Send a message to all members of the group TOOLS:
nNumber= NNETSNDGRP('TOOLS','Data backup in 5 minutes!')
? 'Message has been sent to '+NToC(nNumber)+' stations!'
NNETSNDLOG(<cMessage>,[<lNoSender>],
[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cMessage Designates the message that is written to the log file. The message can be up to 80 characters long (including information about the sender) and can contain only characters that have an ASCII value between 32 and 127.
lNoSender Designates an optional parameter that allows you to suppress the sender information (from ...) when designated as .T.. When this parameter is designated .F., the sender information is generated automatically. The default value is . F..
cServer Designates the name of the file server for which the log file is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETSNDLOG() returns .T. if the message has been sent successfully. If an error occurs, the function returns .F..
Description
NOVELL NET SEND LOG Under Netware 2.1x, each file server maintains a log file. This file is in the directory SYS:SYSTEM under the name NET$LOG.MSG. NNETSNDLOG() allows you to send a message of up to 80 characters to the log file. The message is saved in the form:
If the parameter lNoSender is set to .F. or if no parameter is set, the message contains the sender information. This information consist of the word "from", the name of the sender, and the connection ID. By passing lNoSender with .T., the sender information can be suppressed. With the parameters cServer or nConId, the message can be sent to the log file of any attached file server. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Notes
■ Under Netware 3.x, NNETSNDLOG() returns .F. because file
servers do not maintain a log file.
Examples
Write an application start in the log file of the default server:
IF NNETSNDLOG('Start of the accounting system')
? 'Message has been sent successfully!'
ELSE
? 'Message could not be sent!'
ENDIF
NNETSNDUSR(<cName>,<cMessage>,[<lNoSender>],
[<cServer>|<nConId>]) → nNumber
Netware: 2.2 and 3.11
Arguments
cName Designates the login name of the user to whom the message is sent.
cMessage Designates the message that is sent to cName. The message can be up to 55 characters long (including information about the sender) and can contain only characters that have an ASCII value between 32 and 127.
lNoSender Designates an optional parameter that allows you to suppress the sender information (from ...) when designated as .T.. When the parameter is designated .F., the sender information is generated automatically.
cServer Designates the name of the file server through which the message is sent. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETSNDUSR() returns the number of workstations to which the message cMessage has been sent successfully. The function returns 0 if cName is not logged in or not ready to receive messages.
Description
NOVELL NET SEND USERNNETSNDUSR() allows you to send a message of up to 55 characters to a user. The function can be compared to the Novell utility SEND. The user cName must be logged in either on the default server or on the server specified by cServer|nConId because the sending of messages is processed through a file server. The message is sent to all workstations on which cName is logged in and the message receipt is not disabled (castoff). The message is displayed in line 24 of the screen and must be confirmed with CtrlReturn. The message system of CA-Clipper Tools ( NNETMSGOPN()) allows the interrupt-controlled receipt of messages in the background. The incoming messages can be processed within the application, and the computer is not interrupted in critical moments.
If the parameter lNoSender is set to .F. or if no parameter is set, the message contains the information about the sender. This information consists of the word "from", the name of the sender, and the connection ID. By passing lNoSender with .T., the sender information can be suppressed. With the parameters cServer or nConId, the message can be sent on any attached file server. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
Examples
■ Send a message to user MIKE:
nNumber= NNETSNDUSR('MIKE','Good morning')
? 'Message has been sent to '+NToC(nNumber)+' stations!'
■ Send a message to the supervisor without the sender
information:
NNETSNDCON('SUPERVISOR','You fool!',.T.)
Determines if the logged in user has supervisor rights
Syntax
NNETSPRVSR() → lSupervisorMode
Netware: 2.2 and 3.11
Returns
NNETSPRVSR() returns .T. when the station that is queried has supervisor rights on the default file server.
Description
NOVELL NET SUPERVISOR Supervisor rights are the highest level rights within a network. These rights allow a supervisor, or someone with the same security equivalence, access to all Netware functions. For example, this function allows you to test to see if the account under which the station has been logged in has those rights.
Notes
■ Supervisor rights contain console privileges, existing in
Netware 2.1/ELS II and up.
Examples
Test to see if you have supervisor rights:
? NNETSPRVSR() // .T., when yes
NNETSPSTAT(<nServerPrinter>) → nPrinterStatus
Netware: 2.2 only
Arguments
nServerPrinter Designates one of the five possible server printers for which the status is determined. Values from 0 to 4 are valid.
Returns
NNETSPSTAT() returns the following status codes:
Table 30.1: Status Coding for Server Printer
Code Definition
0 Server printer ready (according to the server!)
1 Server printer off-line
2 Server printer paused from server console
3 Server printer off-line and paused at server console
-1 No corresponding printer available on server
Description
NOVELL NETWORK SERVER PRINTER STATUS With NNETSPSTAT(), you can determine if a particular printer on the default server is currently online or offline. If you receive a return value that is greater than or equal to 2, then the designated printer has been paused from the server console.
If there is no corresponding printer on the default server, the function returns -1.
Notes
■ Further explanations regarding the returned values of 2 or 3
can be found in the Novell Netware documentation, Versions 2.1 and later (in the Console Reference manual under Stop Printer).
Examples
■ Determine the status of server printer 0:
? NNETSPSTAT(0) // 0 Printer online
■ Determine the status of server printer 4:
? NNETSPSTAT(4) // -1 No printer available
NNETSTAID() returns a network station ID as a 12-character string.
Description
NOVELL NET STATION ID This function returns the ID of the network adapter that is built into the station. In the case of an Ethernet card, this ID is the full 12 characters in length; it is guaranteed that this code is unique. With other types of network cards, and frequently with Ethernet clones, this ID depends upon the DIP switch settings on the adapter. These switches must have different settings for each adapter within a network.
Notes
■ If an ID is shorter than 12 characters, the empty places in
the character string are filled with zeroes, starting from the left.
Examples
Determine the station ID:
? NNETSTAID() // e.g. "000F71100123"
NNETSTANUM() returns the station number of the workstation, relative to the default server.
Description
NOVELL NETSTATION NUMBER With NNETSTANUM(), you can query the station number of the network station where the function has been implemented can be queried. This information is always relative to the default file server. The function returns a numeric value, based on Netware version, between 1 and 99. If the value is used in file names, then it can be expanded with leading zeroes using the NToC() function.
Examples
Query the station number as a fixed length string:
? NToC(NNETSTANUM(), 10, 2, "0") // e.g. 09
NNETSTIME() returns the default file server clock time in the format "HH:MM:SS".
Description
NOVELL NET SERVER TIME With NNETSTIME(), you can determine the clock time on the default file server. The time, which is returned in the format "HH:MM:SS", can be passed with SetTime() to DOS and with ATs to the CMOS-RAM. In this way, all applications within a network can be synchronized with regard to the clock time.
Examples
■ Query the clock time of the default file server:
? NNETSTIME() // e.g. "10:28:30"
■ Pass the clock time with an AT to CMOS-RAM:
SetTime(NNETSTIME(), IsAt())
NNETTRSLST(<cName>,[<nType>],[<cServer>|<nConId>]
→ aTrusteeDir
Netware: 2.2 and 3.11
Arguments
cName Designates the name of the bindery object for which the trustee directories and files are determined. In most cases, cName represents the login name of a user.
nType Designates the object type of cName. The default value designates the object type, user.
cServer Designates the name of the file server on which the trustee directories and files are determined. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETTRSLST() returns a two-dimensional array.
The number of lines of the array corresponds to the number of trustee directories and files of cName on the related file server. Each line (subarray) contains a complete path name (including the volume name) and the rights of cName in this directory.
Description
NOVELL NET TRUSTEES LIST Under Netware, the access rights for each user can be assigned on the directory level. Under Netware 3.x, the access rights for each user can be assigned on the file level. These rights are called trustee rights. NNETTRSLST() allows you to determine all trustee assignments for a bindery object. However, supervisor rights on the related file server are required.
NNETTRSLST() returns a two-dimensional array that contains each trustee assignment as a separate line (subarray). Each subarray consists of two elements: a complete pathname that specifies the directory or the file for which the trustee rights have been granted, and a numeric value that represents the rights that have been granted to cName for the directory.
The interpretation of the numeric value depends on the Netware version used. Table 23.17 and 23.18 show the definition of the bits. A right is granted if the corresponding bit is represented in the return value.
Table 23.17: Rights Coding under Netware 2.x
Bit Definition Description
1 READ Read files
2 WRITE Write files
3 OPEN Open files
4 CREATE Create new files
5 DELETE Delete files
6 PARENTAL Create new directories
7 SEARCH Search files in directories
8 MODIFY Modify files or attributes
Table 23.18: Rights Coding under Netware 3.x
Bit Definition Description
1 READ Read files
2 WRITE Write to files
3 RESERVED
4 CREATE Create new files
5 ERASE Delete files
6 ACCESS CONTROL Trustee rights can be modified
7 FILE SCAN Search files in directories
8 MODIFY Modify files or attributes
9 SUPERVISORY All rights / can grant rights
Notes
■ For detailed information about rights and security, see the
Novell documentation.
Examples
Determine and display the trustee directories and files for user MIKE.
Granted rights are represented by the first letter of their definition:
aTrust=NNETTRSLST('MIKE')
FOR i = 1 TO Len(aTrust)
? PadR(aTrust[i,1],64),BitToC(aTrust[i,2],NNETRGHMSK(),.T.)
NEXT i
NNETTRUST(<cName>,[<nType>],<cPath>,[<cRights>|
<nRights>] → lSuccess
Netware: 2.2 and 3.11
Arguments
cName Designates the name of the bindery object for which the trustee rights are granted or removed. In most cases, cName represents the login name of a user.
nType Designates the object type of cName. The default value designates the object type, user.
cPath Designates a path designation that specifies a directory or a file for which the trustee rights are granted. The path can be passed in the Novell notation or in the DOS notation if the directory or file has been mapped to a drive.
cRights Designates a character string that contains the symbols for the rights that are granted to cName on cPath.
nRights Designates a numeric value that contains a bit mask for the rights that are granted to cName on cPath.
Returns
NNETTRUST() returns .T. if the rights have been granted or removed successfully.
Description
NOVELL NET TRUSTEE Under Netware, the access rights for each user can be assigned on the directory level. Under Netware 3.x, the access rights for each user can be assigned on the file level. These rights are called trustee rights. NNETTRUST() allows you to grant or remove trustee rights within a CA-Clipper application However, supervisor rights are required.
cPath specifies the directory or the file for which the trustee rights are granted or removed. To set trustee rights, a value must be passed for cRights or nRights. cRights must contain a character string in which each character represents an attribute. nRights must be passed as numeric value resulting from a bitwise OR operation of the binary significance of the attributes.
The possible rights under Netware 2.x and Netware 3.x are shown in the following tables:
Table 23.19: Rights Coding under Netware 2.x
Bit Definition Description
1 READ Read files
2 WRITE Write files
3 OPEN Open files
4 CREATE Create new files
5 DELETE Delete files
6 PARENTAL Create new directories
7 SEARCH Search files in directories
8 MODIFY Modify files or attributes
Table 23.20: Rights Coding under Netware 3.x
Bit Definition Description
1 READ Read files
2 WRITE Write to files
3 RESERVED
4 CREATE Create new files
5 ERASE Delete files
6 ACCESS CONTROL Trustee rights can be modified
7 FILE SCAN Search files in directories
8 MODIFY Modify files or attributes
9 SUPERVISORY All rights / can grant rights
The first letter of the definition represents the symbol for cRights.
To remove trustee rights, do not pass a value for the parameters cRights|nRights.
Notes
■ For detailed information about rights and security, see the
Novell documentation.
Examples
■ Grant read and write access and the rights to create, delete,
search, and modify files and directories for user MIKE on directory
VOL1:DATEN/APRIL on the default server. The following example
differentiates between Netware 2.x and 3.x:
IF NNETVER()<'3'
lOk=NNETTRUST('MIKE',,'VOL1:DATEN/APRIL','RWOCDPSM')
ELSE
lOk=NNETTRUST('MIKE',,'VOL1:DATEN/APRIL','RWCEFM')
ENDIF
IF lOk
? 'Trustee rights set successfully'
ELSE
? 'Rights could not be set, supervisor rights required!'
ENDIF
■ Remove the trustee rights for user MIKE in directory
VOL1:DATEN/APRIL:
IF NNETTRUST('MIKE',,'VOL1:DATEN/APRIL')
? 'Trustee rights removed successfully'
ELSE
? 'Rights could not be removed, supervisor rights required!'
ENDIF
NNETTTSAB([<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server that is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETTTSAB() returns .T. if the current transaction of cServer has been aborted. If an error occurs, the function returns .F..
Description
NOVELL NET TRANSACTION TRACKING SYSTEM ABORTNNETTTSAB() allows you to abort the active transaction (rollback). All modifications performed by the current workstation in flagged, transactional files on cServer since the start of the transaction with NNETTTSBEG() become invalid. For example, NNETTTSAB() can be called if a successful termination of the transaction is impossible. NNETTTSAB() removes all file lockings of files affected by the transaction.
Notes
■ When you use the Transactional Tracking System (TTS), always
take into account that other stations might not be able to read files attached by the transaction (see the Introduction to this chapter).
Examples
Abort the transaction if the available disk space is too small:
BEGIN SEQUENCE
NNETTTSBEG()
//
// Data manipulation
//
IF DiskSpace() < 50000
BREAK
ENDIF
//
// Data manipulation
//
NNETTTSEND()
RECOVER
NNETTSAB()
END
NNETTTSBEG([<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server that is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETTTSBEG() returns .T. if a transaction on cServer has been opened successfully. If an error occurs, the function returns .F..
Description
NOVELL NET TRANSACTION TRACKING SYSTEM BEGIN A call of NNETTTSBEG() starts an explicit transaction on cServer. After a transaction has been started, each write access to a marked, transactional file (the extended attribute transactional is set) is protocolled and becomes valid if the transaction is terminated. During a running transaction, all file modifications can be undone. If a failure occurs during a transaction (for example, a workstation crash), the Transactional Tracking System (TTS) backs up the transaction immediately.
Only one transaction can be active per workstation. This transaction includes all transactional files into which the data is written.
A file on a server volume can be marked 'transactional' with NNETEXTATT().
Notes
■ When you use the TTS, always take into account that other
stations might not be able to read files attached by the transaction (see the Introduction to this chapter).
Examples
Mark the file CLIENT.DBF as transactional, and start an explicit
transaction:
#include "ctnnet.ch"
NNETEXTATT('CLIENT.DBF',EXA_TTS)
IF .NOT. NNETTTSBEG()
? 'Transaction could not be started!'
ENDIF
NNETTTSEND([<cServer>|<nConId>]) → nTransNumber
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server that is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETTTSEND() returns the transaction number. If the error occurs, the function returns -1.
Description
NOVELL NET TRANSACTION TRACKING SYSTEM END A call of NNETTTSEND() validates all write accesses to flagged, transactional files since the start of the transaction (NNETTTSBEG()). Before the end of a transaction, a buffer commit is executed. At the end of a transaction, the file server assigns a transaction number, that can be used to determine when a transaction has been written successfully.
Notes
■ When you use the Transactional Tracking System (TTS), always
take into account that other stations might not be able to read files attached by the transaction (see the Introduction to this chapter).
Examples
The following example demonstrates a typical transaction. The
transaction is embedded in a begin sequence structure. If no problems
occur, the transaction is completed normally at the end of the
structure. If problems do occur, a break causes a branch into the
recover routine, where the transaction is undone by NNETTTSAB().
BEGIN SEQUENCE
NNETTTSBEG()
//
// Data manipulation
//
IF DiskSpace() < 50000
BREAK
ENDIF
//
// Data manipulation
//
NNETTTSEND()
RECOVER
NNETTSAB()
END
Determines the transaction status after completion
Syntax
NNETTTSSTA(<nTransNumber>,[<cServer>|<nConId>])
→ lWritten
Netware: 2.2 and 3.11
Arguments
nTransNumber Designates a transaction number, which has been returned by NNETTTSEND() at the end of a transaction.
cServer Designates the name of the file server that is used. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETTTSSTA() returns .T. if a terminated transaction has been written completely. If the terminated transaction has not been written completely, the function returns .F..
Description
NOVELL NET TRANSACTION TRACKING SYSTEM STATUS A few seconds after a transaction has been terminated by NNETTTSEND(), Netware starts writing the transaction. NNETTTSSTA() allows you to determine if a transaction that has been completed successfully is already written. The first parameter that is passed contains the transaction number that has been returned by NNETTTSEND().
Notes
■ When you use the Transaction Tracking System (TTS), always
take into account that other stations might not be able to read files attached by the transaction (see the Introduction to this chapter).
Examples
Terminate the transaction, and wait until the transaction has been
written completely:
nTrans=NNETTTSEND()
WHILE !NNETTTSSTA(nTrans)
ENDDO
NNETUSERID([<cUser>]) → cUserID
Netware: 2.2 and 3.11
Arguments
cUser Designates the name of an object of the type user (login name). The default value designates the logged-in user.
Returns
NNETUSERID() returns the ID of the designated object of the type user.
Description
NOVELL NET USER ID With NNETUSERID(), the ID of an object of the type user can be determined if the user is not logged in on any station. The function is always relative to the default file server.
The returned character string corresponds to a hexadecimal (eight place) number that only occurs once within a network.
If the optional cUser parameter is not specified, the function returns the ID for the name where one is currently logged in. This corresponds to a NNETUSERID(NNETWHOAMI) call.
Notes
■ An object ID is automatically assigned by Novell software at
its creation.
Examples
Deterine the ID of a login name:
? NNETUSERID("JIM") // e.g. "0A002300"
NNETUSERS([<cServer>|<nConId>],[<cMask>])
→ aUserListe
Netware: 2.2 and 3.11
Arguments
cServer Designates the name of the file server for which the users are determined. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer. If no server is specified, the function uses the default server. .
cMask Designates a search mask that can contain the wildcard characters "?" and "*". The default character "*" indicates that all users are determined.
Returns
NNETUSERS() returns a one-dimensional array. Each array element contains a user name.
Description
NOVELL NET USERSNNETUSERS() allows you to determine all the users of a file server. The file server can be specified by either its name or its connection ID. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
In order to achieve results with this function, the requesting user must be currently logged in on the specified file server. If the requesting user is not currently logged in on the specified file server, the function returns an empty array.
The users currently logged in on a file server can be determined with the function NNETLGUSER().
Examples
Display a list of all the users on file server NANGERTOOLS2:
aList=NNETUSERS('NANGERTOOLS2')
FOR i = 1 TO Len(aList)
? aList[i]
NEXT i
NNETUSINGR(<cGroup>,[<cServer>|<nConId>]) → aUserList
Netware: 2.2 and 3.11
Arguments
cGroup Designates the group for which the members are determined.
cServer Designates the name of the file server on which cGroup is established. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer. If no server is specified, the function uses the default server.
Returns
NNETUSINGR() returns a one-dimensional array. Each array element contains a user name.
Description
NOVELL NET USERS IN GROUP To improve organization and simplify user access to file server resources, you can create user groups under Novell Netware. Each user can be a member of one or more groups. With the function NNETUSINGR(), all the members of a user group can be determined.
This function requires that the requesting user be logged in on the related file server. If the requesting user is not logged in on the related file server, the function returns an empty array.
Examples
Display all the users that are members of the STONES group on the
current file server:
aList:=NNETUSINGR('STONES')
FOR i = 1 TO Len(aList)
? aList[i]
NEXT i
Determines the server disk space still available to a user
Syntax
NNETUSRFRE([<cUser>]) → nByte
Netware: 2.2 and 3.11
Arguments
cUser Designates the object name, which must be of the type, user. The default value designates the logged in user.
Returns
NNETUSRFRE() returns the disk space that an object (user) can still occupy on the default server.
Description
NOVELL NET USER'S FREE SPACE Available free disk capacity on the file server can be limited relative to an object in newer Novell versions; for example, user JIM can only occupy 10 MB. With NNETUSRFRE(), you can determine how much disk capacity an individual user still has available. If the cUser parameter is not specified, the function returns the space available for the login name.
Notes
■ Console privileges are required in order to determine this
information for other users; however, the user's own free capacity can be determined without additional rights.
■ The value returned for free available space does not guarantee
that it is actually available on the file server hard disk. This can be done using NNETVOLFRE().
Examples
■ Determine your individual disk space still available:
? NNETUSRFRE()
■ Determine the free capacity for user JIM. This function
requires console privileges at least:
IF NNETCOPRIV()
? NNETUSRFRE("JIM") // e.g. 2000 kB
ENDIF
NNETVER([<cDrive>]) → cVersion
Netware: 2.2 and 3.11
Arguments
cDrive Designates a drive. If this parameter is used, the returned version number is related to the file server to which the designated drive is mapped.
() When called without a parameter, the version number of the default file server is returned.
Returns
NNETVER() returns the Novell version number in the format "N.NN".
Description
NOVELL NETWORK VERSION The function returns the version number of the Novell network software being used. If no disk drive is specified, the version number is related to the default file server. With a drive specification, the version number depends on the file server to which the disk drive is mapped. The drive specification was taken into account because different drives can be mapped to different file server versions.
Examples
Display the version number:
? NNETVER() // e.g. 2.15
? NNETVER("T:") // e.g. 3.01
Determines the available capacity of a server volume
Syntax
NNETVOLFRE(<nVolume>) → nBytesAvailable
Netware: 2.2 and 3.11
Arguments
nVolume Designates the number of the selected volume on the related default file server. This value can be from 0 to 31.
Returns
NNETVOLFRE() returns the available free memory capacity on the volume designated by nVolume.
Description
NOVELL NET VOLUME FREE With NNETVOLFRE(), you can determine the amount of free memory capacity available for each volume on the default file server. In this way you can determine if memory intensive file operations can be executed without difficulty, or if files can be copied onto the server.
Notes
■ This function requires that the station have console
privileges at least.
Examples
Determine the capacity still available for all volumes:
FOR I = 0 TO NNETVOLNUM()
? NNETVOLFRE(I) // Available capacity
NEXT I
Determines the maximum number of available server volumes
Syntax
NNETVOLNUM() → nMaxVol
Netware: 2.2 and 3.11
Returns
NNETVOLNUM() returns the maximum number of available volumes on the default file server. If an error occurs, the function returns -1.
Description
NOVELL NET VOLUME NUMBER This function returns the maximum number of available volumes for the default file server. This value can be between 0 and NNETVOLNUM(). With NETVOLNUM() you can determine the name and total free capacity for each active volume. You can also determine all of the available directory entries that are possible.
Notes
■ Volumes between 0 and NNETVOLNUM() can be inactive (not
mounted).
Examples
Determine the names of all the volumes. The function returns a null
string if a volume is inactive:
FOR I = 0 TO NNETVOLNUM()
? NNETVOLNAM(I) // Displays related names
NEXT I
NNETVPASS(<cName>,[<nType>],<cPass>,[<cServer>|
<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cName Designates the name of the bindery object that is processed.
nType Designates the object type of cName. The header file CTNNET.CH contains symbolic constants for a number of object types. The default value designates the object type OBJ_USER.
cPass Designates the password that is verified for cName.
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETVPASS() returns .T. if the password cPass and the password of cName in the bindery are identical. If these passwords are not identical, the function returns .F..
Description
NOVELL NET VERIFY BINDERY OBJECT PASSWORD NNETVPASS() allows you to check to see if a character string matches the password of a bindery object. For example, the function can be used to verify a user's password.
Examples
Check to see if the password HONEY is valid for user JIM:
IF NNETVPASS('JIM',,'HONEY')
? 'Valid password!'
ELSE
? 'Invalid password!'
ENDIF
NNETWHOAMI() returns the names that are logged in at the station in use on the default file server.
Description
NOVELL NET WHO AM I The CA-Clipper NetName() function returns information (limited by the Novell software) in a Novell network when a machine name is defined in the login script. However, NNETWHOAMI() is a special Novell call that returns the name logged in at a station. The returned character string can be up to 48 characters long.
Examples
Determine the name under which the station is logged in:
? NNETWHOAMI() // Character string/max 48 characters
NNETWRTITM(<cObjName>,[<nObjType>],<cProperty>,
<cPropValue>,[<nSegment>],[<lDelete>],
[<cServer>|<nConId>]) → lSuccess
Netware: 2.2 and 3.11
Arguments
cObjName Designates the name of the bindery object that is processed.
nObjType Designates a numeric value that indicates the object type. The header file CTNNET.CH contains symbolic constants for the object types defined by Novell for use with the bindery functions of CA-Clipper Tools. The default value indicates object value OBJ_USER.
cProperty Designates the name of an item property of the object cObjName.
cPropValue Designates the value that is stored. The value must be passed as a character string of up to 128 characters.
nSegment Designates the segment of cProperty in which cPropValue is written. The default value is the first segment.
lDelete Designates whether the segments following nSegment are deleted (.T.) or saved (.F.). The default value (.F.) saves the segments that follow nSegment.
cServer Designates the name of the file server for which the bindery is accessed. Your workstation must be attached to cServer.
nConId Designates the connection ID of your workstation on cServer.
Returns
NNETWRTITM() returns .T. if the operation was completed successfully. If an error occurs, the Novell error code can be queried with the NNETERROR() function.
Description
Important! NNETWRITITM() is a low level bindery function and should be used only with extensive knowledge of the bindery concept and the Novell API.
NOVELL NET WRITE PROPERTY ITEM Internally, Novell Netware defines two different property types: item and set properties. Item properties consist of segments that can accept up to 128 characters. The number of segments within an item property can vary.
A typical example of an item property is the IDENTIFICATION property that contains a user or user group's full name (unlike the login name). NNETWRTITM() allows you to write information to a segment of an item property.
The parameters cName and cType specify the object that is processed. cProperty is the name of the property. The property must have been created before (for example, with NNETCRTPRP()). cPropValue is the character string that is written to nSegment of cProperty. With the parameter lDelete, you can determine whether segments that follow nSegment are deleted (.T.) or not (.F.).
With the parameters cServer or nConId, the bindery of any attached server can be accessed. The connection ID of a server is returned by NNETATTACH() or NNETLOGIN().
To achieve results with NNETWRTITM(), sufficient bindery and property access rights are required. The necessary property access rights depend on the property security of the property that is modified. For efficiency reasons, user defined object types must be passed in the high- low format.
Examples
Set the full name for user MICK:
IF NNETWRTITM('MICK',,'IDENTIFICATION','Michael Smith')
? 'Full name set successfully!'
ELSE
? 'Full name could not be set!'
ENDIF
nLONG|cHexLONG Corresponds to a decimal number or hexadecimal character string to convert.
nBase Designates the number system base, from 2 to 36 (inclusive), to use in the result. The default is the decimal system, base 10.
nLength Designates the length of the string that results. The maximum length is 255. The default is the length required for the conversion.
cPad Designates a pad character to pad the string result on the left. The default value is a space.
Returns
NToC() returns a character string that contains the conversion result of nLONG|cHexLONG into the nBase number system.
Description
NToC() converts a decimal number or hexadecimal string into a number string. The result is a number in base nBase or, if nBase is not specified, in base 10. Use nLength to determine the length of the result string. However, if nLength is longer than the length necessary for the result, the result string is padded on the left with spaces or with a character selected with cPad.
Notes
■ If incompatible parameter combinations are specified, NToC()
returns one or more asterisks (*) as a result.
Examples
■ Convert to base 10:
? NTOC (60000) //"60000"
? NTOC (60000, 10, 7) //" 60000"
■ Convert to base 2:
? NToC(60000, 2) // "1110101001100000"
? NToC("FFFF", 2) // "1111111111111111"
? NToC("30", 2, 8, "0") // "00110000"
■ Convert to base 16:
? NToC(43981, 16) // "ABCD"
■ Convert to base 36:
? NToC(43981, 36, 4) // "XXP"
■ Invalid parameters (overflow):
? NToC("GGGG", 2) // "*"
? NToC(60000, 10, 3) // "***"
? NToC(60000, 1, 4) // "****"
Changes the number of a weekday into a weekday name
Syntax
NToCDoW(<nWeekday>) → cWeekday
Arguments
nWeekday Designates a weekday number from 1 to 7.
Returns
NToCDoW() returns a name that corresponds to its weekday number.
Description
This function converts a weekday number into the corresponding name. Sunday is 1, Monday is 2, Saturday is 7. If you pass a number outside of this range, the function returns a 0 value.
Notes
■ Function operation depends on the country-specific adaptation
of your CA-Clipper compiler. With an English version of CA-Clipper, only English day names are returned.
Examples
An English CA-Clipper returns:
? NToCDoW(1) // "Sunday"
? NToCDoW(4) // "Wednesday"
? NToCDoW(7) // "Saturday"
? NToCDoW(8) // ""
nMonth Designates a month number for which a month name is returned.
Returns
NToCMonth() returns the name that corresponds to the month number.
Description
NToCMonth() determines the month name that corresponds to its month number. January is 1, February is 2, ..., December is 12. If a number outside this range is passed, the function returns a null string as a value.
Notes
The function's operation depends on the country specific adaptation of your CA-Clipper compiler. With an English version of CA-Clipper, only English day names are returned.
Examples
An English CA-Clipper returns:
? NToCMonth(1) //"January"
? NToCMonth(2) //"February"
? NToCMonth(12) //"December"
? NToCMonth(14) //""
Converts a numeric value into a color value in the NN/NN or CC/CC form
Syntax
NToColor(<nAttr>, [<lColorCode>]) → cAttr
Arguments
nAttr Designates the value for the combined numeric color attributes.
lColorCode If designated as .F. or if the parameter is omitted, NToColor() returns a string with a numeric color code. When designated as .T., NToColor() returns a string with the CA-Clipper alpha color coding.
Returns
NToColor() returns the designated color attribute in the NN/NN or CC/CC form.
Description
NToColor() converts a color attribute returned from another function in numeric form, into the alphanumeric data format. Use this attribute in conjunction with the CA-Clipper SET COLOR TO command.
Notes
■ NToColor() returns a null string if the specified attributes
are invalid or unavailable attributes. Acceptable values are in the range of 0 and 255.
■ You cannot specify color attributes in letter format (e.g.,
"B/W") .
Examples
■ Normal display (white on black):
? NToColor(7) // 07/00
? NToColor(7, .T.) // W/N
■ Display red on white. The numeric form 116 yields "04/07":
? NToColor(116) // 04/07
? NToColor(116) // R/W
■ An invalid parameter returns a null string:
? NToColor(380) // ""
? NToColor(-1) // ""
Converts the value returned by a function into a null string
Syntax
Nul(<expValue>) → cNull
Arguments
expValue Designates an expression or function that has a return value you want to suppress.
Returns
Nul() always returns a null string as a value.
Description
Nul() converts a function that returns a value into a function that returns a null string. This suppresses the returned value for every function.
Notes
■ The function is not VOID. It returns a value of a specific
data type — a (null) string. Therefore, you cannot use this function to compare with other data types (see Examples).
Examples
■ Wait for a key stroke:
? "Please press a key :" + Nul(Inkey(0))
■ Show output that uses LIST and waits for a key stroke after 20
lines:
LIST Name, IF(RecNo() %20 = 0, Nul(Inkey(0)), "")
■ This leads to a TYPE MISMATCH:
? 3 = Nul(Inkey(5)) // Error after 5 seconds
? 7 + Nul(Inkey()) // Leads to error, like saying 7+""
nWORD1|cHexWORD1, nWORD2|cHexWORD2, ...nWORDn|cHexWORDn Designates either decimal or hexadecimal number strings.
Returns
NumAnd() joins all designated parameters with the logical "AND" and returns the result.
Description
This function makes it simple to test several bits in a number simultaneously. If bits are connected in an AND configuration, you can mask out specific bits and the unneeded bits are reset to 0. All the numbers specified as parameters are then connected with AND.
Notes
■ An invalid parameter returns a result of -1.
Examples
Test an interface register:
The register contains: 00011101
The constant in binary: 00000111
________
The result: (5) 00000101
nStatus := com_MSR()
IF NumAnd(nStatus, 7) = 5
? "Bit 1 and Bit 2 are set!"
ENDIF
nIgnore Designates the number of characters that are excluded from the search. The default value ignores none.
Returns
The function returns a value that specifies how frequently the cSearchFor sequence was found in the cString.
Description
NumAt() determines how often a particular cSearchFor appears within cString. When you use nIgnore you can lock out a number of characters at the beginning of the cString and keep them out of the search.
The setting for CSetAtMupa() impacts your results. The character string is searched from the left for each occurrence of the cSearchFor string. If CSetAtMupa() is .F., then the search continues after the last character of the found sequence. If CSetAtMupa() is .T., then the search continues after the first character of the found sequence.
Notes
■ By implementing SetAtLike(), wildcard characters can be used
within the search expression.
Examples
■ Count from the first position:
? NumAt("ab", "abcdeabc") // Result: 2
■ Count from the second position. <nIgnore> specifies that one
space is to be skipped:
? NumAt("ab", "abcdeabc", 1) // Result: 1
■ This example shows the impact of CSetAtMupa() when counting
the string "aa" within the <cString> string:
CSetAtMupa(.F.) // Off
? NumAt("aa", "aaaab") // Result: 2
CSetAtMupa(.T.) // On
? NumAt("aa", "aaaab") // Result: 3
■ Examples for the use of SetAtLike() can be found under the
corresponding function description.
nIncrement|nStartValue Designates the incremental value for the internal counter or a new starting value.
lMode Designates whether nIncrement|nStartValue is a new starting value (.T.) or an increment (.F.). The default is increment (.F.).
() Without parameters, the current counter value is returned.
Returns
When called without parameters, this function returns the current counter value; otherwise, it always returns the new counter value.
Description
Always increment count variables and retain the current status when you program counting events. Use NumCount() to simplify this process. When you call NumCount(), the internal counter is increased and the new counter status is returned to the calling program. The count variable is then queried and actualized in one step.
Examples
Data is not output with line numbers, but with a running counter:
NumCount(0, .T.) // Set 0 as a starting value..
LIST OFF NumCount(1), CUST FOR REBATE
The returned value gives the number of logical drives used by DOS.
Description
NumDiskL() returns the number of available drives or the value specified by LASTDRIVE = in CONFIG.SYS. In a NOVELL network, you can determine which is the first network drive (LASTDRIVE +1).
Notes
■ Normally, the function return value is 5, if there is no
deviating input in CONFIG.SYS for LASTDRIVE =.
Examples
Display which drive is the first network drive:
? "First Network Drive: " + Chr(NumDiskL() + 65) + ":"
nWORD|cHexWORD Designates either a decimal number or hexadecimal digit string.
Returns
The higher value byte of the nWORD|cHexWORD 16-bit number is returned.
Description
NumHigh() breaks down a 16-bit number into its two bytes and returns the higher byte as a result. Use this for such functions as SCANKEY() or GETCURSOR(), because NumHigh() separates the two bytes of the keyboard scan code.
Notes
■ An invalid parameter returns a value of -1.
Examples
Break down the combined return value of GETCURSOR():
? "Starting line for the cursor is:", NumHigh(GETCURSOR())
Determines the number of lines required for string output
Syntax
NumLine(<cString>,[<nLineLength>]) → nNumber
Arguments
cString Designates the character string that is processed.
nLineLength Designates the length of an output line. The default value is 80 characters.
Returns
NumLine() returns the number of lines required for text output.
Description
NumLine() can determine the number of lines that are required to output a MEMO field. The return value relates to a line length that is determined by nLineLength.
Notes
■ With the exception of the carriage return and the line feed,
this function treats all characters as printable with a width of 1. If the cString text contains tabs, then you must first use the TabExpand() function to expand the tabs to spaces.
Examples
■ A null string occupies one line:
? NumLine("") // 1
■ A string one character longer also occupies one line:
? NumLine("-") // 1
■ 80 characters, at a line width of 80 characters (default
value), occupy two lines:
? NumLine(Replicate("-", 80)) // 2
■ 100 characters, at a line width of 30 characters, occupy 4
lines:
? NumLine(Replicate("-", 100), 30) // 4
■ A line feed is also handled correctly -- an extra line is
required:
? NumLine("-", +crlf) // 2
? NumLine(Replicate("-", 100) +crlf, 30) // 5
nWORD|cHexWORD Designates either a decimal number or hexadecimal digit string.
Returns
The lower value byte in the nWORD|cHexWORD 16 bit number is returned.
Description
NumLow() breaks down a 16-bit number into its two bytes and returns the higher byte as a result. Use NumLow() with such functions as SCANKEY() or GETCURSOR(), so you can separate the two bytes of the keyboard scan code.
Notes
■ An invalid parameter returns a value of -1.
Examples
Breaks down the combined return value of GETCURSOR():
? "Last line for the cursor is:", NumLow(GETCURSOR())
< nNumber/cNumber> Designates a numeric value in the range of 0 to 65535, or a hexadecimal string within which 8 or 16 bits are mirrored.
l8/16bit Designates whether 16 bits (.F.) or 8 bits (.T.) are mirrored. The default value is .F..
Returns
NumMirr() returns a value by which the bit opposite the first parameter is mirrored. If there is an invalid parameter, a value of -1 is returned.
Description
Use this function in the accompanying font editor to mirror characters with bit patterns. Bits with values in 0 to 65535 range are mirrored. When you mirror bit 16, bit 1 interchanges with bit 16, bit 2 with bit 15, etc.. You can also designate the first parameter as a hexadecimal string in "0ABE" form and the result is always numeric.
Examples
■ Initialize the number to mirror:
nVar := 128 + 64 + 8 + 2 // 00000000 11001010
■ Mirror bit 16:
? NToC(NumMirr(nVar), 2, 16, "0") // 01010011 00000000
■ Only mirror bit 8:
? NToC(NumMirr(nVar, .T.), 2, 16, "0") // 00000000 01010011
nWORD1|cHexWORD1...nWORDn|cHexWORDn Designates either decimal numbers or hexadecimal digit strings.
Returns
The returned value corresponds to all the values designated as parameters joined with a logical OR.
Description
NumOr() allows you to target and set a single bit or multiple bits. For example, use this to set a file attribute.
Notes
■ An invalid parameter returns a result of -1.
Examples
Set bit 5 in the MCR interface register of port 1, without changing any
other bits:
The register contains: 00000011
The constant in binary: 00010000
________
The result: (19) 00010011
com_MCR(1, NumOr(com_MCR(1), 16))
nWORD1|cHexWORD1 Designates a numeric or hexadecimal value in the range of 0 to 65535.
nWORD2|cHexWORD2 Designates a number of rotations in the range of 1 to 15 (1 to 7); as either numeric or hexadecimal.
lLowByte If this optional parameter is designated as .T., then the low byte of the specified WORD is rotated. The default is a 16-bit rotation (.F.).
Returns
NumRol() returns the rotation result.
Description
This function rotates bits to the left in a number between 0 and 65535 (16-bit value). When the high bit rotates it is not just moved out to the left, it is also moved in on the right. Use the optional logical parameter to determine if all 16 or only the low value 8 bits are to rotate.
Notes
■ If a value of > 15(7) is designated for nWORD1|cHexWORD1,
the actual number of rotations for the remainder corresponds to a value divided by 16(8).
■ A right rotation is also possible. One rotation to the right
corresponds to 15(or 7) rotations to the left, etc..
Examples
■ Rotate the 1 value three times to the left:
00000000 00000001 00000000 00001000
? NToC(1, 2, 16, "0"), NToC(NumRol(1, 3), 2, 16, "0")
// Display as binary
■ Value of 60000 -- only rotate the low 8-bit value:
11101010 01100000 11101010 10000001
NumRol(60000, 2, .T.)
■ Construct a rotation two places to the right:
00000000 00000100 00000000 00000001
? NumRol(4, 14)
■ In parameter 2 > 15, there is only one rotation:
? NumRol(1, 33) // Result: 2
cDelimiter Designates the delimiter list used by the passer.
nSkipWidth Designates after what number of delimiter characters or sequences to count a token. This is helpful for counting empty tokens. The default value indicates that empty tokens are not taken into account.
Returns
The number of tokens contained in the cString is returned.
Description
Use NumToken() to determine how many words (or tokens) are contained in the character string. The function uses the following list of delimiters as a standard:
CHR 32, 0, 9, 10, 13, 26, 32, 138, 141
and the characters ,.;:!?/<<>>()^#&%+-*
The list can be replaced by your own list of delimiters, cDelimiter. Here are some examples of useful delimiters:
Table 4-3: Recommended Delimiter Sequences
Description <cDelimiter>
Pages Chr(12)(Form Feed)
Sentences ".!?"
File Names ":\."
Numerical strings ",."
Date strings "/."
Time strings ":."
The skip value designates the number of characters after which a token is counted again. This also allows empty tokens, like blanks within a string, to be counted.
Examples
■ A character string is searched using the standard delimiter
list:
? NumToken("Good Morning!") // Result: 2
■ Your own list of delimiters can be specified for particular
reasons. Since the delimiter list for the following example only
contains the characters ".!?", the result is 3.
? NumToken("Yes! That's it. Maybe not?", ".!?")
■ This example shows how to count empty tokens. Parameters
separated by commas are counted, but some of the parameters are
skipped. A token is counted after at least one delimiter (comma):
String := "one,two,,four"
? NumToken(String, ", ", 1) // Result: 4
nWORD1|cHexWORD1 and nWORD2|cHexWORD2 Designates as either decimal numbers or hexadecimal digit strings.
Returns
The returned value corresponds to all the values designated as parameters joined with a logical exclusive OR.
Description
Only those bits that are different in the 2-bit fields and that you want to link together, are set to 1 in the result value. Use NumXor() to encode smaller numbers.
Notes
■ An invalid parameter returns a result of -1.
Examples
■ Link two numbers with NumXor():
Value 1 in binary: 00000011
Value 2 in binary: 00000101
________
The result: (6) 00000110
? NumXor(3, 5) // Result: 6
■ Encode and decode numbers:
? NumXor(NumXor(nNumber, 9), 9)
NUMBUFFERS() returns the number of buffers that are set in CONFIG.SYS (BUFFERS=nn).
Description
NUMBUFFERS() determines the BUFFERS setting in the CONFIG.SYS file.
Notes
■ The information is not read from the CONFIG.SYS file, but
determined from an internal DOS table. Therefore, the buffers setting in CONFIG.SYS may not contain the same value as numbuffers, if it has been changed since that most-recent system boot.
NUMCOL() returns the number of columns available on the screen or in the current window, under CA-Clipper.
Description
Use NUMCOL() to establish screen width to determine the line break for output.
NUMCOL() receives its return value from the BIOS and then, in conjunction with DSETWINDOW(), returns the number of columns on the physical screen or for a window.
Examples
Column count for the open window:
WOpen(10, 10, 20, 70) // Open window
SETWINDOW(.T.) // Default
? NUMCOL() // 61 columns
DSETWINDOW(.F.) // Do not reroute external output?
NUMCOL() // 80 columns
NUMDISKH() returns the number of physical hard disk drives.
Description
This function determines the number of physical hard disk drives (one or two). These should not be confused with logical hard disk drives, that can be designated with DOS 3.3.
Notes
■ The function receives its information from the BIOS.
Examples
■ How many hard disk drives does my system have?
? NUMDISKH() // Result: 1
Determines the maximum number of files you can open simultaneously
Syntax
NUMFILES() → nNumber
Returns
NUMFILES() returns the maximum number of files you can open simultaneously in all active programs.
Description
NUMFILES() determines the number of files that can be open simultaneously under DOS. This information corresponds to the FILES= setting in the CONFIG.SYS file. However, it is read from an internal DOS table, not this file. Therefore, the function operates with or without CONFIG.SYS, and returns more accurate system information.
Notes
■ The function cannot determine if an additional operating
system adaptation (Novell's SHELL.CFG) has been made under a Novell. network. These adaptations are only used for the current network drive under Novell.
Examples
Display the maximum number of files you can open:
? NUMFILES() // e.g. 30
NUMPRINTER() returns the number of parallel printer interfaces installed on the machine.
Description
Once you establish that multiple printer ports are installed, choose which printer wants to use (e.g., dot-matrix or laser printer). NUMPRINTER() also detects if a printer is not installed over the usual printer interface, because there is no port available.
Notes
■ This function cannot determine if a printer is connected and
ready to operate.
Examples
Determine if a printer interface is available:
? "There are " + Str(NUMPRINTER(), 2) + " Printer ports"
?? "available"
nSocket Designates the number of the socket that is opened.
Returns
OPENSOCK() returns the number of the socket if the socket has been opened successfully. If an error occurs, the function returns 0.
Description
An IPX or SPX communication is handled through "sockets" (see the Introduction to this chapter). OPENSOCK() allows you to explicitly open a socket before a call of IPXOPEN(), SPXESTBCON(), or SPXLISTCON(). If OPENSOCKET() is called with the argument 0, any available socket can be opened. The socket's number is returned by OPENSOCK().
the source socket automatically. A call of OPENSOCKET() is not necessary.
Examples
■ Open socket 20000:
IF OPENSOCK(20000)=0
? 'Socket could not be opened!'
ELSE
? 'Socket has been opened successfully!'
ENDIF
■ Open any available socket:
? 'Socket',OPENSOCK(0),' opened!'
OSVER() returns a character string that contains the version number of the operating system in use.
Description
OSVER() returns the version number of the operating system in use. The format picture clause is always "'9.99". Use OSVER() to determine the DOS version your application uses.
Examples
Certain operations require particular DOS versions:
IF OSVER() < "3.30"
? "COMMIT can not be used!"
ENDIF
nPort|cHexPort Designates a port address to which you can pass a byte. This value can be a decimal integer or hexadecimal string.
nOutByte|cHexOutByte Designates the byte passed to the specified port. This value can be a decimal integer or hexadecimal string.
Returns
OUTBYTE() returns .T. when the operation is successfully completed. A return value of .F. indicates a parameter error.
Description
CA-Clipper Tools always attempts to offer finished solutions at the highest-possible level for such standard hardware as a serial interface port.. However, if highly specialized systems and their ports are to receive data from CA-Clipper, use OUTBYTE() or OUTWORD().
Notes
■ The function does not determine if a port is available, or if
you cannot write to it.
Examples
Transfer a byte to the fifth port address of the first serial interface
port. This is only an example, since CA-Clipper Tools has special
serial interface port functions.
■ With a decimal parameter:
? OUTBYTE(1020, 1) // 5th port COM1, DTR On
■ With a hexadecimal parameter:
? OUTBYTE("3FC", 0) // 5th port COM1, DTR Off
nPort|HexPort Designates a port address to which a word with a 16- bit value is passed. This value can be a decimal integer or hexadecimal (sedecimal) string. The maximum is 65520 ("FFF0" Hex).
nOutWord|cHexOutWord Designates the word passed to the specified port. This value can be designated as a decimal integer or hexadecimal (sedecimal) string. The maximum is 65536 ("FFFF" Hex).
Returns
OUTWORD() returns .T. when the operation is successfully completed. A return value of .F. indicates a parameter error.
Description
CA-Clipper Tools always attempts to offer finished solutions at the highest-possible level for such standard hardware as the serial interface port.. However, if, highly specialized systems and their ports are to receive data from CA-Clipper, use OUTBYTE() or OUTWORD().
Notes
■ The function does not determine if a port is open or if you
cannot write to it.
Examples
Output to a 16-bit port.
■ With a decimal parameter:
? OUTWORD(512, 32) // Write word to an additional device
■ With a hexadecimal parameter:
? OUTWORD("200", "20") // Same port, same value
cCharacter|nCharacter Designates the character with which the beginning of the cString string is filled. The default value is a space, Chr(32).
Returns
The processed cString is returned.
Description
PadLeft() allows you to pad the beginning of character strings with characters, in accordance with a length specification. Spaces or any other characters you choose can be used.
Notes
■ The function works like the CA-Clipper Right() function when
nLength is shorter than the length of cString. If nLength is negative, PadLeft() returns a null string.
■ When the cCharacter|nCharacter parameter is not specified,
spaces are automatically used for padding.
Examples
■ The function works like Right():
? PadLeft("123456", 4) // "3456"
■ Pad the left with spaces:
? PadLeft("123456", 8) // " 123456"
■ Pad the left with the "." character:
? PadLeft("123456", 8, ".") // "..123456"
nLength Designates the selected new length for cString.
cCharacter|nCharacter Designates the character with which the beginning of the cString string is filled. The default value is a space, Chr(32).
Returns
The processed cString is returned.
Description
PadRight() allows you to pad the end of a character string with characters, in accordance with a length specification. Spaces or any other characters that you choose can be used.
Notes
■ The function works like the CA-Clipper Left() function when
nLength is shorter than the length of cString. If nLength is negative, PadRight() returns a null string.
■ When the cCharacter|nCharacter parameter is not specified,
spaces are automatically used for padding.
Examples
■ The function works like Left():
? PadRight("123456", 4) // "1234"
■ Pad the right with spaces:
? PadRight("123456", 8) // "123456 "
■ Pad the right with the "." character:
? PadRight("123456", 8, ".") // "123456.."
nInterestRate Designates the periodic interest rate. 1 corresponds to 100%.
nNumberPayments Designates the number of payments on the loan within the payment period.
Returns
Payment() returns the payment to make for each payment period.
Description
Payment() computes the payment for each period where loan interest applies. The determined amount relates to a loan amount nCapital that is repaid over nNumberPayments, at an interest rate of nInterestRate.
Examples
How high does the monthly annuity amount have to be, if you want to
repay a $2,000.00 loan within 24 months at an annual interest rate of
10%:
nRate := 0.1/12 // The monthly rate
? Payment(2000, Rate, 24) // 92.29 per month
nOriginalPage Designates the page from which you copy.
nCopyPage Designates the target page, the page to which you copy.
Returns
The function returns a value of .T. if the copy is successful.
Description
A complete screen page (nOriginalPage) can be moved to another screen page (nCopyPage). With this function, the entire contents of the screen memory can quickly be copied to another page, without the need for additional working memory for a string.
Notes
■ To find the valid range of page numbers, use the MAXPAGE()
function.
Examples
Copy screen page 0 to page 1:
? PAGECOPY(0, 1) // .T., if successful
PCType() returns a numeric code to identify the type of computer.
Description
This function differentiates between the different types of PC's. The function determines the type of computer installed in the application The following codes apply:
Table 12-5: Computer Type Coding
Value Symb. constants PC-Type
255 PC_NORMAL Normal PC
254 PC_XT PC-XT (w/hard disk)
253 PC_JUNIOR PC jr
240 PC_MODEL30 Model 30
251 PC_XT_2 XT/2
249 PC_LAPTOP Laptop
252 PC_AT AT/XT-286/Model 50/Model 60
248 PC_MODEL80 Model 80
45 PC_COMPAQP COMPAQ Portable
154 PC_COMPAQ COMPAQ Portable Plus
Notes
■ 386 and 486 computers are often coded as AT's.
■ The values correspond to IBM BIOS codes. An incompatible BIOS
might return a different value.
Examples
What type of computer is installed?
? PCType() // 252 an AT!
nPayment Designates the amount of the scheduled periodic payment.
nInterestRate Designates the periodic interest rate. 1 corresponds to 100%.
Returns
Periods() returns the number of payments required to repay the nCapital amount.
Description
Periods() computes how often you must make a payment nPayment to reach the nCapital amount at the nInterestRate interest rate.
Notes
■ If the installment payment is smaller than the interest
amount, repayment lasts forever. In this case, the function returns a value of -1.
Examples
How many months do you need to pay back a $4000 loan at an annual
interest rate of 9.5%, if you want the $200 monthly payments?
nRate := 0.095/12 // Monthly rate
? Periods(4000, 200, Rate) // Number of periods
nSegment|cHexSegment Designates the segment address from which the byte is read. This value can be a decimal integer or hexadecimal string. The maximum is 65520 ("FFF0" Hex).
nOffset|cHexOffset Designates the offset address within the segment specified by nSegment|cHexSegment. This value can be a decimal integer or hexadecimal string. The maximum is 65535 ("FFFF" Hex).
Returns
PEEKBYTE() returns the byte to be read or a value of -1, if there is an error.
Description
PEEKBYTE() reads a byte from a desired memory region within conventional memory. You must specify the segment address and offset.
Examples
■ Show a decimal parameter:
? PEEKBYTE(1000, 2000) // Segment 1000d, Offset 2000d
■ Show a hexadecimal parameter:
? PEEKBYTE("F000", "8000") // The byte at address F800h
nSegment|cHex Designates the segment address from which the character sequence string is read. This value can be a decimal integer or hexadecimal string.
nOffset|cHexOffset Designates the offset address within the segment specified by nSegment|cHexSegment. This value can be a decimal integer or hexadecimal string.
nLength|cHexLength Designates the string length to read, up to a maximum of 65520. This value can be a decimal integer or a hexadecimal string. The default, PEEKSTR(), reads to the first Chr(0).
Returns
PEEKSTR() returns the character string read from memory.
Description
PEEKSTR() reads an area of memory and returns it as a string. The function reads to the first Chr(0) or the length specified through nLength|cHexLength.
Examples
The AT BIOS copyright is found at the F000:0h address. Therefore, each
byte is repeated and CharOdd() is used to display it. It reads to the
first Chr(0):
? CharOdd(PEEKSTR("F000", 0)) // "19xx, 19xx Copyright...."
nSegment|cHex Designates the segment address from which a word is read. This value can be a decimal integer or a hexadecimal string.
nOffset|cHexOffset Designates the offset address within the segment specified by nSegment|cHexSegment. This value can be a decimal integer or hexadecimal string. The maximum is ("FFFE").
Returns
PEEKWORD() returns the word that is read in or a value of -1, if an error occurs.
Description
In contrast to PEEKBYTE(), this function reads 16 bits from memory. In this way, WORDS (16-bit integers) are read directly out of two memory regions within conventional memory. Therefore, you must specify a value for the segment address and offset.
Notes
■ PEEKWORD() assumes that a 16-bit value is presented in the low-
byte/high-byte sequence.
Examples
■ Peek a word using a hexadecimal parameters:
? PEEKWORD("F000", "8000") // The WORD at address F8000h
■ Store a value in memory and then retrieve it:
POKEBYTE("9000", "F000", 1) // 1 stored-9F000h (low byte)
POKEBYTE("9000", "F001", 2) // 2 stored-9F001h (high byte)
? PEEKWORD("9000", "F000") // Word at 9F000h 513
lMode Designates how the function searches for the first alphabetic character in a string. The default value (.F.) searches for the first alphabetic character.
nIgnore Designates the number of characters at the beginning of the character string that are excluded from the search. The default value excludes none (0).
Returns
The value returned is the position of the first alphabetic character in cString. If no alphabetic character is located, the function returns 0.
Description
Starting from the left, PosAlpha() searches for the first alphabetic character in cString that corresponds to the first character that can be changed by the CA-Clipper Lower() or Upper() functions. If lMode is .T., then the function searches for the first non-alphabetic character. The nIgnore parameter can exclude a specific number of characters at the beginning of the cString from the search.
Notes
■ Notice that characters located when lMode is .T. are always
numbers or special characters, but are never alphabetic characters.
■ This function works in conjunction with the NATION module
because different languages use different characters to represent their alphabets.
cString [@] Designates the character string within which the individual character cCharacter|nCharacter is substituted.
cCharacter|nCharacter Designates an individual character or a numeric ASCII value from 0 to 255.
nPosition Designates the position at which the character is substituted. The default value is the last position in cString.
Returns
The string returned is the cString with a cCharacter|nCharacter character in the selected position.
Description
PosChar() allows you to replace an individual character within a string without having to split the string. Since this character is only substituted at the designated position within cString, the string that is modified can be passed by reference.
Notes
■ The value returned by this function can be suppressed by
implementing CSetRef() to save space in working memory.
Examples
■ Substitute a character at position 3:
? PosChar("ABCDEF", "X", 3) // "ABXDEF"
■ Substitute a character in the last position:
? PosChar("ABCDEF", "X") // "ABCDEX"
■ Pass the string by reference:
CSetRef(.T.) // Suppress return value
cVar := "ABCDEF"
PosChar(cVar, "X")
? cVar // "ABCDEX"
cString Designates the character string from which the characters are deleted.
nStartPos Designates from which position the deletion begins.
nNumber Designates the number of characters to delete.
Returns
The modified string is returned.
Description
This function permits the removal of nNumber of characters from cString, beginning from nStartPos.
Notes
■ nStartPos is optional. If this parameter is not specified,
then PosDel() begins at the end of the cString and deletes the specified number (nNumber) of characters.
Examples
■ Delete two characters from a string:
? PosDel("Parameter", 3, 2) // "Pameter"
■ Delete the last two characters:
? PosDel("Parameter", , 2) // "Paramet"
cString1 and cString2 Designate the two character strings that are compared.
nIgnore Designates how many characters at the beginning of the character strings are excluded from the search. The default value excludes none (0).
Returns
PosDiff() returns the first position where cString1 and cString2 differ. If both character strings are equal, then the function returns 0.
Description
PosDiff() compares two strings and determines from which position the first difference occurs. The nIgnore parameter allows you to exclude a particular number of characters from the beginning of both character strings from the search.
Notes
■ Character strings of different lengths can be compared with
each other (see examples).
Examples
■ This example compares two strings of the same length:
cString1 := "X23AB$/A"
cString2 := "X23A8$/A"
? PosDiff(cString1, cString2) // Result: 5
■ Two strings of different lengths can also be compared:
? PosDiff("AB", "ABC") // Result: 3
cString1 and cString2 Designate the two character strings that are compared.
nCompare Designates the number of characters that must be the same. The default value is the length of the shorter string.
nIgnore Designates the number of characters that are disregarded at the beginning of the search. The default value is none.
Returns
PosEqual() returns the position from which the two character strings are the same for nCompare characters. If no corresponding agreement is found, the function returns 0.
Description
PosEqual() allows you to determine at which point two strings agree. The length of this agreement is represented by nCompare. If not specified, nCompare defaults to the length of the shorter string.
Additionally, the nIgnore parameter lets you specify a particular number of characters that are excluded from the start of the strings during the comparison.
Examples
■ In this example, there is no agreement to the end of the
string:
cString1 := "ABCDEFGHI"
cString2 := "XYZDEKLMN"
? PosEqual(cString1, cString2) // Result: 0
■ This example shows the agreement of at least two characters:
? PosEqual(cString1, cString2, 2) // Result: 4
■ This example shows a single character agreement and excludes
the first four characters:
? PosEqual(cString1, cString2, 1, 4) // Result: 5
cString Designates the character string into which characters are inserted.
cInsertstring Designates the new characters that are inserted into cString.
nPosition Designates the position where the new characters are inserted within cString. The default value inserts the characters in front of the last character.
Returns
PosIns() returns the string with the inserted characters.
Description
You can use PosIns() to insert characters into an existing character string. The cInsertstring characters are inserted into the cString at the location specified by nPosition.
Notes
■ The resulting character string is longer than the original, so
this function cannot be called by reference.
Examples
■ Insert "123" at position 2:
? PosIns("abcdefgh", "123", 2) // "a123bcdefgh"
■ Insert "123" at position 8:
? PosIns("abcdefgh", "123", 8) // "abcdefg123h"
■ Give an erroneous position:
? PosIns("abcdefgh", "123", 10) // "abcdefgh"
lMode Designates how the function searches for the first lower case alphabetic character. The default value (.F.) searches for the first alphabetic character that can be changed by the CA-Clipper function Upper().
nIgnore Designates the number of characters at the beginning of the character string that are excluded from the search. The default value excludes none (0).
Returns
The value returned corresponds to the position of the character located. When no matching character is found, the function returns 0.
Description
Starting from the beginning of the string, PosLower() searches for the first lower case alphabetic character in cString. If lMode is .T., the function searches for the first non-alphabetic character that would not be changed by Upper(). The nIgnore parameter excludes a specific number of characters at the beginning of the cString from the search.
Notes
■ Characters located when the lMode parameter is designated as
.T. are not necessarily upper case, alphabetic characters.
■ The function works in conjunction with the NATION module
because different languages use different characters to represent their alphabets.
cCharacter1 and cCharacter2 Designate the first and the last character of the character range.
cString Designates the string within which to search for a character in the cCharacter1 to cCharacter2 range.
lMode Designates if the return value is within the specified range or outside of the range. The default value (.F.) searches for the first character within the range.
nIgnore Designates the number of characters at the beginning of the character string that are excluded from the search. The default value excludes none (zero).
Returns
The value returned corresponds to the position of the located character. If no character is found, the function returns 0.
Description
Beginning from the left, PosRange() searches for the first character in the range cCharacter1 to cCharacter2 within cString. If lMode is specified as .T., then the function searches for the first character that is not in the specified range. This way you could search for control characters within a string by specifying cCharacter1 = Chr(0) and cCharacter2 = Chr(31).
The nIgnore parameter gives you the ability to exclude a particular number of characters at the beginning of the cString from the search.
Examples
■ Search for the first character in the character string cInput
that is not a control character:
cInput := com_Read(1)
? PosRange(Chr(0), Chr(31), cInput, .T.)
■ Ignore the first 10 characters:
? PosRange(Chr(0), Chr(31), cInput, .T., 10)
cString [@] Designates the character string within which the particular characters are replaced.
cReplacementstring Designates a sequence of characters that, starting at nStartPos, replace a portion of cString.
nStartPos Designates from which character within cString the replacement starts.
Returns
PosRepl() returns the modified string.
Description
When you use PosRepl(), you can replace a range of characters within cString with another character string cReplacementstring. The new characters are exchanged beginning at nStartPos.
Notes
■ When the nStartPos parameter is not specified, the
cReplacementstring overwrites the end of the string (see examples).
■ The return value of this function can be suppressed by
implementing CSetRef() to save space in working memory.
Examples
■ Starting at position 3, replace three characters with "XXX":
? PosRepl("ABCDEFG", "XXX", 3) // "ABXXXFG"
■ Replace the last Len(<cReplacementstring>) characters:
? PosRepl("ABCDEFG", "XXX") // "ABCDXXX"
■ The result can be longer than the character string passed.
? PosRepl("ABCDEF", "123", 5) // "ABCD123"
? PosRepl("ABCDEF", "123", 6) // "ABCDE123"
lMode Designates how the function searches for the first upper case, alphabetic character. The default value (.F.) searches for the first alphabetic character that would be changed by the CA-Clipper function Lower().
nIgnore Designates the number of characters at the beginning of the character string that are excluded from the search. The default value excludes none (0).
Returns
The value returned corresponds to the position of the character located. When no matching character is found, the function returns 0.
Description
Starting from the beginning of the string, PosUpper() searches for the first upper case, alphabetic character in the cString that corresponds to the first character that would be changed by the CA-Clipper Lower() function. If lMode is .T., the function searches for the first non- alphabetic character that would not be changed by Lower(). The nIgnore parameter can exclude a specific number of characters at the beginning of cString.
Notes
■ Characters located when the lMode parameter is .T. are not
necessarily lower case, alphabetic characters.
■ The function works in conjunction with the NATION module
because different languages use different characters to represent their alphabets.
nSegment|cHexSegment Designates the segment address in which a byte is stored. This value can be a decimal integer or hexadecimal string. The maximum is 65520 ("FFF0").
nOffset|cHexOffset Designates the offset address within the segment specified by nSegment|cHexSegment. This value can be a decimal integer or hexadecimal string. The maximum is 65535 ("FFFF").
nByte|cHexByte Designates the byte to store in memory. This value can be a decimal integer or hexadecimal string. The maximum is 255 ("FF").
Returns
POKEBYTE() returns .T., if the operation is successfully completed. A return value of .F. indicates a parameter error.
Description
POKEBYTE() writes a byte to a desired memory area within conventional memory. The segment address and offset are required.
Warning! Be aware that this is not always safe. If you inadvertently manipulate the wrong memory location, there may be serious consequences. Use POKEBYTE()ONLY when you have a thorough knowledge of the system environment and there is no other solution than to directly alter a memory location.
Notes
■ The function does not check if you can store the byte in
memory.
Examples
■ Poke a byte using decimal parameters:
? POKEBYTE(32768, 1000, 65) // Can be dangerous!
■ Poke a byte using hexadecimal parameters:
? POKEBYTE("F000", "8000", "41") // Impossible, ROM area
nSegment|cHex Designates the segment address where a word is stored. This value can be a decimal integer or hexadecimal string. The maximum is 65520 ("FFF0").
nOffset|cHexOffset Designates the offset address within the segment specified by nSegment|cHexSegment. This value can be a decimal integer or hexadecimal string. The maximum is 65534 ("FFFE").
nWord|cHexWord Designates the word to be stored in memory. This value can be a decimal integer or hexadecimal string. The maximum is 65535 ("FFFF").
Returns
POKEWORD() returns .T. when the operation is successfully completed. A return value of .F. indicates an error.
Description
POKEWORD() writes a word to a desired memory area within the conventional memory. The segment address and offset are required.
Warning! Be aware that this is not always safe. If you inadvertently manipulate the wrong memory location, there may be serious consequences. Use POKEWORD()ONLY when you have a thorough knowledge of the system environment and there is no other solution than to directly alter a memory location.
Notes
■ The function does not test whether the word is stored in
memory.
■ POKEWORD() stores the nWord|cHexWord word in memory in the
low-byte/high-byte sequence.
Examples
■ Poke a word using decimal parameters:
? POKEWORD(32768, 1000, 65535) // Can be dangerous!
■ Poke a word using hexadecimal parameters:
? POKEWORD("F000", "8000", "FFFF") // Impossible, ROM area
PPCBUFTYP(<nHandle>) → nBufferType
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication buffer.
Returns
PPCBUFTYP() returns a type code that indicates the protocol of the specified communication buffer. For all possible types (IPX, SPX, NetBIOS Datagram, or NetBIOS session), the header file CTPPC.CH contains symbolic constants according to the following table.
Table 31.4: Possible Return Values of PPCBUFTYP()
Value Sym. Con. Definition
1 PPC_IPX IPX
17 PPC_SPX SPX
2 PPC_NBD NetBIOS datagram
18 PPC_NBS NetBIOS session
The numeric values might change in future versions, so you should use symbolic constants. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCBUFTYP() allows you to develop procedures that can work with any communication buffer. With PPCBUFTYP(), protocol specific calls can be made, depending on the buffer type.
Examples
Determine the destination's name within a session and thereby
differentiate between SPX and NetBIOS session buffers:
#include "ctppc.ch"
IF PPCBUFTYP(nHandle)=PPC_SPX
? 'Destination name:',SPXCONTARG(nHandle)
ELSEIF PPCBUFTYP(nHandle)=PPC_NBS
? 'Destination name:',NBSCONTARG(nHandle)
ELSE
? 'Error: No session buffer!'
ENDIF
Closes the communication handle and the connected buffers
Syntax
PPCCANCEL(<nHandle>) → lSuccess
Netware: 2.2 and 3.11
Arguments
nHandle Designates the handle of the communication buffer that is closed.
Returns
PPCCANCEL() returns .T. if the communication buffer has been closed successfully. If an error occurs, the function returns .F..
Description
PPCCANCEL() allows you to close any communication buffer, independently of the protocol used (IPX, SPX, NetBIOS datagram or NetBIOS session). The handle of the selected communication buffer must be passed to PPCCANCEL(). PPCCANCEL() uninstalls the procedures for interrupt controlled sending and receiving and releases allocated memory. When PPCCANCEL() is called, all data in the sending or receiving buffer is lost. After a call of PPCCANCEL(), nHandle is invalid.
Examples
Open and close the communication buffer:
nHandle=IPXOPEN(20000,546)
// ...
// Using the communication buffer ....
// ...
// Close communication buffer
PPCCANCEL(nHandle)
PPCCONACT(<nHandle>) → lAktive
Netware: 2.2 and 3.11
Arguments
nHandle Designates a communication handle that identifies the communication buffer.
Returns
PPCCONACT() returns .T. if nHandle specifies an active connection. If an inactive connection occurs, the function returns .F..
Description
PPCCONACT() is used mainly in conjunction with session- oriented protocols (SPX or NetBIOS session). PPCCONACT() allows you to determine if a connection has been set up after the call of a function that waits for a connection setup in the background: for example, SPXLISTCON() or BSLISTCON(). You can also check to see if a connection is still active. If an error occurs (for example, if a connection has been canceled), the function returns .F..
Notes
■ When used for IPX or NetBIOS datagram connections, PPCCONACT()
always returns .T..
Examples
Wait for an SPX connection setup:
nHandle=SPXLISTCON(20000,1000)
WHILE .NOT. PPCCONACT(nHandle)
ENDDO
Queries the event code that most recently triggered a key trap
Syntax
PPCEVENT(<nHandle>) → nEventCode
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication receiving buffer.
Returns
PPCEVENT() returns a numeric code that specifies the event that most recently triggered a key trap for the communication buffer defined by nHandle. All possible event codes can be seen in the following table.
Table 31.5: Possible Return Values of PPCEVENT()
Value Sym. Con. Definition
1 PPC_RECSUC Packet received successfully
2 PPC_RECFAIL Packet received with errors
4 PPC_RECBUFF75FULL Receiving buffer more than 75% full
8 PPC_RECPACKDISCARD Packet discarded because of a full receiving
buffer
16 PPC_SNDFAIL Failure during sending of a packet
32 PPC_CONESTAB Session set up successfully
64 PPC_CONTERM Session terminated
A value of 0 indicates that no event has been triggered through PPCKEY() since the installation of the event handler. If an error occurs (for example, if the handle is invalid), PPCEVENT() returns -1.
Description
With the function PPCKEY() you can define a key code for each communication buffer to be triggered when a specified event occurs. PPCEVENT() allows you to determine the last event. Dependent on the return value of PPCEVENT(), various actions can be executed in the event handler. If no event mask has been defined for the communication buffer, PPCEVENT() returns 0.
Examples
Open an SPX receiving buffer and wait for a connection in the
background. An event supervision is installed with PPCKEY() for the
communication buffer. The event handler displays a message when a
connection is set up or canceled. Additionally, the receiving buffer is
read as soon as it is 75% full:
#include "ctppc.ch"
PRIVATE nHandle
// Wait for connection on socket 20000
// open receiving buffer of 5000 bytes
nHandle:=SPXLISTCON(20000,5000)
// install event handler
// PPC_CONESTAB+PPC_CONTERM+PPC_RECBUFF75FULL=100
PPCKEY(nHandle,255,100)
SET KEY 255 TO handler
WAIT
PROCEDURE handler
LOCAL nEvent:=PPCEVENT(nHandle)
LOCAL cBuffer
DO CASE
CASE nEvent=PPC_CONESTB
? 'Connection set up!'
CASE nEvent=PPC_CONTERM
? 'Connection terminated!'
CASE nEvent=PPC_RECBUFF75FULL
cBuffer=PPCREAD(nHandle)
ENDCASE
RETURN
Supervises the communication buffer with key traps
Syntax
PPCKEY(<nHandle>,[<nKeyValue>],[<nEventMask>])
→ lSuccess
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication receiving buffer.
nKeyValue Designates the key code that is triggered when specific events occur. All values of the CA-Clipper KEYBOARD command are valid. Without this parameter, a previously set buffer supervision is removed.
nEventMask Designates a numeric value that determines the events that trigger a key trap. The value contains an OR operation of various events according to the following table.
Table 31.6: Event Codes for PPCKEY()
Value Sym. Con. Definition
1 PPC_RECSUC Packet received successfully
2 PPC_RECFAIL Packet received with errors
4 PPC_RECBUFF75FULL Receiving buffer more than 75% full
8 PPC_RECPACKDISCARD Packet discarded because of a full receiving
buffer
16 PPC_SNDFAIL Failure during sending of a packet
32 PPC_CONESTAB Session set up successfully
64 PPC_CONTERM Session terminated
The default value (127) triggers a key trap on each event. The symbolic constants are defined in the header file CTPPC.CH.
Returns
PPCKEY() returns .T. when a key code has been set or removed successfully.
Description
PPCKEY() allows you , independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session), to supervise a communication buffer within a wait state without having to control specific values (for example, the number of characters in buffer). If an event that is specified by nEventMask occurs, PPCKEY() puts the key code nKeyValue into the keyboard buffer. With a previously defined SET KEY procedure, you can react to the event immediately . For example, with PPCEVENT() you can determine the event that triggered the key trap.
If no key code is passed for PPCKEY(), the supervision for the communication handle is removed.
Examples
■ Put key code 255 into the keyboard buffer at any event:
IF PPCKEY(nHandle,255)
? 'Event handler installed successfully!'
ELSE
? 'Event handler could not be installed!'
ENDIF
■ Store key code 255 to the keyboard buffer when a packet is
received:
#include "ctppc.ch"
PPCKEY(nHandle,255,PPC_RECSUC)
■ Store key code 255 to the keyboard buffer when a session is
set up or canceled (only for SPX or NetBIOS session communication):
#include "ctppc.ch"
PPCKEY(nHandle,255,NumOr(PPC_CONESTB,PPC_CONTERM))
■ Remove the event supervision:
PPCKEY(nHandle)
PPCREAD(<nHandle>,[<nLength>],[<lNotDelete>])
→ cString
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication buffer from which the receiving buffer is read.
nLength Designates the number of characters that are read. The default value reads all characters.
lNotDelete Designates whether the characters are deleted (.F.) or not (.T.) after the buffer has been read. The default value (.F.) indicates that the characters are deleted.
Returns
PPCREAD() returns a character string that contains the characters that have been read from the receiving buffer. If an error occurs (for example, if the handle is invalid or the communication buffer has no receiving buffer), the function returns an empty string.
Description
PPCREAD() allows you to read data from the receiving buffer of any communication buffer, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session). The handle of the communication buffer must be specified with nHandle. If only one communication handle is passed, the function returns all characters of the receiving buffer. By designating nLength, a defined number of characters can be read. With the parameter lNotDelete, you can specify if the buffer is cleared (.F.) or not (.T.) after the characters have been read.
Reading only a defined number of characters can be useful if the header of a data packet is also transmitted to the receiving buffer during an IPX or SPX communication. In this case, the header can be read first (30 or 42 characters). The header contains information about the length of the data range that can then be read with a new call of PPCREAD() (see the introduction to this chapter). In this way, the data that is read can be packet oriented.
Notes
■ Between a call of PPCRECCNT() and PPCREAD(), new data can be
transmitted to the receiving buffer.
Examples
■ Read and display all the characters from a receiving buffer:
? PPCREAD(nHandle)
■ Read the header and the data range of an IPX packet
separately:
// Open communication buffer
// Force header transfer
nHandle=IPXOPEN(20000,5000,,,,,.T.)
// Read IPX header (30 bytes)
cHeader=PPCREAD(nHandle,30)
// Determine data range length
// (Attention: high, low sequence)
nLen=Bin2I(CharMirr(SubStr(cHeader,3,2)))-30
// Read data range
cData=PPCREAD(nHandle,nLen)
Determines the number of characters in a communication receiving buffer
Syntax
PPCRECCNT(<nHandle>) → nBytes
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication receiving buffer.
Returns
PPCRECCNT() returns the number of characters in the specified communication receiving buffer. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCRECCNT() determines the number of characters in the receiving buffer of a specified communication buffer, independently of the protocol used (IPX, SPX, NetBIOS datagram or NetBIOS session). It allows you to check to see if new data has been received since the most recent readout.
Examples
Read the buffer if it contains characters:
nCharacter=PPCRECCNT(nHandle)
IF nCharacter>0
cData=PPCREAD(nHandle)
ENDIF
PPCRECDISC(<nHandle>) → nPackets
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication receiving buffer.
Returns
PPCRECDISC() returns the number of packets that have been discarded because of a full buffer since the receiving buffer has been opened. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCRECDISC() determines the number of packets that have been discarded due to a full buffer, independently of the protocol used (IPX, SPX, NetBIOS datagram or NetBIOS session). If more than 65535 packets have been discarded, the count restarts at 0.
Examples
Check to see if packets have been discarded:
IF PPCRECDISC(nHandle)>0
? 'Data integrity not guaranteed!'
ENDIF
Determines the error code of the most recent receiving process
Syntax
PPCRECERR(<nHandle>) → nErrorCode
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication receiving buffer.
Returns
PPCRECERR() returns the error code of the most recent receiving process for the specified receiving buffer. If the packet has been received successfully, the function returns 0. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCRECERR() allows you to determine the error code of the most recent receiving operation, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session). The values are returned directly by the IPX/SPX or NetBIOS driver. Therefore, the return value depends on the type of receiving buffer. There is a description of the error codes for the IPX/SPX communication buffer and for the NetBIOS communication buffer in Appendices D and E.
Packets that have been received but have been discarded due to a full buffer do not create an error code.
Examples
Check to see if the last packet has been received successfully:
IF PPCRECERR(nHandle) = 0
? 'Packet has been received successfully!'
ELSE
? 'Error!'
ENDIF
Determines the number of packets received with a failure
Syntax
PPCRECFAIL(<nHandle>) → nPackets
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication receiving buffer.
Returns
PPCRECFAIL() returns the number of packets received with failure since the buffer has been opened. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCRECFAIL() determines the number of packets received with failure, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session). A faulty packet can be a packet for which the data length does not match the length defined in its header, or a packet that has been discarded because of a full buffer. If a value of 65535 packets has been exceeded, the count starts again at 0.
Examples
■ Check to see if packets have been received with failure:
IF PPCRECFAIL(nHandle)>0
? 'Data integrity not guaranteed!'
ENDIF
■ Determine the number of faulty packets and the number of those
packets that have been discarded due to a full buffer:
? 'Total of faulty packets:',PPCRECFAIL(nHandle)
? 'Discarded thereof: ',PPCRECDISC(nHandle)
PPCRECFLSH(<nHandle>) → lSuccess
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication receiving buffer.
Returns
PPCRECFLSH() returns .T. if the receiving buffer has been cleared successfully.
Description
PPCRECFLSH() allows you to delete all characters from a receiving buffer, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session).
Examples
Clear the receiving buffer:
IF PPCRECFLSH(nHandle)
? 'Buffer has been cleared successfully!'
ELSE
? 'Buffer could not be cleared!'
ENDIF
Determines the number of free characters in a communication receiving buffer
Syntax
PPCRECFREE(<nHandle>) → nBytes
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication receiving buffer.
Returns
PPCRECFREE() returns the free memory in the specified communication receiving buffer in bytes. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCRECFREE() determines the number of characters that are still free in the receiving buffer of the specified communication buffer, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session).
Examples
Read the buffer if less than 5460 characters are free:
nCharacter=PPCRECFREE(nHandle)
IF nCharacter<5460
cData=PPCREAD(nHandle)
ENDIF
Determines the size of a communication receiving buffer
Syntax
PPCRECSIZE(<nHandle>) → nBytes
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication receiving buffer.
Returns
PPCRECSIZE() returns the size of the specified communication receiving buffer in bytes. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCRECSIZE() determines the size of a communication receiving buffer, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session).
Examples
Determine the size of a communication receiving buffer:
? PPCRECSIZE(nHandle)
PPCRECTOT(<nHandle>) → nPackets
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication receiving buffer.
Returns
PPCRECTOT() returns the number of packets received since the buffer has been opened. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCRECTOT() determines the total number of received packets, independently of the protocol used (IPX, SPX, NetBIOS datagram or NetBIOS session). The value also contains faulty and discarded packets. If a value of 65535 packets has been exceeded, the count starts again at 0.
Examples
Display the communication receiving buffer report:
? 'Total of received packets :',PPCRECTOT(nHandle)
? 'Faulty thereof :',PPCRECFAIL(nHandle)
? 'Discarded thereof :',PPCRECDISC(nHandle)
Determines the number of characters in a communication sending buffer
Syntax
PPCSNDCNT(<nHandle>) → nBytes
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication sending buffer.
Returns
PPCSNDCNT() returns the number of characters in the specified communication sending buffer. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCSNDCNT() determines the number of characters in the sending buffer of a specified communication buffer, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session). It allows you to check to see if data written to the buffer has already been sent.
Examples
Write characters into the receiving buffer, and wait until the
characters have been sent:
PPCWRITE(nHandle,cData)
WHILE PPCSNDCNT(nHandle)>0
ENDDO
Determines the error code of the most recent sending process
Syntax
PPCSNDERR(<nHandle>) → nErrorCode
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication sending buffer.
Returns
PPCSNDERR() returns the error code of the most recent sending process for the specified sending buffer. If the packet has been sent successfully, the function returns 0. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCSNDERR() allows you to determine the error code of the most recent sending operation, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session). The values are returned directly by the IPX/SPX or NetBIOS driver, so the return value depends on the type of the receiving buffer. There is a description of the error codes for the IPX/SPX communication buffer and for the NetBIOS communication buffer in Appendices D and E.
Examples
Check to see if the last packet has been sent successfully:
IF PPCSNDERR(<nHandle>) = 0
? 'Packet has been sent successfully!'
ELSE
? 'Error!'
ENDIF
Determines the number of packets sent with failure
Syntax
PPCSNDFAIL(<nHandle>) → nPackets
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication sending buffer.
Returns
PPCSNDFAIL() returns the number of packets sent with failure since the buffer has been opened. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCSNDFAIL() determines the number of packets sent with failure, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session). A faulty packet at an SPX or NetBIOS session connection can be a packet for which the receipt has not been acknowledged by the remote station. If a value of 65535 packets has been exceeded, the count starts again at 0.
Examples
Check to see if packets have been sent with failure:
IF PPCSNDFAIL(nHandle)>0
? 'Data integrity not guaranteed!'
ENDIF
PPCSNDFLSH(<nHandle>) → lSuccess
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication sending buffer.
Returns
PPCSNDFLSH() returns .T. if the buffer has been cleared successfully.
Description
PPCSNDFLSH() allows you to delete all characters from a sending buffer, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session).
Examples
Clear the sending buffer:
IF PPCSNDFLSH(nHandle)
? 'Buffer has been cleared successfully!'
ELSE
? 'Buffer could not be cleared!'
ENDIF
Determines the number of free characters in a communication sending buffer
Syntax
PPCSNDFREE(<nHandle>) → nBytes
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication sending buffer.
Returns
PPCSNDFREE() returns the free memory in the specified communication sending buffer in bytes. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCSNDFREE() determines the number of characters that are still free in the sending buffer of the specified communication buffer, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session).
Examples
Determine the free memory in a sending buffer:
? PPCSNDFREE(nHandle)
Determines the size of a communication sending buffer
Syntax
PPCSNDSIZE(<nHandle>) → nBytes
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication sending buffer.
Returns
PPCSNDSIZE() returns the size of the specified communication sending buffer. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCSNDSIZE() determines the size of a communication sending buffer, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session).
Examples
Determine the size of a communication sending buffer:
? PPCSNDSIZE(nHandle)
Determines the total number of packets that have been sent
Syntax
PPCSNDTOT(<nHandle>) → nPackets
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication sending buffer.
Returns
PPCSNDTOT() returns the number of packets that have been sent since the sending buffer has been open. If an error occurs (for example, if the handle is invalid), the function returns -1.
Description
PPCSNDTOT() determines the total number of sent packets, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session). The value also contains faulty packets. If a value of 65535 packets has been exceeded, the count starts again at 0.
Examples
Display the communication sending buffer report:
? 'Total of sent packets :',PPCSNDTOT(nHandle)
? 'Faulty thereof :',PPCSNDFAIL(nHandle)
PPCWRITE(<nHandle>,<cData>) → nLength
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication buffer.
cData Designates a character string that contains the data that is written to the sending buffer.
Returns
PPCWRITE() returns the number of characters that could not be written to the sending buffer. Therefore, a return value larger than 0 indicates an error (for example, when the sending buffer is full).
Description
PPCWRITE() allows you to write data into the sending buffer of a communication buffer, independently of the protocol used (IPX, SPX, NetBIOS datagram, or NetBIOS session). The parameter nHandle contains the handle of the communication buffer. The data must be passed as a character string (cData). PPCWRITE() transmits the data to the sending buffer. The data is sent from the sending buffer, in an interrupt controlled transmission in the background. If the sending buffer does not have enough memory to accept all the characters, PPCWRITE() returns the number of characters that could not be transmitted to the sending buffer.
Examples
■ Open the IPX sending buffer for a broadcast message, and send
the message "Good morning!":
nHandle=IPXOPEN(20000,,546,'FFFFFFFFFFFFFFFFFFFF')
PPCWRITE(nHandle,'Good morning!')
■ Send data from the character string <cData>, and take into
account that the sending buffer might be full:
nRest=Len(cData)
WHILE nRest>0
nRest = PPCWRITE(nHandle,Right(cData,nRest))
ENDDO
nPrinter Designates the number the printer to initialize. Values can be from 1 to 3 and correspond to the devices LPT1 to LPT3. The default value is LPT1(1).
lMode When designated as .T., CA-Clipper is set internally to the top of form. The default for CA-Clipper is not at the top of form (.F.).
Returns
The returned value corresponds to the status of the nPrinter selected printer. The individual bits are defined as follows:
Table 8-1: Printer Bit Status
Bit Definition
1 Timeout error
2 Not used
3 Not used
4 Transmission error
5 Printer online
6 Out of paper
7 Printer acknowledged
8 Printer not available
Description
Use PrintINIT() to reset a printer to its original state or to redefine the top of form. When lMode is designated as .T., the CA-Clipper internal setting is top of form. This corresponds to a call of SETPRC (0, 0).
cCharacter|nCharacter Designates as a code for an individual character in the range of 0 to 255, or as a string.
nPrinter Designates the printer where output occurs. The values 1 to 3 correspond to devices LPT1 to LPT3.
Returns
PrintSend() returns a value that corresponds to the number of characters that could not be sent to the printer. If 0 is returned, all characters were sent to the printer.
Description
Use PrintSend() when you want to send one or more characters to a printer, and switching from SET PRINTER and SET CONSOLE is undesirable and costly as an option. This function allows you to send characters (and special characters) to a printer at any time.
Examples
■ Send formfeed characters to the printer, when the printer is
not at top of form:
IF .NOT. TOF()
PrintSend(12) // Output Chr(12)
ENDIF
■ Send a character string:
PrintSend("Hello")
nPrinter Designates the printer whose status is determined. The allowed values of 1 to 3 correspond to devices LPT1 to LPT3. The default is LPT1(1).
Returns
The returned value corresponds to the status of the nPrinter selected printer. The individual bits are defined as follows:
Table 8-2: Printer Bit Status
Bit Definition
1 Time out error
2 Not used
3 Not used
4 Transmission error
5 Printer online
6 Out of paper
7 Printer acknowledged
8 Printer not available
Description
If a printer error occurs, PrintStat() allows you to isolate the error more precisely. PrintStat() returns information about why an error occurs.
Examples
In this example, the printer status is only queried when the printer is
not ready:
IF .NOT. PrintReady(1)
nStatus := PrintStat(1)
IF IsBit(nStatus, 6) // Test bit 6
? "Paper out!"
ENDIF
ENDIF
Returns the error code for the last printer output
Syntax
PRINTERROR() → nError
Returns
PRINTERROR() returns the code for the last error that occurred in a print output. The following table provides an overview of all the error codes and their meanings:
Table 2-3: Print Output Error Coding
Code Definition
0 No error occurred
5 Access denied
6 Invalid Handle
127 Canceled by Ctrl-Break
Description
PRINTERROR() allows you to determine why the last print output failed. This function gives you the ability to determine the source of the error from within the CA-Clipper error system and react accordingly. To identify an abort command that used Ctrl-Break, CA-Clipper Tools returns a value of 127.
Notes
■ PRINTERROR() only returns an error code for print errors that
occur during a CA-Clipper printing operation.
Examples
React to an error during a print operation:
nStatus := PRINTERROR()
IF nStatus = 127
? "Print operation aborted by user!"
ENDIF
lIgnoreHighBit When designated as .T., the high bits are not cleared. The default is clears high bits (.F.).
Returns
The returned value specifies if a file is successfully printed. A .T. corresponds to a successful execution.
Description
PRINTFILE() sends the cFileASCII file to the printer while it clears each high bit that is set (MSB — Most Significant Bit) with each carriage return and line feed. This allows files created with MEMOWRITE() to print without any special preparation. If you do not want to suppress the high bit (e.g., when printing a character such as 130, designate the second parameter as .T. to turn it off).
Notes
■ Due to known name conflicts with other add on libraries (e.g.,
dGE, use the name FILEPRINT()on an alternate basis.
■ The settings for SET PRINTER TO and other printer-related
■ Print the Memofile.txt file:
PRINTFILE("Memofile.txt")
■ Use the function name FILEPRINT() on an alternate basis:
FILEPRINT("Memofile.txt")
■ Without high-bit suppression:
FILEPRINT("Memofile.txt", .T.)
nPrinter Designates the number of the printer where output is directed. LPT(1) to LPT(3) are possible.
cCharacter|nCharacter Designates a character that replaces all non-printable characters during a "'Print-Screen". The character can be numeric in the range of 0 to 255 or the character string type.
() A call without parameters uninstalls the function.
Returns
PRINTSCRX() returns .T. when the extended Print Screen output is successfully installed.
Description
The PRINTSCRX() replaces the non-printable characters (code `32) in an output with other characters, but you can also select another printer. This way, Print Screen output is no longer forced to LPT1(PRN). Not only does it influence PRINTSCR(), but also the use of SHIFT-PRINT- SCREEN.
Notes
Warning! The PRINTSCRX() function changes one of the system interrupts. Therefore, prior to ending the program, uninstall this function by calling it without parameters. You can use the CTUS.LIB Extended Drivers or the INTSAVE utility program. The Extended Drivers automatically restores all interrupts to the same status they had at the beginning of the CA-Clipper application.
Examples
■ Print-Screen output to LPT3:
PRINTSCRX(3)
■ Exchange non-printing characters for spaces. Output to LPT2:
PRINTSCRX(2, " ")
■ Same as on previous page, second parameter numeric:
PRINTSCRX(2, 32)
nPayment Designates the amount of the scheduled periodic payment.
nInterestRate Designates the periodic interest rate. 1 corresponds to 100%.
nNumberPayments Designates the number of anticipated payment periods.
Returns
PV() returns the cash value of an interest yield.
Description
PRESENT VALUE The function computes the cash value of regular equal payments nNumberPayments at an nInterestRate interest rate over nNumberPayments payment periods.
Examples
■ How high can a loan be if you pay $175 for 24 months, at an
annual fixed interest rate of 9.5%? Since payments are monthly, the
annual percentage rate is divided by 12:
nRate := 0.095/12
? PV(175, nRate, 24) // $3811.43
■ Annual payments over 2 years at 9.5% per annum:
? PV(175, 0.095, 2) // $305.77
nStartValue Designates a beginning value for the random number generator.
Returns
Rand() returns a random number between 0 and 1.
Description
In contrast to Random(), this function works with a seed algorithm. Multiple calls always returns the same random number sequence when it has the same start value. When you first call Random() without a parameter, it starts as if 100001 is specified as a parameter. Subsequent random numbers can then be influenced by the < nStartValue>. If this value is less than or equal to 0, the clock time is brought into the process.
If you call the function with 100001 as a parameter, it allows you to restart the generator. Then, if you call the function several times without parameter, it returns the "standard sequence" of numbers.
Examples
■ Call after program start:
? Str(Rand(), 18, 15) // 0.831051100158447
? Str(Rand(), 18, 15) // 0.557946857971956
■ If the parameter equals 0, the clock time is incorporated.
Even if the clock has not yet advanced, subsequent values are still
different:
? Str(Rand(), 18, 15) // Time dependent
? Str(Rand(), 18, 15) // Subsequent time
// dependent value
■ Use a number greater than 0:
? Str(Rand(23), 18, 15) // 0.121169930053736
? Str(Rand(23), 18, 15) // 0.121169930053736
■ Show a "new start":
? Str(Rand(100001), 18, 15) // 0.831051100158447
? Str(Rand(), 18, 15) // 0.557946857971956
lMode Designates whether or not to return negative numbers. The default creates only positive numbers.
Returns
Random() returns a random number in the range of 0 to 65535 or when lMode is designated as .T., in the range of -32768 to +32767.
Description
Random() produces random numbers to create a random distribution of test data for DEMO programs or any other application.
Notes
■ If the lMode parameter is not specified, only positive
numbers are returned. When < lMode> is set to .T., the function returns the same number of positive and negative numbers.
Examples
■ Create a random number between 0 and 65535:
? Random()
■ Create a random number between 0 and 1:
? Random()/65535
■ Create a random whole number between 1 and 16:
? Random()%16 +1
■ Create a random number between -32768 and +32767:
? Random(.T.)
cCharacter1 and cCharacter2 Designate the first and the last character of the character range.
cString Designates the character string that is edited.
Returns
The function returns the modified character string.
Description
RangeRem() allows you to delete all characters that are in a particular ASCII range. For example, you could delete all control characters in a character string.
The designated range can run "back to front", meaning cCharacter2 can have a lower value than cCharacter1. In such a case the range extends from the larger value to 255 and also from 0 to the smaller value.
Notes
■ Since the length of the character string is changed, passing
by reference will not work here as it does with RangeRepl().
Examples
■ Delete all control characters:
cString := RangeRem(0, 31, cString)
■ Delete all characters that are not upper case, alpha
characters:
cString := RangeRem(91, 64, cString)
cCharacter1 and cCharacter2 Designate the first and the last character of the character range.
cString [@] Designates the string that is processed.
cReplaceCharacter Designates the single character that replaces those characters in cString that are within the specified range.
Returns
The processed character string is returned.
Description
All characters that are in a particular range can be replaced by a new character. For example, you could replace all control characters with spaces.
The designated range can also run from "back to front", meaning that cCharacter2 can have a lower value than cCharacter1. In such a case the range extends from the larger value to 255 and from 0 to the smaller value.
Notes
■ The length of cString remains unaffected by this function.
■ The return value of this function can be suppressed by
implementing CSetRef() to save room in working memory.
Examples
■ Exchange all control characters in a character string for the
character ".":
cString := "a" + Chr(5) + "b" + Chr(9)
? RangeRepl(Chr(0), Chr(31), cString, ".") // "a.b."
■ A null string can be specified, instead of Chr(0). The
following example exchanges all characters with a code < "A" for the
number "0". Of course, the number "0" remains the number "0":
? RangeRepl("", Chr(65), "123400", "0") // "000000"
■ All characters in the range "0" to "8" are exchanged for the
number "9":
? RangeRepl("0", "8", "0212 - 78 67 43", "9")
// "9999 - 99 99 99"
■ With the exception of upper case letters, all characters are
exchanged for dashes. The optimum call is in conjunction with
CSetRef():
CSetRef(.T.)
cString := "A()&BC/?D"
RangeRepl(91, 64, @cString, "-") // "A--BC--D"
NumberPayments Designates the number of the planned payment periods.
Returns
Rate() returns the loan interest rate.
Description
Rate() determines the annual interest rate for a loan nCapital in the nNumberPayments period at the specified nPayment installment. The calculated interest rate is based on a Newtonian iterative solution procedure:
lk+1=ik - f(ik)/f(ik)
where:
f(i)=(1-(l + i)^-n)/i - PV/PMT
The initial value for i is selected as follows:
-io = PMT/PV - PV/n^2PMT
Notes
■ This function allows a maximum value for the payment period of
1020.
Examples
For a $2500 loan, you pay $86.67 per month for 3 years. What is the
effective annual interest rate?
nLoan := 2500
nPayment := 86.67
nPeriod := 36
? Rate(nLoan, nPayment, nPeriod) * 12 // 0.1501 (15.01%)
cCharacter|nCharacter Designates the character that is removed from the beginning and end of cString. The default value is a space, Chr(32).
Returns
RemAll() returns the modified cString.
Description
RemAll() functions exactly like CA-Clipper's AllTrim(), with one exception. While the CA-Clipper function can only remove spaces, RemAll() can remove any character you choose. The character that is removed can be specified with the cCharacter|nCharacter parameter.
Notes
■ When the cCharacter|nCharacter parameter is not specified,
saces are removed.
Examples
■ Remove the spaces:
? RemAll(" 1 2 3 ") // "1 2 3"
■ Remove the character "0":
? RemAll("007007 ", "0") // "7007 "
cCharacter|nCharacter Designates the character that is removed from the beginning of the cString. The default value is a space, Chr(32).
Returns
RemLeft() returns the modified cString.
Description
RemLeft() functions exactly like CA-Clipper's LTrim(), with one exception. While the CA-Clipper function can only remove spaces, RemLeft() can remove any character you choose. The character that is removed can be specified with the cCharacter|nCharacter parameter.
Notes
■ When the cCharacter|nCharacter parameter is not specified,
spaces are removed.
Examples
■ Remove the spaces:
? RemLeft(" 123 ") // "123 "
■ Remove the character ".":
? RemLeft("..123..", ".") // "123.."
cCharacter|nCharacter Designates the character that is removed from the end of the cString. The default value is a space, Chr(32).
Returns
RemRight() returns the modified cString.
Description
RemRight() functions exactly like CA-Clipper's RTrim(), with one exception. While the CA-Clipper function can only remove spaces, RemRight() can remove any character you choose. The character that is removed can be specified with the cCharacter|nCharacter parameter.
Notes
■ When the cCharacter|nCharacter parameter is not specified,
spaces are removed.
Examples
■ Remove the spaces:
? RemRight(" abc ") // " abc"
■ Remove the character ".":
? RemRight("..abc..", ".") // "..abc"
cOldFileName Designates the name and path of the existing file.
cNewFileName Designates the new name and path for the file.
Returns
The function returns a 0 when the file can be renamed; otherwise, it returns an error code. The codes are defined below:
Table 7-19: RenameFile() Error Codes
Code Definition
0 No error found
-2 File not found
-3 Path not found
-5 Access denied (e.g., in network)
-17 Target file not on same network
Description
Currently, you may not be able to rename a file on a network drive. Another user may currently have the file open. RenameFile() actually says "attempt a RENAME and, should the situation arise, return an error code". This follows the basic programming philosophy: never fall into an error trap when you can avoid it.
Notes
■ The cNewFileName must always contain the complete path for
the designated file (see Examples).
■ Wildcard characters cannot be used.
Examples
■ Rename a file from OLD to NEW:
IF RenameFile("OLD", "NEW") = 0
? "The file can be renamed!"
ENDIF
■ Use the path from the old file specification for the new name:
cFSpecOld := "C:\TEST\TEST.TXT"
cFileName := TOKEN(cFSpecOld, ":\") // last token
cFSpecNew := BEFOREATNUM(cFileName, cFSpecOld) + "TEST.NEW"
RenameFile(cFSpecOld, cFSpecNew)
cString [@] Designates the string that is processed.
cReplacecharacter|nReplacecharacter Designates the character that replaces the character in cSearchCharacter|nSearchCharacter at the beginning and end of cString.
cSearchCharacter|nSearchCharacter Designates the character at the beginning and end of cString that is replaced by cReplacecharacter| nReplacecharacter. The default value designates a space, Chr(32).
Returns
The processed cString is returned.
Description
ReplAll() can be used to exchange all leading and trailing spaces in a character string for any other character. Notice that the first non- replaceable character in either direction causes ReplAll() to stop replacing characters on that side.
Notes
■ The return value of this function can be suppressed by
implementing CSetRef() to save space in working memory.
Examples
■ Replace spaces with dashes. Replace the spaces only on the
side where the character was found:
? ReplAll("abcd ", "-") // "abcd--"
■ Replace zeros with spaces:
? ReplAll("001234", " ", "0") // " 1234"
■ Replace the blanks with dashes on both sides:
? ReplAll(" d ", "-") // "---d--"
■ Replace only continuous sequences of characters at the
beginning and the end of the character string:
? ReplAll(" d d ", "-") // "-d d--"
cString [@] Designates the string that is processed.
cReplacecharacter|nReplacecharacter Designates the character that replaces the character in cSearchCharacter|nSearchCharacter at the beginning of the cString.
cSearchCharacter|nSearchCharacter Designates the character at the beginning of cString that is replaced by cReplacecharacter| nReplacecharacter. The default value is a space, Chr(32).
Returns
The processed cString is returned.
Description
ReplLeft() can be used to exchange all leading characters in a string for any other selected character.
Notes
■ The return value of this function can be suppressed by
implementing CSetRef() to save space in working memory.
Examples
■ Replace the leading spaces with zeros:
? ReplLeft(" 1234", "0") // "001234"
■ Replace the leading zeros with spaces:
? ReplLeft("001234", " ", "0") // " 1234"
■ Replace only the leading spaces:
? ReplLeft(" 1 ", "0") // "001 "
cString [@] Designates the string that is processed.
cReplacecharacter|nReplacecharacter Designates the character that replaces the character in cSearchCharacter|nSearchCharacter at the end of the cString.
cSearchCharacter|nSearchCharacter Designates the character at the end of cString that is replaced by cReplacecharacter| nReplacecharacter. The default value is a space, Chr(32).
Returns
The processed cString is returned.
Description
ReplRight() can be used to exchange all trailing characters in a string for any character you choose.
Notes
■ The return value of this function can be suppressed by
implementing CSetRef() to save space in working memory.
Examples
■ Replace the trailing spaces with dashes:
? ReplRight("abcd ", "-") // "abcd--"
■ Replace the trailing dashes with spaces:
? ReplRight("abcd--", " ", "-") // "abcd "
■ Replace only the trailing spaces:
? ReplRight(" 1 ", "-") // " 1--"
nCursorSetting Designates a value previously returned by the SaveCursor() function.
Returns
RestCursor() always returns a null string.
Description
With SaveCursor(), you can save three pieces of screen information. If those return values are saved, then you can reset Row(), Col(), and CSetCurs() later with RestCursor().
Examples
Save and restore:
nVar := SaveCursor()
DO OUTPUT
RestCursor(nVar)
aSavedGets Designates a variable previously created by the SaveGets() function.
Returns
RestGets() returns .T. when the GET settings are successfully restored.
Description
This function restores the information previously saved to an array with SaveGets(). This reactivates a previously active GET mask.
Notes
Important! Never use the CA-Clipper CLEAR GETS commands within the SaveGets()/RestGets() construction.
Examples
F1 is used to activate the HELP procedure from an input mask. The
active GET is saved and then newly opened. Both GET masks use different
PICTURE definitions like different VALID UDF's:
CLEAR
SET KEY 28 TO HELP // KEYTRAP definition
cFirstname := Space(10)
cLastname := Space(10)
@ 10, 10 GET cFirstname PICTURE "@!"
@ 11, 10 GET cLastname PICTURE "@!" VALID MAINFUNC()
READ
*
* HELP procedure opens new GET
*
PROCEDURE HELP (A, B, C)
LOCAL aOldGets
aOldGets := SaveGets() // Save GETS
WOpen(4, 30, 20, 76) // Open window
WBox() // Window border
cHelp1 := Space(10)
cHelp2 := Space(10)
@ 10, 10 GET cHelp1 PICTURE "@A"
@ 11, 10 GET cHelp2 PICTURE "@A" VALID HELPFUNC()
READ
RestGets(aOldGets) // Recreate GETS
WClose() // Close window
RETURN
FUNCTION MAINFUNC
SOUND(1000, 10) // Short beep
RETURN(.T.)
FUNCTION HELPFUNC
SOUND(1000, 100) // One long beep
RETURN(.T.)
aSavedTraps Designates an array previously created by SaveSetKey().
Returns
RestSetKey() returns .T. when you can restore the aSavedTrapsSET KEY..TO settings.
Description
RESTORE "SET KEY..TO" SETTINGRestSetKey() restores SET KEY..TO settings previously saved to an array with SaveSetKey().
Important! It is impossible to use the saved information any longer that the runtime of an application. The character string that results cannot be saved to a file and reloaded later.
Examples
A key trap definition for the F1 key is changed within a nested input:
CLEAR
SET KEY 28 TO HELP1 // First def. for F1
cFirstname := Space(10)
cLastname := Space(10)
@ 10, 10 GET cFirstname
@ 11, 10 GET cLastname
READ
PROCEDURE HELP1 ( A, B, C)
WOpen(4, 4, 20, 76) // Open window
WBox() // Window borders
aOldKey := SaveSetKey() // Save SET KEY def.
aOldGet := SaveGets() // Save GET def.
SET KEY 28 TO HELP2 // New def. F1
cHelp1 := Space(10) // New GET
cHelp2 := Space(10) // ...e.g. help index
@ 10, 10 GET cFirstname
@ 11, 10 GET cLastname
READ
RestGets(aOldGet) // Recreate old GET
RestSetKey(aOldKey) // Return .T. if OK
WClose() // Close window
RETURN
PROCEDURE HELP2 ( A, B, C) // 2nd help procedure
* e.g. a second help environment - key layout etc.
RETURN
cTokenEnvironment Designates a character string returned by the SaveToken() function.
Returns
RestToken() always returns an empty string.
Description
The internal environment for the incremental tokenizer can be restored using RestToken(). RestToken() does the opposite of the SaveToken() function.
Notes
■ nTokenEnvironment must originate from the current program
run; for example, it cannot have been restored from a (.mem) file.
Examples
■ Here is an incremental tokenizer. Text is broken into
individual lines, and each line is broken into words:
TokenInit(@cTextString, Chr(13) + Chr(10), 2)
cLine := TokenNext()
DO WHILE .NOT. TokenEnd()
cLine := TokenNext(cTextString)
Word(cLine)
ENDDO
■ The function then breaks the lines into words:
FUNCTION Word(cLine)
cOldEnv := SaveToken()
TokenInit(@cLine, " .,-:;")
DO WHILE .NOT. TokenEnd()
cWord := TokenNext(cLine)
? cWord
ENDDO
RestToken(cOldEnv)
RETURN("")
cFileSeekEnvironment Designates a string that contains the FileSeek() environment, which was passed by SAVEFSEEK().
Returns
RESTFSEEK() always returns a null string.
Description
RESTFSEEK() restores a saved FileSeek() environment. Use both of these functions to run through subdirectories recursively.
Examples
The following small program shows all the files in all directories of
the current drive, from the root. The GETFILES procedure can be called
recursively:
DO GetFiles WITH "\" // Starts with root directory
RETURN
* ----------------------------------------
PROCEDURE GetFiles(cSearchPath)
PRIVATE cSeekEnv // Picks up SEEK environment
? // Empty line for new dir.
* All files, all attributes
cFile := FileSeek(cSearchPath + "*.*", 63)
DO WHILE .NOT. Empty(cFile)
IF cFile <> "." // ".." and "." are dummys
IF IsBit(FileAttr(), 5) // Subdirectory?
cSeekEnv := SAVEFSEEK() // Save environment
* Recursive call with extended path!
DO GetFiles WITH cSearchPath + cFile + "\"
RESTFSEEK(cSeekEnv) // Restore environment
ELSE
? cSearchPath + cFile
ENDIF
ENDIF
cFile := FileSeek() // Next file
ENDDO
RETURN
nArc Designates a valid angle measurement in radians.
Returns
RToD() returns the value of the designated parameter in degrees.
Description
In addition to expressing an angle measurement in degrees, it is often useful to express an angle in radians. RToD() converts a radian measurement into degrees.
SaveCursor() returns a numeric value that corresponds to the setting for Row(), Col(), SetCursor(), and CSetCurs().
Description
SaveCursor() saves three pieces of screen information at one time. SaveCursor() returns a combined numeric value that you can save and restore later with RestCursor().
Examples
Save and restore the cursor:
nVar := SaveCursor()
DO OUTPUT
RestCursor(nVar)
SaveGets() returns an array that contains all information necessary to save the active GET environment.
Description
SaveGets() only returns the array with the current GET object. This allows you to save it to a LOCAL variable and restore it later to the previous GET settings through RestGets(). This way, it is also possible to newly open a GET mask or VALID UDF from within a KEYTRAP procedure without losing the previous one.
Notes
Important! Never use the CA-Clipper CLEAR or CLEAR GETS commands within the SaveGets()/RestGets() construction.
■ The array returned by SaveGets() is valid only during the
current program run. Therefore, it is not useful to save this data in the file.
■ Effective with CA-Clipper, the cursor position is always saved
when you leave an input field. If you do not want to do this, place the key code for Pos1 in the keyboard buffer through KEYSEND at the end of the trap procedure.
Examples
F1 activates the HELP procedure from an input mask. The active GET is
saved there and then newly opened. Both GET masks use different PICTURE
definitions like different VALID UDF's:
CLEAR
SET KEY 28 TO HELP // KEYTRAP definition
cFirstname := Space(10)
cLastname := Space(10)
@ 10, 10 GET cFirstname PICTURE "@!"
@ 11, 10 GET cLastname PICTURE "@!" VALID MAINFUNC()
READ
*
* HELP procedure opens new GET
*
PROCEDURE HELP (A, B, C)
LOCAL aOldGets
aOldGets := SaveGets() // Save GETS
WOpen(4, 30, 20, 76) // Open window
WBox() // Window border
cHelp1 := Space(10)
cHelp2 := Space(10)
@ 10, 10 GET cHelp1 PICTURE "@A"
@ 11, 10 GET cHelp2 PICTURE "@A" VALID HELPFUNC()
READ
RestGets(aOldGets) // Recreate GETS
WClose() // Close window
RETURN
FUNCTION MAINFUNC
SOUND(1000, 10) // Short beep
RETURN(.T.)
FUNCTION HELPFUNC
SOUND(1000, 100) // One long beep
RETURN(.T.)
SaveSetKey() returns an array within which information for the current SET KEY..TO settings are saved.
Description
SAVE SET KEY..TO SETTINGSSaveSetKey() saves the current SET KEY..TO settings in an array. This makes it possible to redefine function keys already assigned, and to later restore the old settings with RestSetKey().
Notes
■ The array you create is valid only for the current program
run. Therefore, is not useful to save this data in the file.
Examples
A key trap definition for the F1 key is changed within a nested input:
CLEAR
SET KEY 28 TO HELP1 // First def. for F1
cFirstname := Space(10)
cLastname := Space(10)
@ 10, 10 GET cFirstname
@ 11, 10 GET cLastname
READ
PROCEDURE HELP1 ( A, B, C)
WOpen(4, 4, 20, 76) // Open window^n WBox()
// Window borders
aOldKey := SaveSetKey() // Save SET KEY def.
aOldGet := SaveGets() // Save GET def.
SET KEY 28 TO HELP2 // New def. F1
cHelp1 := Space(10) // New GET
cHelp2 := Space(10) // ...e.g. help index
@ 10, 10 GET cFirstname
@ 11, 10 GET cLastname
READ
RestGets(aOldGet) // Recreate old GET
RestSetKey(aOldKey) // Return .T. if OK
WClose() // Close window
RETURN
PROCEDURE HELP2 ( A, B, C) // 2nd help procedure
* e.g. a second help environment - key layout etc.
RETURN
Saves the incremental tokenizer environment to a variable
Syntax
SaveToken() → cTokenEnvironment
Returns
The character string returned contains the internal environment for the incremental tokenizer.
Description
By saving and later restoring the internal tokenizer environment, an interlocking implementation of the incremental tokenizer is made simple. The complete, previously initialized string is saved, as are the internal pointers and the corresponding file areas. This string serves as a return value for SaveToken(), regardless of the later restoration of the tokenizer environment using RestToken().
Notes
■ The returned value is only valid for the currently running
program because it is concerned with internal pointers.
Examples
■ Here is an incremental tokenizer. Text is broken into
individual lines, and each line is broken into words:
TokenInit(@cTextString, Chr(13) + Chr(10), 2)
DO WHILE .NOT. TokenEnd()
cLine := TokenNext(cTextString)
Word(cLine)
ENDDO
■ The function then breaks the lines into words:
FUNCTION Word(cLine)
cOldEnv := SaveToken()
TokenInit(@cLine, " .,-:;")
cWord := TokenNext()
DO WHILE .NOT. TokenEnd()
cWord := TokenNext(cLine)
? cWord
ENDDO
RestToken(cOldEnv)
RETURN("")
cCharacterstring Designates vertical output for the string.
nDelay Designates that the time delay is set in milliseconds. The default value is 4.
nLine Designates from which line to begin the output. The default is the cursor line.
nColumn Designates from which column to begin the output. The default is the cursor column.
Returns
SayDown() always returns a null string.
Description
SayDown() allows you to have a particular affect on a string output. The output is done vertically, downward from the current or selected cursor position, and can have a time delay between individual characters. When the last line of the screen is reached, the function outputs one more character and then terminates. The SET COLOR TO setting is used as an attribute. The current cursor position is not changed with this function.
Notes
■ Control characters such as with @...SAY commands in CA-
Clipper, are not interpreted.
Examples
Show vertical output from line 10, column 10, with a 100-millisecond
time delay between characters:
SayDown("Clipper", 100, 10, 10)
Line 10: C
L
I
P
P
E
R
cCharacterstring Designates the string to be output with the "move in" effect.
nDelay Designates a time delay in milliseconds. The default value is 4.
nLine Designates the line where the result is output. The default is the cursor line.
nColumn Designates the column where the result is output. The default is the cursor column.
lDirection Designates the direction that the characters are moved onto the screen. If you omit this parameter or designate it as .F., the movement is from the left. If you designate it as .T., the movement is from the right onto the screen. The default is movement from the left (.F.).
Returns
The function always returns a null string.
Description
SAY MOVE IN This function has a particular effect on string screen output. From a certain position characters are individually moved in from the left or right of the screen. After this output, the cursor position is at the end of the string.
Notes
■ Control characters, as with @...SAY commands in CA-Clipper are
not interpreted.
Examples
Show special affect output beginning at line 10, column 10 with a
100-millisecond time delay. The string is moved in from the left:
SayMoveIn("Clipper", 100, 10, 10)
Column 10:
r
er
per
pper
ipper
lipper
Clipper // Result on line 10 !
cCharacterstring Designates the character string to output.
nRow Designates the first line for the output. The default is the cursor line.
nColumn Designates the first column for the output. The default is the cursor column.
Returns
SayScreen() always returns a null string.
Description
SayScreen() produces an screen output and retains all existing attributes. This means that only the characters are overwritten, while the accompanying attributes remain unchanged.
Notes
■ The current cursor position is not changed with the output.
Examples
■ Show the output text at the current cursor position:
SayScreen(" Test SCREEN ")
■ Show output text at the current column position on line 24:
SayScreen(" Test SCREEN ", 24)
■ Show output text at column 70, line 24:
SayScreen(" Test SCREEN ", 24, 70)
All examples in this function return a null string.
cCharacterstring Designates the string to output with the spread effect.
nDelay Designates a time delay in milliseconds. The default value is 4.
nLine Designates the line from which the output begins. The default is the cursor line.
nColumn Designates the column from which the output begins. The default is the cursor column.
Returns
SaySpread() always returns a null string.
Description
SaySpread() has a particular effect on a string output to screen. From a center point, which corresponds to the center of the screen, window or nColumn, characters are displayed outward (they have a type of spread effect). The SET COLOR TO attribute setting is used. The current cursor position is not changed with this function.
Notes
■ Control characters, as with @...SAY commands in CA-Clipper are
not interpreted.
Examples
Show special effect output that begins in the middle of the screen or
window at line 10, with a 100-millisecond time delay:
SaySpread("Characters", 100, 10)
Output will be in the following steps, but always on the same line:
ac
ract
aracte
haracter
Characters // Result on line 10
SAVESEEK() returns the current FileSeek() environment. The information is needed for RESTFSEEK().
Description
The function saves the current FileSeek() environment to a string. For example, if the sequence "First Search - Continued Search" is interrupted by branching into a subdirectory, you must save these files.
Notes
■ Be sure sufficient spare memory is available when working
recursively at a higher level of complexity (which depends on the number of subdirectories). See Examples on the following page.
Examples
The following small program shows all the files in all directories of
the current drive, from the root. The GetFiles procedure can be called
recursively:
DO GetFiles WITH "\" // Starts with root directory
RETURN
* ----------------------------------------
PROCEDURE GetFiles(cSearchPath)
PRIVATE cSeekEnv // Picks up SEEK environment
? // Empty line for new dir.
* All files, all attributes
cFile := FileSeek(cSearchPath + "*.*", 63)
DO WHILE .NOT. Empty(cFile)
IF cFile <> "." // ".." and "." are dummys
IF IsBit(FileAttr(), 5) // Subdirectory?
cSeekEnv := SAVEFSEEK() // Save environment
* Recursive call with extended path!
DO GetFiles WITH cSearchPath + cFile + "\"
RESTFSEEK(cSeekEnv) // Restore environment
ELSE
? cSearchPath + cFile
ENDIF
ENDIF
cFile := FileSeek() // Next file
ENDDO
RETURN
nRow Designates the line from which to determine the attribute. The default is the cursor line.
nColumn Designates the column from which to determine the attribute. The default is the cursor column.
Returns
ScreenAttr() returns the attribute at the designated position.
Description
ScreenAttr() returns the current screen attribute at nRow and nColumn. You can query targeted attributes this way and save them to use later, or process them later with InvertAttr().
Notes
■ If no parameters are passed, the current cursor position is
queried.
Examples
■ The attribute for the current cursor position:
nVar:= ScreenAttr()
■ The attribute at the current column position in line 23:
nVar:= ScreenAttr(23)
■ The attribute at column 70, line 23:
nVar:= ScreenAttr(23, 70)
cFileName Designates the name and path of the screen file.
lOverwrite Designates whether you are to append to an existing file (.T.), or to overwrite it (.F.). The default is overwrite (.F.).
nOffset Designates the file offset from which you append, when lOverwrite is designated as .T.. The default is the end of file.
lTrim If this optional parameter is designated as .T., the function trims the file when the written data ends and before the last byte of the file. The default is do not trim (.F.).
Returns
ScreenFile() returns the number of bytes written to the screen file.
Description
ScreenFile() saves the contents of a screen to a file. Since the CA-Clipper SAVE SCREEN and RESTORE SCREEN also work with windows when you use the CA-Clipper Tools Extended Drivers, use ScreenFile() to save the entire screen. The number of characters you can write this way depends on the respective screen mode. For example, in a 50-line VGA mode you can write 8000 instead of 4000 characters. Use SCREENSIZE() to determine the exact screen size at any given time. You can only use the nOffset parameter when you specify lOverwrite at the same time. nOffset then specifies from which position in the screen file the new screen data is to be written. If the nOffset position lies before the end of the file, the file is overwritten. If it exceeds the end of the file, the data is appended. The default value for nOffset is selected, so if you omit it and designate lOverwrite as .T., the file is appended. This behavior allows you to save the contents of several screens to a file.
It is possible that a screen could be written to an already existing file, and that everything beyond this screen is trimmed off. The lTrim logical parameter must be designated as .T..
Notes
■ If ScreenFile() creates a new file, use SetFCreate() to create
an alternate attribute for this new file .
■ If you turn on the CA-Clipper Tools CSetSafety() internal
switch, the target file is not overwritten, even if the lOverwrite parameter is designated as .F..
■ Wildcards within the file name are not permitted here.
Examples
■ An existing file is overwritten:
ScreenFile("screen.tst") // Result: 4000>
ScreenFile("\screen.tst") // Result: 4000>
ScreenFile("a:\screen.tst") // Result: 4000
■ On a VGA card in 50-line mode:
ScreenFile("screen.tst") // Result: 8000
■ The file is appended:
ScreenFile("screen.tst", .T. ) // Result: 4000
■ Insert a screen from an offset of 4000 ( i.e., after the first
screen):
ScreenFile("screen.tst", .T., 4000) // Result: 4000
■ Insert a screen after the third screen:
ScreenFile("screen.tst", .T., 12000) // Result: 4000
■ Overwrite an existing file in the fourth screen and trim off
the rest of the file:
ScreenFile("screen.tst", .T., 12000, .T.) // Result: 4000
■ Wildcards not permitted:
ScreenFile("screen.*") // Result: 0
cSearchString Designates the character string to search for in screen memory.
cAttr|nAttr Designates the new color attribute to use in the sequence located in screen memory. Can be specified as a numeric or in the manner required under CA-Clipper.
lUpperLower Designates whether the function is case sensitive (.T.) or not (.F.).
lAll Designates whether to mark each occurrence (.T.) or only the first (.F.). The default marks only the first (.F.).
cForwardDelimiter This optional parameter designates which character preceding the cSearchString to use as a delimiter. The default is no delimiter considered.
cTrailingDelimiter This optional parameter designates which character after the cSearchString to use as a delimiter. The default is no delimiter considered.
Returns
ScreenMark() returns a .T. when it locates the designated string at least once.
Description
ScreenMark() searches in the screen memory for a specified character sequence and emphasizes it with a new attribute. For example, you could mark words out of MemoEdit() in inverse video. When you press a cursor key, ScreenMark() is always called in the MemoEdit() that controls UDF.
If you are searching for a specific word, then designate lUpperLower as .T.. If case sensitivity is not a major consideration, then designate lUpperLower as .F..
If you want only words and not word fragments, then work with the two delimiter characters cForwardDelimiter and cTrailingDelimiter. Otherwise, the word "LOCK" is marked if the word "BLOCK" occurred.
If you define a space (see Note) for cForwardDelimiter as a separator for the expression, then LOCK is no longer marked with BLOCK. You can specify all delimiters that could be valid in character string form. The function allows a targeted expression to begin in the first position or end at the last position on the screen or window.
Notes
Important! The CA-Clipper Tools uses Chr(255) as the default to clear the screen, since the character can take on a color attribute on all screen adapters. Be sure to consider this when you create a delimiter list.
■ The cursor position is not changed with this function.
Examples
■ Mark the first word "Clipper" on the screen (exactly) with the
INVERS attribute:
? ScreenMark("Clipper", "0/7", .T.) // Not found if .F.
■ Mark all occurrences of "Clipper" (regardless of the case),
the attribute is white/blue:
? ScreenMark("Clipper", "W/B", .F., .T.) // Not found if .F.
■ Search for all "LOCK" words. Expressions, such as "BLOCK" are
not to be marked. Blanks (when you use the CA-Clipper Tools these
are Chr(255)), slashes, dashes, and brackets, are delimiters:
cListA := Chr(255) + "/("
cListB := Chr(255) + "-)"
? ScreenMark("LOCK", "W/B", .F., .T., cListA, cListB)
cAttrString Designates which attributes to mix with the characters in the cCharacterstring.
nRow Designates the starting line of the output. The default is the cursor line.
nColumn Designates the starting column of the output. The default is the cursor column.
Returns
ScreenMix() always returns a null string.
Description
ScreenMix() allows you to combine two character strings — cCharacterstring which contains characters, and cAttrString which contains attributes. You can mix them together and output the resulting character string directly to the screen. This assigns the first attribute of cAttrString to the first character in cCharacterstring, and so on. The first character is displayed in the color determined by the first attribute. The nRow and nColumn parameters determine the first line and column for the output.
Notes
■ If the parameters for line and column (nRow and nColumn)
are not specified, the output begins at the current cursor position.
Examples
■ The following two character strings determine the text and
attribute to output with ScreenMix(). The first "1" is red on white
(116) and the help text is blue on white (113):
cCharacter: = "1Help"
cAttribute: = Chr(116) + Replicate(Chr(113), 5)
■ Show output at the current cursor position:
ScreenMix(cCharacter, cAttribute)
■ Show output at line 24 at the cursor column:
ScreenMix(cCharacter, cAttribute, 24)
■ Show output at line 24, column 0:
ScreenMix(cCharacter, cAttribute, 24, 0)
nRow Designates the first line to read. The default is the cursor line.
nColumn Designates the first column to read. The default is the cursor column.
nCharCount Designates how many characters to read. The default is to the end of the window or screen area.
Returns
ScreenStr() returns the character string that contains all of the bytes read from the screen.
Description
ScreenStr() returns a specified portion of the screen or window contents. nRow specifies the first line, and nColumn the first column to read from. nCharCount designates the number of characters to read, if you do not want the entire screen or window content.
Notes
■ The returned character string contains all the attribute
bytes. For the entire screen, a variable that is 25 lines by 80 columns, is a total of 4000 characters.
■ If nRow or nColumn are not specified, then the function
automatically uses the corresponding coordinates of the current cursor position. The function does not change the cursor position.
Examples
■ Read all characters with their accompanying attributes from
the cursor position to the end of the screen:
cVar: = ScreenStr()
■ Show all characters and attributes from the cursor position in
line 24:
cVar: = ScreenStr(24)
■ The last 10 characters and attributes in line 24:
cVar: = ScreenStr(24, 70)
■ The last 10 characters (without attributes) in line 24:
cVar: = CharOdd(ScreenStr(24, 70))
SCANKEY([<lMode>]) → nKeyValue
Warning! Augmented from CA-Clipper Tools. This is new optional
parameter.
Arguments
lMode Designates whether or not to ignore the additional keys on the European extended keyboard.
Returns
SCANKEY() returns the scan code for the key pressed.
Description
SCANKEY() returns an untranslated scan code for a key. This allows you to differentiate between keys or key combinations that return the same Inkey() value. SCANKEY() does not take the character out of the buffer. The function waits for a keyboard input and returns the scan code which corresponds. The third example shows how a returned value is converted into something you can display, as in ctscan.ch by SCANKEY(). Although it depends on the keyboard, the scan codes may differ from those listed in ctscan.ch.
Notes
■ No key traps (including the CA-Clipper internal key traps),
Queries the number of characters that can be displayed on a screen or window
Syntax
SCREENSIZE(<lMode>) → nScreenSize
Warning! Contains <lMode>, an additional optional parameter over
and above CA-Clipper Tools.
Arguments
lMode If this parameter is designated as .T., then SCREENSIZE() returns the size of the physical screen; otherwise, it returns the size of the selected window. The default (.F.) is the selected window size.
Returns
SCREENSIZE() returns the number of bytes available for screen output, in an active window, or the physical screen.
Description
SCREENSIZE() determines the screen size memory in bytes. With 25 lines and 80 columns, there are exactly 2000 characters. For each character, there is also an attribute byte that results in 4000 bytes of screen memory.
If SCREENSIZE() is called without parameters or with .F., it returns the active window size. When called with .T., it returns the physical screen size.
Examples
Display the number of available bytes:
WOpen(10, 10, 20, 70) // Open a window
? SCREENSIZE() // Size of window
? SCREENSIZE(.T.) // Size of physical screen
nSeconds Designates the number of seconds since midnight to convert into a character string in time format.
lHundredth If this optional parameter is designated as .T., the resulting time string contains hundredths of seconds. The default is no hundredths (.F.).
Returns
SecToTime() returns a time string that corresponds to nSeconds in the "HH:MM:SS" or "HH:MM:SS:hh" format.
Description
This function can be applied in two areas — to convert numeric time spans in seconds, and to convert a point in time into the "HH:MM:SS" or "HH:MM:SS:hh" format.
If hundredths of seconds are also desired in the time string result, then designate the second parameter as .T.. The portion of the value for nSeconds to the right of the decimal is also converted.
Notes
■ Seconds since midnight are in the range of 0 to 86400. With
larger values, the function internally executes the operation nSeconds % 86400 and then uses the result value. 86400 seconds corresponds to an entire day.
■ There is no rounding when values like 45366.98 are converted
without hundredths.
Examples
■ Calculate the span between two times. The result is displayed
in the "HH:MM:SS" format:
nBeginning := 170
nEnd := 3656
? SecToTime(nEnd - nBeginning) // "00:58:06"
■ With hundredth seconds:
? SecToTime(45873.22, .T.) // "12:44:33:22"
Provides an additional search mode for all AT functions
Syntax
SetAtLike([<nNewMode>,[<cCharacter>]]) → nOldMode
Arguments
nNewMode Designates which mode the AT functions and StrDiff() should use during searches. At this time, the 0 and 1 modes are permitted. The default value is 0.
cCharacter Designates optional wildcard characters only. The default value is "?".
() When called without parameters, the function returns the current mode.
Returns
When a parameter is passed, the function returns the previous mode. If no parameter is passed, the function returns the current mode.
Description
Generally speaking, all AT functions like AtNum(), AfterAtNum(), and the function StrDiff(), operate to find an exact match during the execution of the search sequence. When you use SetAtLike(1), an additional mode can be selected which permits the use of wildcard characters. For every position containing a wildcard character within the search expression, any character can occur in the character string that is searched. The first character of the search expression cannot be a wildcard, and the entire expression cannot consist of wildcards. These restrictions simultaneously avoid unwanted recursions with AtRepl().
The customary "?" has been used as the default wildcard character. However, it can be replaced by using the optional cCharacter parameter. Any character you choose can be set as a wildcard character, increasing the flexibility of this group of functions.
Notes
■ The DOS supported "*" wildcard character is not available for
this function.
■ The nNewMode parameter was selected to be a numeric value to
allow future implementation of additional modes.
Examples
■ Set the SetAtLike(1) wildcard mode to on:
SetAtLike(1)
■ Determine the beginning position at the start of the last
search expression:
cTextsequence := "ABCDEABC123AXCK"
? AtNum("ABC", cTextsequence) // 6
? AtNum("A?C", cTextsequence) // 12
■ Determine if the search expression occurs with the text
sequence:
cTextsequence := "ABCDEABC123AXCK"
? NumAt("ABC", cTextsequence) // 2
? NumAt("A?C", cTextsequence) // 3
■ Determine the portion of the text sequence behind the last
occurrence in the search expression:
cTextsequence := "ABCDEABC123AXCK"
? AfterAtNum("ABC", cTextsequence) // 123AXCK
? AfterAtNum("A?C", cTextsequence) // K
■ Determine the portion of the text sequence before the last
occurrence in the search expression:
cTextsequence := "ABCDEABC123AXCK"
? BEFOREATNUM("ABC", cTextsequence) // ABCDE
? BEFOREATNUM("A?C", cTextsequence) // ABCDEABC123
■ Determine the portion of the text sequence from the last
occurrence aligned at position 15:
cTextsequence := "ABCDEABC123AXCK"
? AtAdjust("ABC", cTextsequence, 15) // ABCDE ABC123AXCK
? AtAdjust("A?C", cTextsequence, 15) // ABCDEABC123 AXCK
■ AtRepl() poses an unusual situation. If a search expression
containing wildcard characters (like the one in the following
example) is exchanged for a sequence where you only find other
characters at the wildcard positions, a recursion occurs internally
if CSetAtMupa() is on:
CSetAtMupa(.T.)
cTextsequence := "ABCDEABC123AXCK"
? AtRepl("D?", cTextsequence, "DX") // ABCDXXXXXXXXXXXX
■ Wildcard characters reduce the valence with the StrDiff()
function:
? StrDiff("ABC", "AXC") // Valence 3
? StrDiff("A?C", "AXC") // Valence 0
nLONG|cHexLONG Designates either a decimal number or hexadecimal number string.
nBitPos1 ... nBitPos32 Designates which bit numbers to set.
Returns
SetBit() sets the designated bits and returns the result.
Description
For example, SetBit() allows you to set one or more bits to change a serial interface register. This is in contrast to NumOr(), where the bit numbers can be set and do not need to be previously converted. The value 1 represents the bit with the lowest value; 32 is the bit with the highest value.
Notes
■ An invalid parameter returns a result of -1.
Examples
Set bits 1, 2, and 5 in a numeric field:
nBitfield := 0
nBitfield := SetBit(nBitfield, 1, 2, 5) // Result: 19
cClearAttr|nClearAttr Designates the desired attribute for CLEARA. The default is white on black (7).
Returns
SetClearA() always returns a null string
Description
SETCLEAR(A)ttribute SetClearA() allows you to set the current, standard attribute for screen- oriented CA-Clipper Tools functions. If this function is not called within a program, the standard attribute of 7 (white on black) is used by the clearing functions.
Notes
■ You can specify the cClearAttr|nClearAttr parameter in
different ways (see Introduction to this chapter).
Examples
■ Use the standard attribute:
SetClearA()
■ Shown below are three ways to set the clear attribute:
SetClearA(19)
SetClearA("03/01")
SetClearA("B/GR")
cClearCharacter|nClearCharacter Designates the desired clear character for CLEARB. Can be a number in the range of 0 to 255 or the character string type. The default value is Chr(255).
Returns
SetClearB() always returns a null string.
Description
SetClearB() sets the default character for screen-oriented CA-Clipper Tools functions. If this function is not called within a program, character Chr(255) is used by the clearing functions. This character (a "hard"' blank) can accept a color attribute on all screen adapters.
Notes
■ When you call SetClearB() without designating the
cClearCharacter|nClearCharacter parameter, the standard character Chr(255) is used.
Examples
■ Use Chr(255) as the standard character:
SetClearB()
■ Use Chr(178) as a clear character SetClearB(178)
nCursorType Designates a cursor type between 0 and 4 (see Clipper 5.0, setcurs.ch).
idCursorForm Designates a value previously returned from this function. The nCursor return value is a 16-bit integer.
nTopLine Designates the beginning scan line of the new cursor.
nBottomLine Designates the ending scan line of the new cursor.
lMode Designates whether the cursor is set to the overwrite (.F.) or the insert (.T.) mode. The default value (.F.) designates that the cursor is set to the overwrite mode.
Returns
If the SetCursor() function is called with parameters, it returns the previous setting. When the function is called without parameters, it returns the current cursor setting. When a value between 0 and 4 is returned, then the cursor type was set through CA-Clipper's SetCursor() function. When the return value is less than 0, the return value is the cursor value that had been set using nTopLine and nBottomLine.
Description
SetCursor() is also a function under CA-Clipper. The CA-Clipper Tools implementation makes several extensions available over and above the CA-Clipper function. When the CTUS.LIB extended driver is linked in, these extensions become available.
One method for using the SetCursor() function is with only a numeric parameter between 0 and 4. With this parameter, the function is CA-Clipper compatible. Please refer to your CA-Clipper documentation for the cursor type corresponding to the individual values.
The second method for using the SetCursor() is exclusively for restoring a cursor type previously saved from the return value. A cursor saved using GETCURSOR() can also be implemented this way, however, use of the GETCURSOR() function for the creation of new applications is not recommended!
The third and last method allows you to implement a cursor completely of your own design by specifying the start and stop pixel lines. Specify the nTopLine and nBottomLine; the first parameter serves as the start line, and the second parameter serves as the end line for the cursor display.
In all three variants of this function's syntax, you can determine the type of cursor you want to change, in the overwrite or the insert modes, by specifying lMode.
Notes
■ The range used for the nTopLine and nBottomLine parameters
is dependent on the screen adapter used and the font installed.
■ To preserve complete compatibility with the former version of
the function call without parameter, ct.ch must be linked in.
Examples
■ In this example, the cursor for both modes is saved, and then
restored:
nNormCursor := SetCursor(.F.) // Overwrite mode
nInsCursor := SetCursor(.T.) // Insert mode
* Cursor is changed in the program
SetCursor(nNormCursor, .F.) // Reset cursor
SetCursor(nInsCursor, .T.) // Reset cursor
■ Here is an example of a setting using the first and last pixel
line:
SetCursor(10, 13) // Cursor as thick
// underscore
dDate Designates which date to use to set the system date.
lMode Designates whether the date should also be set in the CMOS- RAM of an AT. The default is do not write (.F.).
Returns
SetDate() returns .T. when the date is successfully set.
Description
When you use this function to set the system date from within your CA-Clipper application, all files acquire this date with each write procedure.
Notes
■ Please note that you can only implement the optional lMode
parameter for AT-compatible machines. The correct operation of SetDate() cannot be guaranteed on machines that use a hardware clock. The default value for lMode is .F..
Examples
■ Set the system date in each case; but the hardware clock only
on an AT:
dNewDate := CToD("07/30/91")
IF IsAt()
SetDate(dNewDate, .T.)
ELSE
SetDate(dNewDate)
ENDIF
■ Or, more compactly:
SetDate(dNewDate, IsAt())
■ An attempt to set (.AND...) attributes at pseudo files can
trigger a system crash.
Examples
■ Set a file to HIDDEN:
? SetFAttr("TEST.TXT", 2) // Returns 0, if successful
■ When a file is not available:
? SetFAttr("ABCDEFGH"), 2) // Returns: -2
■ Influence the return value:
nAttribute := SetFAttr("TEST.TXT", 7)
IF nAttribute <> 7
*...
ENDIF
Default attribute for creating with CA-Clipper Tools functions
Syntax
SetFCreate([<nNewFileAttr>]) → nOldFileAttr
Arguments
nNewFileAttr Designates a file attribute for a new file.
Returns
SetFCreate() returns the current default attribute or the previous file attribute, if the parameter is specified.
Description
CA-Clipper Tools functions use a value of 32 (setting the ARCHIVE bit) to preset the default for file creation. For example, use SetFCreate() when a file needs to acquire another attribute in a network environment.
Table 7-22: Coding the File Attribute
Value Symb. constants Assigned attribute
0 FA_NORMAL
1 FA_READONLY READ ONLY (Read-only)
2 FA_HIDDEN HIDDEN (Hidden files)
4 FA_SYSTEM SYSTEM (System files)
32 FA_ARCHIVE ARCHIVE (Changes since last backup)
Notes
■ The set values only apply to files you create with CA-Clipper
Tools functions.
Examples
■ Create a read-only file:
SetFCreate(1)
StrFile("Nantucket", "TEST.TXT")
■ Query the attribute set:
? SetFCreate()
cFile Designates for which file the date and/or time is changed. Drive and path designations are possible, wildcards are not.
dFileDate Designates the date for the file. The default is the system date.
cFileTime Designates the time for the file. The default is the system time.
Returns
SetFDaTi() returns .T. when the change is successfully executed.
Description
SetFDaTi() permits you to set the clock date and time of a file. Since the date and time of a file usually change at the same time, these have been brought together in one function. It is possible to only change the time or the date, when one parameter is given and the other is not. The different parameter types tell the function what is to change.
Notes
■ The time is given in a 24-hour format, that is between
"00:00:00" and "23:59:59".
Examples
■ Set the date and time:
SetFDaTi("C:\TEXT\TEST.TXT", CToD("01/01/91"), "01:10:00")
■ Set current date and time:
SetFDaTi("TEST.TXT") // Date() + Time()
■ Only change the date:
SetFDaTi("TEST.TXT", Date() -10) // Ten days prior to today
■ Only change the time, resetting to start time:
SetFDaTi("TEST.TXT", SecToTime(Start))
cFontString Designates a string that contains a valid font definition.
nFontArea Designates the number of the desired font area. For EGA adapters, the values are 1 to 4, for VGA, they are 1 to 8 or the number allowed by MAXFONT().
nOffset Designates the character position at which the font table is transmitted to the screen adapter. The default value is 0.
nCounter Designates the number of characters for which a new font is loaded. The default value is 256.
lCompute Use this parameter only when nOffset and nCounter are not in concurrent use. When designated as .T., the function computes the pixel height from the length of the font string.
Returns
The function returns an error code with the following definitions:
Table 6-4: Error Code Definitions
Error Code Definition
0 Font loaded successfully
-1 Invalid font area designated
-2 Impossible in current video mode
-4 The <lOtherPixelHeight> mode is invalid (the Extended
Drivers has not been linked in)
Description
With SetFont(), you can load a screen font from a string into the font area of an EGA or VGA card. FONTSELECT() allows you to determine the font to serve for normal and the font to serve for high-density output.
Technical Background
EGA and VGA cards permit you to modify all 256 characters of the character generator or any portion of it with software. For this purpose, load a previously created pixel pattern for the character in the corresponding position in a font area on the screen card. Normally, an EGA card has a maximum of four font areas and a VGA has eight. You can redefine any of the 256 characters within these font areas. Use MAXFONT() to determine the actual number of font areas.
Building fonts into a program requires unnecessary memory space. It is also awkward to construct string fonts within a program. The GETFONT() and SetFont() functions load a font from a screen card into a string variable, or from such a variable into a font area on the card. However, FONTLOAD() only offers the ability to load a font from a file into a particular area of the screen card. In both cases, use FONTSELECT() to activate the loaded font when necessary.
To construct new fonts, a font editor is included in CA-Clipper.
Variable Pixel Height
In principle, the EGA and VGA screen adapters provide the ability to display fonts with 2 to 32 pixels per character (1 pixel/character only, when there are 200 scan lines). ROM fonts are only available for pixel heights of 8, 14, and 16, which explains the great expansion of the EGA 25/43-line and VGA 25/28/50-line modes. You must construct individual fonts for all other pixel heights. This is easy with the CA-Clipper Tools font editor.
If you deviate from the mode just set, use SetFont() to implement other desired pixel heights, where the lCompute parameter is designated as .T. The pixel height is computed with the following formula:
Pixel height = Len(Font-String)/256
Partial fonts cannot be used for this calculation, only fonts that contain the full 256 characters.
Since a change in pixel height also leads to a change in the screen mode and line count, always link in the CTUS.LIB Extended Drivers.
Notes
■ The screen adapters do not permit you to mix fonts with
different pixel heights.
■ When an EGA card does not require the full use of memory, you
can reduce a maximum number of four font areas. Use MAXFONT() to determine the number of available fonts at any given time.
Examples
■ Load all 256 font characters in font area 2:
? SetFont(cFontString, 2) // 0 < OK
FONTSELECT(2) // Font area 2 for<R>
// non-highlighted
■ Exchange the top 128 characters of a font in font area 3:
? SetFont(cFontString, 3, 128, 128) // 0 <F128M><142><F255D><N>OK
FONTSELECT(3) // Font area 3 for<R>
// non-highlighted
■ In this example, the just-installed font height is doubled
wherever possible. This is simple, since each byte in the font
string is doubled:
cFont := GETFONT()
SetFont(CharMix(cFont, cFont), .T.)
■ The font strings can be torn down to individual pixel lines.
This example shows pixel lines as a bit pattern in a binary display:
cFont := GETFONT()
nPixel := CharPix()
FOR A = 0 TO 255
FOR B = 1 TO nPixel
nByte := Asc(SubStr(cFont, (nPixel * A) + B, 1))
? NToC(nByte, 2, 8, "0")
NEXT B
Inkey(0)
?
NEXT A
nOrgKeyValue Designates the original key code that is translated into the value of nNewKeyValue.
nNewKeyValue Designates a new key code for nOrgKeyValue. If not specified, SetKXLat() turns off the key translation designated by nOrgKeyValue.
() Calling this function without a parameter uninstalls all of the key translations previously performed.
Returns
SetKXLat() returns .T. when the translation code is successfully installed, and .F. if a parameter contains errors or additional memory can not be allocated. The number of allowable key code translations can be calculated as follows:
maximum allocatable memory / 4
Description
With this function, keyed input can be translated or even switched off. Symbolic constants for the codes have been defined in the ctscan.ch include file. The following formula applies to each key:
cKeyValue = Chr(ASCII) + Chr(SCAN_CODE)
Many key combinations have no ASCII equivalent. In these cases, the Chr(ASCII) byte is 0. However, some key and key combinations have a scan code, allowing the differentiation of keys with the same ASCII code (e.g. the decimal point on the numeric key pad and the period in the alpha numeric field).
Scan code 0 is returned when you input an ASCII code through the numeric key pad in the form Alt + number.
When the function is called without cNewKeyValue, the translations specified in cOrgKeyValue are uninstalled.
Calling the function without any parameters discards all existing translations.
Notes
■ The numeric coding previously used for the key codes is still
valid.
■ All symbolic constants from the CA-Clipper file inkey.ch can
be used.
■ A new translation for a key overwrites the previous one.
■ Memory for the key code translations is allocated dynamically.
Examples
■ Press the "A" and the keyboard returns the code of "B' (in
reality you would seldom use this):
SetKXLat(KS_A, KS_B) // .T. if successful
■ Translate the left arrow into the down arrow on the key pad.
Both keys then return the same code:
? SetKXLat(KS_LEFT, KS_DOWN) // .T. if successful
■ Turn the up arrow in the cursor control block off. Key code:
? SetKXLat(KS_DOWN, KS_DISABLE) // .T. when successful
■ Turn the up arrow back on:
? SetKXLat(KS_DOWN)
■ Uninstall all translations:
SetKXLat()
idKeyTable Designates a character string that contains the key definitions as described below.
Returns
The function returns .T. when the key table is successfully installed.
Description
With SetKXLat() code translations can only be defined for individual keys. In contrast, with SetKXTab() an entire table can be implemented. SetKXLat() is primarily for use in the restoration of a key table that has been saved with GetKXTab(). Four bytes are needed to translate a single key; two bytes are needed for the scan code for the original key; and two bytes are needed for the scan code for the key that is simulated. The construction of the table progresses in the following form:
cByte1 := Chr(ASC1) // Key to be translated cByte2 := Chr(ASC2) // Key to be translated cByte3 := Chr(ASC1) // Key to be simulated cByte4 := Chr(ASC2) // Key to be simulated
cTable := cByte1 + cByte2 + cByte3 + cByte4
with symbolic constants:
cTable := KS_A + KS_B // Translate "A" to "B"
The symbolic constants for key codes can be found in the ctscan.ch include file.
Notes
■ The installation of a new key table overwrites the existing
table.
Examples
Save the existing key table and reset it later:
cKXTab := GetKXTab()
DO KEYCHANGE
SetKXTab(cKXTab)
nKeyValue Designates the character code passed to LastKey().
Returns
SetLastKey() always returns a null string.
Description
SetLastKey() changes the contents of the memory area used by LastKey(). This allows you to save the current contents of the LastKey() buffer in an error trap and restore it when you return to the program.
Examples
Save the last key value so it can be changed and restored later:
nCharacter: = LastKey() // Save character code *... *...
SetLastKey(nCharacter) // Reset LASTKEY
Sets the precision level for trigonometric functions
Syntax
SetPrec(<nPrecision>) → cNull
Arguments
nPrecision Designates the number of places for computational precision in the range of 1 to 16. The default value is 16.
Returns
SetPrec() always returns a null string.
Description
SET PRECISION CA-Clipper Tools works with the default precision set at 16 places to the right of the decimal for trigonometric functions. If you do not want this precision level, or you want a faster execution speed, reduce the number of places accordingly. The following functions are affected:
nRow Designates the new cursor line. The default is the current BIOS line.
nColumn Designates the new cursor column. The default is the current BIOS column.
Returns
SetRC() always returns a null string.
Description
This function resets the internal value that CA-Clipper returns for the current Row() line and Col() column. The cursor automatically moves to this new location at the same time. When output is not through CA-Clipper, the CA-Clipper internal values for Row() and Col() may deviate from the actual position returned in the BIOS. If you implement SETRC without a parameter, then the position returned from the BIOS is set within CA-Clipper.
Notes
■ Negative values or those too large for the line or column, are
corrected automatically.
Examples
■ Set the BIOS line and column in CA-Clipper and display:
SetRC()
? Row(), Col()
■ The BIOS line and the CA-Clipper column are used:
SetRC(, Col())
? Row(), Col()
■ The CA-Clipper line and the BIOS column are used:
SetRC( Row())
? Row(), Col()
cTime Designates a character string that contains the time that is to become the system time.
lMode Designates whether the time should also be set in the CMOS-RAM of an AT. The default is do not write to CMOS-RAM.
Returns
The function returns .T. when the time is set successfully.
Description
When you use this function to convert the time into the system time from within your CA-Clipper application, all files acquire this time with each write procedure.
Notes
■ Please note that you can only implement the optional lMode
parameter in AT-compatible machines. The correct operation of SetTime() cannot be guaranteed on machines that use a hardware clock. The default value for lMode is .F..
Examples
■ Set the system time in each case; but the hardware clock only
on an AT:
cNewTime := "10:20:00"
IF IsAt()
SetTime(cNewTime, .T.)
ELSE
SetTime(cNewTime)
ENDIF
■ Or, more compactly:
SetTime(cNewTime, IsAt())
Sets the tone frequency and duration for Chr(7) or CA-Clipper's "beep"
Syntax
SETBELL([<nFrequency>,<nDuration>]) → cBlank
Arguments
nFrequency Designates the frequency for the bell tone in Hertz. Values from 21 to 65535 are possible.
nDuration Designates the duration of the bell tone in 1/100 seconds. Values from 1 to 65535 are possible.
() Calling this function without parameters resets the function to the default value of 880.30 (a frequency of 880 Hertz and a duration of 0.3 seconds).
Returns
This function always returns a null string.
Description
Previously, when you output Chr(7) or completed a GET command with SET BELL ON, only an unchangeable tone was produced. With SETBELL(), the frequency and duration of this tone can be modified. The frequency range for this tone is between 21 and 65535 Hertz. However, the use of frequencies outside the audible range (above approximately 16000) doesn't make much sense.
The bell tone default setting is 880 Hertz with a duration of 0.3 seconds. These values are reset if no parameters are passed.
Examples
■ Select a tone of 300 Hz with 0.2 second duration:
SETBELL(300, 20)
■ Reset the function to the default values:
SETBELL()
nTimeDelay Designates the time delay in milliseconds with which boxes are opened in "grow" mode.
Returns
The function always returns a null string.
Description
Normally boxes are only formed with the WBox() function, the CA-Clipper @ .. BOX command, or the CA-Clipper @ .. CLEAR TO .. [DOUBLE] command. By using SETBOXGROW(), you can establish the display for empty boxes in a "grow" mode
A box grows from the midpoint of the window outward when SETBOXGROW() has been set. The nTimeDelay parameter is the time delay in milliseconds between the individual steps.
But there are two exceptions to the rule on the nTimeDelay parameter. If the parameter is 0, the box is (re)opened, but not in "grow" mode. And if the parameter is 1, the box is opened in "grow" mode, but without a time delay.
Notes
■ The "grow" mode is only functional when a fill character has
been specified. If you do not specify a parameter with WBox(), the default settings are used.
■ When you work with "snow prevent", do not specify a time delay
for boxes.
Examples
Specify 10 milliseconds between each growth step of a box:
SETBOXGROW(10)
WOpen(2, 2, 23, 78) // Nothing happens
WBox() // The box is generated with
// a time delay
Determines the number of lines after which the screen display pauses
Syntax
SETLINES(<nLines>) → cNullString
Arguments
nLines Designates the number of lines after which the screen display pauses.
Returns
The function always returns a null string.
Description
SETLINES() allows you to simulate a DOS MORE command for commands like LIST or DISPLAY. To properly function, one input command must always be present in the related instruction (see example).
Notes
■ Only line feeds are counted.
■ If you use values less than or equal to 0 for nNrLines, the
screen display does not pause.
Examples
In this example, the screen output stops after 20 lines. Inkey() allows
you to continuously query the keyboard, while the Nul() suppresses the
return value for Inkey().
USE DATA
SETLINES(20) // Stop after 20 lines
LIST Field1, Field2, Nul(Inkey())
nLastColumn Designates the rightmost column that the extended driver supports for screen output. The highest value possible is 253, assuming sufficient screen memory is available. Only odd numbers of columns are permitted because the value is 0-based.
nScrollBorder Designates the left and right column borders that move the screen when crossed by the cursor. Values from 0 to MaxCol(.T.)/2 are valid. Larger values are corrected to the maximum value. When a value is passed for this parameter, scroll is turned on. When no parameter is passed, scroll is off.
Returns
SETMAXCOL() returns .T. when nLastColumn is successfully set.
Description
This function allows you to set the number of columns that the extended driver accepts for CA-Clipper screen output. Two different types of screen output can be determined:
Special Screen It is possible to use full page screens or other special screens that display more than 80 columns, and whose column count is not automatically recognized by the BIOS (this is always hardware based). These screens must be compatible with the usual screen adapter with regard to the organization of the screen memory (character attributes), the attribute bytes themselves, and the basic address of the screen memory. The function doesn't switch any modes; the internal settings of the extended drivers are simply adjusted. Specific screen settings must be carried out through the hardware's driver module.
Virtual Screen It is also possible to set a column count higher than what can be displayed on the screen. In this case there is only a portion of the total screen memory visible. If a CA-Clipper input command (such as GET/READ) is built larger than the visible area, the extended driver automatically moves screen memory in accordance with cursor movement. This movement always occurs when the cursor moves beyond the left or the right borders set in nScrollBorder. In this way, the portion of text that is worked on is always visible. The visible area of the virtual screen can also be set using the FIRSTCOL() function if needed.
Virtual screens are possible on CGA, EGA, and VGA adapters as well as those that can fully emulate them. The maximum number of columns you can install, assuming a 25-line and 80-column mode (CGA80() or MONOCHROME()), can be determined in the following manner:
With eight screen pages you will have a value of >255. In other words a maximum of 254 columns can be used, which exactly equals the maximum value for SETMAXCOL() of 253. To switch back to the number of actually displayed columns, call the function with the corresponding value and no border.
Notes
■ We are not able to provide any kind of technical support when
unknown screen hardware is used. Full page screens do exist on the market which fulfill the conditions described above.
■ Changing the number of columns breaks down the existing screen
contents and renders it unusable. This switch should always be linked to a CLEAR.
■ Virtual screens use the memory area for additional screen
pages. The number of screen pages decreases in proportion to the growth of the virtual screen.
■ If the nScrollBorder is larger than or equal to half of the
visible columns, then the display in the middle of the screen is scrolled under the cursor.
■ If the cursor is switched off, the automatic scroll depends
only on keyboard input.
■ When windows are open, the column count cannot be changed,
regardless of the automatic scroll setting.
Examples
■ Set the number of columns to 96 (special screen):
SETMAXCOL(95) // 96 columns
@ 10, 80 SAY "CA-Clipper"
■ Switch a VGA adapter already in 50-line mode (VGA50()) to a
virtual 100-column mode with a border of 3 characters:
CLEAR // Best to have the screen clear
? SETMAXCOL(99, 3) // Returns .T. if successful
■ Switch off the automatic scroll:
SETMAXCOL(MaxCol(.T.))
nLastLine Designates the last line that the extended driver supports for screen output. The highest value possible is 254, assuming sufficient screen memory is available.
nScrollBorder Designates the top and bottom borders that move the screen when crossed by the cursor. Values from 0 to MaxCol(.T.)/2 are valid. Larger values are corrected to the maximum value. When a value is passed for this parameter, scroll is turned on. When no parameter is passed, scroll is turned off.
Returns
SETMAXROW() returns .T. when nLastLine is successfully set.
Description
This function allows you to set the number of lines that the extended driver accepts for CA-Clipper screen output. You can determine two different types of screen output.
Special Screen It is possible to use full page screens or other special screens that display more than 25 lines, and whose line count is not automatically recognized by the BIOS (this is always hardware based). These screens must be compatible with the usual screen adapter with regard to the organization of the screen memory (character attributes), the attribute bytes themselves, and the basic address of the screen memory. The function doesn't switch any modes; the internal settings of the extended drivers are simply adjusted. Specific screen settings must be carried out through the hardware's driver module.
Virtual Screen It is also possible to set a line count higher than what can be displayed on the screen. In this case, only a portion of the total screen memory is visible. If a CA-Clipper input command such as GET/READ is built larger than the visible area, the extended driver automatically moves screen memory in accordance with cursor movement. This movement always occurs when the cursor moves beyond the left or the right borders set in nScrollBorder. In this way, the portion of text that is worked on is always visible. The visible area of the virtual screen can also be set using the FIRSTROW() function if needed.
Virtual screens are possible on CGA, EGA, and VGA adapters as well as those that can fully emulate them. The maximum number of lines you can install, assuming a 25-line and 80-column mode (CGA80() or MONOCHROME()), can be determined in the following manner:
In other words, a maximum of 204 lines can be used, which exactly equals the maximum value for SETMAXROW() of 203.
You can switch back to the number of lines that actually display by calling the function with the corresponding value and no border.
Notes
■ We are not able to provide any kind of technical support when
unknown screen hardware is used. Full page screens do exist on the market which fulfill the conditions described above.
■ Please notice that virtual screens use the memory area for
additional screen pages. The number of screen pages decreases in proportion to the growth of the virtual screen.
■ If the nScrollBorder is larger than or equal to half of the
visible columns, then the display in the middle of the screen is scrolled under the cursor.
■ If the cursor is switched off, the automatic scroll depends
only on keyboard input.
■ When windows are open, the line count cannot be changed,
regardless of the automatic scroll setting.
Examples
■ Set the number of lines to 72 (full page screen):
SETMAXROW(71) // 72 lines
@ 65, 20 SAY "CA-Clipper"
■ Switch a VGA adapter to a 100-line screen. As soon as the
cursor is in the region of the top or bottom tow lines, the screen
moves:
? SETMAXROW(99, 2) // Returns .T. if successful
■ Switch off the automatic scroll:
SETMAXROW(MaxRow(.T.))
nScreenPage Designates the screen page number to select. The value can be as high as you like, depending on the screen card, its mode, and available memory. The first page is 0.
lHidden Designates whether or not output is displayed. If this parameter is .T., the output is in the page selected, but is not displayed. If this parameter is .F., the output is displayed. The default value is .F..
Returns
SETPAGE() returns .T. when it is possible to physically or virtually select the screen page.
Description
SETPAGE() allows you to switch to another screen page on the video adapter that you use. If the lHidden parameter is not passed (or is designated as .F.), the output, and therefore the selected page, is visible. By contrast, if lHidden is .T., the output is sent to the new page, but the page that was visible when you invoked SETPAGE() remains visible. It is therefore possible to construct hidden screens.
Notes
Important! This function cannot be implemented when windows are open.
■ Virtual screen output cannot be achieved using a string output
(i.e. SETSCRSTR()). Use SETSCRSTR() when there is only one page available on the screen adapter.
Examples
■ Select two pages with the output immediately visible. The
output with the returned value is on the new page:
? SETPAGE(1) // .T., if OK
■ Hide the output:
SETPAGE(0) // Displayed
SETPAGE(1, .T.) // Output here
nPrinter Designates whether the printer output is through DOS (0) or BIOS on printer 1, 2, or 3.
nRepeatRate Designates how frequently an output attempt is made from extended drivers if the printer is not ready. The default value is 1000 attempts.
Returns
The function returns .T. when the selected output setting is successfully established.
Description
The default setting for CA-Clipper's printer output is through DOS. SETPBIOS() configures the extended driver in such a way that all subsequent printer output is directed through the BIOS. This configuration gives you certain advantages. You can determine the timeout for printers that are not ready. Using nRepeatRate, you determine how frequently the output should be attempted before the program falls into an error trap. Printer output on local printers is usually quicker, at least as long as the printer is able to accept the files quickly enough (hardware spoiler, built in printer buffer memory).
For BIOS output, you must always designate the selected printer with the nPrinter parameter. This setting then has absolute priority over any previously setting using the CA-Clipper SET PRINTER TO command.
Notes
■ If you use the SET PRINTER TO command, the extended drivers
ignore the SETPBIOS() setting.
■ The extended driver can test to see if the printer is busy or
not, before the output of a single character, but only when the extended driver outputs with BIOS. In this case, the extended driver waits until the printer can once again receive files.
■ BIOS output functions in all systems that have an interrupt
17h that is compatible with the IBM BIOS.
■ BIOS output successfully operates in those networks that
reroute the corresponding interrupt 17h.
Examples
■ Specify printer output through BIOS to LPT2, independently of
the CA-Clipper SET PRINTER TO setting:
SET PRINTER TO LPT1
? SETPBIOS(2) // .T. if OK
■ This is the same setting with a shortened timeout:
SETPBIOS(2, 100) // 100 repetitions
■ Reset the print output to DOS:
? SETPBIOS(0) // .F. when via DOS
nASCIIPos|cCharacter Designates the position or the character in the key table that is overwritten by the cPrintCharacter. This parameter can be designated as a numeric value, between 0 and 255, or as an individual character.
cPrintCharacter Designates the sequence of characters that are copied into the key table, starting from the nASCIIPos position.
() By invoking the function with no parameters, the existing key table is cleared.
Returns
SETPXLAT() returns .T. when the key table is active.
Description
CA-Clipper normally passes all characters between 0 and 255 to the printer, without changing any of the characters. This always leads to problems when the printer is set up with a different font style. For example, a 7 bit printer, which looks for things like German umlauts, can cause problems with the IBM extended character set. Output through a key table that you can build yourself is more flexible than a special drive module for different printers.
Imagine the key table as a memory area of 256 bytes. Memory position 65 normally contains the character Chr(65). Using SETPXLAT() you could exchange this character for Chr(66). Thus an "A" sent to the printer no longer produces an "A", but a "B". There are also other ways to substitute characters from a particular position.
Notes
■ The key table is only created at the moment that an exchange
under SETPXLAT() is requested. Therefore, memory is not used up unnecessarily.
Examples
■ Here is the solution for multiple calls of SETPXLAT():
SETPXLAT(65, Chr(66)) // B
■ You can also call the function as follows:
SETPXLAT("1", "AB") // 12 AB
cFileSpecification Designates the new file name for the QUIT file which can include a path and file extension. The default name for this file is the name of the active .EXE file with a .Q extension.
Returns
SETQNAME() returns .T. when the new name and path are successfully set.
Description
The DSETQFILE() function allows you to create a QUIT file when a CA-Clipper application returns to DOS. The default name for this file is the name of the .EXE file with a .Q extension. Unless otherwise specified, the QUIT file is saved in the directory from which the application was started.
Using SETQNAME() you can designate an alternate name and a completely different path for saving the QUIT file.
Notes
■ Calling this function without parameters returns .F., the
default value. The QUIT file name is reset to the default name.
Examples
Change the name for the QUIT file:
SETQNAME("C:\LOGS\PROTO.LOG")
DSETQFILE(.T.) // Alternative name for QUIT file
nModeNumber Designates the number of the selected mode that corresponds to the designation in the table below.
Returns
The function returns .T. when the selected mode is installed.
Description
SETSCRMODE() supports every video mode that the current screen adapter supports. However, non standard mode settings under the CA-Clipper and CA-Clipper Tools combination are not a good idea. For example, this applies to all graphic modes where CA-Clipper or CA-Clipper Tools cannot work. The following modes are anticipated within the CA-Clipper Tools:
Table 2-4: Modes and Their Coding
Mode Mode Number
CGA40 Monochrome 0
CGA40 Color 1
CGA80 Monochrome 2
CGA80 Color 3
Monochrome 7
EGA43 (EGA only) 299 (43+256)
VGA28 (VGA only) 284 (28+256)
VGA50 (VGA only) 306 (50+256)
Notes
Important! We cannot guarantee that you won't have problems if you use any special mode and screen adapter together with Clipper and CA-Clipper Tools.
■ This function cannot be implemented when windows are open.
Examples
■ Implement the EGA43-line mode:
EGA43()
■ Save the current screen mode:
nOldMode := GETSCRMODE()
■ Reinstall the current screen mode later:
SETSCRMODE(nOldMode)
lMode Designates whether subsequent screen output is put into the internal memory area (.T.) or is to reappear on the screen (.F.). The default is mode off (.F.)
Returns
SETSCRSTR() returns .T. when the subsequent screen output is routed to an internal memory area. The function returns .F. when anything other than window 0 is selected.
Description
SETSCRSTR() selects a mode where all screen output is redirected to an internal memory area. After switching on this mode, the memory area is initialized as if you had cleared the screen with an @ 0, 0 CLEAR. All screen output that results from the CA-Clipper driver module or the CA- Clipper Extended Drivers is rerouted to this memory area. The data stored there is then passed to a variable with GETSCRSTR(), and after the mode is switched off, it is passed to the CA-Clipper RestScreen() function. Since the entire screen output is always rerouted and must always be selected (with the exception of window 0), call RestScreen() with the maximum coordinates for the physical screen of 0, 0, MaxRow(), MaxCol().
Notes
Warning! You cannot implement this function when windows are open.
■ If the CTUS.LIB Extended Drivers is not linked in, you cannot
use a CA-Clipper Library function to reroute screen output to a variable.
■ External programs, DOS and BIOS output, can also be redirected
in a string. To do this, you must set DSETWINDOW() on (.T.).
■ Since no output appears on the screen during this hidden
output mode, switch off "snow prevent" through NoSnow(.F.).
■ Use SET CURSOR ON/OFF, if you also want to switch the cursor
off.
Examples
■ Show hidden output. Should the need arise, switch back to the
physical screen:
WSelect(0)
? SETSCRSTR(.T.) // .T. when mode on
@ 10, 10 SAY "XXXXXXX" // Normal screen output
*....
@@ 15, 10 SAY "YYYYYYY
■ Always call the GETSCRSTR() function before SETSCRSTR(.F.):
cVar := GETSCRSTR()
? SETSCRSTR(.F.) // .F. when mode off
RestScreen(0, 0, MaxRow(), MaxCol(), cVar)
Sets the default opening mode (share mode) for CA-Clipper Tools file functions
Syntax
SETSHARE(<nShareMode>) → lAccepted
Arguments
nShareMode Designates the desired share mode.
Returns
SETSHARE() returns .T. when the desired share mode is implemented (must be DOS version - 3.1 or higher).
Description
The setting you implement here influences all CA-Clipper Tools functions that open, read, or write to a file. The share mode can be set here. It determines when a program opens a file under DOS and how other programs within a network may address this file. The CA-Clipper Tools default is 0, compatibility mode. The following codes apply:
Table 7-23: Share Mode Coding
Code Share Mode
0 Compatibility mode. Here DOS or the network software itself
determines the share mode. In Novell networks, the SHAREABLE
attribute plays an important role in this relationship.
1 Both read and write by other programs are locked out.
2 Write by other programs are locked out.
3 Read by other programs are locked out.
4 Not locked. Read and write by other programs is allowed
Notes
Important! This function can only be used with DOS versions 3.1 or higher. Older versions return .F..
Examples
■ Change share mode, prohibit writing by others:
? SETSHARE(2) // .T., when >= DOS 3.1
■ Bad parameter:
? SETSHARE(12) // .F.
cTabTable Designates a character string with tab definitions in a format as defined below. Can be a maximum of 32 characters long.
or:
nTabWidth Designates (as an exception) an individual numeric value for the tab value. A blank is then used for the tab setting.
() If you call the function without parameters, the tab settings from the CA-Clipper console output are uninstalled.
Returns
SETTAB() returns .T. when the character string that contains the tab settings is installed successfully.
Description
Using this function, you can switch to a mode in which CA-Clipper console output (with the exception of @..SAY) can interpret tab characters. This function allows tabs to be blanks or any other character you choose. The tab positions and the character used for each tab jump are passed in a character string with the following format:
You do not need to specify every tab position within a line. Any tab position that is not specified is worked out as follows:
previous Tab Pos. + previous Tab Pos.
For example, if the first position is 0, the second is 8, and no other positions are specified, then the tab positions are 16, 24, 32 etc.
When you call the function with nTabWidth, only one tab width can be specified. All positions are calculated as multiples of this value. A space is used as the tab character.
Notes
■ A tab position within a string can never be less than one
previously designated. The function returns .F., indicating an error.
■ If the difference between the last and the next to last tab
positions is 0, or if the last position specified is 0, then additional tabs on this line are not taken into account.
■ The tabs are exclusively for screen output, not for printer or
ALTERNATE files.
Examples
■ Set tabs that expand to spaces with a tab width of 8:
SETTAB(8)
■ Set tabs for positions 8, 16, 24, etc. Use a "." as the tab
character:
cTab := Chr(9)
cTabString := Chr(8) + "." + Chr(16) + "."
SETTAB(cTabString)
? "AAAA" + cTab + "BBB" + cTab + "CCCCCC" + cTab + "DDD"
* The resulting output: AAAA. . . .BBB. . . . .CCCCCC. .DDD
■ Format the output in conjunction with LIST:
USE <file>
LIST OFF cTab + FIELD1 + cTab + FIELD2 + cTab + FIELD3
Increases number of time ticks to produce a more precise time measurement
Syntax
SETTIC([<lAcceleration>]) → lAccelerated
Arguments
lAcceleration When this parameter is .T., the number of timer ticks is increased by a factor of 128. The default is normal timer ticks (.F.).
() With no arguments, SETTIC() returns the current status of the timer as a .T. when accelerated; .F. if it is not.
Returns
The SETTIC() function returns .T. when the timer is accelerated; otherwise, it returns .F..
Description
If the integrated timer in your computer uses SETTIC(.T.) to accelerate, then the number of ticks per second increases from 18.2 to around 2500. This makes time measurement more precise and allows you to compare the speed of different routines more accurately.
The computer's clock time, which is also based on the timer tick, continues to operate correctly.
Notes
Warning! You must uninstall SETTIC() before you leave a program; otherwise, you will hang the system. However, if the Extended Drivers CTUS.LIB is linked in, then SETTIC() uninstalls automatically when you exit the program.
■ As long as the timer is accelerated, you cannot implement the
KeySec(), ShowTime(), and SHOWKEY() functions because they use the timer tick. Therefore, you must uninstall these functions before you implement SETTIC(.T.).
■ Do not place (link) SETTIC() within an overlay, since an
interrupt service routine can never be within an overlay. Of course, you can call SETTIC() from an overlay.
■ Since each timer tick must call an interrupt service, your
program's execution speed decreases.
Examples
Measure an individual UDF in ticks. The tick rate increases first, and
then decreases after UDF is executed and the number of resulting ticks
is queried:
SETTIC(.T.)
MY_UDF(I) // Needs to be measured...
SETTIC()
? "Required ticks:", GETTIC()
nRow Designates the row where the time is displayed. The default is the cursor row.
nColumn Designates the column where the time is displayed. The default is the cursor column.
lMode Designates whether seconds are to appear in the time display (.F.), or not (.T.). The default is display seconds (.F.).
cAttr|nAttr Designates to the screen attribute to use for the time display. Strings in the form "NN/NN" or "CC/CC" (e.g., "0/7" or "B/GR") are possible. The default is the setting for CLEARA (see Introduction, Video Functions).
l12/24 By designating this parameter as .T., a 12-hour display is selected. The default is a 24-hour display (.F.).
lAM/PM If you have a 24-hour display, you may want to switch on an am/pm display. When you specify this parameter as .T., an "a" or "p" (as in DOS), appears to reflect the time. The default is no display (.F.).
() A call without parameters uninstalls the time display.
Returns
ShowTime() always returns a null string.
Description
This function permits you to constantly display the time in any screen position desired. ShowTime() is interrupt controlled and has the ability to display the time in either "hh:mm:ss" or "hh:mm" format. A 12- or 24- hour display can be selected, with or without an am/pm display.
Notes
Warning! ShowTime() works with the interrupt system. Before leaving your CA-Clipper application, you must uninstall ShowTime() , so that the interrupt vectors can be restored. Otherwise, the system will be unstable and will eventually crash. Simultaneous use of the accompanying Extended Drivers Modules automatically restores the interrupt vectors in use.
■ Specify the screen attribute as either a numeric or a string
in "NN/NN" form. If no attribute is specified, the value for CLEARA applies (see Introduction Video Functions).
Examples
■ Display a clock in row 0, column 70, with no seconds display
and the standard attribute. When a display is shown in row 0, switch
SCOREBOARD off!
SET SCOREBOARD OFF
ShowTime(0, 70, .T.) // Turn on clock
*...
*...
nSHOWTIME() // Uninstall clock
■ Show a 12-hour display with am/pm on the lowest row. White
letters on a blue background:
ShowTime(24, 70, .T., "W/B")
cKey Designates which key to monitor in the form of a letter ("C", "N", "S", or "I"). If cKey is the only parameter in SHOWKEY()
(C, N, S, or I), the respective key monitoring is uninstalled.
Line Designates the line where the display occurs.
nColumn Designates the column where the display occurs.
cTextON Designates text for the active status. A maximum length of 15 characters is allowed.
cTextOFF Designates text for the inactive status. There is a maximum of 15 characters and it must have the same length as cTextON.
cAttrON|nAttrON Designates the color attribute for the active status. The default value is 7/0.
cAttrOFF|nAttrOFF Designates the color attribute for the inactive status. The default value is the same as in cAttrON|nAttrON.
() If you call SHOWKEY() without parameters, it uninstalls.
Returns
The SHOWKEY() function always returns a null string.
Description
SHOWKEY() is an extremely versatile system that can be used to monitor the NUM-LOCK, SCROLL-LOCK, CAPS-LOCK, and INSERT keys. After it is installed, you can display an indicator for each key, the desired screen position, and a color attribute (without concerning the CA-Clipper program). You can establish a display for both the active and inactive status with individual color attributes. However, both these strings must have the same length.
Since the system INSERT status is handled separately from the CA-Clipper INSERT status, this monitoring can only be implemented from within a READ. An indicator display, in so far as it has been activated, is refreshed in intervals of approximately 200 milliseconds. Therefore, when you clear a portion or the complete screen, do not concern yourself with restoring this display.
Notes
Warning! Always uninstall this function before you leave a program or use the Extended Drivers provided with this CA-Clipper Tools. The function changes interrupt vectors. You may cause a system crash, if the old status is not restored before you exit the program! Use the enclosed INTSAVE program to avoid this problem.
Examples
■ Display "CAPS" if CAPS-LOCK is on: CAPS-LOCK for off: " ",
in line 24, column 50. The default value for on and off is "7/0"
SHOWKEY("C", 24, 50, "CAPS", " ")
■ Attributes can be numeric and or designated as in CA-Clipper:
SHOWKEY("N", 24, 60, "NUM ON", "NUMOFF", 112, "W/R")
■ Inverse the display for on and off:
SHOWKEY("S", 24, 70, "SCRL", " ", "0/7")
■ Uninstall the NUM-LOCK display:
SHOWKEY("N")
■ Uninstall the function:
SHOWKEY()
nValue Designates the number to determine as a mathematical sign.
Returns
Sign() returns 1, 0, or -1, based on whether the number passed as a parameter is positive, null, or negative.
Description
This function simplifies mathematical expressions. If constructions or functions become unnecessary. Sign() returns three different values, in accordance with the specified parameter:
1 positive numbers 0 the number 0
-1 negative numbers
Examples
■ Show a positive number:
? Sign(48335) // Result: 1
■ Show a negative number:
? Sign(-258) // Result: -1
nFrequency Designates the tone frequency in hertz.
nDuration Designates the duration of the tones in 1/100ths seconds; or when lTimer is set at .T., in intervals of 1/18.2 seconds.
lTimer Designates whether the tones designated as values are created on a basis of 1/100ths seconds (.F.); or 1/18.2 seconds (.T.). The default value is 1/100th seconds (.F.).
or:
cToneSequence Designates a character string that contains an entire melody. Use the CA-Clipper I2Bin() function to produce 2-byte values for frequency and duration. The string format assumes 2 bytes for frequency and 2 bytes for duration, which are alternated until the melody is defined.
lTimer Designates if you want the designated tones values created on a basis of 1/100ths seconds (.F.) or 1/18.2 seconds (.T.). The default value is 1/100th seconds (.F.).
Returns
SOUND() always returns a null string as a value.
Description
Use SOUND() to create tones at intervals of 1/100th seconds, in the range of 21 to 65535 hertz, for a maximum of 655.36 seconds.
To make it compatible with parameters for the CA-Clipper Tone() function or various other programming language functions, select the 1/18.2- seconds interval. To achieve this, designate the last parameter as .T..
The table below shows tones and their frequencies for three octaves at 1/100th second intervals. To go one octave higher, double the frequency value.
Table 13-8: Tones and their Frequencies
Tone Freq. Tone Freq. Tone Freq.
C 3 131 C 4 262 C 5 523
C# 139 C# 277 C# 554
D 147 D 294 D 587
D# 156 D# 311 D# 622
E 165 E 330 E 659
F 175 F 349 F 698
F# 185 F# 370 F# 740
G 196 G 392 G 784
G# 208 G# 415 G# 831
A 220 A 440 A 880
A# 233 A# 466 A# 932
B 247 B 494 B 988
Frequency values that lie below 21 hertz, are not perceived by the human ear. You can use them as pauses.
Notes
■ You can find additional uses for SOUND() in the sample file
Melodies.prg.
Examples
■ Show the tonal scale:
SOUND(262, 40)
SOUND(294, 40)
SOUND(330, 40)
SOUND(349, 40)
SOUND(392, 40)
SOUND(440, 40)
SOUND(494, 40)
SOUND(523, 40)
■ Call with a string parameter:
cVar := I2Bin(262) + I2Bin(40) + I2Bin(294) + I2Bin(40)
SOUND(cVar)
■ Pause for one-half second:
SOUND(0, 50)
A comparison value used to determine the processor speed
Syntax
SPEED([<lMode>]) → nCPUSpeed
Arguments
lMode If designated as .T., causes all interrupts, with the exception of the clock, to switch off.. The default value is "Leave interrupts on" (.F.).
Returns
SPEED() returns a percentage value to compare to a normal 4.77 MHz PC- XT, which corresponds to 100%.
Description
The function determines, in a precise fashion, the speed to compare to a 4.77 MHz PC. To make the measurement more precise, switch the interrupts off. The only exceptions are the timer interrupts that refresh working memory.
Notes
Warning! When you use the optional parameters to shut off all interrupts (with the exception of the timer interrupts) you cannot work simultaneously with the serial interface. After you take the measurement, you can restore all interrupts.
Examples
■ For a normal AT:
? SPEED(.T.) // 470 4.7 times PC
■ Switch off interrupts in the same system:
? SPEED(.T.) // 480 4.8 times PC
SPOOLACTIV() returns .T. when the DOS memory-resident print spooler is installed.
Description
Before you implement any print spool functions, use SPOOLACTIV() to test if the DOS PRINT program is installed. If inactive, then you must leave the application because memory-resident programs cannot load from within CA-Clipper applications.
Notes
■ Use SPOOLACTIV() to continue output stopped with SPOOLENTRY().
Examples
Test if PRINT is loaded:
IF SPOOLACTIVE()
SPOOLADD("C:\TEST\PRINT.DAT")
ELSE
? "Spooling not possible !"
ENDIF
nFile Designates a file to add to the print spool queue.
Returns
SPOOLADD() returns .T. when the file is successfully added to the spool queue.
Description
SPOOLLADD() passes a new file to the spooler where data is printed in the background. If no data can be added because the file does not exist or because the queue is full, the function returns to .F..
Examples
Print to a file, then print it in the background:
SET PRINTER TO C:\TEST\PRINT.DAT // Redirect print
SET DEVICE TO PRINT // Print Output
@....SAY....
@....SAY....
SET DEVICE TO SCREEN
SET PRINTER TO // Close output file
IF SPOOLACTIV()
SPOOLADD("C:\TEST\PRINT.DAT") // .T., if correct
ELSE
*'normal' print
ENDIF
Determines the number of entries in the print spool queue
Description
The function allows you to determines the number of entries in the print spool queue. This value can be useful in a loop in conjunction with SPOOLENTRY(). A file currently being printed is not counted.
Notes
■ When using SPOOLENTRY() in conjunction with SPOOLCOUNT(),
■ Display entries (stops output):
FOR I = 1 TO SPOOLCOUNT()
? SPOOLENTRY (I) // Path and file name
NEXT I
SPOOLACTIV() // Continue printing
■ Delete the next-to-last entry:
? SPOOLDEL(SPOOLENTRY9SPOOLCOUNT() -1 //.T., when done
cFile Designates which file to remove from the print spool queue.
Returns
SPOOLDEL() returns .T. when the designated file is successfully removed from the print spool queue.
Description
If the wrong file is put in the print spool queue, and is not yet printed, you can delete it from the internal list. SPOOLCOUNT() and SPOOLENTRY() return information about files currently in the queue.
Examples
Delete all files with the extension .SYS form the print queue:
FOR I = 1 TO SPOOLCOUNT
cFile:= SPOOLCOUNT(0)
IF RIGHT (cFile)
ENDIF
NEXT I
SPOOLACTIV() // Continue
nEntryNumber Designates to which queue entry to return the file name. The default is the last entry.
Returns
SPOOLENTRY() returns the complete file specification for the designated queue entry or a null string for an invalid parameter.
Description
SPOOLENTRY() determines the file path and name for a particular entry in a print spool queue. If the optional parameter is not specified, the function returns the last entry. If no matching entry is available, then a null string is returned.
Call SPOOLENTRY() to stop the current print output. Call SPOOLACTIV() to continue the function.
Examples
■ The last entry:
? SPOOLENTRY() // File name incl.path
SPOOLACTIV() // Continue output
■ The next to last entry:
? SPOOLENTRY(SPOOLCOUNT() -1) // "" if not available
SPOOLACTIV() // Continue output
SPOOLFLUSH() returns .T. when you can remove all entries.
Description
SPOOLFLUSH() allows you to remove all entries from the print spool queue. An entry currently being printed, is not taken into account, (just as with SPOOLCOUNT()).
Examples
Delete the spool queue:
IF SPOOLFLUSH() // All deleted ?
? "Print spool queue is empty !"
ENDIF
Determines the target internet address of an SPX communication
Syntax
SPXCONTARG(<nHandle>) → cInterNetAddr
Netware: 2.2 and 3.11
Arguments
nHandle Designates the communication buffer.
Returns
SPXCONTARG() returns the destination's internet address. If nHandle does not specify an SPX communication buffer or the SPX connection is not active, the function returns an empty string.
Description
SPXCONTARG() allows you to determine the destination's internet address after a successful call of SPXLISTCON(). The address is returned as a 20-character hexadecimal string that contains 10 bytes in hexadecimal form. The leading eight characters indicate the destination's network number. The following 12 characters indicate the station ID (node address).
Examples
Wait for an SPX connection in the background. After the connection has
been set up, display the destination's internet address:
nHandle=SPXLISTCON(20000,1000,1000)
WHILE .NOT. PPCCONACT(nHandle)
ENDDO
? 'Connection set up with ',SPXCONTARG(nHandle)
Opens the SPX sending and receiving buffer and tries a connection setup
Syntax
SPXESTBCON(<nSourceSocket>,[<nRecBuffer>],
[<nSendBuffer>],<cTargetAddr>,[<nTargetSocket>],
[<nPacket>],[<lHeader>],[<nRepeat>],[<lWatchDog>],
[<nECBs>]) → nHandle
Netware: 2.2 and 3.11
Arguments
nSourceSocket Designates the socket number of the communication's transmitting side.
nRecBuffer Designates the selected size of the receiving buffer. If no value is passed for nRecBuffer, no receiving buffer is established. The minimum size of the receiving buffer is nPacket. If the value for nRecBuffer is too small, it is changed automatically by SPXESTBCON(). The maximum size of the receiving buffer is 64 KByte.
nSendBuffer Designates the selected size of the sending buffer. If no value is passed for nSendBuffer, no sending buffer is established. The minimum size of the sending buffer is nPacket. If the value for nSendBuffer is too small, it is changed automatically by SPXESTBCON(). The maximum size of the sending buffer is 64 KByte.
cTargetAddr Designates the destination's internet address. The target address is a 20-character string that represents a 10-character byte sequence. The leading eight characters of cTargetAddr contain the network number of the target station. The remaining 12 characters specify the station ID of the target station (node address).
nTargetSocket Designates the socket number of the communication's remote side. The default value is nSourceSocket.
nPacket Designates the packet size of the data that is sent. The packet size can be between 1 and 534 bytes. Values outside of this range are changed automatically. The default value is 534 Bytes.
lHeader Designates whether the data range and the header of the packet (.T.) or the data range alone (.F.) are transmitted to the receiving buffer.
nRepeat Designates the number of repeat attempts if a faulty packet transmission occurs. The value is valid for all sending operations processed during a session. A value of 0 indicates that SPX assumes the standard repeat value.
lWatchDog Designates whether the watchdog is activated (.T.) or not (.F.). This parameter allows the supervision of the connection with watchdog, an SPX internal mechanism. If the supervision is activated, watchdog checks in regular intervals to see if the remote station is still responding. The default value (.T.) activates the watchdog.
nECBs Designates the number of ECBs (Event Control Blocks) that are added to the listening pool for the current connection. The default value is 2. With a higher value, the performance can be improved (for example, when working with slow computers).
Returns
If an operation is successful, SPXESTBCON() returns a communication handle. The return value contains a numeric value that is greater than 0. You should store the handle in a variable because all further operations that refer to an established buffer require a communication handle. If an error occurs, the function returns 0.
Description
SPXESTCON() allows you to establish a communication buffer for an SPX communication with another station in the network. SPXESTCON() also tries to set up an SPX connection (session) to this station. The communication buffer can contain a sending and receiving buffer through which the interrupt controlled sending and receiving of data is processed.
nSourceSocket is the socket number of the communication's transmitting side (see the Introduction to this chapter). The socket can be opened with the function OPENSOCK() before the call of SPXESTBCON(). If nSourceSocket has not been opened, it is opened by SPXESTBCON() automatically. If 0 is passed for nSourceSocket, SPXESTBCON() opens any available socket.
The parameters nRecBuffer and nSendBuffer determine the size of the receiving and sending buffers. The buffers are automatically designed for one NetBIOS packet. Each buffer can be up to 64 KByte in size. However, the size of the buffer that is allocated by SPXESTBCON() depends on the application and the configuration of the computer used.
The remote partner is specified by cTargetAddr. The target address must be passed as a 20-character string (for example, "4921750400001B025A99"). Two bytes each represent one byte in hexadecimal form. For an SPX communication, the target address must be unique. It is not allowed to pass a broadcast address ("FFFFFFFFFFFFFFFFFFFF"). Application specific mechanisms are required to determine the stations waiting for a connection (for example, the storage of the net addresses of the waiting stations in a database or in the bindery). If the current workstation is logged into a Netware server, the network address of a logged in remote station can be determined with the function NNETADR() by passing the user name. Under Netware Lite, the leading eight characters of cTargetAddr (network number) must be passed with 0.
nTargetSocket is the destination's internet address. The default value is nSourceSocket.
nPacket determines the maximum size of the data range of the SPX packets that are sent or received. The maximum value (and the default value) is 536 bytes. Smaller packets can be sent without failure. However, larger packets are discarded. The value of nPacket is also valid for use in sending data.
With lHeader you can determine if the header of an SPX packet (42 bytes) is transmitted to the receiving buffer. The header can contain important information about the received packet. For a description about the header structure, see the Introduction to this chapter.
The number of repeat attempts for faulty sending operations during the session can be specified with nRepeat. A value of 0 sets an SPX internal standard value.
A session is supervised by an SPX watchdog. If the watchdog determines that the remote station is not responding, a key trap can be triggered (see PPCKEY()). The connection flag for the session is set to .F.. If you want to deactivate the watchdog, the parameter lWatchdog can be designated .F..
SPX needs Event Control Blocks (ECBs) for receiving data and for administration purposes. The ECBs are created and managed by SPXESTBCON() automatically. The default value is two ECBs for each SPX session. The value can be increased if slow computers are used. However, you cannot prevent data loss that is the result of a full receiving buffer.
If all parameters have been set correctly and the buffers have been established successfully, SPXESTBCON() tries to set up a session between the current workstation and the target station. However, the target station must expect the connection setup. If a CA-Clipper application is running on the target station, the function SPXLISTCON() must have been called. If no acknowledgment is returned by the target station within a specified timeout (about 30 seconds), SPXESTBCON() releases the reserved buffer and returns 0.
After a successful connection setup, SPXESTBCON() returns a communication handle that is greater than 0. If a value has been passed for nRecBuffer, SPXESTBCON() initiates an interrupt controlled receiving mechanism that receives incoming packets in the background and then copies them to a receiving buffer. The data can then be read with the PPCREAD() function within a CA-Clipper application. If the receiving buffer is full, incoming data is discarded without notifying the sender. Data should be removed from the receiving buffer and processed as soon as possible. You should either read the contents of the buffer periodically (polling) or supervise the buffer on an event- oriented basis (for example, with the function PPCKEY()).
Notes
■ Unlike an IPX communication, an SPX communication is
connection-oriented. A connection is established between two stations. As long as no error occurs, a successful delivery of sent packets is guaranteed.
Examples
■ Attempt to set up an SPX connection to the target address
"4921750400001B025A99". If the connection can be set up, establish a
5000 byte receiving buffer and a 1000 byte sending buffer. The
source and destination socket number is 20000:
nHandle=SPXESTBCON(20000,5000,1000,"4921750400001B025A99")
IF nHandle=0
? 'Error during connection setup!'
ENDIF
■ The remote station can wait for the connection with the
following call:
nHandle:=SPXLISTCON(20000,2000,2000)
Opens the SPX sending and receiving buffer and waits for a connection in the background
Syntax
SPXLISTCON(<nSourceSocket>,[<nRecBuffer>],
[<nSendBuffer>],[<nPacket>],[<lHeader>],
[<nRepeat>],[<lWatchDog>],[<nECBs>]) → nHandle
Netware: 2.2 and 3.11
Arguments
nSourceSocket Designates the socket number of the communication's transmitting side.
nRecBuffer Designates the selected size of the receiving buffer. If no value is passed for nRecBuffer, no receiving buffer is established. The minimum size of the receiving buffer is nPacket. If the value for nRecBuffer is too small, it is changed automatically by SPXLISTCON(). The maximum size of the receiving buffer is 64 KByte.
nSendBuffer Designates the selected size of the sending buffer. If no value is passed for nSendBuffer, no sending buffer is established. The minimum size of the sending buffer is nPacket. If the value for nSendBuffer is too small, it is changed automatically by SPXLISTCON(). The maximum size of the sending buffer is 64 KByte.
nPacket Designates the packet size of the data that is sent. The packet size can be between 1 and 534 bytes. Values outside of this range are changed automatically. The default value is 534 Bytes.
lHeader Specifies whether only the data range (.F.) or the data range and the header of the packet (.T.) are to be transmitted to the receiving buffer.
nRepeat Designates the number of repeat attempts if a faulty packet transmission occurs. The value is valid for all sending operations processed during a session. A value of 0 indicates that SPX assumes the standard repeat value.
lWatchDog Designates whether the watchdog is activated (.T.) or not (.F). This parameter allows the supervision of the connection with watchdog, an SPX internal mechanism. If the supervision is activated, watchdog checks in regular intervals to see if the remote station is still responding. The default value (.T.) activates the watchdog.
Returns
SPXLISTCON() returns a communication handle if the buffer has been established successfully. If an error occurs, the function returns 0.
Description
SPXLISTCON() allows you to establish a communication buffer for an SPX communication with another station in the network. SPXLISTCON() also installs a handler that waits for a connection setup by any other station. The communication buffer can contain a sending and receiving buffer through which the interrupt controlled sending and receiving of data is processed.
nSourceSocket is the socket number of the communication's transmitting side (see the Introduction to this chapter). The socket can be opened with the function OPENSOCK() before the call of SPXLISTCON(). If nSourceSocket has not been opened, it is opened by SPXLISTCON() automatically. If 0 is passed for nSourceSocket, SPXLISTCON() opens any available socket.
The parameters nRecBuffer and nSendBuffer determine the size of the receiving and sending buffer. The buffers are automatically designed for one NetBIOS packet. Each buffer can be up to 64 KByte in size. However, the size of the buffer that is allocated by SPXLISTCON() depends on the application and the configuration of the computer used.
nPacket determines the maximum size of the data range of the SPX packets that are sent or received. The maximum value (and the default value) is 536 bytes. Smaller packets can be sent without failure. However, larger packets are discarded. The value of nPacket is also valid for use in sending data.
With lHeader you can determine if the header of an SPX packet (42 bytes) is transmitted to the receiving buffer. The header can contain important information about the received packet. For a description of the header structure, see the Introduction to this chapter.
The number of repeat attempts for faulty send operations during the session can be specified with nRepeat. A value of 0 sets an SPX internal standard value.
A session is supervised by an SPX watchdog. If the watchdog determines that the remote station is not responding, a key trap can be triggered (see PPCKEY()). The connection flag for the session is set to .F.. If you want to deactivate the watchdog, the parameter lWatchdog can be designated .F..
SPX needs Event Control Blocks (ECBs) for receiving data and for administration purposes. The ECBs are created and managed by SPXLISTCON() automatically. The default value is two ECBs for each SPX session. The value can be increased if slow computers are used. However, you cannot prevent data loss that is the result of a full receiving buffer.
If all parameters have been passed correctly and the buffers have been established successfully, SPXLISTCON() returns a communication handle. However, a communication handle does not indicate that an SPX has already been set up. After SPXLISTCON() has been executed, a handler waits for a connection request in the background. The communication handler, returned by SPXLISTCON(), cannot be used for sending and receiving before a connection has been established. The current connection status after a call of SPXLISTCON() can be queried with PPCCONACT(). It is also possible to trigger a key trap with PPCKEY().
Notes
■ Unlike an IPX communication, an SPX communication is
connection-oriented. A connection is established between two stations. As long as no error occurs, a successful delivery of sent packets is guaranteed.
Examples
■ Wait for an SPX connection setup:
nHandle=SPXLISTCON(20000,1000)
WHILE .NOT. PPCCONACT(nHandle)
ENDDO
■ After an SPX connection has been set up successfully, put key
code 255 into the keyboard buffer:
#include "ctppc.ch"
nHandle=SPXLISTCON(20000,5000,1000)
PPCKEY(nHandle,255,PPC_CONESTB)
lNewSwitch Designates the new setting for the DOS BREAK switch.
Returns
SSETBREAK() returns the current BREAK setting when no parameter is specified; otherwise, it returns the previous setting.
Description
Normally, DOS only checks screen and keyboard functions for the Ctrl-Break key combination. If you want to check more frequently (i.e., during disk operations), use SSETBREAK() to turn on the BREAK switch.
Notes
■ You can also use BREAK= ON|OFF to set BREAK in DOS
Examples
Activate BREAK and save the old status:
lOld_Break := SSETBREAK(.T.)
lNewSwitch Designates the new setting for the DOS VERIFY switch.
Returns
SSETVERIFY() returns the current VERIFY setting when no parameter is specified; otherwise, it returns the previous setting.
Description
Normally, DOS does not check to see if copied data arrives at the target error free. The DOS VERIFY switch determines whether to check written data. Of course, verification takes time. To be safe, make critical copies with the switch set to on (.T.).
Notes
■ You can also use VERIFY= ON|OFF to set VERIFY in DOS.
Examples
Activate VERIFY and save old status:
lOld_Verify:= SSETVERIFY(.T.)
Selects the standard color value for SET COLOR TO output
Syntax
Standard() → cNull
Returns
Standard() always returns a null string.
Description
Standard() permits you to reselect the standard attribute for CA-Clipper @...SAY and ? outputs, after you use Enhanced() or Unselected() to switch over. An attribute is considered a standard, when it is the first parameter is passed by SET COLOR TO.
Examples
Change attribute output to enhanced, and then switch back to standard:
? "........"
? "........"
Enhanced()
? "Different attribute!"
Standard()
? "........"
? "........"
cString1 Designates the first character string for the comparison. The replace, insert, and delete operations are carried out in this string. The maximum length for this string is 254 characters.
cString2 Designates the second character string for the comparison.
nReplace Designates the number of valences (between 0 and 255) that are allocated for the replacement of a character. The default value is 3.
nRemove Designates the number of valences (between 0 and 255) that are allocated for the removal of a character. The default value is 6.
nInsert Designates the number of valences (between 0 and 255) that are allocated for the insertion of a character. The default value is 1.
Returns
StrDiff() returns a value corresponding to the difference between the two character strings. The value can between 0 and 65535.
Description
Two different character strings can be made equal by deleting, inserting, or replacing characters within the first string. StrDiff() attempts this in any combination until agreement has been reached. Since specific valences are allocated for each of the three individual operations, the end result is a total of valences from which the degree of similarity can be determined. With several paths to your end goal, the one to use is always the one that results in the smallest valence. In this way you can determine which stings of a group of character strings are the most similar.
Notes
■ The maximum length of the combined string is determined as
follows:
2 * (Len(par1) + 1) * (Len(par2) + 1) <= 65530
■ If both strings are the same length, each can be a maximum of
180 bytes long. The result:
2 * 181 * 181 65522
■ Implementing the SetAtLike() function allows you to use
wildcard characters within the search sequence.
Examples
■ Here are some examples of StrDiff():
? StrDiff("ABC", "ADC") // 3 - Replace 1 character
? StrDiff("ABC", "AEC") // 3 - Replace 1 character
? StrDiff("CBA", "ABC") // 6 - Replace 2 characters
? StrDiff("ABC", "AXBC") // 1 - Insert 1 character
? StrDiff("AXBC", "ABC") // 6 - Delete 1 character
■ Examples for the use of SetAtLike() can be found under the
corresponding function description.
cCharacterstring Designates the character string to write to a file.
cFile Designates a file name. Drive and path designations are permitted, but no wildcards.
lOverwrite If not designated or designated as .F., determines whether or not a new file is created. When .T., it writes to an existing file. The default is create new file (.F.).
nOffset Designates an offset within the file from which the cCharacterstring string is to be written. The default is End of file.
lCutOff When this optional parameter is designated as .T., the function truncates the file if data written ends before the last file byte. The default is no cut off (.F.).
Returns
StrFile() returns the actual number of bytes written.
Description
This function provides another capability besides writing the contents of a string to a file. In contrast to the CA-Clipper Fxxxx() functions, only one function call is necessary to write data to a file. However, it can result in some speed disadvantages, since files acted on by StrFile() cannot be held open.
If the target file is unavailable, the StrFile() function always creates it.
Notes
■ The attribute to create a new file, can be designated with the
■ As recommended with the share mode, reads and writes from
other network programs should be locked out with SETSHARE() for this period of time.
■ This function acknowledges the setting for CSetSafety().
Examples
■ Add to the end of a file:
? StrFile("ABCDEFGH", "TEST.TXT", .T.) // Result: 8
■ A file with drive and path designations, result: 10:
? StrFile("0123456789", "C:\TEXT\TEST.TXT", .T.)
■ Data in an existing file is overwritten from position 20 with
a designated string:
? StrFile("NANTUCKET", "TEST.TXT", .T., 20) // Result: 9
■ A 5-character string is written starting at position 10 in an
existing file 20-characters long. Since the final parameter is
specified as .T. once, and specified as .F. once, you see different
results:
? StrFile(Replicate("X", 20), "TEST.TXT")
? StrFile("AAAAA", "TEST.TXT", .T., 10, .F // "XXXXXXXXXXAAAAAXXXXX"
? StrFile("AAAAA", "TEST.TXT", .T., 10, .T // "XXXXXXXXXXAAAAA"
cCharacterstring Designates the character string to display.
nRow Designates the starting line for the output. The default is the cursor line.
nColumn Designates the starting column for output.
Returns
StrScreen() always returns a null string.
Description
StrScreen() displays the contents of a variable to the screen (assuming that it is in a particular format). You must always have a character, an attribute, another character, etc., in the designated character string.
nRow and nColumn specify the first row and column in which to write the string.
Notes
Warning! The string must also contain attribute bytes. Use ColorToN() to create the combined numeric attributes.
■ Output does not alter the cursor position.
Examples
■ Output "ABC" at the current cursor position with a different
attribute for each character:
StrScreen("A"+Chr(1)+"B"+Chr(2)+"C"+Chr(3))
■ Output ABC with different attributes at the current cursor
column in line 24:
StrScreen("A"+Chr(1)+"B"+Chr(2)+"C"+Chr(3), 24)
■ Output ABC with different attributes at column 70, line 24:
StrScreen("A"+Chr(1)+"B"+Chr(2)+"C"+Chr(3), 24, 70)
cString1 [@] and cString2 [@] Designate the two strings that are interchanged. At least one of the character strings must be passed by reference.
Returns
StrSwap() always returns a null string. This function only affects strings that have been passed by reference.
Description
StrSwap() interchanges the strings cString1 and cString2. The exchange continues until all the characters in the shorter character string have been moved. The function terminates when the last character of the shortest string is exchanged.
Notes
■ The character strings are changed directly. Therefore, at
least one of the strings must have been passed by reference to get a result.
Examples
■ In this example, two strings are passed by reference:
cStr1 := "1234567890"
cStr2 := "ABCDEFGHIJKLM"
? StrSwap(@cStr1, @cStr2) // Return value: ""
■ The two strings subsequently contain these characters:
? cStr1 // "ABCDEFGHIJ"
? cStr2 // "1234567890KLM"
■ In this example, only one of the strings is passed by
reference:
cStr1 := "1234567890"
cStr2 := "ABCDEFGHIJKLM"
? StrSwap(cStr1, @cStr2) // Return value: ""
■ Both strings subsequently contain the characters of the string
passed by reference:
? cStr1 // "1234567890"
? cStr2 // "1234567890KLM"
cBytes Designates a character string that is recognized as a byte sequence.
Returns
StrToHex() returns a character string that contains each byte (character) of the passed string in its two-character, hexadecimal form. The returned string is exactly twice as long as cBytes.
Description
StrToHex() is useful when working with the internet addresses that are required in conjunction with the IPX/SPX functions of Point To Point communication.
Examples
Convert the byte sequence to hexadecimal form:
? StrToHex(Chr(27)+'A') // "1B41"
STACKFREE() returns the number of bytes available on the stack.
Description
This function helps avoid system crashes. If the returned value falls below 100, do not permit deeper branching. Either change the program so that a large nesting depth cannot be reached, or increase the stack size when linking.
Notes
■ The stack is a low-level system area. Each DO requires some
memory bytes, before a RETURN can ensue.
Examples
■ Query the stack size:
? STACKFREE() // < 100 ??
■ Link the application within increased stack size:
RTLINK FI Test /ST:8000
nTabWidth Designates the tab width. The default value is 8.
cCharacter|nCharacter Designates the characters that are used when expanding the tabs. The default value is a space, Chr(32).
Returns
The modified cString is returned.
Description
The TabExpand() function replaces all tab characters (Chr(9)) in cString with the corresponding number of spaces or cCharacter| nCharacter. The nTabWidth parameter can be used to set varying tab widths.
Notes
■ In the absence of the nTabWidth parameter, TabExpand() has a
default tab width of 8.
■ The carriage return and line feed, where the high bit is set,
are taken into consideration.
■ SETTABS() does not affect this function.
Examples
■ TabExpand() only fills to the next tab position:
? TabExpand("-" +Chr(9) +"!") // "- !"
? TabExpand("----" +Chr(9) +"!") // "---- !"
■ You can fill with any character you like:
? TabExpand("-" +Chr(9) +"!", "+") // "-+++++++!"
■ The tab width can be selected:
? TabExpand("-" +Chr(9) +"!", 4) // "- !"
? TabExpand("----" +Chr(9) +"!", 8) // "---- !"
? TabExpand("----" +Chr(9) +"!", 8, "+") // "----++++!"
cString Designates a character string that is packed with tab characters.
nTabWidth Designates the tab width. The default value is 8.
cCharacter|nCharacter Designates which characters are replaced by a tab. The default value is a space, Chr(32).
Returns
TabPack() returns the modified character string.
Description
This function does not simply exchange a simple sequence of the same characters for a tab; instead, it takes into account the true tab positions. If a space (or the cCharacter|nCharacter) is found at a tab position, and immediately preceding it there is at least one identical character, the function replaces this sequence (maximum nTabWidth) with a Chr(9). With tab characters, text can be packed by individual tab widths. As with every good text editor, there is no replacement with a tab within single or double leading characters.
Notes
■ For the beginning of a line, the function takes into account
the "normal" carriage return (Chr(13)/Chr(10)) as well as the high bit return (Chr(141)) used by MemoEdit(). Previously existing tab characters are also taken into account.
■ If another tab already exists, this tab can be removed with
TabExpand(). The new tab can then be inserted using TabPack().
Examples
We have avoided replacing spaces with tabs in the following examples to
keep the example legible. Tab width is 8 (default). "*" is exchanged
for tab characters.
? TabPack("AAAAAAA*", "*") // "AAAAAAA*"
? TabPack("AAAAA***", "*") // "AAAAA" + Chr(9)
? TabPack("AAAAA*****", "*") // "AAAAA" + Chr(9) + "**"
crlf := Chr(13) + Chr(10)
cText := "ABCD+" + crlf + "++---+++++"
? TabPack(cText, 4, "+") // "ABCD+" + crlf +
// "++---" + Chr(9) + "++"
cDirectory Designates the drive and directory where the temporary file is to be created. The default is the current drive/directory.
cExtension Designates the file extension for the file. The default is no extension.
nFileAttr Designates a file attribute for the file. The default is the SetFCreate() setting.
Returns
Returns the name of the temporary file. If no file is created, the function returns a null string.
Description
If you only need a file for a short time and want to avoid conflicts with existing files, use TempFile() to create a file with a unique name. Names created by TempFile() use the system date and system time. You can hide the file, if you specify an attribute. Attributes are coded as follows:
Table 7-24: File Attribute Coding
Value Symb. constants Definition
0 FA_NORMAL
1 FA_READONLY READ ONLY
2 FA_HIDDEN HIDDEN (Hidden files)
4 FA_SYSTEM SYSTEM (System files)
32 FA_ARCHIVE ARCHIVE (Changed since last backup)
Notes
■ The temporary file name is always 8 characters long and
consists exclusively of numbers with a period, if no extension has been specified. The file is created with a length of 0 bytes.
■ A designated file attribute has precedence over a setting
■ Create a temporary file in the current drive and directory:
cTempFile := TempFile()
■ Create a temporary file in the root directory of the E: drive:
cTempFile := TempFile("E:\")
■ Create a temporary file with a .TMP extension and a HIDDEN
attribute in the root directory of the A: drive:
cTempFile := TempFile("A:\", "TMP", 2)
cTime Designates a character string that contains the time in the format "HH:MM:SS:hh". The default is the system time.
Returns
The returned value designates how many seconds have elapsed between midnight and cTime. Hundredths of seconds are contained as a decimal value.
Description
When computing time periods, or when adding times, it is simpler to deal with seconds since midnight instead of time designations. These calculations are simplified significantly. The SecToTime() function converts the result into a time designation again. Starting from back to front, you can omit the hundredths, seconds, and minutes from the time string that is passed as a parameter. These values are then assumed to be "00".
If you do not specify a parameter, the function uses the current time on the system clock.
Examples
■ A simple conversion:
? TimeToSec("12:44:33:22") // Result: 45873.22
■ The period between two times is calculated. The result is
displayed in seconds:
cBegin := "12:55:44:33"
cEnd := "14:56:12:22"
? TimeToSec(cEnd) - TimeToSec(cBegin) // Period in seconds
■ Possible formats:
? TimeToSec("12")
? TimeToSec("12:44)
? TimeToSec("12:44:33)
? TimeToSec("12:44:33:22")
cTime Designates a character string that contains the time to test.
Returns
TimeValid() returns .T. when cTime is a valid time; or .F. when cTime is an invalid time.
Description
With input that requires time manipulation, writing your own UDF to check time inputs was unavoidable up to now. TimeValid() permits complete checking of a time designation. You can use this function effectively with a VALID clause within a READ mask.
Notes
■ Note the format for time designations. There must always be
two digits for hours, minutes, seconds, and hundredths; otherwise, the time it is regarded as invalid. Valid examples are "12", "12:59", "12:59:59", and "12:59:59:99". By contrast, invalid examples are "24", "12:60", or "12:1", and/or "12:". If you work with time strings that are not completely filled and that you need to check with TimeValid(), then they must be TRIMmed prior to the use of TimeValid() (see following Examples).
Examples
■ Using the VALID clause with TRIM, all valid times are
accepted, even if no seconds or minutes are specified:
cBegin := Space(11)
@ 5, 10 SAY "Please input time for beginning work:";
GET cBegin VALID TIMEVALID(Trim(cBegin))
READ
■ Using a VALID clause without TRIM, hours and minutes must be
specified, so that TimeValid() can confirm a valid time:
cBegin := Space(5)
@ 5, 10 SAY "Please input time for beginning work:";
GET cBegin VALID TIMEVALID(cBegin)
READ
Determines the most recent TokenNext() position within a string
Syntax
TokenAt(<lLastTokenPos>) → nPosition
Arguments
lLastTokenPos When designated as .T., this parameter returns the delimiter position after the last token found.
Returns
TokenAt() returns the beginning position of the token most recently returned using TokenNext(). If TokenInit() and TokenNext() have not been called prior to calling TokenAt(), the function returns 0.
Description
TokenAt() returns the starting position of the token most recently extracted by TokenNext(). If TokenAt() is used in conjunction with SubStr(), the delimiters before the token in an incremental tokenizer are available. To determine the delimiter position before the last token, set TokenAt() to -1. To determine the delimiter position after the last token, set TOKENAT to .T..
Please notice that the character string initialized by TokenInit() no longer contains the original delimiters. If you need the original delimiters, you should make a copy before you call TokenInit().
Examples
This example shows five tokens and their starting positions:
cString := "This is a search, 234"
cCopy := String
TokenInit(@cString)
? TokenNext(), TokenAt() // "This", 1
? TokenNext(), TokenAt() // "is", 6
? TokenNext(), TokenAt() // "a", 9
? TokenNext(), TokenAt() // "search", 11
? TokenNext(), TokenAt() // "234", 18
? SubStr(cCOPY, TokenAt() -1, 1 // Delimiter : ","
Determines if more tokens are available in TokenNext()
Syntax
TokenEnd() → lEndToken
Returns
TokenEnd() returns .T. after the last token has been queried with TokenNext().
Description
Reviewing the return value of TokenNext(), as the final condition for tokenizing, is not always definitive. The end of one cycle is shown here as a null string, which is returned just like an "empty" token (empty line).
By contrast, TokenEnd() always returns definite information if there are more tokens to be returned by TokenNext(). This makes TokenEnd() ideal for use as a loop condition.
Examples
Break up text into individual lines. The text is initialized so that
two consecutive (3. Parameter) CR/LF sequences return a null string:
TokenInit(TextString, Chr(13) + Chr(10), 2)
DO WHILE .NOT. TokenEnd()
Line := TokenNext(TextString)
? "Line - " + Line
ENDDO
cString [@] Designates a character string for which tokenizing is initialized. This must be passed by reference!
cDelimiter Designates a list (character string) of individual delimiters for tokenizing.
nSkipDistance Designates the number of delimiting characters/sequences after which a value, or a null string (if necessary), is returned. The default value indicates that these characters/sequences are not counted.
() When called with no parameters, TokenNext() is set to begin at the start of the string.
Returns
The function returns .F. when the string variable cannot be initialized. For example, the function returns .F. if the string variable was not passed by reference.
Description
When used in conjunction with the TokenNext() function, an extremely versatile incremental tokenizer is available to you. Specific separation processes can be implemented much more quickly than with the group of functions around Token(). The speed increase is achieved in two ways.
TokenInit() exchanges all delimiting characters for the first one in the delimiter list. This means the entire delimiter list does not have to be searched every time. The second advantage is that TokenNext() does not always begin its search for the token that is extracted at the beginning of the string (see the function description for TokenNext()). However, in contrast to Token(), TokenNext() is unable to extract a specific token.
You can also use the third parameter, a skip distance for the delimiter characters. This allows recognition of empty lines within a text. In this case, an empty line would be displayed by a CrLfCrLf sequence. Since TokenInit() takes all designated delimiting characters and exchanges them for something uniform, this sequence is changed to CrCrCrCr. A skip distance of 2 means that the two delimiters (in this case, Cr)) return a token each time. Since nothing precedes this example, TokenNext() returns a null string.
The function uses the following list of delimiters as standard:
CHR 32, 0, 9, 10, 12, 26, 32, 138, 141
and the characters ,.;:!?/<<>>()^#&%+-*
This list can be replaced by your own delimiter list, cDelimiter. Here are some examples of meaningful delimiting characters:
Table 4-5: Recommended Delimiting Sequences
Description <cDelimiter>
Pages Chr(12)(Form Feed)
Sentence ".!?"
File Name ":\."
Numeric strings ",."
Date strings "/."
Time strings ":."
Notes
■ When using a skip value, you must use the TokenEnd() function
as a loop condition.
■ When TokenInit() exchanges all delimiting characters for a new
one, the first delimiter on the list is always used. This ensures that no character contained in the token becomes a delimiter.
■ When you use the TokenInit() or TokenNext(), you cannot use
the TokenSep() function. The required information can be determined using TokenAt() in conjunction with the original string (status before TokenInit()).
To determine the delimiter position before the last token, set TokenAt() to -1. To determine the delimiter position after the last token, set TOKENAT to .T..
Examples
■ Break a string into words. First the string must be
initialized:
cDelim := "!?.,-"
cString := "A.B-C,D!E??"
TokenInit(@cString, cDelim) // "A!B!C!D!E!!"
Do While .NOT. TokenEnd()
cWord := TokenNext(cString)
? cWord
ENDDO
■ Break text into lines. Take blank lines into account using a
skip distance of 2:
nCounter := 0
TokenInit(cTextString, Chr(13) + Chr(10), 2)
DO WHILE .NOT. TokenEnd()
nLine := TokenNext(cTextString)
++ nCounter
ENDDO
? nCounter
cString [@] Designates the string that is searched for tokens (words).
cDelimiter Designates the delimiter list used by the token.
nNumber Designates the token in which the initial alphabetic character is converted into a lower case, alphabetic character. The default value designates that all tokens are converted.
Returns
The processed character string is returned.
Description
TokenLower() converts the initial alphbetic character of the tokens in the cString into a lower case, alphabetic character. If you specify a value for nNumber, only this number of tokens is processed. If you do not specify a value for nNumber, all tokens in the cString are processed. The function uses the following list of delimiters by default:
CHR 32, 0, 9, 10, 13, 26, 32, 138, 141
and the characters ,.;:!?/<<>>()^#&%+-*
The list can be replaced by your own list of delimiters, cDelimiter. Here are some examples of useful delimiters:
Table 4-6: Recommended Delimiter Sequences
Description <cDelimiter>
Pages Chr(12)(Form Feed)
Sentences ".!?"
File Names ":\."
Numerical strings ",."
Date strings "/."
Time strings ":."
Notes
■ The return value of this function can be suppressed by
implementing CSetRef() to save space in working memory.
Examples
■ Convert the initial letter of all tokens into lower case
letters:
? TokenLower("good Morning") // "good morning"
■ This example shows that there are no detrimental effects if
you specify a token number that does not exist:
? TokenLower("good Morning",, 5) // "good morning"
■ Process the first two tokens using your own delimiter:
? TokenLower("/AB/AB/AB", "/", 2) // "/aB/aB/AB"
idTokenInitVar Designates the name of the character string previously initialized using TokenInit(). This is the only way to access this string once it has been stored by the Virtual Memory Manager (VMM).
Returns
TokenNext() returns the next token from the string variable designated by TokenInit(). If there are no more tokens, a null string is returned.
Description
In conjunction with TokenInit(), this function provides a speed optimized variation of the normal Token() function. The increase in speed is achieved in two ways.
TokenInit() exchanges all delimiting characters for the first delimiter in the list. This means the entire delimiter list does not have to be searched every time. The second advantage is that TokenNext() does not always begin its search for the token that is extracted at the beginning of the string.
The TokenAt() function allows you to determine the position of TokenNext().
Although the address of the string that is processed and the internal counter have already been determined or initialized by TokenInit(), CA-Clipper Tools still needs the variable name. The function does work without this parameter, but only as long as the initialized character sequence has not been stored to VMM. You should enter the variable name in each case because there is no explicit control over this! If there is no access to the variable, a runtime error occurs.
Notes
■ When you use TokenInit() or TokenNext(), you cannot use the
TokenSep() function. The required information can be determined using TokenAt() in conjunction with the original string (status before TokenInit()).
■ To determine the delimiter position before the last token, set
TokenAt() to -1. To determine the delimiter position after the last token, set TOKENAT to .T..
Examples
Break down a string:
cDelim := "!?.,-"
cString := "A.B-C,D!E??"
TokenInit(@cString, cDelim) // "A!B!C!D!E!!"
DO WHILE .NOT. TokenEnd()
cWord := TokenNext(cString)
? cWord
ENDDO
Provides the separator before or after the token most recently retrieved by TOKEN()
Syntax
TokenSep([<lMode>]) → cDelimiter
Arguments
lMode Designates which delimiter is returned. When this parameter is specified as .T., the function returns the delimiter after the most recently retrieved token. The default value (.F.) specifies that the delimiter before the token most recently retrieved is returned.
Returns
The return string is the delimiter found directly before the token most recently retrieved. If there is no delimiting character present at the beginning or end of a character string, the function returns a null string.
Description
When mathematical expressions are broken down, the delimiting characters are of great interest. TokenSep() is always concerned with the most recently retrieved token determined by the Token() function. Using the lMode parameter, you can specify whether the delimiter returned is the one before or after the token most recently retrieved.
Notes
■ The TokenSep() function cannot be used in conjunction with
■ To find the delimiter position before the last token, set
TokenAt() to -1. To find the delimiter position after the last token, set TOKENAT to .T..
Examples
■ In this example, there are delimiters before and after the
last token:
? TOKEN("Hello, World!") // Last token: "World"
? TokenSep() // Leading separator: ","
? TokenSep(.T.) // Trailing separator: "!"
■ This example shows how to force a token to include the
delimiter immediately before it (the wrong setting):
? TokenSep() + TOKEN("32+45*70", "+-*/", 2) // "45"
■ TOKEN() must be executed prior to TokenSep(). Notice the
additional parenthesis:
? TokenSep() + (TOKEN("32+45*70", "+-*/",2) // "+45"
cString [@] Designates the string that is searched for tokens (words).
cDelimiter Designates the delimiter list used by the token.
nNumber Designates the number of tokens in which the initial letter is converted into upper case. The default value converts all tokens.
Returns
The processed character string is returned.
Description
The TokenUpper() function converts the initial letter of the tokens in the cString into an upper case letter. If you specify a value for nNumber, only this number of tokens is processed. If you do not specify a value for nNumber, all tokens in cString are processed. The function uses the following list of delimiters by default:
CHR 32, 0, 9, 10, 13, 26, 32, 138, 141
and the characters ,.;:!?/<<>>()^#&%+-*
The list can be replaced by your own list of delimiters, cDelimiter. Here are some examples of useful delimiters:
Table 4-7: String Manipulations
Description <cDelimiter>
Pages Chr(12)(Form Feed)
Sentences ".!?"
File Names ":\."
Numerical strings ",."
Date strings "/."
Time strings ":."
Notes
■ The return value of this function can be suppressed by
implementing CSetRef() to save space in working memory.
Examples
■ Convert the initial letter of all tokens into upper case
letters:
? TokenUpper("Good morning") //"Good Morning"
■ There are no detrimental effects if a larger number of tokens
is specified than are available:
?TokenUpper("Good morning",, 5) //"Good Morning"
■ Process the first two tokens using your own delimiter:
?TokenUpper("/ab/ab/ab", "/", 2) //"Ab/Ab/ab"
Queries the version number of the CA-Clipper Tools in use
Syntax
ToolVer(<lCheckDriver>) → cVersion
Arguments
lCheckDriver When passed as .T., the function checks if the Extended Drivers correspond to the library. If not, the function returns "0.00".
Returns
ToolVer() returns CA-Clipper Tools as a string in the "n.nn" format; or "0.00", if the Extended Drivers does not correspond to the library.
Description
This function determines the current CA-Clipper Tools version. It also allows you to check if the CT.LIB and the Extended Drivers CTUS.OBJ agree. This agreement is essential. If they do not agree, the function returns "0.00".
Examples
■ Query the CA-Clipper Tools version:
? ToolVer() // e.g. "5.01"
■ Verify the driver version:
IF ToolVer() <> ToolVer(.T.)
? "Wrong driver or driver not linked in..."
ENDIF
cDelimiter Designates the delimiter list used by the token.
nNumber Designates which token in the cString is copied.
nSkipWidth Designates the number of delimiter characters or sequences that count as delimiters for a token, even an empty token. The default value indicates that empty tokens are not taken into account.
Returns
Token() returns the token for which the number has been specified or returns the last token in the cString.
Description
The Token() function allows you to break down date and time strings, sentences, file names and paths, etc.. When you specify a value for nNumber, the token with this number is returned. If you do not specify a value for nNumber the function returns the last token in the cString. The function uses the following list of delimiters as a standard:
CHR 32, 0, 9, 10, 13, 26, 32, 138, 141
and the characters ,.;:!?/<<>>()^#&%+-*
The list can be replaced by your own list of delimiters, cDelimiter. Here are some examples of useful delimiters:
Table 4-4: Recommended Delimiter Sequences
Description <cDelimiter>
Pages Chr(12)(Form Feed)
Sentences ".!?"
File Names ":\."
Numerical strings ",."
Date strings "/."
Time strings ":."
The skip value designates the number of characters after which a token is counted again. This also allows empty tokens within a string, like blanks, to be counted.
Notes
■ When you use the skip width with NumToken() or Token(), or if
you use both functions, this value for the skip width must be equal in both functions.
Examples
■ Select the last token in the character string:
? TOKEN("Clipper") // "Clipper"
? TOKEN(" , Clipper . ") // "Clipper"
? TOKEN("Clipper COMPILER!") // "COMPILER"
■ Select the first token in a character string:
? TOKEN("Clipper", 1) // "Clipper"
? TOKEN("Clipper COMPILER!", 1) // "Clipper"
■ Select the third token:
? TOKEN("This is a test.", 3) // "a"
■ In this example only four tokens are present:
? TOKEN("This is a test.", 5) // ""
■ This example shows how to count empty tokens. Parameters
separated by commas are counted, but some of the parameters are
skipped. Therefore, a token is counted after one delimiter (comma).
A parameter is skipped where two delimiters (commas) appear without a
parameter:
cString := "one,two,,four"
nCount := NumToken(cString, ",", 1) // Result: 4
FOR nI = 1 TO nCount
? TOKEN(cString, ",", nI, 1)
NEXT nI
■ If the string contains different delimiters in varying
combinations, then preparation with the aid of another function is
always important (to enhance readability, periods have been used
instead of spaces):
cString := "one, two,,four,...,six,.,eight"
cString := CharRem(".", cString)
? TOKEN(cString, ",", 6, 1) // "six"
cPathDesignation Designates a path as a standard. It is assumed that it is in accordance with DOS rules.
Returns
TrueName() returns the standardized path whenever possible.
Description
Path designations are made for the drive as well as the path itself, with regard to the current position designation. With TrueName(), related path designations are changed around so that they relate to the root directory of a particular drive.
The function does not test to see if a path exists. If the designated path is not valid or the specified drive is unavailable, it returns a null string.
Notes
Warning! Additional information is built into the path of network drives. Under PC-LAN/MS-NET, the path contains the designation:\ServerName. Under Novell, \ServerNameVolumeName (see Examples).
Examples
■ Which complete path corresponds to the current disk drive?
? TrueName(".") // e.g. "C:\TEST1"
■ Anything valid under DOS is acceptable:
? TrueName("..\..\TEST1\.\TEST2") // e.g. "C:\TEST1\TEST2"
■ In a Novell network, remove tokens 2 and 3, server name, and
volume name:
IF NNetwork()
cPath := TrueName(cOldPath)
cToken1 := TOKEN(cPath, ":\", 1)
cToken2 := TOKEN(cPath, ":\", 2)
cToken3 := TOKEN(cPath, ":\", 3)
cPath := cToken1 + AfterAtNum(cToken2 + cToken3, cPath)
ENDIF
cProcedure Designates the name of the procedure that is called when any input key is touched.
() If you call the function without parameters, the procedure to monitor selected keyboard input is uninstalled.
Returns
At any given time, the function returns the name of the previously active trap procedure. If no call has ever been made to TRAPANYKEY(), the function returns a null string.
Description
TRAPANYKEY() calls a given procedure for all keys that generate input. This is somewhat similar to SET KEYAnyKeyTOcProcName.
The scan code transmitted by the key is passed as a parameter to the trap procedure, but it is not yet stored in the keyboard buffer. To input normally, each character must be sent to the keyboard buffer using either the KEYBOARD command, or the KEYSEND() function. Using KEYSEND() is generally preferred because the previous keyboard buffer is always added to the characters that have not yet been amended by the CA-Clipper application — therefore you do not lose input.
The Procedure Call When you use this function, you do not call any CA-Clipper key trap. When CA-Clipper tries to collect a keyboard input, this call is redirected within the driver by the TRAPANYKEY() procedure. CA-Clipper checks the keyboard, with the exception of special input commands like GET/READ, so these traps almost always work.
Important! In contrast to CA-Clipper key traps, these internal input commands do not have the option to ignore the interruption because no internal input routine is reentrant. You cannot, under any circumstances, use the same input command in the called procedure. This applies the GET/READ, PROMPT, ACCEPT, and any similar input instructions. You can easily use INPUTMODE(.T.) to determine which input command is currently active when you call a procedure.
Notes
■ The transmitted key codes must continue to be processed within
the trap procedure. Otherwise no additional input is possible, and you cannot even exit the program using Alt-C.
■ In contrast to CA-Clipper KEY TRAPS, recursions are
automatically avoided.
■ If the designated procedure does not exist, then the function
uninstalls itself and does not produce a runtime error. If a warning regarding a missing procedure is required during linking, use the EXTERNALprocedure statement.
Examples
In this example, two established abbreviations are input within
MemoEdit(), and then the accompanying phrases are expanded into the
text. The trap procedure recognizes the last three keys that were input
and compares this sequence with the defined abbreviations. In each
case, these phrases are sent using KEYSEND() and inserted in the
existing keyboard buffer. Since the functions are called with .T. for
the second parameter, no characters are lost even if you type quickly.
At this time, the third character of the recognized abbreviation has not
yet been placed in the keyboard buffer and therefore does not yet exist
in text, so only two Chr(8) (backspace) characters are used to delete
the two characters that have already been transmitted. The entire
sequence must be expanded with Chr(0) before it can be placed in the
keyboard buffer because KEYSEND() works on the basis of scan codes.
Notice the SET TYPEAHEAD enlarged keyboard buffer.
CLEAR
cLastThree := ""
SET TYPEAHEAD TO 50
TRAPANYKEY("Trap_Key")
cTextVar := Space(5000)
@@ 00, 00 TO MaxRow(), MaxCol(), DOUBLE
cTextVar := MemoEdit(cTextVar, 1, 1, MaxRow() -1, MaxCol() -1)
TRAPANYKEY()
RETURN
PROCEDURE Trap_Key(nKey)
cLastThree := Right(cLastThree, 2) + Chr(nKey)
DO CASE
CASE cLastThree == "ys"
cLine := Chr(8) + "Yours Sincerely"
KEYSEND(CharMix(cLine, Chr(0)), .T.)
CASE cLastThree == "yvt"
cLine := Chr(8) + "Yours Very Truly"
KEYSEND(CharMix(cLine, Chr(0)), .T.)
OTHERWISE
KEYSEND(I2Bin(nKey), .T.)
ENDCASE
RETURN
cProcedure Designates the name of the procedure that is called during active CA-Clipper input commands.
lParameter Designates whether a parameter is passed internally to the specified trap procedure. If this logical parameter is .T., then no parameter is passed internally to the specified trap procedure. This allows you to significantly improve performance.
() If this function is called without a parameter, the previously set trap is uninstalled.
Returns
This function returns the name of the previously set trap procedure. If no trap was set, TRAPINPUT() returns a null string.
Description
This function is different from a CA-Clipper key trap. When one of the CA-Clipper input commands is active, the specified trap procedure is always called when CA-Clipper attempts to retrieve the keyboard input. This function is completely independent of whether or not there really has been a keyboard input. Additionally, the ensuing inputs are not influenced in any way, but are passed to the CA-Clipper command unchanged.
The Procedure Call Three parameters are transmitted by the called procedure, as with CA-Clipper trap procedures. These parameters are the procedure name, the line number, and the variable name. All three parameters are transmitted unless the lParameter option is .T.
Important! In contrast to CA-Clipper key traps, these internal input commands do not have the option to ignore the interruption because no internal input routine is reentrant. You cannot, under any circumstances, use the same input command in the called procedure. This applies the GET/READ, PROMPT, ACCEPT, and any similar input instructions. You can easily use INPUTMODE(.T.) to determine which input command is currently active when you call a procedure.
Notes
■ In contrast to CA-Clipper SET KEY TO traps, recursions are
automatically avoided.
■ If the designated procedure does not exist, then the function
uninstalls itself and does not produce a runtime error. If a warning regarding a missing procedure is required during linking, use the EXTERNALprocedure statement.
Examples
The following example shows a MemoEdit() extension to a very simple
communications program. This is only intended to demonstrate a possible
application. This solution is unsuitable for a full fledged
communications program because at some point the memory available to
MemoEdit() would be insufficient.
The main purpose of the example is to show how using TRAPINPUT() can
convert characters from the serial port into keyboard input for a
CA-Clipper application. Each time the CA-Clipper program looks for
keyboard input, the characters in the serial port input buffer are added
to the available keyboard buffer. Please notice that the example uses
KEYSEND().
To complete this example, all local keyboard input is transmitted
through the TRAPANYKEY() procedure over the serial port. The other
terminal is expecting an echo of these characters. Alt-C remains
functional in this example. The application can also be changed to take
into account other control keys.
CLEAR
nPort := 1
com_Open(nPort, 1000)
CON_DTR(2, .T.)
com_Init(nPort, 1200, "N", 8 , 1)
TRAPINPUT("Trap1")
TRAPINPUT("Trap2")
cTextVar := Space(5000)
cTextVar := MemoEdit(cTextVar)
com_Close(nPort)
RETURN
PROCEDURE Trap1(a, b, c)
IF com_Count(nPort) > 0
KEYSEND(CharMix(com_Read(nPort), Chr(0), .T.)
ENDIF
RETURN
PROCEDURE Trap2(nKey)
IF nKey <= 255
com_Send(nPort, Chr(nKey))
ELSE
KEYSEND(I2Bin(nKey), .T.)
ENDIF
RETURN
cProcedure Designates the procedure name that is called when the specified shift keys are selected.
nBitMap Designates the bit values that allow you to specify which of the shift keys should call the procedure. The description section below has a table of valid values.
() If you call the function without parameters, you uninstall a previously selected function that monitored the switching keys.
Returns
The function returns the name of the previously set trap procedure. If no trap was set, TRAPINPUT() returns a null string.
Description
This function makes it possible for all the shift keys, like Shift, Ctrl, Alt, Num-Lock etc., to trigger a procedure call. If the system has the European extended (MF-2) keyboard available, which can be determined by using the KBDTYPE() function, then additional differences like left and right Ctrl keys must be taken into account. The key scan codes and their assigned bits must be added to determine the value for the nBitMap parameter. The following code applies:
Table 2-5: Coding the Switching Keys
Bit Key
1 Right shift at the instant actuated
2 Left shift at the instant actuated
3 Ctrl at the instant actuated (left or right)
4 Alt at the instant actuated (Alt - Shift/Alt)
5 Scroll-Lock ON/OFF
6 Num-Lock ON/OFF
7 Caps-Lock ON/OFF
8 Insert ON/OFF
9 Ctrl left at the instant actuated
10 Alt left at the instant actuated
11 Ctrl right at the instant actuated
12 Right Alt (not valid for US keyboards)
13 Scroll Lock at the instant actuated
14 Num-Lock at the instant actuated
15 Caps-Lock at the instant actuated
16 Alt Print Scrn at the instant actuated
The Procedure Call If the selected switching key or keys are actuated, then the specified procedure is called. The call is always passed as a numeric parameter and the status of all the switching keys at the time of the call. The coding of the passed value corresponds to the table above.
Using this function will not reproduce any CA-Clipper key trap. Each time that CA-Clipper queries the keyboard, the switching keys are checked, and if required, the procedure is called directly from the driver. In this way, these traps are always functional.
Important! In contrast to CA-Clipper key traps, these internal input commands do not have the option to ignore the interruption because no internal input routine is reentrant. You cannot, under any circumstances, use the same input command in the called procedure. This applies the GET/READ, PROMPT, ACCEPT, and any similar input instructions. You can easily use INPUTMODE(.T.) to determine which input command is currently active when you call a procedure.
Notes
■ In contrast to CA-Clipper KEY TRAPS, recursions are
automatically avoided.
■ The parameter passed to the trap must be passed in every case,
even when it is not needed.
■ If a designated procedure does not exist, then the function
uninstalls itself and does not produce a runtime error. If a warning regarding a missing procedure is required during linking, use the EXTERNALprocedure statement.
Examples
In this example, the Trap_Alt procedure is called as soon as the Alt key
is actuated. It is not in any way necessary for a GET/READ mask to be
active for this example. This is only intended to be an example of an
application.
The trap procedure waits in a loop for as long as you hold the Alt key,
or until an additional combination key that delivers an INKEY code is
actuated. Pressing the Alt key displays an additional help list from
which you can select the program option. In this case, Alt-M appends
the text "Yours Sincerely" to the keyboard buffer.
CLEAR
TRAPSHIFT("Trap_ALT", 8)
cVar1 := Space(50)
cVar2 := Space(50)
@ 10, 20 GET cVar1
@ 11, 20 GET cVar2
READ
TRAPSHIFT()
RETURN
PROCEDURE Trap_ALT(nStatus)
@ MaxRow(), 0 SAY "........Help Line........"
nInVar := 0
DO WHILE NumAnd(KbdStat(), 8) = 8 .AND. nInVar = 8
nInVar := Inkey()
ENDDO
DO CASE
CASE nInVar = 306 // ALT-M
KEYSEND(CharMix("Yours Sincerely", Chr(0), .T.)
ENDCASE
@ MaxRow(), 0
RETURN
Selects the unselected color value for SET COLOR TO output
Syntax
Unselected() → cNull
Returns
Unselected() always returns a null string.
Description
Unselected() takes a color attribute designated by SET COLOR TO as unselected (fifth color value), and designates it as the active attribute for CA-Clipper @...SAY and ? output. Use Standard() to switch back to the normal attribute.
Examples
Output with the unselected attribute:
? "........"
? "........"
Unselected()
? "Different attribute!"
Standard()
? "........"
? "........"
nTopLine Designates the line for the upper-left corner of the area.
nLeftColumn Designates the column for the upper-left corner of the area.
nBottomLine Designates the line for the bottom-right corner of the area.
nRightColumn Designates the line for the bottom-right column of the area.
cReplacementCharacter|nReplacementCharacter Replaces each character within the window, with the exception of those within the range of cInitialCharacter|nInitialCharacter and cEndCharacter|nEndCharacter.
cInitialCharacter|nInitialCharacter Designates the beginning of the bracketed area. The character can be number in the range of 0 to 255, or the character string type. The default value is 176.
cEndCharacter|nEndCharacter Designates the end of the bracketed area. The character can be number in the range of 0 to 255 or the character string type. The default value is 223.
Returns
UnTextWin() always returns a null string.
Description
Use UnTextWin() to delete particular character from within a screen area. You can bracket off a specific area of characters. This area begins with cInitialCharacter|nInitialCharacter and ends with cEndCharacter|nEndCharacter. The preset values have bracketed out characters 176 to 223 (the graphics characters). This allows you to clear a screen, but retain the boxes.
The designated area can even "double back"; EndCharacter could be smaller than Initial Character. In this case, the area stretches from the larger value to 255 and, inclusive of 0, to the smaller value. You might say these two areas are designated.
Examples
■ Clear the screen, with the exception of the boxes. Since no
range is specified, 176 to 223 are bracketed out:
UnTextWin(0, 0, 24, 79, " ") // ""
■ Clear all characters, with the exception of uppercase letters
(65-90). A numeric BLANK is designated as a clear character:
UnTextWin(0, 0, 24, 79, 32, 65, 90) // ""
■ Double back on an area. All characters with the exception of
uppercase letters are deleted:
UnTextWin(0, 0, 24, 79, 255, 91, 64) // ""
VGA28() returns .T. when the screen adapter that you use (VGA only) successfully switches to this mode.
Description
In order to generate a pixel height of 14, like that of EGA (for instance, to use the accompanying font editor on a VGA adapter), this mode must be implemented.
Notes
Important! This function cannot be used when windows are open.
Examples
Switch to 28-line mode:
IF IsVGA()
VGA28()
ENDIF
@ 27, 00 SAY Center("CA-Clipper") // Last screen line
WAIT
CGA80() // Return to 25 line
// mode
VGA50() returns .T. when the screen adapter that you use successfully switches to this mode.
Description
This function can only be used on a VGA card. It generates a 50-line mode, which automatically increases CA-Clipper screen output to the maximum allowable coordinates. It is therefore not necessary to also call the SETMAXROW() and SETMAXCOL() functions.
Notes
Important! This function cannot be used when windows are open.
Examples
Switch to 50-line mode. You can then output from line 0 to 49:
IF IsVGA()
VGA50() // Switch mode
ENDIF
@ 49, 10 SAY "CA-Clipper" // Last line
WAIT
CGA80() // Return to 25 line mode
cColor|nColor Designates the color to change as a CA-Clipper color code or in the range of 0 to 15. If no RGB value is specified, the color palette is reset to its default value.
nRedValue Designates the palette setting for the red portion in the range of 0 to 63.
nGreenValue Designates the palette setting for the green portion in the range of 0 to 63.
nBlueValue Designates the palette setting for the blue portion in the range of 0 to 63.
() When the function is called without parameters, the palettes for all colors are reset to their default values.
Returns
VGAPalette() returns .T. when the selected setting is successfully implemented.
Description
A VGA card offers a larger color selection for the palette than the EGA adapter. The three basic colors to add color synthesis are red, green, and blue. With the nRedValue through nBlueValue parameters, the intensity for each of these three colors is set, and different color combinations can result. You can assign one color mix to one or more of the SET COLOR TOcColor|nColor installed colors.
If only the color is designated as a parameter, then the accompanying palette is reset to its default value. When you call the function without parameters, all the palettes are reset.
Notes
■ The FONTRESET() function resets all color palettes.
Examples
■ Show a lot of red, a little green, and some blue as a new
setting for color 3:
? VGAPalette("BG", 60, 4, 10) // .T., when accepted
■ Reset the red palette:
VGAPalette("R")
■ Reset all palettes:
VGAPalette()
Returns bit-coded information about available video modes
Syntax
VideoType() → nVideoBitMode
Returns
VideoType() returns a value that reveals the bit codes for available video modes.
Description
This function returns bit-coded information about which video modes are available. If needed, you can set more bits. A HERCULES adapter is also a monochrome adapter; and a VGA card can emulate many different modes. The following codes are used:
Table 6-6: Coding of Screen Modes
Bit Definition
1 Monochrome adapter
2 CGA adapter
3 HERCULES adapter
4 MCGA adapter
5 PGA adapter
6 EGA adapter
7 GA adapter
Since different cards imitate several modes, the following values are usually returned:
Table 6-7: Grouping of Screen Modes
Value Symb. constants Definition
1 VCARD_MONOCHROME Monochrome adapter
2 VCARD_CGA CGA adapter
5 VCARD_HERCULES HERCULES, also emulates monochrome
10 VCARD_MCGA MCGA, also emulates CGA
19 VCARD_PGA PGA, also emulates CGA and monochrome
55 VCARD_EGA EGA, emulates all those previously
mentioned, except MCGA
127 VCARD_VGA VGA, emulates all those previously mentioned
Notes
■ The information presented here assumes absolute hardware
compatibility.
Examples
■ Is it a VGA card?
IF IsBit(VideoType(), 7)
*...
ENDIF
■ Is CGA mode available?
IF IsBit(VideoType(), 2)
*...
ENDIF
When you call an external program through RUN, or add on library routines that change the screen mode or other related settings, use VIDEOINIT() to reinitialize the CA-Clipper Tools internal video system.
Notes
■ Despite the fact no value is returned, the Var variable
contains a value of .F. when you attempt something like Var:= VIDEOINIT().
Examples
■ After calling an external program...
RUN VGATEST.EXE
■ ...reset the CA-Clipper video system:
VIDEOINIT()
cDrive Designates the drive whose volume serial number is queried. The default is the current disk drive.
Returns
VolSerial() returns the volume serial number of the DOS disk, hard disk, or a 0, when you are not dealing with a DOS 4.0 or higher disk (see Notes). When the current drive is unavailable, it returns -1.
Description
VOLUME SERIAL NUMBER Beginning with DOS version 4.0, every floppy or hard disk receives a volume serial number during formatting. This is a 32-bit number is created by DOS using the date, clock time, and a counter.
Notes
■ Incompatibilities are possible.
■ The function always returns a value from the disk parameter
block of a floppy or hard disk. Based on the Microsoft recommendation for DOS versions prior to 4.0, a value of 0 is returned.
Examples
Query the volume serial number:
? VolSerial() // 0, when no DOS 4.x disk
Establishes a volume label for a floppy or hard disk
Syntax
Volume(<cDiskName>) → lEstablished
Arguments
cDiskName Designates a name to use on a new volume label. A drive designation is allowed; path designation and wildcards are not.
Returns
Volume() returns .T. when the new volume entry is created.
Description
DOS provides a volume label as a disk identifier. With the Volume() function you can establish this label. There is never more than one label per floppy or hard disk. A volume label can be up to 11 characters long, but when you use a period (.) it must always follow the eighth character.
You can query the volume label with FileSeek(), since the value 8 is assigned as the volume attribute.
Notes
■ A new volume label is always created in the root directory.
■ The function acknowledges the CSetSafety() setting and, if
necessary, does not overwrite an existing label.
Examples
■ Establish a volume label for A: drive:
■ Query the A: drive volume label:
? FileSeek("A:\*.*", 8) // Based on example 1 "VOLO815"
Pauses a specified time in increments of 1/100 seconds
Syntax
WaitPeriod([<nDelay>]) → lNotElapsed
Arguments
nDelay Designates the waiting period at initialization in 1/100ths of seconds. Values from 1 to 8, 640, 000 (one day) are possible.
Returns
WaitPeriod() returns .T. , if the time span designated at initialization has not elapsed.
Description
This function sets a time span for a CA-Clipper DO WHILE loop to run. The function must initialize prior to the loop, since you must specify the nDelay parameter in 1/100th seconds. Subsequently, the function can be implemented without a parameter for additional loop conditions. It returns .T., as long as the designated time span has not yet run out.
Notes
■ The function notes the status of the internal timer at
initialization. From that point on, the initialization should always precede the respective DO WHILE; otherwise, the time delay is incorrect. The passing of midnight (the time resets to the 0 value) is taken into account.
Examples
Run a loop for 5 seconds:
WaitPeriod(500) // Initialization, 5 seconds
DO WHILE <cond1> .AND. <cond2> .AND. WaitPeriod()
*...
ENDDO
WAClose() returns 0 when successful or -1 if an error occurs.
Description
This function closes all windows in a work session. If no windows were opened with WOpen(), then WAClose() returns a value of -1. If windows were opened with WOpen(), then WAClose() returns a value of 0.
Examples
WOpen( ... ) // Many windows will be opened
WOpen( ... )
WOpen( ... )
WAClose() // Close all windows!
nToprow, nLeftcolumn, nBottomrow, nRightcolumn Designate the screen coordinates (upper left and lower right) within which windows can be opened.
() If WBoard() is called without parameters, then the window border is reset to the boundaries of the physical screen, which as a rule corresponds to a call of WBoard(0, 0, 24, 79).
Returns
WBoard() returns a -1 if an error occurs. If no errors occur, WBoard() returns a 0.
Description
This function defines the screen area where windows are permitted. Windows are subsequently only visible in this defined area. You can use this function to protect an area of the screen from being overwritten with windows, even when you allow the user to move the window interactively. The boundaries designated by WBoard() become the screen boundaries for window functions.
Notes
■ WBoard() is only effective when there are no open windows.
■ Always consider that closing individual windows or all the
windows never influences the setting of the window border. So if you neglect to specifically eliminate the window border, you can have unanticipated problems later when you open windows.
Examples
Leave only the upper half of the screen free for window functions:
WBoard(0, 0, 12, 79)
cFramecharacter Designates a string of up to nine characters.
nFrametype Designates one of eight different border types.
() If the function is called without parameters, a double line border is created automatically and the window is filled with the CLEARB character (see SetClearB()).
Returns
WBox() returns the number of the current window.
Description
This function works like the CA-Clipper @...BOX command, except that WBox() always encloses the currently selected window. You can specify an individual character with which to frame the entire window. You can specify up to nine different characters for the corners, and the horizontal and vertical lines. You can also specify a character with which to fill the window. The frame characters start to fill the frame in the upper left corner and continue clockwise around the frame. When specified, the ninth character is used to fill the window.
There is a simplified way to specify eight basic border types. If you choose to pass a numeric entry, instead of the string of characters, WBox() interprets the numeric entry as shorthand for defining a box type. The following sample shows the border types assigned to each of the 16 values. Notice that numbers between 0 and 3, and 8 and 11, delete the area in the window while the other numbers do not.
Frame types:
Delete: 0 1 2 3
Do Not Delete: 4 5 6 7
Delete: 8 9 10 11
Do Not Delete: 12 13 14 15
Notes
■ The available work area for the window is reduced by two rows
and two columns (corresponds to a WFormat(1, 1, 1, 1)). This prevents the border from being unintentionally overwritten. When WBox() is called a second time, the window is reduced again. If a window is too small to frame, WBox() returns a value of -1 and changes nothing.
■ If you want to put a title in a frame, you can place the title
in the top row of the window border by specifying @ .. SAY for the row.
Examples
■ This function frames a window with a double row and then fills
it. The window output area is automatically reduced by 1 for each
page:
WSelect(nWindow)
WBox(" ")
■ This code shows a frame with simple lines, filled with
Chr(177):
SetClearB(177) // The delete character
WBox(1) // Box type 1, delete interior
Returns a window to the visible screen area, or centers it
Syntax
WCenter([<lCenter>]) → nCurrentWindow
Arguments
lCenter Designates the center of the display. If the parameter is .T., the function computes the center of the display and moves the window to that position. If the parameter is .F. or if no parameter is passed, the function returns a window to the visible screen area. The default value is .F..
Returns
WCenter() returns the number of the currently selected window.
Description
WCenter() can take a window that has been moved out of visible range and make it fully visible. The window can also be centered by passing .T. for lCenter.
Notes
■ WCenter() always relates to the currently selected window.
Examples
Make nWindow fully visible:
WSelect(nWindow)
WCenter()
Returns the position of the leftmost column of the active window
Syntax
WCol([<lAfterWCENTER>]) → nCol
Arguments
lAfterWCENTER Designates an optional parameter. If this parameter is .T., the function returns what the position of the leftmost column of a window would be after a call of WCenter(). (The function does not call WCenter()) The default value (.F.) returns the current position.
Returns
WCol() returns the coordinate relative to the leftmost column of the selected window.
Description
This function allows you to determine the current position of the leftmost column of the selected window. This allows you to save a window's position if the window was moved previously with the cursor keys. This way the window can later be reopened at exactly the same position.
Additionally, by passing the optional parameter with a .T., you can determine what the window position would be after a WCenter() without actually calling WCenter().
Notes
■ Values can be negative. Negative values place the first
column outside of the visible range.
Examples
This program saves the position of a window, then reopens it in that
position:
nTop := 10
nLeft := 15
WOpen(nTop, nLeft, nTop + 10, nLeft + 40)
* Someone moves the window!
nTop := WRow() // Save the current
nBottom := WCol() // position of upper left
WClose() // corner and close the window
* Other program sections
WOpen(nTop, nLeft, nTop + 10, nLeft + 40) // Open w/old values
dDate Designates a date for which the week it lies in, is determined. The default is the system date.
Returns
Week() returns a sequential week number that designates in which week of the year dDate lies.
Description
The week of the year in which a day lies is information required by a number of technical financial calculations or wage accounting. This function determines this week and acknowledged all calendar rules.
Notes
■ When no date is specified, then Week() uses the system date.
An empty date leads to a 0 result.
Examples
Determine the week for a date:
dDate := CToD("03/14/92")
? "This date is in week: ", Week(dDate)
Returns the position of the leftmost column of the formatted area of a window
Syntax
WFCol([<lRelative>]) → nValue
Arguments
lRelative Designates an optional parameter. If this parameter is .T., then the function returns the absolute value of the difference between WCol() and WFCol().
Returns
WFCol() returns the position of the leftmost column of the formatted area within a window, or the difference between the outer border and the formatted area of a window.
Description
This function is particularly useful if information in a window must be saved to a file. There are four functions (WFCol(), WFLastCol(), WFRow(), WFLastRow()) which allow you to establish the coordinates of the formatted area of a window. This information can then be saved for later use.
In order to avoid complex calculations, you can determine the difference between the outer border and the formatted area when you use the optional logical parameter. You can then pass this value when you call WFormat() to restore the old value.
Notes
■ When used in Window 0, the function returns the value for
Returns the position of the rightmost column of the formatted area of a window
Syntax
WFLastCol([<lRelative>]) → nValue
Arguments
lRelative Designates an optional parameter. If this parameter is .T., then the function returns the absolute value of the difference between WLastCol() and WFLastCol().
Returns
The function either returns the position of the rightmost column of the formatted area within a window, or the difference between the outer border and the formatted area of a window.
Description
This function is particularly useful if information in a window must be saved to a file. There are four functions (WFCol(), WFLastCol(), WFRow(), WFLastRow()) which allow you to establish the coordinates of the formatted area of a window. This information can then be saved for later use.
When you use lRelative, you can determine the difference between the outer border and formatted area of a window. You can pass this value later when you call WFormat() to restore the old value.
Notes
■ When used in Window 0, the function returns the value for
Returns the position of the bottom row of the formatted area of a window
Syntax
WFLastRow([<lRelative>]) → nValue
Arguments
lRelative Designates an optional parameter. If this optional parameter is .T., then the function returns the absolute value of the difference between WLastRow() and WFLastRow().
Returns
The function either returns the position of the bottom row of the formatted area within a window, or the difference between the outer border and the formatted area of a window.
Description
This function is particularly useful if information in a window must be saved to a file. There are four functions (WFCol(), WFLastCol(), WFRow(), WFLastRow()) which allow you to establish the coordinates of the formatted area of a window. This information can then be saved for later use.
In order to avoid complex calculations, you can determine the difference between the outer border and the formatted area of a window when you use the optional logical parameter. You can pass this value later when you call WFormat() to restore the old value.
Notes
■ When used in Window 0, the function returns the value for
nTopRow,nLeftColumn,nBottomRow,nRightColumn Designate the coordinate values for the text output area of a selected window.
Returns
WFormat() returns the currently selected window's handle.
Description
The WFormat() function can be used to reduce the area in which text output occurs compared to the actual area of the window. This allows you to define a margin between the text and the borders of a window where you cannot write. The four parameters define the margin between the old border and the output area.
Notes
■ The sum of the nTopRow and nBottomRow values must not
exceed the internal height of the window and that the sum of the nLeftColumn and nRightColumn values must not exceed the internal width of the window. In any size window, the output area can be reduced down to one character.
■ Negative values increase the text output area while positive
values reduce it. A WFormat() with very large negative values removes all borders.
■ This function cannot be used with the physical screen (Window
0).
■ To write in the border area, you can also use a negative row
value in @ .. SAY: (@ -1, 5 SAY "Help with input").
Examples
■ The function reduces the output area of the selected window at
the top and bottom by one row each, and by two columns each on the
right and left. The area becomes two rows and four columns smaller:
WSelect(nWindow)
WFormat(1, 2, 1, 2)
■ Here, all borders previously set with WFormat() are canceled,
making it possible to write within the entire window again:
WFormat()
Returns the position of the top row of the formatted area of a window
Syntax
WFRow([<lRelative>]) → nValue
Arguments
lRelative Designates an optional parameter. If this parameter is .T., then the function returns the absolute value of the difference between WRow() and WFRow().
Returns
The function either returns the position of the top row of the formatted area within a window, or the difference between the outer border and the formatted area of a window.
Description
This function is particularly useful if information in a window must be saved to a file. Four functions (WFCol(), WFLastCol(), WFRow(), WFLastRow()) allow you to establish the coordinates of the formatted area of a window. This information can be saved for later use.
In order to avoid complex calculations, you can determine the difference between the outer border and the formatted area of a window when you use the optional logical parameter. You can transmit this value later when you use the WFormat() to restore the old value.
Notes
■ When used in Window 0, the function returns the value for
Returns the position of the rightmost column of the active window
Syntax
WLastCol([<lAfterWCENTER>]) → nColumn
Arguments
lAfterWCENTER Designates an optional parameter. If this parameter is .T., the function returns what the position of the rightmost column would be after a call of WCenter(). (This function does not call WCenter().) The default value (.F.) returns the current position.
Returns
WLastCol() returns the position of the rightmost window column, relative to the physical screen.
Description
The WCol() function allows you to determine the leftmost column (left border) of a window. To avoid complex calculations, you can use the WLastCol() function to determine the rightmost column (right border) of a window.
The returned value can be greater than that of the rightmost column of the screen. In such an instance, the window overlaps the right border.
Additionally, by setting the logical parameter to .T., the position a window occupies after a call of WCenter() is returned without actually calling WCenter().
Examples
A window is moved:
? WLastCol() > MaxCol() // .T. Window overlaps border
Returns the position of the bottom row of the active window
Syntax
WLastRow([<lAfterWCENTER>]) → nRow
Arguments
lAfterWCENTER Designates an optional parameter. If this parameter is .T., the function returns what the position of the bottom row would be after a call of WCenter(). (This function does not call WCenter().) The default value (.F.) returns the current position.
Returns
WLastRow() returns the position of the bottom row, relative to the physical screen.
Description
The WRow() function allows you to determine the top row (top border) of a window. To avoid complex calculations, you can use the WLastRow() function to determine the bottom row (bottom border) of a window.
The returned value can be greater than that of the bottom row of the screen. In such an instance, the window overlaps the bottom border.
By passing the logical parameter as .T., the position of a window after a call of WCenter() can be determined without actually calling WCenter().
Examples
A window is moved:
? WLastRow() > MaxRow() // .T. Window overlaps border
() If you designate a parameter as .T., you can move the window over that border. If you designate a parameter as .F., you cannot move the window over that border.
Returns
If there is an error the function returns -1. If no errors occur, WMode() returns 0.
Description
WMode() can be used to define whether each screen page can be moved, interactively or with WMove(), beyond the edge of each side of the screen or beyond the area defined by WBoard(). The WMode() setting is valid for all open windows.
Notes
■ This function can be implemented when windows are already
open.
Examples
Here we specify that the window can only be moved over the top or bottom
of the screen:
WMode(.T., .F., .T., .F.)
nRow Designates the row of the new top left corner of the currently selected window.
nColumn Designates the column of the new top left corner of the currently selected window.
Returns
WMove() returns the handle of the window that is moved.
Description
WMove() allows you to move the currently selected window to a particular position within the area defined by WBoard().
Notes
■ WSetMove() does not affect the operation of WMove(). By
comparison, WMode() does have an effect on WMove().
■ nRownColumn can have negative values. In contrast to the
interactive mode, a window can be moved completely under a border using WMove().
Examples
This function call moves the selected window up one row and over one
column to the left, if the related border has not already been reached:
WMove(WRow() - 1, WCol() - 1)
WNum() determines the highest open window number (handle) so that you can iterate a loop over the range of open windows (see Winstore.prg in the samples directory). Remember that any number of handles, from 0 to the highest handle number, can be inactive.
Examples
Open three windows, and then close the second window. WNum() returns
the highest window number, but there are two inactive handles:
nW1 := WOpen(3, 3, 10, 12)
nW2 := WOpen(10, 10, 20, 70)
nW3 := WOpen(5, 5, 22, 60)
WSelect(nW2)
WClose()
? WNum() // Result corresponds to nW3
Reduces the multiple appearances of particular double characters to one
Syntax
WordOne([<cDoubleCharacter>],<cString>) → cString
Arguments
cDoubleCharacter Designates which 2-byte sequences are only to appear once together in cString. The default value is for all 2-byte sequences.
cString Designates a string that has only specific 2-byte sequences that appear together after manipulation.
Returns
WordOne() returns the modified character string.
Description
A unique operation is carried out on a string that is constructed out of 2-byte sequences ("words"). The multiple sequence appearances must lie immediately beside one another, which allows a CharSort() with an element length of 2 to be executed.
These sequences can be integers that have been generated using the CA-Clipper I2Bin() function and have been deposited in a string. In conjunction with other string functions like WordOnly(), WordOne() is an extremely effective system for working with these kinds of files.
Notes
■ The term "word" is not used here in the textual sense, but
rather as it is used in assembler programming. A "word" consists of units of 16 bits, or more precisely, 2 bytes.
Examples
■ This is a simple example with characters that can be
displayed. The "AB" lie one after the other but not the "12":
? WordOne("12ABAB12") // "12AB12"
■ The function always runs through the string in ordered pairs:
? WordOne("12", "1212ABAB") // "12ABAB"
Finds the common denominator between two strings on the basis of double characters
Syntax
WordOnly(<cDoubleCharacter>,<cString>) → cString
Arguments
cDoubleCharacter Designates the 2-byte sequences that are not removed from cString.
cString Designates a character string from which 2-byte sequences that do not appear in cDoubleCharacter are removed.
Returns
WordOnly() returns the modified string.
Description
This function deletes all 2-byte sequences in cString that do not appear in cDoubleCharacter. This function is very useful in applications where 16-bit integer values have been saved to strings using the CA-Clipper I2Bin() function.
Notes
■ The function always processes strings in ordered pairs.
Examples
■ This example shows a simple common denominator. The second
string contains only the 2-byte sequences that are also contained in
the first string:
? WordOnly("AABBCCDD", "XXAAYYBBZZ") // "AABB"
■ Both strings are always processed in ordered pairs:
? WordOnly("AABBCCDD", "XAAYYBBZZ") // "BB"
cSearchDoubleCharacterstring Designates multiple 2-byte character strings which are replaced by corresponding character strings from cReplaceDoubleCharacterstring within cString.
cString [@] Designates the character string within which the 2- byte length sequences are exchanged.
cReplaceDoubleCharacterstring Designates multiple 2-byte character strings which replace corresponding character strings from cSearchDoubleCharacterstring within cString.
lMode Designates whether the character string cString is run through in single steps (.T.) or in ordered pairs (.F.). The default value (.F.) designates ordered pairs.
Returns
The modified character string is returned.
Description
With this function, 2-byte sequences in a string can be exchanged for another sequence of the same length. By using WordRepl() and its analog function CharRepl(), you can develop a very fast algorithm for SoundEx() functions. Strings read from screen memory or generated by the CA-Clipper I2Bin() function can be easily processed.
The cString can be processed in a number of different ways. It is here that the lMode parameter plays an important role, similar to the CSetAtMupa() functions.
There are different modes of execution for the function:
■ Depending on the lMode parameter, the string is processed in
single steps or ordered pairs.
■ CSetAtMupa() is successful only when lMode is designated
as .T.. If CSetAtMupa() is .T., then WordRepl() continues with the second character exchanged in a sequence. If CSetAtMupa() is not .T., WordRepl() continues with the character behind the second character.
Notes
■ The term "word" is not used here in the textual sense, but
rather as it is used in assembler programming. A "word" consists of units of 16 bits, or more precisely, 2 bytes. The cReplaceDoubleCharacterstring parameter can be shorter than cSearchDoubleCharacterstring.
■ The function exchanges sequences in
cSearchDoubleCharacterstring that do not have corresponding sequences in cReplaceDoubleCharacterstring with the last sequence in cReplaceDoubleCharacterstring.
■ The return value of the function can be suppressed by
implementing CSetRef() to save space in working memory.
Examples
■ Exchange "XX" for "CC":
? WordRepl("CC", "AABBCCDDEE", "XX") // "AABBXXDDEE"
■ Here is an example of use with CSetAtMupa() and <lMode>:
CSetAtMupa(.F.) // Default
? WordRepl("aa", "laaaa", "ba") // "labaa"
? WordRepl("aa", "laaaa", "ba", .T.) // "lbaba"
■ CSetAtMupa() only affects the function call when <lMode> is
.T.:
CSetAtMupa(.T.) // Multi-pass mode on
? WordRepl("aa", "laaaa", "ba") // "labaa"
? WordRepl("aa", "laaaa", "ba", .T.) // "lbbba"
Exchanges double characters that lie beside each other in a string
Syntax
WordSwap(<cString>,[<lMode>]) → cString
Arguments
cString [@] Designates the character string within which the 2- byte sequences are exchanged.
lMode Designates whether the adjoining bytes are exchanged (.T.) or not (.F.). The default value (.F.) designates that the adjoining bytes are not exchanged.
Returns
WordSwap() returns the modified character string.
Description
With WordSwap(), 2-byte sequences within a character string are exchanged for each other. In this respect the function works exactly like CharSwap(), except that 16-bit groups are being exchanged.
The function is used on strings that contain 32-bit integers created by the CA-Clipper L2Bin(). The exchange serves as a preparation for a sort of these integers using CharSort(). In order to achieve a correct sort, you must exchange two adjacent bytes (low/high ordering of 16-bit integers), in addition to exchanging the 16-bit groups.
Notes
■ When lMode is .T., adjoining bytes are only exchanged after
being exchanged as two 2-byte groups.
■ The return value of this function can be suppressed by
implementing CSetRef() to save working memory space.
cDoubleCharacterList Designates multiple 2-byte sequences which are exchanged for corresponding individual characters from the cCharacterlist.
cString Designates the character string within which 2-byte sequences are exchanged for individual characters.
cCharacterlist Designates a sequence of individual characters which correspond to 2-byte sequences in cDoubleCharacterList for replacement within cString.
Returns
WordToChar() returns the modified character string.
Description
When you use SOUNDEX algorithms, sequences of two characters must often be exchanged for a single other character. WordToChar() makes this process extremely simple and quick.
The function processes the cString in 1-byte steps. The behavior after exchanging a sequence for a character is determined by CSetAtMupa(). If CSETATMUPA is .F., the search for more sequences continues after the exchanged characters. If CSETATMUPA is .T., the search for more sequences continues and includes the exchanged characters.
Notes
■ The term "word" is not used here in the textual sense, but
rather as it is used in assembler programming. A "word" consists of units of 16 bits, or more precisely, 2 bytes.
■ cCharacterlist can be shorter than cDoubleCharacterList.
When this occurs, the function exchanges the sequences in cDoubleCharacterList that do not have corresponding sequences in cCharacterlist for the last sequence in cDoubleCharacterList.
Examples
■ This example shows a simple replacement:
? WordToChar("aa", "Xaaaa", "a") // "Xaa"
■ This example shows WordToChar() in conjunction with
CSetAtMupa():
CSetAtMupa(.F.) // Multi pass off
? WordToChar("aa", "Xaaaa", "a") // "Xaa"
CSetAtMupa(.T.) // Multi pass on
? WordToChar("aa", "Xaaaa", "a") // "Xa"
nTopRow Designates the top row. The value can be between 0 and 24.
nLeftColumn Designates the leftmost column. The value can be between 0 and 79.
nBottomRow Designates the bottom row. The value can be between 0 and 24.
nRightColumn Designates the rightmost column. The value can be between 0 and 79.
lDelete Designates whether the area of the screen selected for the newly opened window is erased (.T.) or not (.F.). The default value (.F.) does not erase the area.
Returns
WOpen() returns a handle to the new window. If there is an error, WOpen() returns -1.
Description
WOpen() opens a new window. If a window can be opened, then the function returns a number (handle) for this window. If a window is opened with invalid coordinates, WOpen() returns -1 and the window that was active at the time of the function call is still active.
Notes
■ Beginning with CA-Clipper 5.01, windows that lie completely
under the actual screen border, or under the borders defined by WBoard(), can also be opened.
■ After you open a window, all screen output is redirected to
the window if it is not written directly into screen memory. This applies to output from CA-Clipper, DOS, and other programs. If the output rows are longer than the window is wide, then there is a line feed (i.e. for SCOREBOARD output).
■ If a shadow has been selected using WSetShadow(), the window
screen area is cleared when you open the window.
Examples
This function opens a window with the top left corner in row 5 at column
10, and the bottom right corner in row 20 at column 70. If the window
opens successfully, the returned value is 1:
nWindow := WOpen(5, 10, 20, 70)
Returns the position of the top row of the active window
Syntax
WRow([<lAfterWCENTER>]) → nRow
Arguments
lAfterWCENTER Designates an optional parameter. If this parameter is .T., the function returns what the postion of the top row of a window would be after a call of WCenter(). (This function does not call WCenter().) The default value (.F.) returns the current position.
Returns
WRow() returns the row of the currently selected window, relative to the physical screen.
Description
WRow() determines the current position of the top row of the currently selected window. This allows you to save a window position for a window that was moved previously using the cursor keys or WMove(). You can later reopen the window at exactly this position.
If you used invalid parameters with WMove() to move a window, WRow() lets you determine the current window position. WRow() is particularly helpful since WMove() automatically adapts to the invalid parameters. WRow() can also be helpful after you use the WCenter() function. The new coordinates can be determined using WRow() and WCol().
Additionally, with the specification of the optional parameter, you can determine the position of a window after a call of WCenter() without actually calling WCenter().
Notes
■ The value returned can be negative. If so, the first row is
outside of the visible area.
Examples
This program can determine the position of the window at all times:
nTop := 10
nLeft := 15
WOpen(nTop, nLeft, nTop + 10, nLeft +40)
* Someone moved the window!
nTop := WRow() // Save the current position
nLeft := WCol() // of the upper left corner
WClose() // Close the window
* Other program sections
WOpen(nTop, nLeft, nTop + 10, nLeft + 40) // Open with old
// values
nActivateWindow Designates the handle of the window that is selected. Without this parameter, the function returns the handle of the currently selected window.
Returns
WSelect() returns the handle of the current window.
Description
WSelect() allows you to take an already open but inactive window and reactivate it. You can specify numbers from 1 to 255. Window 0 corresponds to the physical screen. By omitting the parameter you can determine the handle of the window currently selected.
lNewMoveMode Designates whether a window can be moved interactively (.T.) or not (.F.) with the SCROLL LOCK key or the KSetScroll() function. The default value (.T.) allows the window to be moved.
Returns
When called without parameters the function returns the current setting for WSetMove(). If a parameter is passed, it returns the previous setting.
Description
This function allows you to prevent (or permit) a user to interactively move a window with the cursor keys. If no parameter is specified, the function returns the current status of the switch without changing the current status.
Notes
■ The WSetMove() setting does not affect the WMove() function;
it only affects the interactive setting. The WMode() setting determines if a window can be moved under a border of an area set by WBoard().
Examples
This example specifies that the current window cannot be moved
interactively:
WSetMove(.F.)
WOpen(5, 5, 15, 15)
cAttribute Designates the color attribute for window shadows. It can be represented as a numeric string ("nn/nn") or as a color string ("cc/cc"). A value of -1 turns off the shadow display.
() When you call the function without parameters, it returns the current shadow color setting.
Returns
WSetShadow() returns the previously set shadow color, or it returns -1 if no shadow color has been set.
Description
WSetShadow() sets individual color attributes for shadows of every window, which are displayed below and to the right of each window. The WSetShadow() setting then applies to all subsequently opened windows.
Notes
■ When you use shadows, the window screen area is erased during
opening.
■ The proportions of the right and lower shadows are adapted to
the height of the characters. For example, the proportion is 2:1 with 25 rows; and the proportion is 1:1 with 50 rows.
Examples
In order to experiment with shadows, you should first fill the screen
with a character like Chr(176):
SetClearB(176)
CLEAR // Fill screen with Chr(176)
WSetShadow("N+") // Gray shadows
WOpen(1, 1, 10, 50)
WBox()
WSetShadow(-1) // Switch shadow display off
WOpen(15, 1, 20, 50)
WBox()
Inkey(0) // Switch on move mode using
// SCROLL-LOCK
WAClose()
Determines the step width of interactive window movement
Syntax
WStep(<nVertical>,<nHorizontal>) → nResult
Arguments
nVertical Designates the number of rows the window steps when moved interactively.
nHorizontal Designates the number of columns the window steps when moved interactively.
Returns
If an error occurs, WStep() returns -1. If no errors occur, it returns 0.
Description
WStep() allows you to set the number of steps a window moves with each key stroke.
Exact Positioning
Normally, in the case of a step size greater than (1,1), you would not be able to select every screen position. However, unique interactive mode behavior lets you select every screen position anyway! Pressing two opposing arrow keys, one immediately after the other, causes a step size of 1 to become effective for that axis. This step size allows precise positioning of the window!
Notes
■ This function only operates when all windows are closed. The
preset values are 2 rows for the vertical steps and 5 columns for the horizontal steps. The maximum values are 6 rows for the vertical steps and 20 rows for the horizontal steps. If a step value exceeds the maximum value, then the step value is set to the maximum correct value.
Examples
When you use the cursor keys, the selected window is moved 1 row
vertically and 3 rows horizontally:
WStep(1, 3)
cString Designates a character string of 128 or 1024 (depending on nMode) characters. Excess characters are cut off; missing characters are filled with Chr(0).
nBlockNumber Designates the related block number.
lCRC Designates whether an XMODEM block is to be formed with a checksum (.F.) or with a 16-bit CRC (.T.). The default value (.F.) is a checksum.
nMode Designates different block types. Mode 1 designates a 128 byte block with start character Chr(1). Mode 2 designates a 1kByte block with start character Chr(2). The default value is a mode 1, 128 byte block.
Returns
This function returns an XMODEM block that is "ready to go".
Description
This function generates a data block according to XMODEM conventions, which can then be output directly using com_Send(). The block number and the packet verification procedure that you choose can be designated. The function automatically takes into account the fact that after block number 255, XMODEM waits for 0 again (block number %256). So you can go as high as you like with your variables.
An X-MODEM block has the following construction:
SOH+BN+Complement of BN+128 data bytes+1 byte CS or: SOH+BN+Complement of BN+128 data bytes+2 byte CRC
This is the construction for a 1k byte block:
STX+BN+Complement of BN+1024 data bytes+1 byte CS or: STX+BN+Complement of BN+1024 data bytes+2 byte CRC
■ Verification of the 8-bit checksum corresponds to the
NumLow(ASCII-SUM(Data)) function call.
■ A programming sample using XMODEM protocols under CA-Clipper
can be found in the following example program.
Examples
This is an example of a simplified XMODEM transfer. Initialization of
the port is assumed:
nBlockNum := 0 // 1st block
lChkMode := .T. // Use CRC
nBlkSize := 128 // XMODEM block size
nPointer := 0 // Start point in file
cData := FileStr("TEST.TXT", nBlkSize, nPointer)// Read data
DO WHILE Len(cData) > 0
COM_SEND;
(1, XMoBlock(cData, nBlockNum, lChkMode)) // Send block
nBlockNum := nBlockNum +1 // Next block
nPointer := nPointer +nBlkSize // File pointer
cData := FILESTR;
("TEST.TXT", nBlkSize, nPointer) // Read data
ENDDO
cString Designates a character string that is reviewed to determine if it represents a valid XMODEM block.
lCRC Designates whether to check for a checksum (.F.) or a CRC (.T.). The default value (.F.) tests for a checksum.
Returns
XMoCheck() returns the block number for the cString transferred by an XMODEM block. The function returns a value between 0 and 255, or returns -1 if the block had errors.
Description
XMoCheck() checks a received XMODEM block for errors. The block header is checked, and depending on the way the lCRC parameter has been set, XMoCheck() tests the checksum or the CRC. The function then returns the block number as a value between 0 and 255. If there were inaccuracies in the block, -1 is returned. The standard XMODEM blocks (128 byte blocks) and the 1k blocks are recognized on the first character automatically. The header of a 128 byte block starts with Chr(1). The header of a 1k block starts with Chr(2).
Notes
■ "Unpacking" the data after checking the block for accuracy is
very simple using SubStr(cBlock, 4, 128) for 128 byte blocks or SubStr(cBlock, 4, 1024) for 1k blocks.
■ There is an example for the programming of an XMODEM protocol
in Xmodem.prg in the samples directory.
Examples
In this example, the block is received and unpacked. Test to see if the
following block has been received:
cBlock := com_Read(1) // If 132 characters
nBlkNr := XMoCheck(cBlock) // Test with checksum
IF nBlkNr >= 0
cData := SubStr(cBlock, 4, 128) // Extract data
* ...
ENDIF
Converts an expression of any data type into a string
Syntax
XToC(<expValue>) → cValue
Arguments
expValue Designates an expression of any desired data type.
Returns
XToC() returns a character string version of the expValue parameter.
Description
At first glance, the XToC() function does not appear to accomplish anything that cannot be done with the other functions. However, the advantage lies in the fact that you do not have to pay attention to the input data types. For example, you can convert the data in every field within a loop into a string. You could then link these into a longer string and use them to index or for comparisons.
Each data type always returns a string with a particular fixed length:
Table 13-9: Resulting String
Data Type Result Length
Numeric 8
Logical 1
Date 8
String Unchanged
Notes
■ The index string cannot be longer than 256 characters.
Examples
■ In the case of logical parameters, XToC() works like LToC():
? XToC(.T.) // "T"
? XToC(.F.) // "F"
■ Numeric values always return an 8-byte string:
? XToC(0) // Length 8
? XToC(9.9) // Ditto
? XToC(-9.9) // Ditto
? XToC(99) // Ditto
? XToC(-99) // Ditto
■ A string returns the same string:
? XToC("123ABCabc") // "123ABCabc"
■ A date returns the ANSI date:
? XToC(CToD("12/31/99")) // "19991231"
? XToC(CToD("01/01/00") // "19000101"
■ An empty or false date returns an empty string rather than a
null string:
? XToC(CToD(" / / ") // " "
? XToC(CToD("77/77/77") // " "
■ Show a function where all the fields in a database are
combined into one string. This way, you can do a complete comparison
of the two data strings:
FUNCTION STRINGREC
PRIVATE nI, nFieldNo, cField, cStringRec
cStringRec := ""
nFieldNo := FCount() // Number of fields
FOR nI = 1 to nFieldNo
cField := Field(nI) // Field name
cStringRec := cStringRec + XToC(&cField)
NEXT nI
RETURN (cStringRec)
cString Designates any character string in which you choose to insert a 0-bit.
Returns
The function returns a character string with the 0-bit inserted.
Description
This function has been incorporated to allow simplified programming of data transmission protocols to the CCITT specification. CCITT determines that each data block has a start and a stop flag, like "01111110". To ensure that the flag bit pattern doesn't appear within the data, a 0-bit is inserted after every fifth 1-bit. These explicit flags allow a transfer protocol to resynchronize itself more quickly if a transmission error occurs. For example, this process is implemented by ISDN or X.25 networks.
Notes
■ Due to the inserted bit, the character string that is returned
is longer than the character string that is transmitted. Length increases a maximum of 20%, which can be calculated as follows:
nMaxLen = Len(cString) + Ceiling(Len(cString)/5)
Examples
■ For any five bytes of the original string, a maximum of one
additional byte can arrive as a result. This example tests, if there
is enough available free memory, for the resulting string:
cCharacter := Chr(CToN("11111111", 2)
cString := Replicate(cCharacter, 6)
nMaxLen := Len(cString) + Ceiling(Len(cString) /5)
//Here: 8
IF nMaxLen < Memory(1) * 1024 - 100
cString := ZeroInsert(cString)
ENDIF
■ This example shows the construction of a typical data block:
cFlag := Chr(CToN("01111110", 2)) // According to
// CCITT
cData := "Also transmit ????!"
CRC := com_CRC(cData)
cBlock := cData + SubStr(L2Bin(CRC), 1, 2) // Add CRC to
// string
cBlock := ZeroInsert(cBlock)
cBlock := cFlag + cBlock + cFlag
idDataBlock Designates a character string in which a 0-bit has been inserted using ZeroInsert().
Returns
ZeroRemove() returns the character string to the same condition it was in prior to ZeroInsert().
Description
This function is the opposite of ZeroInsert(). This means that the 0- bit that was inserted, according to the special CCITT rule, is now removed. Removing the bit decreases the length of the block up to 20%.
Examples
This example shows the construction of a typical data block:
cFlag := Chr(CToN("01111110", 2)) // According to
// CCITT
cData := "Also transmit ????!"
CRC := com_CRC(cData)
cBlock := cData + SubStr(L2Bin(CRC), 1, 2) // Add CRC to
// string
cBlock := ZeroInsert(cBlock)
cBlock := cFlag + cBlock + cFlag
* ... transmission of the data block:
cData := RemAll(cFlag, cBlock) // Remove flag
cData := ZeroRemove(cData)
*... and subsequently the important CRC checks, etc.
This section describes the Novell error codes that will occur in conjunction with NNETxxxxxx() functions. The error from the previously called function must be determined using NNETERROR(). Some of the error codes, like 254 or 255 have multiple meanings, and only permit a precise definition of the nature of the error in conjunction with the network function used.
Error codes 1 - 18, as well as 32 - 33 are DOS error messages and correspond to those described in Appendix C: