Contents - J User Manual

1	Introduction	8	Window Controls
2	First Steps	9	DDE and OLE
3	Session Manager	10	VBX Controls
4	J Programs	11	ODBC
5	Development	12	Callling DLLs
6	Utilities	13	Packages
7	Window Driver	14	Runtime
	SQL Appendix		Copyright
Help Hints	SM Summary
WD Reference	WD Commands
Form Edit	Data Conversions

J Introduction and Dictionary


Chapter 1   Introduction

Introduction

About J

Syntax Conventions

Installation

Reading Product Updates

The J Program Item

The J DLL files

The JSM.INI file

Internet

Product Support


Chapter 2   First Steps

First Steps

Loading J

Profile File

Demos

The J Session

Script Files

The J environment

Window Driver

Loading scripts

Sample application 1

Sample application 2

Sample application 3


Chapter 3   Session Manager

Session Manager

Execution Windows

Script Windows

Input Log

Menus

Toolbar

Status Bar

View Menu

Controlling the Session Manager

Tools Menu

Document Windows

Printing Commands


Chapter 4   J Programs

J Programs

Explicit Definition

Local and Global Names

Locales

Control Words


Chapter 5   Application Development

Application Development

Profile.js

Stdlib.js

Winlib.js

Jadelib.js

Project Files

Jadelib editor


Chapter 6   Standard Utilities

Standard Utilities

Compare

Convert

Dates

DD

Dir

Debug

DLL

Files

Format

Jadeutil

Misc

Myutil

Numeric

Trig

Winutil


Chapter 7   Window Driver

Window Driver

Window Driver Results

Non-Wait commands

Wait Commands

The Wait Loop

Parent Verbs


Chapter 8   Window Controls

Window Controls

Parent Windows

Location and Size

Child Controls

Child Classes

Common Dialog Boxes

Fonts

Accelerator Keys

Parent Menus

Sendkeys

Tab and Cursor Keys

Ownerdraw


Chapter 9   DDE and OLE

DDE and OLE

DDE

Server and Client

DDE conversations

J Commands and Events

Communications Protocol

DDE Examples

J to J Hot Link

J to J Cold Link

Word for Windows to J Cold Link

OLE

Object Packager

Graphics


Chapter 10   VBX Controls

VBX Controls

Accessing VBX controls

Using the Spinbutton Control

Setting Property Values

Creating VBX command verbs


Chapter 11  ODBC Data Driver

ODBC Data Driver

The SQL language

Installing ODBC

ODBC Connection and Statement Handles

Data Driver

Listing the Data Sources

ODBC error messages

Connecting to a data source

Selecting and reading data

Updating a record

Creating a new file


Chapter 12   Calling DLL Procedures

Calling DLL Procedures

Memory Management


Chapter 13   Packages and Examples

Packages and examples

Packages

Example Scripts

JFiles


Chapter 14   Runtime Applications

Runtime applications


SQL Appendix

SQL Statements

SQL Elements

SQL Reserved Keywords


Help Hints

File jsm.hlp is the J User Manual and a few additional topics and file jsmid.hlp is the J Introduction and Dictionary.

Help/How to Use Help is worth reading.

Use Help window Edit/Copy to copy examples to session manager windows. The copy window does not display boxes properly, but they do copy.

Help window Help/Always on Top keeps help visible while working in other windows.

Vocab button in the Dictionary gets the vocabulary topic.

TAB and Enter select jumps.


Session Manager
Session Manager Summary

There are two types of windows.

JX windows provide sentences to J for execution and display. In a JX window:

Enter on last line passes line to J for execution.

Enter on other lines copies to last line for editing.

Ctrl+End moves to last line.

Ctrl+ up and down arrow keys recall input lines.

Ctrl+D shows list box with history of input lines

Ctrl+Break requests execution interrupt.

JS windows are script edit windows. A JS window can be opened from the File menu and can be run from the Run menu.

Ctrl+F6 and Ctrl+Tab cycle through the JX and JS windows.


Data Type Conversions

Data types native to J are 1 byte characters, 4 byte integers (long integer), and 8 byte IEEE floating point numbers (long float).

Other systems use additional data types of 2 byte integers (short integer), 2 byte unsigned integers (unsigned short integer), and 4 byte IEEE floating point numbers (short float).

J may require these formats to exchange data with others and in parameters to DLL procedures.

ic=.3!:4	convert integers

fc=.3!:5	convert floats

Positive left argument converts numbers to characters.

0 or negative argument converts characters to numbers.

Left argument absolute value of 0 or 1 works with characters as short numbers.

Left argument absolute value of 2 works with characters as long numbers.

 0 ic char	character (unsigned short integer) to integer

 1 ic int	integer to character (short integer)

_1 ic char	character (short integer) to integer

 2 ic int	integer to character (integer)

_2 ic char	character (integer) to integer

 1 fc float	float to character (short float)

_1 fc char	character (short float) to float

 2 fc float	float to character (float)

_2 fc char	character (float) to float


Copyright

Author: Chris Burke

Second Printing, with corrections, January 1995

Copyright 1994-1995 All Rights Reserved

Iverson Software Inc.

33 Major Street

Toronto, Ontario

Canada M5S 2K9

ISBN 1-895721-09-1

The J logo is a trademark of Iverson Software Inc.

Microsoft is a registered trademark and Windows is a trademark of Microsoft Corporation. Other trademarks are the property of their respective owners.


Chapter 1 Introduction
1:  Introduction

This User Manual and the accompanying J Introduction and Dictionary document J Release 2 for Windows, an application development system. This system operates under the Microsoft Windows or Windows for Workgroups operating systems, version 3.1 or later. It consists of a full implementation of the J programming language, plus a Windows-based application development environment.


About J
1:  About J

J is a general purpose programming language designed by Ken Iverson and Roger Hui, and available on a wide variety of computers and operating systems, including PC Windows, PC DOS, Mac and various UNIX machines. J is distinguished by its simple and consistent rules, a large set of  built-in capabilities, powerful facilities for defining new operations, and a general and systematic treatment of arrays.

The language is the same on all computers, except only for host-specific features such as the Window Driver in this version; as a result J programs not dependent on such features can be ported without change between computers.

The J language is fully documented in the J Introduction and Dictionary. This User Manual for J Release 2 for Windows covers the application development environment, features specific to this release and several examples of using J.


Syntax Conventions
1:  Syntax Conventions

Where possible, this manual shows examples exactly as you see them on your computer. Items shown in courier font represent actual system output, or information you should enter as shown. Items you enter into the computer are indented 3 spaces to distinguish them from the computers response. Items shown in Arial font represent information displayed by DOS or the operating system.


Installation
1:  Installation

Your J for Windows package should contain the following:

•	J Introduction and Dictionary

•	J User Manual

•	One set of 3.5 high density diskettes

•	License Agreement

Take time now to check the contents of your package. If your package is not complete, contact your dealer.

J for Windows requires an 80386, 80486 or Pentium based PC or compatible running Windows or Windows for Workgroups version 3.1 or later. A math coprocessor is recommended, but not required. J will run acceptably in 4 MB memory, but the more memory available, the better. You will need about 6 MB of hard disk available.

J Release 2 for Windows is distributed on 4 disks (Personal system), or 5 disks (Professional system). The additional disk in the Professional system contains the runtime files.

Three of these disks are setup disks, i.e. use Microsoft Windows standard setup procedure to install.

You must install the J Setup disk. We recommend you also install the VBX and SQL ODBC Setup disk, which is required for many of the examples in the User Manual. You need only install the ODBC Setup disk if you need ODBC access.

The remaining disks are used as and when needed, either during the installation, or afterwards if you want to add specific ODBC drivers, or make a runtime system. You will be prompted for these disks when necessary.

To install J for Windows, you must first be running Windows. Insert the J SetUp disk in drive a: (or other available drive). From the Program Manager, select the File/Run menu option. In the Command Line box, enter:

a:setup

and choose the OK button.

Once installation is complete, repeat the procedure with the VBX and SQL ODBC Setup disk, and the ODBC Setup disk if required.

Setup creates a new directory, if necessary, on your hard drive. It then copies the J system files to it, creates a new Program Manager Group and a J Program Item icon to load the J system. Once setup is complete, you can load J by double-clicking on the icon. Setup will by default install in directory c:\j2. You may choose another directory if you wish. The examples in this manual assume you have used the default directory.

Setup copies files to the J directory and to the windows\system directory. In some cases the files copied may exist elsewhere on your system.  If you wish, you may delete any duplicate files or replace older versions with newer versions - if you do so, be careful to backup the older versions first in case you have other software that requires them.

If you choose to install J into a directory that already exists, setup will overwrite any existing files of the same name. In this case, you should backup your files first.

When you load J, if you do not get the line drawing characters, then you need to set up an appropriate font using the View/Set Font menu item. We suggest using Terminal/Regular/9 point as the session font. Once the font has been selected, use the File/Save jsm.ini menu option to save the setting as the default.

Note that to ensure the examples given in this manual work correctly, you should set the profile.js file in the Command Line as described Chapter 2.


Reading Product Updates
1:  Reading Product Updates

The setup creates the readme.wri in the J directory. This contains last-minute information about the product that was received after the documentation was printed, and notes for upgrades. You can read and print this file using Windows Write.


The J Program Item
1:  The J Program Item

You can customize entries in the J Program Item if you wish. The Command Line should include the full path name of the JSM.EXE file, followed by any of the optional parameters:

filename	  	is the  profile or initial file loaded when J is loaded. Set this to 	profile.js if you wish to use the utility scripts supplied with J.

/ddename  	sets the ddename on start up

/emu	forces use of JEMU.DLL even when the system has a 	coprocessor.

/max	start maximized

/min 	start minimized

/n	noisy - set this if you wish to see the output from running the 	initial file.

/no3d	3D Windows controls are not used

The Working Directory entry in the J Program Item is ignored - when you load J, the working directory is automatically set to the directory in which the JSM.EXE file is found.

You need only one copy of JSM.EXE on your system. If you want to store your application in a different directory, it is strongly recommended that you load the one copy of JSM.EXE and then reference files in the application directory using their full DOS pathname, rather than making copies of JSM.EXE for each application directory.


The J DLL files
1:  The J DLL files

The J language interpreter is stored in a DLL file, J387.DLL for systems with a math coprocessor, and JEMU.DLL for systems without a math coprocessor - the appropriate file is used on start up. If you load two or more copies of J at once, copies of these files are made as needed, named J387_1.DLL, and so on. These additional copies may not be deleted when you terminate your J session, but you can delete them manually if you wish.  Do not delete J387.DLL or JEMU.DLL!


The JSM.INI file
1:  The JSM.INI file

This file is created in the \windows subdirectory and stores window size and font specifications. The same file is used whenever J is loaded. Typical entries are:

[Settings]

WindowPos=2,3,96,408,-4,-4,1,164,638,478

[Font]

Height=-12

FaceName=Terminal

Weight=400

PitchAndFamily=49

CharSet=255

[PrintFont]

Height=-94

FaceName=MS LineDraw

Weight=400

CharSet=2

PitchAndFamily=49


Internet
1:  Internet

The conference comp.lang.apl contains an active discussion group on J.


Product Support
1:  Product Support

If you experience problems, you should first contact the dealer from whom you purchased the product, or the main distributor, Strand Software. When you call, you should be at your computer and have the appropriate product documentation at hand. Be prepared to give the following information:

•	the version number and serial number of your system (both shown in the Help/About menu item)

•	the type of hardware you are using

•	the exact wording of any messages that appeared on your screen what happened, and what you were doing when the problem occurred

•	how you tried to solve the problem


Chapter 2 First Steps
2:  First Steps

In this chapter we illustrate some important features of J for Windows. For more information on the topics covered here, see the later chapters of this manual, and the J Introduction and Dictionary.


Loading J
2:  Loading J

After installing the system, you can load J by selecting the J icon in Program Manager, and either double-clicking on the icon, or pressing Enter.


Profile File
2:  Profile File

Typically, you will want to customize your system so that on start up:

•	your utility programs are loaded automatically

•	any default settings are changed as required

You can do this by specifying a file to be loaded on start up, in the command line of the Program Manager item. For this purpose, we recommend you start with the file profile.js stored in the J directory. Note that profile.js is an ordinary file and you are free to modify it or use your own file if preferred.

To load this file automatically when you start J, in Program Manager select the J icon, then click on the File/Properties menu item, and change the Command Line to:

c:\j2\jsm.exe profile.js

Then click the OK button.

If you loaded J without the profile, you can always load it from within J, by selecting the menu item Run/File, then clicking on profile.js. You can reload this file at any time; indeed this should be done if you make any changes to the files it reads in.

The profile file is discussed further in Chapter 5. For the time being, you should be aware that it reads in several utility programs, and also changes the display output to boxed form.

Check that the profile file has been loaded by entering one of the names it defines. Type nl (a verb that produces a namelist) and press Enter:

nl

ÚÄÂÄÄÂÄ¿

³4³!:³1³

ÀÄÁÄÄÁÄÙ

If the profile were not loaded, nl would not be defined, and you would get a value error message:

nl

³value error

If you can see the 4!:1 characters correctly, but not the line drawing characters, then you are using a font that does not support line drawing characters. You can set up an appropriate font using the View/Set Font menu item. We suggest using Terminal/Regular/9 point as the session font. Once the font has been selected, use the File/Save jsm.ini menu option to save the setting as the default. You can also select the printer font in the same way - we suggest using MS Linedraw, or if not available, the ISIJ font.

Note that this manual assumes the standard profile has been read in. If you do not load the profile file, the examples will not work!

For example, the default output display is the linear form, which displays without the boxes:

nl

4!:1

However, the boxed form is used throughout this manual because this format is easier for beginners to understand Js word-formation rules.


Demos
2:  Demos

You might like to try out some of the demos included with the system. For example, to run a demo of the graph VBX control, enter:

load 'examples\graph\grafdemo.js'

This demo includes a variety of graph types, which can be selected from the Graph menu. With each display, you can press the view definition button to see the actual commands used to create the display. Press Esc or the close button to end the demo.

To run a demo showing several types of Windows controls on a single form, enter:

load 'examples\demo\controls.js'

This demo may take a few seconds to load - it uses three VBX controls which must be read in.

As with the graph demo, the actual commands used to create each control can be viewed by pressing the small button next to the control. Press Esc to end the demo.

For more information on the demos included with the system, see Chapter 12 - Packages and Examples.


The J Session
2:  The J Session

After J is loaded, the session manager window appears, with a child window 1.jx. These windows are standard Windows controls, and can be moved, resized, maximized, and minimized into an icon. If you wish, maximize both windows by clicking on the maximize button at the top right corner of each window.

The child window 1.jx is an execution window - you can type sentences into this window, which are executed when you press Enter. J is ready for input when the message in the status bar at the foot of the screen displays Ready. Typically the caret is indented 3 spaces - this helps distinguish user entries from the computers responses.

In the following examples, you should key in the indented entries (shown in courier font) and press Enter. Use Ctrl up-arrow to retrieve previous entries for editing and re-entry:

Add 5 to the three numbers 10 20 30:

5 + 10 20 30

15 25 35

*: squares its argument:

*: 10 20 30

100 400 900

+/  sums its argument:

+/ 10 20 30

60

Character strings are entered using quotes:

'hello world'

hello world

Names can be assigned using  =.:

a=. 5

b=. 10 20 30

plus=. +

square=. *:

sum=. +/

text=. 'hello world'

Note that no result is shown if the last statement was an assignment; otherwise the result is displayed. You can do both, using the same function [ as in:

[text=. 'hello world'

hello world

We can now use the names defined:

a plus b

15 25 35

square b

100 400 900

sum b

60

c=. a plus b

sum c

75

Now let's try some simple data manipulations. Define a character string a as follows (note that this redefines a):

[a=. 'toronto ontario'

toronto ontario

Count of a:

   #a

15

3 copies of each element of a:

   3#a

tttooorrrooonnntttooo   ooonnntttaaarrriiiooo

Make a 3 by 10 table from a:

   3 10$a

toronto on

tariotoron

to ontario

Reverse a:

   |.a

oiratno otnorot

Use the itemize function ,: on a. The display is unchanged:

,:a

toronto ontario

Itemize converts its argument into a single item. The count of the itemize of a is 1:

   #,:a

1

Make 3 copies of the item:

   3#,:a

toronto ontario

toronto ontario

toronto ontario

Make a 3 by 10 table from the item:

   3 10$,:a

toronto ontario

toronto ontario

toronto ontario

...

Apply reverse (there is only 1 item, so it has no effect):

|.,:a

toronto ontario

Find positions where the letter 'o' occurs. Note = tests for equality, and is not an assignment:

   a='o'

0 1 0 1 0 0 1 0 1 0 0 0 0 0 1

The utility bx returns indices (counting starts from 0):

   bx a='o'

1 3 6 8 14

Assign the indices to x:

x=. bx a='o'

Use from { to index the letters 'o':

   x { a

ooooo

Use amend } to amend them, here replacing with 'Z':

   'Z' x } a

tZrZntZ ZntariZ

Take the nub (unique elements) of a:

   ~. a

torn ai

Classify elements of a according to the nub:

   a </. a

ÚÄÄÄÂÄÄÄÄÄÂÄÄÂÄÄÂÄÂÄÂÄ¿

³ttt³ooooo³rr³nn³ ³a³i³

ÀÄÄÄÁÄÄÄÄÄÁÄÄÁÄÄÁÄÁÄÁÄÙ

Count elements of a, classified according to the nub:

   a #/. a

3 5 2 2 1 1 1

Creating names

You create a new definition by assignment. Names created can be used in other definitions; in fact there is no distinction between names built-in to the language, and names assigned by the user. Here are some examples.

We define a verb sumsquare that sums the squares of its argument. We use the atop conjunction, which joins two verbs together to create a single verb:

atop=. @

   sumsquare=. sum atop square

sumsquare b

1400

The following defines a function that is essentially the same as sumsquare:

ssq=. +/ @ *:

ssq b

1400

Entering a name alone displays its definition:

sumsquare

ÚÄÄÄÂÄÂÄÄÄÄÄÄ¿

³sum³@³square³

ÀÄÄÄÁÄÁÄÄÄÄÄÄÙ

ssq

ÚÄÄÄÄÄÂÄÂÄÄ¿

³ÚÄÂÄ¿³@³*:³

³³+³/³³ ³  ³

³ÀÄÁÄÙ³ ³  ³

ÀÄÄÄÄÄÁÄÁÄÄÙ

You could also define sumsquare using explicit definition. In this case the definition is given as a character string, with the argument indicated by y.:

sumsquare=. 3 : '+/ *: y.'

sumsquare

ÚÄÂÄÂÄÄÄÄÄÄÄÄ¿

³3³:³+/ *: y.³

ÀÄÁÄÁÄÄÄÄÄÄÄÄÙ

sumsquare 10 20 30

1400

You could use the elements of the sumsquare definition directly, without assigning a name:

+/ @ *: 10 20 30

1400

3 : '+/ *: y.' 10 20 30

1400

In the following, x is a list of lists of numbers (a boxed list), and each creates a new verb that is applied to each item of its argument:

x=. 1 2 3 4 ; 10 20 30 ; 100 200

each=. &.>

x

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄ¿

³1 2 3 4³10 20 30³100 200³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÙ

sumsquare each x

ÚÄÄÂÄÄÄÄÂÄÄÄÄÄ¿

³30³1400³50000³

ÀÄÄÁÄÄÄÄÁÄÄÄÄÄÙ


Script Files
2:  Script files

In the session so far, we have defined several names by assignment. In fact, all definitions in J are created by assignment, but we typically automate the process by writing the definitions in files called script files, which can be read into the session as required.

A script file is an ordinary text file that contains J sentences, which when read in are executed as if the sentences had been typed directly into the session. Typically, all J programming is done in these script files. Let's create a script file, as follows:

Open a script window by selecting File/New JS. You can switch between windows by clicking with the mouse, by pressing Ctrl-F6 (or Ctrl-Tab) to cycle through the windows, or by selecting the window from the Window menu.

When you type into the script window, the sentences are not executed. To run the script, select the menu item Run/Window, which loads the script into the execution session. For example, enter into the script window the following definitions:

cube=. ^&3

cuberoot=. ^&(%3)

Select Run/Window, then in the execution session, try:

cube 10 20 30

1000 8000 27000

cuberoot 10 20 30

2.15443 2.71442 3.10723

   cube cuberoot 10 20 30

10 20 30

You may wish to rearrange the script window and session window so that both are easily visible. If you have a SuperVGA or larger display, this is usually not a problem. On a VGA screen, there will be some overlap between the two windows. One solution is to fit the execution window flush with the bottom left of the screen, and the script window flush with the top right, overlapping in the middle.

For example:

Another solution is to tile the windows. Select Window/Tile to tile them vertically:

The script you have created is a temporary script. To save it permanently, change to the script window, select File/Save As, and save the file with a name other than n.js for integer n, e.g. save as myscript.js.


The J environment
2:  The J environment

When you load J, it reads in the start-up file specified in the Command Line in the Program Item Properties dialog box. As recommended, you should already be using the supplied start-up script file profile.js. This file in turn reads in several other script files, creating definitions that can assist you in writing your J applications. The following examples demonstrate:

The verb nl (namelist) returns the names currently in use. The argument is the nameclass (0=nouns, 1=adverbs, 2=conjunctions, 3=verbs, 6=locales):

nl 0

ÚÄÂÄÂÄÂÄ¿

³a³b³c³x³

ÀÄÁÄÁÄÁÄÙ

   nl 1

ÚÄÄÄÄ¿

³each³

ÀÄÄÄÄÙ

nl 2

ÚÄÄÄÄ¿

³atop³

ÀÄÄÄÄÙ

nl 3

ÚÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÂÄÄÄÄÄÄÄÄÄ¿

³cube³cuberoot³plus³square³sum³sumsquare³

ÀÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÁÄÄÄÄÄÄÄÄÄÙ

nl 0 1 2 3

ÚÄÂÄÄÄÄÂÄÂÄÂÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂ

³a³atop³b³c³cube³cuberoot³each³plus³...

ÀÄÁÄÄÄÄÁÄÁÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁ

You can view any definition by entering its name alone. Thus nl is defined as:

nl

ÚÄÂÄÄÂÄ¿

³4³!:³1³

ÀÄÁÄÄÁÄÙ

The verb names also returns the names currently in use, but formats them into columns to the current display width, and if given an empty argument, shows all names in classes 0-3:

names ''

a         atop      b         c         cube...

each      plus      square    sum       sumsquare...

You may wonder why, if names '' shows all names, then nl and names do not appear in the list. The reason is that they are deliberately hidden by being defined in a different locale.

Locales (or namespaces) allow you to keep separate lists of names in the same session. For example, they enable you to load standard utility programs that are always available throughout your session, but which do not appear when you list the names you have created specifically for your work. They also permit you to create applications that can be loaded into their own locales without conflicting with other definitions you may have created.

By default, names are created and referenced in the base locale. To create or reference names in any other locale, you use names followed by:  underscore, locale name, underscore. For example abc_def_ is the name abc in the locale def; read it as:  abc in def.

The default profile populates two locales, named j and z. The j locale contains application development utilities - useful when building applications, but typically not required to run an application. The z locale is the parent or root locale - when J searches for a name, it looks first in the specified locale or in the base locale if no locale were specified; if not found, it then looks in the z locale. Thus the z locale typically contains utilities that are made available to programs stored in any other locale.

You can use names to list the names that have been defined in these locales. For example, names in j:

names_j_ ''

ALPH         JDIR         PROJECT      PUBLIC

SOURCE       buildproject buildpublic  buildsource

edit         j_build3     j_builder    j_exist

j_getnames   j_getscripts...

Names in z:

names_z_ ''

CR           CRLF         EAV          FF

LF           PAV          TAB          WDBREAK

WDBUTTON     WDCANCEL     WDCLOSE      WDDDEADVISE

WDDDEEX      WDDDEPOKE...


Window Driver
2:  Window Driver

The names in the z locale beginning with the letters wd access the Window Driver, which allows J to communicate with the Windows operating system. Try the following examples (click OK or press Esc to exit):

wdinfo 'this is a windows message box'

wdselect >;:'blue green red purple brown'

ÚÄÂÄ¿

³1³3³

ÀÄÁÄÙ

The result of wdselect has 2 elements: the first is 1 if the user presses OK, and the second is the index of the selection.

The main Window Driver function is wd, which takes an argument of a character string of commands that is passed to the Window Driver. The following creates a window with a push button.

wd 'pc abc;cc pushme button;pshow;'

Once the window is shown, select the execution session by clicking on it with the mouse, or by pressing Alt-Tab. When you select the execution session, the window will disappear - it is still active but hidden by the execution session.

Query the active parent windows:

wd 'qp;'

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ¿

³*type  ³10 result³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´

³*parent³sysresult³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´

³*data  ³abc      ³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÙ

The *data item shows all active parent windows (in this case, only abc).

To close this window, enter:

wd 'pclose;'

Alternatively, to close all active windows, enter:

wdreset ''


Loading scripts
2:  Loading scripts

You load scripts to define functions and variables in the current session. Several scripts are included with the system. For example, the script files.js contains utilities to access DOS files. This script is not loaded by the standard profile, so initial references to these utilities result in a value error:

fread '\config.sys'

³value error

³      fread'\config.sys'

Note that the error message indicates the position where the error was found by inserting 4 spaces.

You can use load to load the files.js script file. Having done so, the file utilities are now available:

load 'files'

   fread '\config.sys'

device=c:\dos\setver.exe

device=c:\dos\ansi.sys

device=c:\dos\dblspace.sys

...

load determines the DOS filename to load by looking it up in filename tables created in the j locale. PUBLIC_j_ is one such table. Each row contains: short name, full DOS pathname, locale:

PUBLIC_j_

ÚÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿

³compare   ³c:\j\main\compare.js             ³z³

ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´

³convert   ³c:\j\main\convert.js             ³z³

ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´

³dates     ³c:\j\main\dates.js               ³z³

ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´

...

The utility scripts provides easy access to the filename tables. To list all short names, enter:

scripts ''

compare    convert    dates      dd         debug

dir        dll        files      fileutil   format

gnuplot    graph      jadelib    jadeutil...

For a verbose listing:

scripts 'v'

act        c:\j\packages\finance\act.js

compare    c:\j\main\compare.js               z

convert    c:\j\main\convert.js               z

...


Sample application 1
2:  Sample application 1

The file examples\data\sales.dat contains 12 months sales data for 50 agents. The file is in ASCII format, and therefore you can browse it using any text editor. The data is to be read in a format suitable for performing analyses, such as finding total sales for each agent, and displaying names and total sales.

Load the files and misc utility scripts by entering:

load 'files misc'

Since the data file may be referenced several times, it is helpful to give it a name:

FL=. 'examples\data\sales.dat'

You can view this file using the fview utility:

fview FL

Use the scrollbars to move around the file. To close fview, press Esc, or select Close from the screen menu button.

The first few rows and columns look like:

SYMONS        2,469   1,207     181   3,688...

DONOHOE      43,343   7,723  25,798  33,529...

MACDONALD    19,010  34,878  24,959  26,827...

...

To read files you can use the verbs 1!:1 or 1!:11. For example, to read the entire file:

1!:1 <FL

However, it is usually easier to use the file utilities. In this case, we would like to read the data into a matrix, with one row per agent. The verb fread with a left argument of  m returns the data as a matrix:

DAT=. 'm' fread FL

The shape of DAT is 50 rows by 132 columns:

$DAT

50 132

You can view this data using wdview (the same viewer used by fview):

wdview DAT

Each row of the data starts with the agents name, followed by 12 months sales data. Note that some of the entries are 0 (no sales), and some are negative (presumably sales returns).

Start by separating the names and sales. One way to do this is to take the required number of characters from each row. In this case, the names are up to 11 characters long, therefore we should take 11 characters from each row:

NAMES=. 11 {."1 DAT

Note the "1 (rank 1) is necessary, since we want to apply the take to each row. If you omitted the "1, you would get the the first 11 items of DAT, here, the first 11 rows. Try:

11 {.DAT

SYMONS        2,469   1,207     181   3,688...

DONOHOE      43,343   7,723  25,798  33,529...

MACDONALD    19,010  34,878  24,959  26,827...

...

Compare the following displays of  NAMES:

NAMES

wdview NAMES

list NAMES

Another way of isolating the names, would be to chop the data up into columns, and take the first column. The verb chop does this:

chop DAT

ÚÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄ...

³SYMONS     ³ 2,469³ 1,207³ ...

³DONOHOE    ³43,343³ 7,723³2...

³MACDONALD  ³19,010³34,878³2...

³KELLY      ³13,783³12,839³ ...

...

Therefore you could have retrieved the names by chopping the data into columns, and opening the first column:

>{.chop DAT

The sales data is the rest of DAT. Select this by dropping off the first 11 characters in each row:

SALES=. 11}."1 DAT

The sales data is in character format, and to perform analyses, we should convert this to numeric. In general, you use ". (do) to convert from character to numeric, however, in this case the data contains commas and minus signs (both of which are J verbs). The comma should be deleted, and the minus sign replaced with the negative sign.

To remove the comma, apply the without verb -. to each row. Assign this to a new noun NSALES:

NSALES=. SALES-."1 ','

To convert the minus sign, use the utility charsub:

NSALES=. '-_' charsub NSALES

Check that this has been done correctly:

wdview NSALES

NSALES is now in a format that can be converted to numbers:

NSALES=. ". NSALES

$NSALES

50 12

Note, it was unnecessary to use "1 with the ". verb in order to apply it to each row,  since ". is defined to be a rank 1 verb. Thus ". is the same as "."1.

NAMES and NSALES are now in a suitable format for analysis. Try:

•	view data sorted by names:

wdview DAT /: NAMES

•	determine total sales for each agent:

totalsales=. +/"1 NSALES

•	view data sorted by total sales (in decreasing order):

wdview DAT \: totalsales

•	view names and total sales sorted by total sales:

wdview (NAMES,.":,.totalsales) \: totalsales

•	display sales by month:

(>:i.12),.+/NSALES

 1 1110557

 2  893329

 3  776053

...


Sample application 2
2:  Sample application 2

The next example is a simple Windows dialog box that allows to you display text in various fonts.  To load the example, enter:

load 'examples\demo\fontdemo.js'

The source for this file (except for standard utilities) is given in file examples\demo\font.js. You can open this file as a script file, by entering:

open 'examples\demo\font.js'

You may wish to print this script file out first, for easy reference. You can use the Print command from the File menu to do so.

You can run the script file by selecting Run/Window from the menu, or equivalently, pressing Ctrl-W.

The script file defines a noun WPFONT, and several verbs. View WPFONT by changing to an execution window and entering its name:

WPFONT

fontdef -13 0 0 0 700 0 0 0 0 1 2 1 34 "MS Sans Serif";

pc font; pn "Font Demo";

xywh 10 8 150 8; cc s0 static;

cn "Enter your text here:";

xywh 10 20 200 90; cc c0 edit es_multiline ws_border; cfocus;

...

WPFONT contains a character string of the commands used to build the font dialog box.  For example, the command pc font creates a window called font; the pn "Font Demo" command sets the window name, which appears in the title of the window. To create the font dialog box, call wd with an argument of WPFONT.

The verb fontdemo runs the demo. Try:

fontdemo ''

Entering fontdemo by itself, displays its definition:

fontdemo

ÚÄÂÄÂÄÄÄÄÄÄÄÄÄ¿

³3³:³wd WPFONT³

³ ³ ³wdml 1   ³

ÀÄÁÄÁÄÄÄÄÄÄÄÄÄÙ

In this case, fontdemo is defined as a verb (the nameclass is 3), and has two sentences: the first sends the WPFONT command string to the Window Driver to build the font dialog box; the second invokes a standard message handler that takes cares of the responses from Windows (e.g. when the user presses a button).

When Windows sends a response, the message handler invokes the function font, which is defined as a simple case statement. If the user presses a button, it executes fnbutton; if the form is closed, it executes fnclose; otherwise, it does nothing.

fnbutton in turn is a simple case statement. If the button pressed was the Change Font button, it invokes fnfont, which calls up the Font Common Dialog Box. If the button pressed was the Close button, it executes fnclose; otherwise, it does nothing.

Finally, the fnclose verb closes the form by issuing the pclose command to Windows.

You can set up this example as a standalone program that can be run directly from the Program Manager. To do so, in Program Manager, select the File/New menu command. In the New Program Object dialog box, ensure that Program Item is checked, then press OK. In the Program Item Properties dialog box, enter the Command Line as follows:

c:\j2\jsm.exe examples\demo\fontdemo.js

In this case, we assume that J has been installed in the c:\j2 directory. Change the Command Line entry if need be.

Check the Run Minimized box, and then select OK. The new Program Item is created. Double click the icon to run the example.


Sample application 3
2:  Sample application 3

This last example demonstrates some of the utilities which are read into the j locale.

The demo reads a file of city data, containing the longitutude and latitude for several cities. A dialog box allows entry of a city name, after which the distances from that city to all other cities are calculated and displayed.

The data file is an ordinary ASCII file, which you can view as follows:

fview 'examples\data\cities.dat'

The demo was written using two source files, examples\demo\citycalc.js and examples\demo\citywp.js, being the calculations and the windows program parts of the demo. In general, most non-trivial systems will require more than one source file, so an immediate question is how to organize these source files so as to be able to load them easily.

The solution is to create a project file, in this case, examples\demo\cities.js, that when loaded, reads in the required files and sets up other definitions as needed.

First, load the project file. Note the left argument of j, which means that cities.js is loaded into the j locale:

'j' load 'examples\demo\cities.js'

Run the cities demo, by entering:

cities ''

Select a city, then press OK to view the distances.

Now view the cities.js file:

open 'examples\demo\cities.js'

The file contains the following:

require 'files'

'examples\demo' buildsource 0 : 0

citycalc

citywp

)

load 'citycalc citywp'

savecity=. 3 : 0

new=. 'examples\demo\citydemo.js'

src=. 'stdlib winlib files citycalc citywp'

new scriptmake src

'cities 0' fappends new

'done'

)

The statement require 'files' ensures that the files utilities are loaded.

Next the verb buildsource is called, with a left argument of the DOS pathname, and a right argument of  the two source file names, citycalc and citywp. This adds the two names to the filename table SOURCE in the j locale, which allows the two source files to be referenced by short name only. To check this, enter:

scripts ''

citycalc citywp

convert  dates    dd    debug    files    format  ...

This shows the new names in the filename list. Similarly, scripts 'v' will show their full DOS filenames.

Next the two source files are loaded.

Finally, a verb savecity is defined, which when run, will build a single script from the source files shown. This script will be named citydemo.js. Check this by entering:

savecity_j_ ''

done

Once the citydemo.js file is created, you can create a new Program Item for the demo. As in the previous example, create a new Program Item, this time setting the Command Line to be:

c:\j2\jsm.exe examples\demo\citydemo.js

Run the demo by double-clicking on the icon.


Chapter 3 Session Manager
3:  Session Manager

J for Windows combines the language interpreter with a user interface called the session manager. When you load J, you in fact load the session manager which in turn loads the language interpreter.

The session manager is a Windows multiple document interface (MDI) application,  which allows the use of several document windows at one time within the same session. The session manager has a header, a menu line, Toolbar and Status Bar lines (which may be turned off), and one or more document windows.

You use the session manager by working with the document windows. You can have as many of these windows open as you wish -  each window is attached to the same session. Only one window is active at a time.

There are two types of document window: execution windows and script windows:

•	An execution window allows sentences to be evaluated. When you type into the execution window and press Enter, the sentence you entered is executed, and the result is displayed below.

•	A script window allows sentences to be entered without being evaluated. Typically you use script windows to write your applications, then run the scripts by loading them into an execution window.

Both window types represent ordinary DOS files that can be saved during the session for use later on. Both are Windows edit controls, and you can use standard Windows commands to manipulate them, for example you can cut and paste between the windows and the Clipboard. You can move them about, resize them and minimize or maximize them.

The following shows a typical session with two document windows active:

In this example, there is an execution window 1.jx and a script window 1.js. A sentence defining a verb sumsquare has been entered into the script window, and this was run to create the definition in the session. A sentence using sumsquare has been entered into the execution window, with the result shown. This sentence is kept in an input log shown in the Toolbar window at the top.

There are however differences in the way J treats each window type, as follows:


Execution Windows
3:  Execution Windows

Execution windows are distinguished by their DOS file extension of .jx. When you load J, it creates a new execution window for the session. These windows are named 1.jx, 2.jx etc. By default, 1.jx is used, however, if a file of this name already exists, the next available unused name is picked.

You can type sentences into an execution window. When you press Enter, the system reads the line on which the cursor is positioned. If this line is at the foot of the execution window, it is executed and the result displayed below. Otherwise, the line is copied to the foot of the execution window - press Enter again to execute it.

There is always at least one execution window, but you can open as many as you wish - all are attached to the same session. This is useful for experimenting with some sentences - you could open a new execution window to do so, without writing to your original execution window. Open a new execution window by selecting New JX from the File menu.

The execution windows 1.jx, 2.jx and so on represent temporary files. That is, while the J session is active, if you have a window 2.jx, then there is a DOS file of that name (temp\2.jx), but when you close the window or terminate the J session, this file is deleted. If you want to save these files, you must explicitly save them with a name other than n.jx (for integer n); for example, mywork.jx.  If you do save an execution window in this way, the session manager treats it as a permanent file, and will save the file again when you close the window or terminate the session. You can load it in your next session - it will again be treated as a permanent file.

In no case are you prompted when closing an execution window - if it is temporary, the file is deleted; if it is permanent, the file is saved.

Note that you cannot close the original execution window.


Script Windows
3:  Script Windows

Script windows are typically distinguished by their DOS file extension of .js. Note that this extension is not required - in fact any file that does not have an extension of .jx is treated as a script window. However, it is good practice to use .js for any file intended as a J script.

When you create new script windows, the names used are 1.js, 2.js and so on. By default, 1.js is used, however if a file of this name already exists, the next available unused name is picked.

You can type sentences into a script window, but these are not evaluated. When you press Enter, the cursor is simply moved to the line below. To run a script window, you can either select an execution window and then enter a sentence to load the corresponding script file, or you can run it directly by selecting one of the options from the Run menu or pressing the equivalent Ctrl key:

•	Window	Ctrl+W        	- runs script window

•	Selection 	Ctrl+E	- runs selected text only

•	Line	Ctrl+R	- runs current line only

•	File	Ctrl+T	- runs a script file, selecting from the 	  File/Open dialog box

By default, these options are run silently - script output will only display if there is an error. To run the options with display on, hold down the Shift key when you click on the menu option, or press Shift-Ctrl-key.

When you select the Run/Window menu option, the session manager first saves the script as a DOS file (if changes have been made), then loads this file into the most recently active execution window. In some cases, you do not have to switch to the execution window at all - for example if you are developing a Windows application, then you can create and test the parent and child controls directly from the script window.

Note that the options in the Run menu load the script into the base locale. If your application requires that the script be loaded into a different locale, you must explicitly load it there. You can do this by switching to an execution session and entering an expression to load the script file into the required locale. You can also create a new Tools menu item to do this directly from the Tools menu. See the description in the section on session manager commands below.

You can open as many script windows as you wish - all are attached to the same session.

The script windows 1.js, 2.js and so on represent temporary files. That is, while the session is active, if you have a window 2.js then there is a DOS file of that name (temp\2.js), but when you close the window or terminate the session, you are prompted for the file to be deleted. You can save these files if you wish with the same name, but when you load them again, they are still treated as temporary and you will again be prompted to delete them when they are closed.

If you explicitly save them with a name other than n.js, for example, mywork.js, then the J session manager treats them as permanent files. If you close a permanent file or terminate the J session, you are prompted to save the file, if it has been changed. You are also prompted to save the file when you first save changes to a permanent script file that you have loaded in a session (which may be when you run it as a script).

Prompting for script windows is therefore as follows:

•	if the file is temporary (i.e. the name is n.js), you are prompted to delete the file when it is closed.

•	if the file is permanent (any name other than n.js) and you have made changes to it, you are prompted to save the file when it is closed, or when you first run it as a script.


Input Log
3:  Input Log

All sentences entered into execution windows are stored in an input log. You can recall entries by either pressing the Ctrl up-arrow and Ctrl down-arrow keys to cycle backwards and forwards through the log; or by selecting an entry from the Input Log combobox shown in the Toolbar at the top of the screen. Ctrl-D can be used to drop down this combobox.

When you recall an entry from the input log, it is read into the currently active execution window, or the most recently active execution window if the currently active window is a script window. Only one input log is maintained, even if there is  more than one execution window.

The input log does not store duplicate entries. If you recall an item from the middle of the log and execute it, the item now only appears at the end of the log - the entry in the middle of the log is deleted.


Menus
3:  Menus

The session manager includes a Menu bar which, for the most part, contains standard Windows menus:

The File menu is used for file access: open, close, save, delete, print and save .ini file. It also includes a list of the most recently accessed files. You can also exit the session by selecting: File, Exit.

The Edit menu provides standard edit capabilities. You can also use this menu to restore a window from file (overwriting changes made since the file was originally loaded), or to toggle a files Read Only status. A file marked Read Only may not be changed, until its Read Only status is explicitly removed.

The View menu allows you to show or hide the Toolbar and Status Bar lines, and to set the fonts for the session manager and printouts.

The Run menu allows you to run a script window, highlighted text, the current line, or a script file, either silently or, if the Shift key is held down, with output displayed in an execution window.

The Tools menu contains user-defined items. This menu can be customized as described in the section below on Session Manager Commands.

The Window menu allows standard window positioning (e.g. Tile, Cascade), and allows you to select the current active window. (You can also select the active window by pressing Ctrl-Tab to cycle through the active windows.)

The Help menu provides standard help facilities.


Toolbar
3:  Toolbar

The Toolbar is shown directly below the Menu bar, and includes a Find Log combobox and an Input Log combobox:

•	The Find Log combobox is used to enter search text, and maintains a list of most recently used search items. To search for text in the active window, select the combobox by either pressing Ctrl-F or clicking on it with the mouse, enter the text to be searched for, then press Ctrl-G to go to the next found text.

•	The Input Log combobox maintains a list of the most recently entered execution sentences. To re-enter a sentence, select from this combobox. Alternatively, you can cycle through the input log by pressing the Ctrl up-arrow and Ctrl down-arrow keys.

You cannot type into the edit field of the Input Log combobox.

You can hide the Toolbar by unchecking the Toolbar item in the View menu. Note that when you do so, the Find Log and Input Log comboboxes are not shown, unless explicitly selected with Ctrl-F or Ctrl-D.


Status Bar
3:  Status Bar

The Status Bar is shown at the foot of the screen. It displays a help message, followed by several status boxes:

•	Ready/Running shows whether the interpreter is waiting for input, or running the previous input.

•	CAPS shows the status of Caps Lock

•	NUM shows the status of Num Lock

•	The two numbers (e.g. 00011/0021) show the cursor position in the active window.

You can hide the Status Bar by unchecking the Status Bar item in the View menu.


View Menu
3:  View Menu

View menu items select various display options.

•	You can show or hide the Toobar or Status Bar

•	You can set the font for the J session and for the printer. Once set, you should select File/Save jsm.ini to save them permanently.

•	You can set the default display for J objects, as one or more of:

Linear Display

Box Display

Tree Display

These selections correspond to the verbs 5!:2, 5!:4 and 5!:5.

Selecting any of these menu items toggles the corresponding display on and off. If you are toggling a display on, then any other display that is on is switched off, except that if you hold down the Shift key when you toggle a display on, any other display that is on remains on.


Controlling the Session Manager
3:  Controlling the Session Manager

A J program can use the Window Driver (wd) to access some aspects of the Session Manager, such as the Tools menu and the document windows. The names of Window Driver commands specific to the session manager start with the letters sm.


Tools Menu
3:  Tools Menu

You can add your own menu items to the Tools menu using smsetcmd. These also define the function keys. Your menu items can be accessed either by selecting the item directly from the Tools menu, or by pressing the corresponding function key. Function keys F2-F9 are available for this purpose.

The form is:

wd 'smsetcmd num type name sentence;'

where:

•	num corresponds to the function key being defined.

•	type is one of :

0 = remove definition

1 = add definition, when invoked displays the sentence being run.

2 = add definition, when invoked does not display the sentence being run.

•	name is the text that appears on the Tools menu

•	sentence is the sentence that will be run when the menu item is invoked.

For example, the following will assign the sentence load 'laserjet' to the function key F2 and corresponding menu item LaserJet. The sentence will display when invoked:

wd 'smsetcmd 2 1 "LaserJet" "load ''laserjet''";'

When you next select the Tools menu, you will see the new menu item LaserJet. It is a good idea to define a HotKey letter and include the number of the corresponding function key in the menu item. If you do this, you can also right-justify the function key name by preceding it with a TAB. Thus, the above command could have been entered as:

wd 'smsetcmd 2 1 "&LaserJet',TAB,'F2" "load ''laserjet''";'

The menu item will now appear as:

LaserJet	F2

To remove this definition, enter:

wd 'smsetcmd 2 0;'


Document Windows
3:  Document Windows

There are several Window Driver commands to access the document windows. In most cases, you must first select the window that is to be the target of subsequent commands (this need not be the active window). To select a window, you actually select its DOS filename:

qsmact	file name of selected window

qsmall	file names of all windows

qsmcsize	size of current execution window

qsmout	file name of current execution window

qsmsize	size of selected window (pixels)

qsmwh	size of MDI client area (pixels)

smappend	appends text to selected window

smcascade	cascade windows

smclose 	close selected window

smfocus	activates selected window

smfont 	sets current font in selected window

smmove xywh 	move and size selected window (pixels)

smopen	opens selected DOS filename, if not already open

smread	reads data from selected window

smsave	saves selected window (if modified)

smscroll	n	scrolls selected window

smsel	selects window, by its filename

smshow param	shows selected window, with parameters from the set:

sw_hide            sw_maximize

sw_minimize        sw_restore

sw_show            sw_showmaximized

sw_showminimized   sw_showminnoactive

sw_showna          sw_shownoactivate

sw_shownormal

smssetcmd n t name sentence	modifies Tools menu

smtile	tile windows down

smtilea	tile windows across

smwrite	writes text to selected window

For example, the following will open file user\mywork.js for editing and make it the active window:

wd 'smsel "user\mywork.js";smopen;smfocus;'

Having opened the window, you could write some text (e.g. in the noun TXT) to it as follows:

wd 'smwrite "',TXT,'";'


Printing Commands
3:  Printing commands

Several Window Driver commands support printing. Their names all begin with smp:

smps 	invoke menu File/Print setup

smp	print selected window (select with smsel)

smpf file	as smp, but prints file

smpd	as smp with print dialog box

smpdf file	as smpf with print dialog box

smpv	as smp with print preview

smpvf file	as smpf with print preview

Print preview invokes the print dialog box when the Print button is selected.

A print file can contain printing commands. There are 3 print commands:

[print_command_init "header" "footer"]

[print_command_font mbfont information]

[print_command_page]

Print commands must appear exactly as shown. They must start at the start of a line and the ] must be the last character on the line. Whitespace is only allowed in the parameter area between the print_command_... and the ].

To be recognized as a print file, the first two lines of a file must be an init command and a font command.

The init command gives the header and footer text,  and the font command gives the font description for the header and footer and the initial font for the text. If the header or footer is empty ("") then it is not displayed. A &f is replaces by the filename and a &p is replaced by the page number. The page command forces a new page.

These commands allow simple reports with mixed fonts. Note that fonts cannot be mixed on a line.

Verbs wdprint and wdprintfile in script winutil.js support printing. Load this script, then try:

wdprint i.2 3 4 5

wdprintfile 'examples\data\printme.txt'


Chapter 4 J Programs
4:  J Programs

This chapter discusses several aspects of J programs, specifically:

•	Explicit Definition

•	Local and Global Names

•	Locales

•	Control Structures


Explicit Definition
4:  Explicit Definition

Explicit definition uses the colon conjunction : to create definitions from their character string representations.

This is the standard way of creating definitions in programming languages, but it is useful to note that, unlike most other languages, J definitions conform to the ordinary rules for the language, and therefore can be used in any expression. There is no special definition mode, and no need for an external compiler.

For example, the following creates a verb which adds 3 to twice its argument:

fn=. 3 : '3 + +: y.'

fn 2 3 5 7

7 9 13 17

The names x. and y. refer to the verbs left and right argument (they are local variables in the definition).

The verb need not be assigned a name:

10 + (3 : '3 + +: y.') 2 3 5 7

17 19 23 27

The left argument of the colon conjunction is the result nameclass, where 0=noun, 1=adverb, 2=conjunction, 3=verb (the same as the result of the nameclass verb 4!:0). You may find it helpful to name this argument and also the colon conjunction:

verb=. 3

define=. :

fn=. verb define '3 + +: y.'

The display elucidates the definition:

fn

ÚÄÂÄÂÄÄÄÄÄÄÄÄÄ¿

³3³:³3 + +: y.³

ÀÄÁÄÁÄÄÄÄÄÄÄÄÄÙ

The right argument of the colon conjunction may be a single character string, or a list of character strings either delimited by LF or given as a boxed list. If it is a list of character strings and one string begins with a colon, then this string separates the monadic and dyadic versions of the result (either of which may be empty). For example, to add a dyadic form to the above definition, in which the left argument is added to twice the right argument:

fn=. 3 : ('3 + +: y.';':';'x. + +: y.')

10 fn 2 3 5 7

14 16 20 24

fn

ÚÄÂÄÂÄÄÄÄÄÄÄÄÄÄ¿

³3³:³3 + +: y. ³

³ ³ ³:         ³

³ ³ ³x. + +: y.³

ÀÄÁÄÁÄÄÄÄÄÄÄÄÄÄÙ

Equivalently:

fn=. 3 : ('3 + +: y.',LF,':',LF,'x. + +: y.')

If the definition contains several lines, they are executed in order, except where control words are used (described later in this chapter).

To enter a definition containing several lines, it is convenient to use the script form of an explicit definition. If the right argument of the colon conjunction is 0, this means that the character representation of the definition is read from all lines entered after the current line up to but not including any line that begins with a right parenthesis. This form is typically used in scripts:

fn=. 3 : 0

3 + +: y.

:

x. + +: y.

)

This form of explicit definition may still be used in ordinary J expressions, for example it may form part of a larger definition:

newfn=. +/ @ (3 : 0) \

3 + +: y.

:

x. + +: y.

)

   newfn 2 3 5 7

7 16 29 46

newfn

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿

³ÚÄÄÄÄÄÂÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿³\³

³³ÚÄÂÄ¿³@³ÚÄÂÄÂÄÄÄÄÄÄÄÄÄÄ¿³³ ³

³³³+³/³³ ³³3³:³3 + +: y. ³³³ ³

³³ÀÄÁÄÙ³ ³³ ³ ³:         ³³³ ³

³³     ³ ³³ ³ ³x. + +: y.³³³ ³

³³     ³ ³ÀÄÁÄÁÄÄÄÄÄÄÄÄÄÄÙ³³ ³

³ÀÄÄÄÄÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ³ ³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ


Local and Global Names
4:  Local and Global Names

Names can be assigned using =. (local assignment) and =: (global assignment). These two assignments have different meanings only within an explicit definition, otherwise they are the same.

Within an explicit definition, a local assignment creates a name that is valid and visible only within that definition; it is not visible to any other explicit definition that it calls. A global assignment creates a name that is valid globally and that is visible globally, except when an explicit definition is running that has created a local definition with the same name, in which case only that local definition is visible.

For example, define nouns x and y; in this case, local assignment is used, but global assignment would be the same:

x=. y=. 2

Create a function by explicit definition which assigns a noun x locally, and adds the local value of x to the global value of y. The function then reassigns y globally and again adds the two values. The result is the two sums. On exit, the global value of x is unchanged:

f=. 3 : 0

x=. 7

r=. x+y

y=: 5

s=. x+y

r,s

)

f ''

9 12

x,y

2 5

It is important to understand the behaviour of local and global assignments within scripts. When you load a script using one of the script verbs 0!:0 etc., or tacit equivalents, then no explicit definition is being used, and local assignments are the same as global assignments. However, when you load a script using a verb that was defined explicitly, then local assignments in the script are local to that verb. This is a useful feature that in effect allows you to have local variables within a script. The J utilities that load scripts (load and require) both do so using explicit definitions; moreover they have no local definitions so there can be no conflict between the local names defined in a script, and in the verb that loads the script.


Locales
4:  Locales

Names are stored in one or more locales (namespaces), which allow you to partition the names in use. The main benefits are:

•	name conflicts are avoided when loading two applications at the same time.

•	commonly-used utility functions can be made available without their names cluttering up listings of work in progress.

Locales are created and deleted automatically - you create a locale by defining an object in it, and delete a locale by deleting all objects in it.

You can create any number of locales. There may only be one parent locale, and any number of child locales, for example:

Child locales: 	(base)  	j   	laserjet  	stats  	user

Parent locale: 	   z

The only difference between the parent and child locales is in how J searches for a name. If a name is referenced in a child locale and not found, J then searches for the name in the parent locale. If then found, the definition in the parent locale is used, as if it had been found in the child locale; if not found, no further search is made.

The base and z locales are treated specially:

The base locale

The base locale is the default locale, i.e. if no specific locale reference is made, names are created and referenced in this locale, for example:

x=. 1 2 3

defines x in the base locale (except where noted, these examples assume there is nothing on the stack). Typically, development work is done entirely in the base locale.

The base locale's name is actually empty. In the diagram above, it is shown as (base).

When you invoke a function in another locale, this temporarily switches the default locale from base to this locale; this is the only way of changing the default locale.

A key feature of the design is that the default locale is a child locale - and not the parent locale.

The z locale

The z locale is the single parent locale. It differs from child locales only in the way J searches for a name. For example, consider:

res=. format i.100

J will first search for format in the base locale, and if found, will execute it. Otherwise it searches for format in the z locale, and if found, executes it in the context of the base locale. In both cases, res will be defined in the base locale.

If format is only defined in the z locale, it will not appear in namelists of the base locale. Indeed, the main use for the z locale is used to store utilities that will be available to programs in any child locale, but whose names would not appear in namelists of those locales.

Note that in the above examples, no locale reference was used. Clearly, this would normally be the case when dealing with the base and z locales, but it is also typical of the definition as a whole - in practice, you rarely need to make locale references.

The standard profile loads several utilities into the z locale, for example, the utility nl:

nl_z_=: 4!:1

When you reference nl by itself (i.e. with no locale reference), J first looks for nl in the base locale, and not being found, uses the definition in the z locale. However, the function is executed in the base locale, returning names found in the base locale:

nl 3

ÚÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÂÄÄÄÄÄÄÄÄÄ¿

³plus³square³sum³sumsquare³

ÀÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÁÄÄÄÄÄÄÄÄÄÙ

You can reference nl in another locale, for example the j locale. As before, it is not found in the j locale, so J uses the definition in the z locale. However, the function is executed in the j locale, returning names found in the j locale:

   nl_j_ 3

ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÂ

³buildproject³buildpublic³buildsource³edit³...

ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÁ

As another example, you could define a function to read a script, then use it to load scripts into locales:

scriptread_z_=: 0!:0

scriptread_myfiles_ <'main\files.js'

Locale References

To specifically reference a name in a locale, you append to the name: underscore, locale name, underscore. For example calc_def_ is the name calc in the locale def (read as: calc in def); calc_z_ is therefore calc in z, and calc__ is calc in base.

You create a locale by creating objects in it. For example, assume the locale temp does not exist. Enter:

x_temp_=. 1 2 3

names_temp_ ''

x

The first sentence creates the locale temp and the name x in it. The second sentence executes the utility names  in the context of the temp locale (names formats namelists, and is read into the z locale with J's standard profile).

Locales have nameclass 6:

nl 6

ÚÂÄÄÄÂÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄ¿

³³def³j³laserjet³stats³temp³user³z³

ÀÁÄÄÄÁÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÙ

The utility clear takes a locale name as an argument, and erases all names in it:

clear 'temp'

nl 6

ÚÂÄÄÄÂÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÂÄ¿

³³def³j³laserjet³stats³user³z³

ÀÁÄÄÄÁÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÁÄÙ

A function calc_def_ is executed in the context of the locale def, i.e. it temporarily switches the default locale from base to def while the function is running. Therefore, names referenced by calc have locale def, unless their locale is specifically given. The following assigns global names LEN in locale def, and NDX in locale util:

calc_def_=. 3 : 0

LEN=: 10

NDX_util_=: 5

)

This is equivalent:

calc_def_=. 3 : 0

LEN_def_=: 10

NDX_util_=: 5

)

Using Locales

Now lets look at a typical example of using locales, and examine why locale names are typically not referenced by the user.

One of the packages supplied with J is a set of functions to support printing with a LaserJet. To load this system, you enter:

load 'laserjet'

This populates a locale laserjet with about 50 utility programs, and reads 5 cover functions into the z locale. These cover functions call corresponding functions defined in the laserjet locale, for example:

ljprint=. ljprint_laserjet_

In actual use, only the cover functions are invoked, and the user need not be aware that the real work is being done in the laserjet locale, or indeed that a large number of utility functions have been read in.

Now suppose some development work has to be done on the system. Would it not be inconvenient to have to keep referring to names in the laserjet locale with their full locale name, e.g. as ljprint_laserjet_? The answer is no, since all development work in J is done on the source script files, which are defined independently of the locales into which they may be read.

Finally, suppose you have set suspension on, and one of the laserjet functions crashes. If   you want to view local definitions in the suspended function, then while the function is suspended, all local names can be referenced without specifying the locale name, since invoking a function in the laserjet locale temporarily switches context to that locale.

Locales and script files

If your application uses more than one locale, we recommend you create separate script files for each locale, so that each script is only loaded into one locale. You could, if you wish, include definitions for more than one locale in a script, but this loses the modularity of the link between a script and a locale.


Control Words
4:  Control Words

The sentences in explicit definitions are normally executed in order. You can change the order in which sentences are executed by using various control words, such as if., else., elseif. and while.. Control words have meaning only within explicit definitions - they do not apply elsewhere.

An explicit definition consists of a list of sentences and control words. The control words group the sentences into blocks (which may be empty) and determine which blocks are executed. The control words and the sentences they apply to are the control structures.

The following is a typical example. A test is performed on the argument, and, if empty, a message is displayed and the function exited; otherwise execution continues:

fn=: 3 : 0

if. 0=#y. do.

  wdinfo 'argument is empty' return.

end.

...

)

Control Structures

The control words if., try., while. or whilst. begin control structures which must end with end.. They may be summarized as follows:

if. T do. B end.

if. T do. B else. B end.

if. T do. B elseif. T do. B elseif. T do. B ... end.

try. E catch. B end.

while. T do. B end.

whilst. T do. B. end.

Here, T, B and E are sentence blocks:

•	T is a test block - the block is executed, and the value of the test is 0 (false) if the first element of the result of the last sentence in the block is 0, otherwise it is 1 (true). If true, the block following do. is executed, otherwise execution continues past the do. block. The control words else. and elseif. are optional. Note that a test block may consist of more than one sentence.

•	B is any sentence block. It may itself contain control structures.

•	E is an errortest block - the block is executed and if an error occurs, the block following catch. is executed, otherwise execution continues past the catch. block.

Any of these sentence blocks may be empty. An empty T block has value true. An empty E block has no error.

In the while. control structure, the test T is performed, and if true, the block B is executed. This is repeated until T is false.

In the whilst. control structure, the block B is performed first, then the test T is performed, and if true, B is performed again. This is repeated until T is false. (A handy mnemonic is that st stands for skip test.)

In the try. catch. control structure, note that the catch. mechanism will not work if suspension has been set on (e.g. 13!:0 [1), since it is assumed that the user will want to suspend on the error. Also, a definition using adverse (::) will not invoke catch.; instead, the adverse definition will be executed.

Note that the result of any function is the result of the last sentence executed, excluding the sentences in any T block. In the following example, the last T block is true (the result of the last sentence executed in the T block is 1), so the function exits immediately. The result is 10, being the last sentence prior to the T block, not 20:

fn=: 3 : 0

10

if.

20

1

do. return. end.

30

)

fn ''

10

The function may be rewritten so as to return 20:

fn=: 3 : 0

10

if.

1

do. 20 return. end.

30

)

fn ''

20

Conditional control structures must begin with a control word, and must end with end.. They may be arbitrarily nested. You can use indentation and spacing to improve readability:

showdef=: 3 : 0

nc=. 4!:0 <y.

if. nc<0 do.

  if. nc=_1 do.

    wdinfo 'name not found' return.

  else.

    wdinfo 'invalid name' return.

  end.

end.

5!:2 <y.

)

Additional Control Words

The remaining control words are:

break.	exit from while. or whilst. control structure

continue.	return to T block in while. or whilst.  control structure

goto_name.	go to matching label

label_name.	target of goto

return.	exit function.

The goto is a family of control words. You must supply a name for the goto and matching label, for example: goto_next. and label_next.. Note goto can exit from a control structure:

countdown=: 3 : 0

out=. 1!:2&2

while. 1 do.

  if. y.=0 do. goto_fini. end.

  out y.=.<:y.

end.

label_fini.

'finished'

)

countdown 3

2

1

0

finished

The goto structure is included in the language for completeness - it is typically included in the control structures of other languages. However, it is not really needed, and programs making use of goto may be hard to read. For this reason, it is nearly always better to express your programs using the other control structures.


Chapter 5 Application Development
5:  Application Development

Building applications in J typically consists of creating one or more script files containing the application definitions, plus functions that will read in the script files and start the application.

The system provides several utility programs that can be included in your application, and a set of utilities that help you work with script files while creating the application. These utilities are all installed in subdirectory main of the J directory, and can be accessed with the standard profile file, profile.js. You can modify them as you wish, though we recommend you use them unchanged until you become familiar with them; and then if necessary, copy them to your own application directories before making changes.

You need not use the utilities provided, though you are strongly encouraged to do so. However, you can either load J with no definitions at all, or else create your own profile file to read in your own definitions.

The utilities in subdirectory main fall into 2 categories:

•	standard libraries - three files which contain core definitions. They should always be read in and can therefore be assumed to be available for other programs.

•	standard utilities - various other utilities,  which can be read in as needed.

This chapter describes the profile.js file and the standard libraries:

stdlib.js    	general purpose utilities, required for all applications. Read into the z locale

winlib.js	Windows utilities, required for any Windows application. Read into the z locale

jadelib.js	application development utilities, required only when developing  applications, and not for the final system. Read into the j locale.

You may also wish to read in other utility scripts. In particular, you will probably want to include winutil.js, which contains additional support for Windows applications, and jadeutil.js, which contains cover functions for jadelib that are read into the z locale, to allow jadelib functions to be called from the z locale. These scripts and various other utilities are described in the next chapter.


Profile.js
5:  Profile.js

The file specified in the Command Line of the J Program Item is read in when J is loaded. The standard file is profile.js, which is stored in the main J directory. The file, as installed, is as follows:

NB. standard j profile

NB. bootstrap script loader:

boot_z_=: 3 : '0!:0 <''main\'',y.'

NB. main libraries

NB. this section should not need modifying:

boot_z_ 'stdlib.js'

boot_z_ 'winlib.js'

boot_j_ 'jadelib.js'

NB. user definitions - modify as required:

boot_z_ 'winutil.js'

boot_z_ 'jadeutil.js'

boot_z_ 'myutil.js'

NB. delete bootstrap:

4!:55 <'boot_z_'

NB. set box display:

9!:3 [ 2

This script does the following:

•	defines a verb that can read in scripts from the main directory.

•	reads in the stdlib.js and winlib.js scripts into the z locale; and the jadelib.js script into the j locale.

•	reads in utility scripts winutil.js, jadeutil.js and myutil.js into the z locale.

•	deletes the bootstrap definition

•	sets output display to the boxed form.


Stdlib.js
5:  Stdlib.js

Stdlib.js contains various general-purpose definitions that can be assumed available by any other script. It should be loaded into the z locale.

Nouns:

TAB	tab

LF        	 	linefeed

FF         	formfeed

CR        	carriage return

CRLF       	CRLF pair

PAV        	ASCII 254

EAV        	ASCII 255

Verbs:

boxopen

Box argument if open. This permits verbs that require boxed arguments to accept open arguments. For example, you could define:

script=: 0!:0 @ boxopen

then use either:

script 'work.js'

or

script <'work.js'

clear

Clear all names in a locale The argument is the locale name, which if empty defaults to the base locale. For example:

clear ''    	NB. clear base locale

clear 'tools'   	NB. clear tools locale

clearall

Clear all locales. An argument is required, but ignored.

clearall ''      	NB. clear all definitions

cutopen

Cuts argument if open.

Form:  opt cutopen data

If opt is given, it is the delimiters used to cut the right argument. Otherwise the delimiter used is LF if contained in the right argument, otherwise blank. This provides an easy way of allowing a verb that accepts a boxed list to be given an open list instead. For example:

readfiles=: 1!:1 @ cutopen

readfiles '\autoexec.bat \config.sys profile.js'

datatype

Returns noun datatype, for example:

datatype 1 2 3j4

ÚÄÄÄÄÄÄÄ¿

³complex³

ÀÄÄÄÄÄÄÄÙ

datatype &.> 1;2;'three'

ÚÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ¿

³ÚÄÄÄÄÄÄÄ¿³ÚÄÄÄÄÄÄÄ¿³ÚÄÄÄÄÄÄÄ¿³

³³boolean³³³integer³³³literal³³

³ÀÄÄÄÄÄÄÄÙ³ÀÄÄÄÄÄÄÄÙ³ÀÄÄÄÄÄÄÄÙ³

ÀÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÙ

do

Do (defined as ".). This provides a name for the ". verb. In particular, it provides an easy way to execute statements in another locale. For example, to execute 4!:1 in the j locale:

do_j_ '4!:1 [ 3'

Read as:  do in j, the expression 4!:1 [ 3

empty

Returns an empty result. All verbs return a result, but this result is sometimes not used. empty returns an empty matrix that will not display, and can therefore be used as the last statement in a function for which no display result is wanted. For example:

setfont=: wd bind 'smfont;'

setfont ''	NB. displays unwanted result

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ¿

³*type  ³ 2 nowait³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´

³*parent³sysnowait³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÙ

setfont=: [: empty wd bind 'smfont;'

setfont ''	NB. empty result

erase

Erase names. For example:

erase 'data read set'

1 1 1

a_t_=: b_t_=:  123

   names_t_ ''

a b

   erase_t_ 'a'

1

   names_t_ ''

b

list

List data formatted in columns.

Form:  [width] list data

The right argument is a boxed or numeric list; or a character vector delimited by CR, LF, CRLF or ' '; or a character matrix. The result is formatted to the width given in the left argument, which defaults to the output screenwidth. For example:

40 list i.35

0  1  2  3  4  5  6  7  8  9  10 11 12

13 14 15 16 17 18 19 20 21 22 23 24 25

26 27 28 29 30 31 32 33 34

names

Returns a formatted namelist. The argument is one or more nameclasses, if empty defaults to 0 1 2 3. The optional left argument is a starting letter. For example:

names_j_ 0	NB. nouns in j locale

ALPH       JDIR       MYPROJECTS PROJECT

PUBLIC     SOURCE

'w' names_z_ 3	NB. verbs in z locale beginning w

wd          wdclipread  wdclipwrite wdctext...

wddata      wde         wdg         wdinfo...

wdmltest    wdreset...

nc

Nameclass   	- name for 4!:0

nl

Namelist	- name for 4!:1

The nameclasses used by nc and nl are:

_2	invalid name

_1	undefined (but a valid name)

 	 0	noun

 1	adverb

 2	conjunction

 3	verb

 6	locale

toCR

Converts character strings to be delimited by CR. Specifically, a single CR is left unchanged; a single LF is converted to CR; and a CRLF pair is converted to a single CR.

toLF

Converts character strings to be delimited by LF. Specifically, a single CR is converted to LF, a single LF is left unchanged; and a CRLF pair is converted to a single LF.

toCRLF

Converts character strings to be delimited by CRLF. Specifically, a single CR is converted to CRLF; a single LF is converted to CRLF; and a CRLF pair is left unchanged.

toCR, toLF and toCRLF convert characters strings to use a specific delimiter. Typically, DOS text files have lines ending in the CRLF pair, while J expects text variables to have lines ending in LF. Other programs may require lines ending in CR only. For example, to read in a text file:

toLF 1!:1 <'myfile.dat'

type

Returns object type, for example:

type 'TAB';'toCR'

ÚÄÄÄÄÂÄÄÄÄ¿

³noun³verb³

ÀÄÄÄÄÁÄÄÄÄÙ

Conjunctions:

bind

Binds argument to a monadic verb. This allows you to create a verb that calls another verb with a specific argument. The new verb ignores its argument.  For example, if:

finished=: wdinfo bind 'finished'

then:

finished ''

is equivalent to :

wdinfo 'finished'

casetable

Builds case statements. The left argument is a gerund and the right argument a noun. The resulting verb is a case statement. It looks up the noun in its argument, and executes the corresponding item from the gerund. This is frequently used in Windows programming, for example the following verb executes one of the verbs fbutton, fmenu, fclose depending on whether the corresponding nouns were returned by Windows:

t=. WDBUTTON,WDMENU,WDCLOSE

fbutton`fmenu`fclose casetable t


Winlib.js
5:  Winlib.js

Winlib.js contains various definitions that can be assumed available by any script making use of the Window Driver. It should be loaded into the z locale.

Nouns:

Names WDFKEY, WDMENU and so on are given for all possible *types and standard *ids that can be returned by the Window Driver, for example:

WDFKEY=:   	,:'*type';' 3 fkey'

WDMENU=:   	,:'*type';' 4 menu'

WDBUTTON=: 	,:'*type';' 5 button'

View the file for a complete list. For example, to check if the user pressed a function key, perform the following lookup on the result of a wait command:

res=. wd 'wait;'

if_fkey=. WDFKEY e. res

Verbs:

wd

Main windows driver - name for 11!:0

wdclipread

Read clipboard (an argument is required but ignored).

wdclipwrite

Writes character data to the clipboard. Any linefeeds are converted to the CRLF pair. The result is the number of characters written. For example:

$dat=. 'Lockstock',LF,'Barrel'

16

   wdclipwrite dat

17

   wdclipread ''

Lockstock

Barrel

Note, if you are using the clipboard to export numeric or boxed data to another application, you may want to use the clipfmt utility in format.js to format the data in a standard format recognized by most other applications, before writing to the clipboard.

wdctext

Build ctext expression. This utililty is helpful when writing text to an edit or listbox. Suppose TXT is the text to be written, then the following are equivalent:

'ctext ',EAV,TXT,EAV,';'

wdctext TXT

wddata

Windows driver returning *data item only. This is a cover function for 11!:0 that only returns the *data item of the Windows result. The following are equivalent:

'*data' wdg wd 'qm;'

wddata 'qm;'

wde

wd with error message. This calls the windows driver 11!:0, and returns an empty result. However, if the result from windows contains an error, the error message is displayed.

This function is particularly useful when developing Windows applications, and can be used instead of wd. In particular, it is often the case that wd is called, but the result is not required, and therefore not examined. Using wde enables you to track any errors quickly. For example, you might create a window as follows:

mywin=: 3 : 0

wde 'pc MyForm;'

wde 'xywh 10 10 50 12;cc OK button;'

wde 'pas 10 10;pcenter;pcloseok;pshow;'

wd 'wait;'

)

In this case, wde is used to create the window; wd sends the wait command and its result is the result of the function.

wdinfo

Information message box. The argument is either a character string of the message text, or a boxed list of 2 character strings, title and message text. The message is displayed in the message common dialog box. For example, try:

wdinfo 'title';'message text'

wdg

Get item from result of wd. The right argument is a result from the Window Driver. The left argument is the item required. For example:

wd 'qm;'

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿

³*type  ³10 result   ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´

³*parent³sysresult   ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´

³*data  ³640 480 8 16³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ

'*parent' wdg wd 'qm;'

sysresult

wdml

Standard message loop handler. This function can be used to handle the result from a wait command. The argument is the number of parent windows that were created by the calling function.  See the description in Chapter 7 - Window Driver.

wdreset

Resets the Window Driver. An argument is required but is ignored:

wdreset ''

wdselect

Windows selection box. Select rows of a character matrix using a windows list box.

Form: 	opt wdselect [title;] matrix

The right argument is either a character matrix, or a boxed list: title;character matrix. If the argument is empty, the list box is closed.

The left argument is optional, of up to 3 elements (each default 0). The second and third options are only referenced when the box is created:

0  	index of initial selection

 	1	0=single selection, 1=multiple selection

 	2	0=close on exit, 1=leave open if selection made

The result is a 2 item boxed list:

 	0 	0=cancel, 1=accept

 	1 	indices of selections

wdview

Windows text viewer, using an edit control.

Form:  [name] wdview [header;] text

The right argument is either character text, or a boxed list: header;character text. The optional left argument is the window name.

wdwait

Issues a wait command. An argument is required but ignored. The result is the response from Windows.


Jadelib.js
5:  Jadelib.js

Jadelib.js contains definitions that assist in developing applications. It provides various ways of accessing script files, utilities to create a single script from several scripts, and an editor. It is loaded by the standard profile, but should not be required in completed applications.

All jadelib definitions are created in the j locale. In general, you can use this locale to store any definitions specific to your application development.

There are two companion scripts:

•	scripts.js defines filename tables, and is loaded whenever jadelib.js is loaded; you can edit this file to include your own file names

•	jadeutil.js contains cover functions for the most commonly used jade utilities, and is read into the z locale by the standard profile.

Filename tables

Jadelib creates filename tables in the j locale: PUBLIC, PROJECT and SOURCE. These filename tables are defined separately for convenience but, for the most part, are treated by the jadelib utilities as if they were a single table.

•	PUBLIC contains names of utility scripts, to which you would often need access.

•	PROJECT contains names of project scripts, that would typically be loaded only when you were working on a specific project.

•	SOURCE contains names defined by the project files you have loaded in your session.

PUBLIC and PROJECT are both defined in file scripts.js. SOURCE is defined by the verb buildsource, typically used in project files. These tables:

•	allow scripts to be accessed using a short name, e.g. load 'graph' instead of load 'packages\vbx\graph.js'.

•	specify locales into which the scripts are loaded, e.g. load 'files' loads the files.js script into the z locale.

•	provide lists of script files that can be used under program control.

The filename tables are 3-column matrices with one row per file. Each row contains: short name; full DOS pathname; locale. If the locale is empty, the base locale is assumed. The last column of the PROJECTS table is always j.

The following are typical entries:

ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿

³files ³c:\j2\main\files.js        ³z³

ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´

³format³c:\j2\main\format.js       ³z³

ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´

³graph ³c:\j2\packages\vbx\graph.js³ ³

ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ

The following utilities reference these filename tables. They are defined in the j locale, but equivalent functions are made available in the z locale if you load the jadeutil.js script. Note that the utilities which load in scripts are written using explicit definition, and therefore respect local and global definitions. For example, if a script contains definitions:

a=. 1 2 3

b=: 10 20

then a is defined locally, and is available only while the script is being loaded; b is a global definition.

load

Loads one or more scripts.

Form:  [locale] load scriptnames

scriptnames is a list of one or more scripts, and is given as a character or boxed list. locale is optional - if given, it specifies the locale into which the scripts are read.

load looks up scriptnames in the filename tables. If found, the full DOS pathname is used, and if the optional locale were not given, the locale specified in the filename tables is used. For names not found, load assumes the script names given are the full DOS pathnames. For example, assuming the filename tables are defined as originally installed, then:

load 'format graph user\apps\print.js'

will load main\format.js into the z locale, packages\vbx\graph.js into the base locale, and user\apps\print.js file into the base locale.

open

Opens one or more scripts as script windows.

Form: open scriptnames

The argument is the same as for load. For example:

open 'files format'

require

Loads one or more scripts. The syntax is identical to load. However, if the scripts have been loaded already, it does not reload them, thus reducing the time needed to load scripts.

save

This builds a single script file from the current active definitions.

Form:	newfile save locales

locales 	is a boxed list of locale names. If empty, defaults to all.

newfile 	is the new script file name

For example:

Save definitions in all locales to file:

'myapp.js' save ''

Save definitions in base,  z and util locales to file:

'myapp.js' save '';'z';'util'

scripts

Provides access to the filename tables. To list the filename tables (in order SOURCE, PUBLIC, PROJECT):

scripts''

convert  dates    dd       debug    dll

files    format   graph    jadelib  jadeutil

jfiles   kfiles   laserjet...

For a verbose listing, including the full DOS filenames and locales:

   scripts 'v'

convert   \j2\system\convert.js     z

dates     \j2\system\dates.js       z

...


Project Files
5:  Project Files

A project file is an ordinary script file that is typically used to load and build your application. The idea is that to access a specific application, you need only load the corresponding project file, which should in turn load the required script files. It usually only makes sense to use a project file for applications written using more than one script file.

Project files should always be loaded into the j locale. It can contain any definitions you wish, but would typically include:

•	script filenames that would be added to the SOURCE filename table

•	commands to load the source scripts

•	a verb to build a single script that contains the completed application

The following is a typical example:

NB. Pform project file

PATH=: 'c:\j2\apps\pform\'

PATH buildsource=: 0 : 0

pfinit

pfcalc

pfprint

)

require 'act convert files'

load 'pfinit pfcalc pfprint'

j=. 'stdlib act convert files'

SAVEPFORM=: j,' pfinit pfcalc pfprint'

NB. save single script file for application:

pfsave=: 3 : 0

new=. PATH,'pfexec.exj'

new scriptmake SAVEPFORM

)

Names in a project file can be chosen at will, except only that you should avoid overwriting existing definitions in the j locale.

Two utilities used in project files are buildsource and scriptmake:

buildsource

This is used to add file names to the SOURCE filename table.

Form: path buildsource filenames

path is the DOS directory path

filenames is a character string, with rows delimited by LF, typically built using 0 : 0. Each row contains a file definition, consisting of a short name for the file, optionally a full name (if different from the short name), and optionally a locale.

For example:

'\j2\apps\work' buildsource 0 : 0

data

format fmt

print print util

)

builds the following entries in SOURCE:

ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄ¿

³data  ³\j2\apps\work\data.js ³    ³

ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄ´

³format³\j2\apps\work\fmt.js  ³    ³

ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄ´

³print ³\j2\apps\work\print.js³util³

ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÙ

scriptmake

This builds a single script file from one or more source script files.

Form:	newfile scriptmake source

source 	is an open or boxed list of one or more source file names

newfile 	is the new script file name

For example:

'myapp.js' scriptmake 'stdlib winlib user\mywork.js'


Jadelib editor
5:  Jadelib editor

The editor is defined in the j locale and also in the z locale if the script jadeutil.js is loaded. It provides a convenient way of accessing a single definition by name.

Form: 	edit name

name is any name that is defined in the session. The editor looks it up in the list of script files that have been loaded so far. If found, it reads in the script file and searches for any line that begins with a global definition for the name, that is, a line beginning:

name =:    ....

(Blanks between name and =: are ignored.)

If found, the script file is opened for editing, and scrolled down so that the name is shown at the top of the screen. For example, try:

edit 'list'

The script stdlib.js is opened, and scrolled to:

list=: 3 : 0

w=. {.wcsize''

w list y.

...

If the name is not found, it is assumed to be the name of a script file, which is then opened.


Chapter 6 Standard Utilities
6:  Standard Utilities

In addition to the standard libraries stdlib.js, winlib.js and jadelib.js, the subdirectory main contains several scripts of utilities:

compare.js	comparison programs

convert.js	various conversions

dates.js	time and date handling

dd.js	names for Data Driver verbs

debug.js	names for debug verbs

dir.js	DOS directory utilities

dll.js	names for DLL verbs

files.js	DOS file access

format.js	formatting

jadeutil.js	cover functions for jadelib

misc.js	miscellaneous utilities

numeric.js 	numeric functions

trig.js 	trigonometric functions

winutil.js	windows utilities

Each of these files is named in PUBLIC_j_, so can be loaded by name only (without the .js extension), for example, to load the files.js script, enter:

load 'files'

The subdirectory main also contains four other scripts, makerel.js, myutil.js, primitiv.js and xenos.js, here briefly described:

•	makerel.js is used to build a runtime system. See Chapter 14 for details.

•	myutil.js is called by the standard profile. You can modify this to load your own routines on start up (without having to modify profile.js). For example, to load the dates and files scripts automatically on start up, modify myutil.js to include the line:

load 'dates files'

•	primitiv.js contains names for J functions, and xenos.js contains names for external conjunctions. In general, we do not recommend you load these scripts, indeed the names used may conflict with names in other utility script files. However, it may be appropriate for users who do not need the standard utility scripts, but instead will load J only with these definitions.


Compare
6:  Compare

The script compare.js contains comparison programs.

compare

Compare character data, returning list of differences. Arguments may be character strings with lines delimited by LF, or character matrices (trailing blanks are ignored). The result shows lines not matched, in the form:

n [l] text

where:

n    	=  0=left argument, 1=right argument

[l]   	=  line number

text  	=  text on line

For example:

a=. >;:'one two three four five'

b=. >;:'one three four five six'

a;b

ÚÄÄÄÄÄÂÄÄÄÄÄ¿

³one  ³one  ³

³two  ³three³

³three³four ³

³four ³five ³

³five ³six  ³

ÀÄÄÄÄÄÁÄÄÄÄÄÙ

a compare b

0 [1] two

1 [4] six

fcompare

Compare DOS files, returning list of differences. This calls the compare function to compare the text in both files. This works best with text (i.e. readable files). For example, if you have an earlier version of your system in the \jbak subdirectory, then try:

fcompare 'main\myutil.js \jbak\main\myutil.js'


Convert
6:  Convert

The script convert.js contains various conversion utilities:

av

Convert between characters and ASCII character indices. For example:

av 'strachan'

115 116 114 97 99 104 97 110

av av 'strachan'

strachan

detab

Remove tabs from a character string.  The optional left argument is tab width, default 4.  For example:

8 detab 'one',TAB,'two',TAB,'three'

one     two     three

dfh

Convert to decimal from hex. See also hfd. For example:

dfh _4[\'89ABCDEF'

35243 52719

hex

Adverb to modify function to behave in hex mode. For example:

'AB' + hex '1234'

12DF

hfd

Convert to hex from decimal. See also dfh. For example:

hfd 15 16 255 256

00F

010

0FF

100

quote

Return character argument enclosed in quotes, with any quotes in argument doubled. For example:

quote 'Pete''s Place'

'Pete''s Place'

tolower

Convert character argument to lowercase.  For example:

tolower 'Sir Richard'

sir richard

toupper

Convert character argument to uppercase. For example:

toupper 'Sir Richard'

SIR RICHARD

vfm

Convert to a vector from a character matrix. Rows are separated by LF, and any trailing blanks deleted. For example:

vfm names=: >;:'tom dick harry'

tom

dick

harry

   a.i.vfm names

116 111 109 10 100 105 99 107 10 104 97 114 114 121


Dates
6:  Dates

The utilities in script dates.js provide calculations on dates.

calendar

Returns a calendar as a boxed list of months.

Form:	calendar year [,months]

The argument is one or more numbers: year, months. If no months are given, it defaults to all months. For example:

calendar 1994 9 10

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³         Sep         ³         Oct         ³

³ Su Mo Tu We Th Fr Sa³ Su Mo Tu We Th Fr Sa³

³              1  2  3³                    1³

³  4  5  6  7  8  9 10³  2  3  4  5  6  7  8³

³ 11 12 13 14 15 16 17³  9 10 11 12 13 14 15³

³ 18 19 20 21 22 23 24³ 16 17 18 19 20 21 22³

³ 25 26 27 28 29 30   ³ 23 24 25 26 27 28 29³

³                     ³ 30 31               ³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

todate

Converts day numbers to dates. Day numbers start at 0 for 1 January 1800. Inverse of todayno.

Form:	[opt] todate daynumbers

opt is optional. If given:

0 	each date has the form:	yyyy mm dd     (default)

1          	each date has the form:	yyyymmdd

For example:

todate 0 1 2 3 + todayno 1992 2 27

1992 2 27

1992 2 28

1992 2 29

1992 3  1

todayno

Converts dates to day numbers. Day numbers start at 0 for 1 January 1800. Inverse of todate.

Form:	[opt] todate dates

opt is optional. If given:

0 	dates are in the form:	yyyy mm dd     (default)

1          	date are in the form:	yyyymmdd

For example:

1 todayno 19940523 19940911 19941231

70999 71110 71221

Note that the conversion between dates and day numbers is exact, and therefore todate and todayno provide a means of performing exact date arithmetic. For example, the following calculates the duration in years between 1 Oct 1962 and 23 May 1994:

365.25%~-/1 todayno 19940523 19621001

31.6413

tstamp

Formats a timestamp given as yyyy mm dd hh mm ss (e.g. as in result of 6!:0). Fractional seconds are ignored. For example:

tstamp 6!:0 ''

 23 May 94 11:18:42

valdate

Validates dates - returns 1 if date is valid. For example:

valdate 1996 2 28, 1996 2 29,: 1996 2 30

1 1 0


DD
6:  DD

The utilities in script dd.js provide names for the ODBC Data Divers. See chapter 11 on ODBC for details.

ddcnm	column names selected by ddsel

ddcol	column names in the table

ddcom	commit transaction

ddcon	connect to data source identified by ODBC source name

dddis	disconnect from data source

ddend	close statement handle

dderr	error info on last command (name, source, warning, message)

ddfet	fetch next record from selected data

ddsel	prepare and execute sql selection statement

ddsql	prepare, execute, and end sql statement

ddsrc	data source names available from ODBC manager

ddrbk	rollback transaction

ddtbl	selection handle for tables in data source

ddtrn	begin transaction


Dir
6:  Dir

The script dir.js contains DOS directory utilities.

dir

Returns the DOS directory in various formats. Subdirectories are shown first.

Form: 	[opt] dir dirname

dirname  = dos file specification,   if empty, defaults to *.*

opt is optional:

   	- if empty, defaults to 'n'

   	- if character, returns a formatted directory,

       	where opt is the sort option:

         	d=by date

         	n=by name

         	s=by size

   	- if numeric, there are 1 or 2 elements

         	0   	0= list short names

               	1= boxed list of full pathnames

               	2= full directory list

         	1	0= filenames only (default)

               	1= include subdirectories

For example:

dir'main'

compare.js      2671 30-Dec-94 13:06:34

convert.js      1481 25-Nov-94 14:46:08

dates.js        2501 14-Dec-94 10:11:24

...

1 dir 'main'

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÂ...

³main\compare.js³main\convert.js³main\dates.js³...

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÁ...

dircompare

Compare two DOS directories. For example, comparing with an earlier version of the J system in \jbak:

dircompare 'main \jbak\main'

comparing  main\  and  \jbak\main\

not in  \jbak\main\:

compare.js dll.js     dir.js

not in  main\:

winlib.bak

not same in both:

jadeutil.js xenos.js    convert.js...

dirs

Browse DOS directory in various formats. The browser allows files to be viewed, opened (in a script window), or run. For example:

dirs'main'

dirss

String search through DOS directory. For example:

'numeric' dirss 'main\*.js'

main\dir.js (1)

ize  NB.    - if numeric, there are 1 or 2 element

main\format.js (4)

          format numeric matrix, various options

t         simple numeric formatter  NB. ruler

NB.   NB. nums = numeric vector or matrix or boxed

simple format of numeric vector or matrix in reada

main\numeric.js (1)

             NB. numeric utilities  NB.   NB.  bas

...

dirtree

Return DOS directory tree. For example:

>{."1 dirtree 'packages'

packages\color\colortab.js

packages\color\color.txt

packages\color\color.js

packages\files\dbase.js

...


Debug
6:  Debug

The utilities in script debug.js provide names for the debug verbs:

dbjmp

jump to line number given in argument

dbnxt

run next line (the argument is ignored)

dbr

reset stack and disable (0) or enable (1) suspension

dbret

exit and return argument

dbrun

run current line again (the argument is ignored)

dbs

display stack (the argument is ignored)

dbsq

stop query (the argument is ignored)

dbss

stop set. For example:

dbss 'fn 0'   	stop fn on monadic line 0

dbss 'fn :2'  	stop fn on dyadic line 2

dbss 'fn 0 2;1'	stop fn on monadic lines 0 2, on dyadic line 1

dbss 'fn *:*' 	stop all lines of fn

dbss '* 0:0'	stop all names on monadic 0 and dyadic 0

dbss '* *:*' 	stop all names, all lines


DLL
6:  DLL

The functions in script dll.js support calling procedures in Dynamic Link Libraries (DLLs). For further information, see Chapter 12.

Names for the 15!: functions:

cd	15!:0	call DLL procedure

memr 	15!:1	memory read

memw 	15!:2	memory write

mema 	15!:3	memory allocate

memf 	15!:4	memory free

Names for the 3!: conversion functions:

ic 	3!:4	convert integer/character

fc 	3!:5	convert float/character

Bitwise operations:

AND	bitwise and

OR	bitwise or

XOR	bitwise exclusive or

For example:

OR 1 2 4

7

7 AND 13

5


Files
6:  Files

The utilities in script files.js simplify access to DOS files. For these utilities:

•	Where a file name is required as an argument, it should be a single name given either as an open or boxed character string, or as a file handle as in the following:

fread '\config.sys'

fread <'\config.sys'

fread 270802

•	Verbs that read files take a right argument of the file name only to read the entire file, or a file name linked with 2 numbers, the starting position and the size of the read. The starting position may be negative, and if so is determined by counting backwards from the end of the file.

•	Verbs that write to a file return a numeric result of the number of characters written, or a character error message.

•	String verbs, freads, fappends and fwrites, convert text strings between DOS and J formats. DOS text strings may be delimited by the CRLF pair, or by isolated CR or LF characters. J text strings are assumed delimited by the LF character alone. When converting J text strings to DOS format, the LF characters are replaced by CRLF.

fappend

Append character text to file. The text is first ravelled. The file is created if necessary. Returns number of characters written, or an error message.

Form: 	 text fappend filename

For example:

  	'chatham' fappend 'newfile.txt'

7

fappends

Append character text to file.  The text is first ravelled into a vector with each row terminated by the CRLF pair. Any single LF or CR characters in the text are converted into the CRLF pair. The file is created if necessary. Returns number of characters written, or an error message.

Form:	fappends filename

For example:

abc' fappends 'newfile.txt'

5

a.i. fread 'newfile.txt';_5 5

97 98 99 13 10

fdir

File directory verb. For example:

fdir 'main\s*.js'

ÚÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÂÄÄÄÂÄÄÄÄÄÄ¿

³scripts.js³1994 8 1 18 49 26³1376³rw-³-----a³

ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄ´

³stdlib.js ³1994 8 3 15 14 6 ³4690³rw-³-----a³

ÀÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÁÄÄÄÄÄÄÙ

ferase

Erases a file, returning 1 if successful, otherwise an error message.

ferase '\j2\mywork.tmp'

1

fexist

Returns 1 if the file exists, otherwise 0. For example:

fexist '\config.sys'

1

fexist '\config.yss'

0

fread

Reads characters from a file.

Form:  [opt] fread filename [;start, size]

The right argument is a filename, optionally linked with the starting position of the read, and the size of the read. If size is not given, the rest of the file is read.

The left argument is optional.  If not given, the characters read are returned unchanged, otherwise, if opt is:

b	return result as boxed list

m        	return result as a matrix

s 	convert CR or CRLF to LF  (same as freads)

For example:

fread '\config.sys';0 50

device=c:\dos\setver.exe

device=c:\dos\ansi.sys

   'b' fread '\config.sys';0 50

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³device=c:\dos\setver.exe³device=c:\dos\ansi.sys³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

   $'m' fread '\config.sys';0 50

2 24

freadr

Read records from a file which contains fixed length records, delimited by  CR, LF or the CRLF pair. The result is a matrix with one record per row.

Form:	 freadr filename [;start,size]

The right argument is a filename, optionally linked with the starting record to be read, and the number of records to be read. If size is not given, the rest of the file is read. For example:

(3 ": ,.10*i.30) fwrites 'mydata.dat'

150

freadr 'mydata.dat';20 3

200

210

220

freads

Reads characters from file, converting any CRLF pairs or isolated CR characters into LF characters. Equivalent to 's'&fread.

Form: 	freads filename[start,size]

The right argument is defined as for fread. For example:

$freads '\config.sys';0 50

48

freplace

Replace characters in file.

Form: 	dat freplace filename;start

(10$'a') fwrite 't1.dat'

10

'XYZ' freplace 't1.dat';3

3

fread 't1.dat'

aaaXYZaaaa

fsize

Returns size of file. For example:

fsize '\config.sys'

189

fview

View file using a Windows edit box.

Form:  	fview filename[start,size]

The right argument is defined as for fread. For example:

fview '\config.sys'

fwrite

Write character text to file.  The text is first ravelled. If the file already exists, it is overwritten. Returns number of characters written, or an error message. For example:

'abc' fwrite 'newfile.txt'

5

fread 'newfile.txt'

abc

fwrites

Write character text to file.  The text is first ravelled into a vector with each row terminated by the CRLF pair. Any single LF or CR characters in the text are converted into the CRLF pair. If the file already exists, it is overwritten. Returns number of characters written, or an error message. For example:

'abc' fwrites 'newfile.txt'

5

a.i. fread 'newfile.txt'

97 98 99 13 10


Format
6:  Format

The script format.js contains various formatting utilities.

clipfmt

Formats an array of rank 0 1 or 2 as typically required by other software reading the clipboard. Columns are separated by TAB, rows by CRLF.  For example:

a.i. clipfmt i.2 3

48 9 49 9 50 13 10 51 9 52 9 53 13 10

To write data to a spreadsheet or similar Windows application, use clipfmt to format, and wdclipwrite to write to the clipboard, then paste into the target application, for example:

wdclipwrite clipfmt i.2 3

colhdr

Returns a matrix of column headers. This provides an easy way of generating column headers for a report.

Form:  (width [;just]) colhdr text

The right argument is the text for the column headers. The left argument describes column width and, optionally, the justification, as follows:

width  = 	column widths

  	just = 	a singleton or vector of integers:

      	0 = 	centre header, then right justify (default)

      	1 = 	center header in width

      	2 = 	right justify

      	3 = 	left justify

For example:

t=.'Monthly,net,pay'

hdr=.'Number,of,employees;Total,salary;',t

Format in widths 15, 12, 12 with text centered over column, then right justified:

15 12 12 colhdr hdr

        Number        Total     Monthly

          of         salary       net

      employees                   pay

Format each column in width 10, left justified:

(10;3)colhdr hdr

Number    Total     Monthly

of        salary    net

employees           pay

flatten

Return the display form of an array as a character vector. This is useful when printing, or when writing data to another application that does not support multi-dimensional arrays. For example:

flatten i.2 3 4

 0  1  2  3

 4  5  6  7

 8  9 10 11

12 13 14 15

16 17 18 19

20 21 22 23

  $ flatten i.2 3 4

89

fmt

Provides a numeric formatter with various options.

Form:  formatspecs fmt data

The right argument is a numeric list or matrix, the left is various format specifications, either edit or positional, separated by commas, as follows:

•	edit formats have the form: [o]w[.d], where:

o is optional qualifiers from the set:

     	nr	n repetitions (must be given first)

      	b	blank if zero

      	c	commas

      	z	zero fill

  	w is field width

  	d is decimal places

•	positional formats have the form:

  	xn    = n blanks, e.g. x3

For example:

[dat=. (?3#1e8),.0.01*?3 2$1e4

7.70205e7 91.38 52.97

8.27817e7 46.44 94.09

1.25365e7     5 76.15

Format the first column using commas, in width 12; skip two spaces, then format the next two columns in width 6 with 2 decimal places:

'c12,x2,2r6.2' fmt dat

  77,020,454   91.38 52.97

  82,781,730   46.44 94.09

  12,536,537    5.00 76.15

fold

Fold character vector into a matrix of given width.

Form: [width] fold data

width is optional, if not given it defaults to the current screen width. For example:

txt=. 'Pitt is to Addington as London is to Paddington'

20 fold txt

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³Pitt is to Addington³

³as London is to     ³

³Paddington          ³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

hexdump

Show character data as hex values and displayable characters. For example:

hexdump fread '\config.sys';0 96

00   64 65 76 69-63 65 3D 63  3A 5C 64 6F-73 5C 73 65  ³device...

10   74 76 65 72-2E 65 78 65  0D 0A 64 65-76 69 63 65  ³tver.e...

20   3D 63 3A 5C-64 6F 73 5C  61 6E 73 69-2E 73 79 73  ³=c:\do...

30   0D 0A 64 65-76 69 63 65  3D 63 3A 5C-64 6F 73 5C  ³..devi...

40   64 62 6C 73-70 61 63 65  2E 73 79 73-0D 0A 64 65  ³dblspa...

50   76 69 63 65-3D 63 3A 5C  64 6F 73 5C-68 69 6D 65  ³vice=c...

nfmt

Provides a simple formatter for numeric data.

Form: [opt] nfmt data

Useful in viewing numeric data interactively. The optional left argument has up to 3 elements, with the default shown in parentheses:

0 = maximum decimal places, max 9  	(4)

1 = minimum field width            	(0)

2 = display width	(current screenwidth)

For example:

[dat=. %: >:i.18

1 1.41421 1.73205 2 2.23607 2.44949 2.64575...

4 nfmt dat

 1.0000  1.4142  1.7321  2.0000  2.2361  2.4495

 2.6458  2.8284  3.0000  3.1623  3.3166  3.4641

 3.6056  3.7417  3.8730  4.0000  4.1231  4.2426

ruler

Returns a formatted ruler.

Form:	[opt] ruler length

opt is optional, if =0 (default) ruler is horizontal, if=1, ruler is vertical. For example:

ruler 50

ÅÁÁÁÁÅÁÁÁÁÅÁÁÁÁÅÁÁÁÁÅÁÁÁÁÅÁÁÁÁÅÁÁÁÁÅÁÁÁÁÅÁÁÁÁÅÁÁÁÁ

0    5   10   15   20   25   30   35   40   45

ÅÂÂÂÂÅÂÂÂÂÅÂÂÂÂÅÂÂÂÂÅÂÂÂÂÅÂÂÂÂÅÂÂÂÂÅÂÂÂÂÅÂÂÂÂÅÂÂÂÂ

sqzint

Squeeze list of integers into a short character list. See also sqzrun. For example:

sqzint (i.1000) -. 123 600 601 950

0-122,124-599,602-949,951-999

sqzrun

Squeeze list of numbers into a short character list. See also sqzint. For example:

sqzrun 1.1 1.1 1.1 7 9 9 10.3

3#1.1,7,2#9,10.3

table

(adverb) Display a function table for a dyadic function. The left argument is the function. The result is a new dyadic function that displays the arguments and result in a table. For example, the following shows a function table for ! (out of):

! table ~ _4+i.9

ÚÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³  ³ _4  _3 _2 _1 0 1 2 3 4³

ÃÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³_4³  1  _3  3 _1 0 0 0 0 0³

³_3³  0   1 _2  1 0 0 0 0 0³

³_2³  0   0  1 _1 0 0 0 0 0³

³_1³  0   0  0  1 0 0 0 0 0³

³ 0³  1   1  1  1 1 1 1 1 1³

³ 1³ _4  _3 _2 _1 0 1 2 3 4³

³ 2³ 10   6  3  1 0 0 1 3 6³

³ 3³_20 _10 _4 _1 0 0 0 1 4³

³ 4³ 35  15  5  1 0 0 0 0 1³

ÀÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ


Jadeutil
6:  Jadeutil

The script jadeutil.js contains cover functions for utilities in the j locale, defined in jadelib.js. For example, you can use edit instead of edit_j_. See the description of jadelib in chapter 5 for details.

The script is loaded automatically by the default profile file.

The functions are:

edit

edit name

load

load script files

loadj

load script files into j locale (e.g. use for loading project files)

open

open script file in script window

require

load script files if not already loaded

save

save current definitions to a script file

scripts

provide access to the script directories


Misc

The script misc.js contains miscellaneous utilities.

assert

Displays message if first value is 0. Useful when testing systems. For example, try:

'color check' assert 'black' -: 'white'

boxcols

box columns of matrix

Form:	 partition boxcols mat

The left argument is either a single integer being the width of each partition, or a boolean indicating the beginning of each partition. For example:

3 boxcols i.3 7

ÚÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄ¿

³ 0  1  2³ 3  4  5³ 6³

³ 7  8  9³10 11 12³13³

³14 15 16³17 18 19³20³

ÀÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÙ

   1 0 1 0 0 0 1 boxcols i.3 7

ÚÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄ¿

³ 0  1³ 2  3  4  5³ 6³

³ 7  8³ 9 10 11 12³13³

³14 15³16 17 18 19³20³

ÀÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÁÄÄÙ

bx

Return indices of 1s in a boolean. For example:

bx 1 0 0 1 0 1 1 0

0 3 5 6

charsub

Substitute characters in character data. The left argument is one or more character pairs, listed sequentially. For example, a common requirement when reading in numeric data from file is to replace any minus signs with the J negative sign, and replace numeric formatting characters such as $ signs with blanks:

'-_$ ' charsub '$123 -456 -789'

123 _456 _789

chop

Chop a character vector or matrix into a boxed list. A matrix is chopped into columns.

Form: 	opt chop txt

The left argument is an optional delimiter, which defaults to LF if in text, else blank. For example:

chop 'one two three'

ÚÄÄÄÂÄÄÄÂÄÄÄÄÄ¿

³one³two³three³

ÀÄÄÄÁÄÄÄÁÄÄÄÄÄÙ

chop ":i. 4 5

ÚÄÄÂÄÄÂÄÄÂÄÄÂÄÄ¿

³ 0³ 1³ 2³ 3³ 4³

³ 5³ 6³ 7³ 8³ 9³

³10³11³12³13³14³

³15³16³17³18³19³

ÀÄÄÁÄÄÁÄÄÁÄÄÁÄÄÙ

deb

Delete extra blanks from character vector, i.e. any leading or trailing blanks, and any duplicate blanks. For example:

<deb '  voyage   of   the   beagle    '

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³voyage of the beagle³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

diff

First difference of numeric list. For example:

diff 10 20 21 33 29 35

10 1 12 _4 6

join

Join boxed items. For example:

[a=. (3 4$'abcd');(,.'XYZ');":i.3 2

ÚÄÄÄÄÂÄÂÄÄÄ¿

³abcd³X³0 1³

³abcd³Y³2 3³

³abcd³Z³4 5³

ÀÄÄÄÄÁÄÁÄÄÄÙ

join a

ÚÄÄÄÄÄÄÄÄ¿

³abcdX0 1³

³abcdY2 3³

³abcdZ4 5³

ÀÄÄÄÄÄÄÄÄÙ

ljust

Justify characters to left. See also rjust below.

nubcount

Returns nub of an array, linked with the count of each item. For example:

nubcount (/: ?~@#) 1 3 1 5 2 # 'abcde'

ÚÄÂÄ¿

³d³5³

ÃÄÅÄ´

³b³3³

ÃÄÅÄ´

³e³2³

ÃÄÅÄ´

³c³1³

ÃÄÅÄ´

³a³1³

ÀÄÁÄÙ

pathname

Splits DOS file name into DOS path name, and shortname. For example:

pathname 'c:\j2\packages\graph.js'

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ¿

³c:\j2\packages\³graph.js³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÙ

rjust

Justify characters to right. For example:

[a=. 3 5$'abc   '

abc

 abc

  abc

ljust a

abc

abc

abc

rjust a

  abc

  abc

  abc

rplc

Replace characters in a character string.

Form: 	string rplc old;new

For example:

'to be or not to be' rplc 'be';'wed'

to wed or not to wed

scriptform

The argument is a list of one or more names. Returns representations of each name in the multi-line script form for most explicit definitions, otherwise in the linear representation. This is useful for writing object definitions to a script file. For example:

[a=. scriptform 'join charsub deb'

join=: ,.&.>/

charsub=: 3 : 0

NB. characterpairs charsub data

NB. For example:

NB.    '-_$ ' charsub '$123 -456 -789'

NB.  123 _456 _789

NB. Use <rplc> for arbitrary string replacement.

:

'ft'=. ((#x.)$0 1)<@,&a./.x.

t {~ f i. y.

)

deb=: #~ (+. 1&|.@(> </\))@(' '&~:)

   $a

280

show

Show names using a linear representation to a maximum of the screen width. Useful for a quick overview of the currently available names. For example:

show nl 3

boxopen: <^:(< -: {:@;~)

browse: 3 :(12 58$'NB. browse jade script names

bx: # i.@#

charsub: 3 :(8 48$'NB. characterpairs charsub data


Myutil
6:  Myutil

The script myutil.js is loaded by the standard profile, and may be customized as required. It contains several example definitions, including functions to access DOS directories via a pop up box, and suggested settings for some of the function keys.

Open the file and read the comments for further details.

To view the function key settings, ensure the script is loaded, then select the Tools menu, and move the menu bar through the menu items. The status bar shows a brief description of each definition.


Numeric

The script numeric.js contains various numeric utilities.

baserep

Return y. in base x. For example:

16 baserep 12345

3 0 3 9

clean

Cleans small values to zero

Form: 	tolerance clean data

Returns numeric data argument with values less than tolerance (default 1e_10) set to 0. For example:

^j.1p1

_1j1.22461e_16

  clean ^j.1p1

_1

colsum

Sums data columns of a matrix on key columns.

Form:	key colsum mat

For example:

(1 2 colsum m);(2 colsum m);m

ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿

³64 0 1 66500³ 64 0 1  66500³30 0 1 32000³

³36 0 2 36000³108 2 2 112000³36 0 2 36000³

³44 0 3 54000³ 81 1 3 101500³41 1 2 45000³

³72 1 2 76000³              ³31 1 2 31000³

³37 1 3 47500³              ³44 0 3 54000³

³            ³              ³34 0 1 34500³

³            ³              ³37 1 3 47500³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ

fraction

Converts a decimal number into a fraction. The result has 2 items, numerator and denominator. For example:

fraction 6 %~ i.7

0 1 1 1 2 5 1

1 6 3 2 3 6 1

groupndx

Form: 	groups groupndx data

Returns group indices of numeric data. The values in groups are the starting numbers in each group. For example:

0 3 6 groupndx i.10

0 0 0 1 1 1 2 2 2 2

randomize

Sets a random value into random link. A right argument is required but ignored.

The value of  random link in a new session is always 16807. If your application uses  random numbers,  then the same random numbers will be generated each time you start a session. If you start your application by invoking randomize, this will ensure the random numbers differ each time.

range

Form: 	 range start, end [stepsize]

Returns range from start to end in steps of stepsize (default 1). For example:

range 10 15

10 11 12 13 14 15

range 3 19 4

3 7 11 15 19

recur

Solves a recurrence relation

Form:	m recur a

Solves the recurrence relation r(i)=a(i)+r(i-1)*m(i-1). For example:

0.05 0.06 0.06 recur 100 120 140 160

100 125 147.5 168.85

round

Round y. to nearest x. For example, round to 2 decimal places:

0.01 round 1.234567*10^i.5

1.23 12.35 123.46 1234.57 12345.7

rounddist

Distributive rounding. Round y. to nearest x. preserving total rounded to nearest x.. For example, round to 1 decimal place:

(;~+/)0.1 rounddist 6#1.23

ÚÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³7.4³1.3 1.3 1.2 1.2 1.2 1.2³

ÀÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

   0.1 round +/6#1.23

7.4


Trig
6:  Trig

The script trig.js provides names for the trigonometric circle functions, plus related definitions.

sin	1&o.

cos	2&o.

tan	3&o.

sinh	5&o.

cosh	6&o.

tanh	7&o.

arcsin	_1&o.

arccos	_2&o.

arctan	_3&o.

arcsinh	_5&o.

arccosh	_6&o.

arctanh	_7&o.

Constant pi:

pi	1p1

Convert between degrees and radians

dfr	*&(180%pi)	degrees from radians

rfd	*&(pi%180)	radians from degrees

Adverb to convert function to use degrees:

indegrees	@rfd

Corresponding basic functions

sind	sin indegrees	Sin

cosd	cos indegrees	Cos

tand	tan indegrees	Tan

For example:

(sind;cosd;tand) 30 45

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄ¿

³0.5 0.7071068³0.8660254 0.7071068³0.5773503 1³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÙ


Winutil
6:  Winutil

The script winutil.js contains various windows utilities.

syssmbreak

This is a generic handler for the Windows driver result of :

*parent syssmbreak

When called, it invokes wd 'pclose;'. Therefore, if this verb is defined and the windows message handler (wdml) is running, then when the user presses break, the parent command will close the active window.

wdmltest

This is a copy of wdml that can be used for development purposes. It behaves as wdml, except that the results returned by the Window Driver are displayed in the execution session, and stored in the global WDM. The active parents are stored in the global WDP.

WDM and WDP are boxed arrays, with one item appended each time Windows returns a result.

wdquery

Invokes standard query message box.

Form: [opt] wdquery [title;] message

 	opt has one or two elements:

0{  = 	0    okcancel        	(ok=0 cancel=1)

1    retrycancel     	(retry=0 cancel=1)

2    yesno             	(yes=0 no=1)

3    yesnocancel    	(yes=0 no=1 cancel=2)

4    abortretryignore  	(abort=0 retry=1 ignore=2)

1{ = 	default button (0, 1 or 2)

For example:

3 wdquery 'Proposal Letter';'OK to save new defaults?'

wdstatus

Puts a status message on the screen. This is useful when runnning a long application - you can display the current status of your job.

Form: [title] wdstatus message

title 	 	optional message box title.

message	message

If the message is empty, the status message box is closed.

The default text size is 1 row of 50 characters. Once created, the status message box is not resized. For a larger size, call wdstatus initially with a message of the maximum size required (pad with blanks if need be). For example, try:

'reading file' wdstatus 'at record 100'

wdstatus 'at record 200'

wdstatus ''

wdtest

As wd, except that on any error: sets globals WDR and WDLAST,

resets the Window Driver and returns an error message. This may be used

instead of wd when developing applications.

WDLAST is the last windows command given, and WDR is its result.

winapi

This adverb returns a verb for the corresponding Windows API function call, for example:

   'getcurrenttask' winapi ''

ÚÄÄÄÄ¿

³5343³

ÀÄÄÄÄÙ

winconst

This returns a numeric value for windows constants, which are listed in the file

examples\data\winconst.dat.  For example:

winconst 'EM_GETMODIFY EM_SETMODIFY'

ÚÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³1032 1033³EM_GETMODIFY EM_SETMODIFY³

ÀÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ


Chapter 7 Window Driver
7:  Window Driver Overview

The Window Driver provides access under program control to many features of the Windows graphical and operating system environment. Character strings created in J are passed to the Window Driver, which then assembles and executes the appropriate Windows function calls, and returns the result to J. Commands supported include:

•	creation and use of Windows controls to allow user input

•	instructions to the J session manager

•	DDE and OLE links to other Windows software

•	access to VBX controls

•	status queries

The Window Driver is provided by the verb 11!:0, typically named wd:

wd=: 11!:0

wd is defined in script file winlib.js, which should be loaded when using the Window Driver.

wd is monadic and takes an argument of a character string which is passed to Windows for execution. The argument is a list of statements, each of which must end in a semicolon. Several may be given at a time, and the result is the result of executing the last statement. Each statement is a command followed by any required parameters. For details and a list of commands see Appendix A.

The result of wd is a 2-column boxed array, with the first column containing identifiers, and the second containing corresponding data. Typically, there are several rows, with the first row indicating the type of response. For example, the following queries the metrics used by Windows (screen width, screen height, x logical unit and y logical unit); the response contains the required values in the row identified by *data:

wd 'qm;'

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿

³*type  ³10 result   ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´

³*parent³sysresult   ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´

³*data  ³640 480 8 16³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ

This shows a 640 by 480 screen, with the current screen font being 8 pixels wide and 16 pixels high.

In the next example, the Windows statement invokes a dialog box that allows the user to select a font. The result is returned after the user closes the dialog box, and contains a string of items that describe the font selected:

wd 'mbfont;'

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³*type  ³10 result                                     ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*parent³sysresult                                     ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*data  ³-32 0 0 0 700 0 0 0 0 1 2 1 34 "MS Sans Serif"³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

The following example executes the Windows Write program (the *data result is the Windows taskhandle)

wd 'winexec write;'

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ¿

³*type  ³10 result³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´

³*parent³sysresult³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´

³*data  ³10775    ³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÙ

The next example executes Write with the given filename argument (Write loads the file). Write is shown in a maximized window:

wd 'winexec "write mytext.wri" sw_maximize;'

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ¿

³*type  ³10 result³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´

³*parent³sysresult³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´

³*data  ³13287    ³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÙ


Window Driver Results
7:  Window Driver Results

The result of executing wd is a 2-column boxed array, which contains various information. The most complex case to handle involves the use of the wait instruction to wait for user input. It is helpful to consider first those commands that do not use the wait instruction:


Non-Wait commands
7:  Non-Wait commands

Non-wait commands return immediately, and might be used to send a simple instruction or query to Windows. In the case of an instruction, the result can often be discarded. For example, the following sets the session manager in focus and discards the result:

empty wd 'smfocus;'

In the case of a query, the result is required. The following queries the name of the active session windows:

wd 'qsmact;'

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿

³*type  ³10 result ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´

³*parent³sysresult ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´

³*data  ³c:\j2\1.jx³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ

The verb wdg (window driver get) extracts specific items from this result:

'*type' wdg wd 'qsmact;'

10 result

For many such queries, the only relevant element of the result is the item corresponding to the identifier *data. The verb wddata issues the wd command, and returns the *data element alone:

wddata=: '*data' & wdg @ wd

wddata 'qsmact;'

c:\j2\1.jx

In some cases, the data result is a character string delimited by LF, which can be formatted by list. The following displays the possible types of responses to wd (these are the identifiers in the first row of any Windows result):

list wddata 'qt;'

 0 ?          1 error      2 nowait     3 fkey

 4 menu       5 button     6 close      7 enter

 8 cancel     9 break     10 result    11 ddepoke

12 ddeex     13 ddereq    14 ddeadvise 15 ddestart

16 smbreak   17 timer     18 vbxn


Wait Commands
7:  Wait Commands

If the last command given is wait, a result is returned only after the user takes some action, for example, selecting a menu item. Note that a variety of responses are possible; indeed since several windows may be active at any one time, the response may indicate an action in any of these windows.

Creating a Window

The following example creates a window mywin, captioned My Window; adds a push button named pressme; then shows it and waits for the user to respond. In this case, the user clicks the mouse on the button:

t=. 'pc mywin;pn "My Window";'

wd t,'cc pressme button;pshow;wait;'

The response from Windows is:

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³*type  ³ 5 button                    ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*parent³mywin                        ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*id    ³pressme                      ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*pinfo ³1 0 0 200 200 192 173 640 480³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

The response shows that:

•	a button was pressed (*type is 5 button)

•	the active (parent) window was mywin

•	the specific button pressed was pressme

•	the window size and position is given in *pinfo

Note that after Windows returns this result, the window created is still active. You can close it by issuing a pclose command, or by resetting the Window Driver:

wd 'pclose;'

or

wd 'reset;'

Where the event that causes a response from Windows is for a parent window, data for all children is included in the response. The next example creates a window with two edit controls. The user types into both controls, then closes the window:

wd 0 : 0

pc mywin;pn "My Window";

xywh 5 5 100 12;cc e0 edit;

xywh 5 20 100 12;cc e1 edit;

pas 5 5;pcenter;pcloseok;pshow;wait;

)

The response from Windows is:

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³*type  ³ 6 close                        ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*parent³mywin                           ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*id    ³sysclose                        ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*pinfo ³1 206 189 228 101 220 74 640 480³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³e0     ³typed in first control          ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³e1     ³and in second control           ³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

In the simplest cases, the response from Windows can be handled directly. Consider this case where you want to display some text in a control. The user can press an OK button to close the display. The result from Windows is not required - after any response, the control is closed:

view=: 3 : 0

wd 'pco viewer;'

wd 'xywh 5 5 200 150;'

wd 'cc e0 edit es_multiline ws_hscroll ws_vscroll ws_border;'

wd wdctext y.

wd 'cedro;cfoem;'

wd 'xywh 220 5 40 12;cc OK button;'

wd 'pas 5 5;pcenter;pshow;wait;'

empty wd 'pclose;'

)

For example, to view the autoexec.bat file:

view 1!:1 <'\autoexec.bat'


The Wait Loop
7:  The Wait Loop

In general, the application program examines the response from Windows, takes some action, and then re-issues the wait command. This is referred to as a wait or message loop. The verb wdml defined in winlib.js handles this as follows:

•	each response from Windows to a wait command contains the *parent identifier, which indicates the parent (typically the name of the active window) that originated the response. The user should define verbs with the same name as the parent, for all parents for which some action should be taken. Typically, this simply means creating a verb for each active window the user creates. The argument to these verbs will be the response from Windows.

•	wdml should be called as the last statement in a program that invokes a Windows task. The argument to wdml is the (maximum) number of  active windows the program has created.

•	wdml first examines the number of active windows. If there are more active windows than its argument, wdml terminates, since it can assume another copy of wdml is already running. Otherwise wdml invokes the wait command.

•	on receiving a response from Windows, wdml executes the parent verb corresponding to the *parent identifier in the response. The argument given to the parent verb is the response itself. If no such parent verb has been defined, wdml bypasses this step.

•	If at least one active window remains, wdml re-issues the wait command. If there are no more active windows, wdml terminates.

Note that this method handles an arbitrary number of active windows, as with the examples provided in directory examples\demo. Try:

loadj 'examples\demo\demo.js'

demo ''


Parent Verbs
7:  Parent Verbs

Parent verbs can be in any form, but a natural construction is to use a case statement, which invokes a verb depending on the Windows response. To simplify construction of such verbs, the file winlib.js defines nouns for all standard Windows response types, for example:

WDFKEY=:    ,:'*type';' 3 fkey'

WDBUTTON=:  ,:'*type';' 5 button'

WDCLOSE=:   ,:'*type';' 6 close'

...

The conjunction casetable defined in stdlib.js builds a suitable case statement. For example, suppose that you create a window mywin, and want to execute verbs myfkey, mybutton and myclose on the corresponding Windows response, then the parent verb mywin could be defined as:

v=. myfkey`mybutton`myclose

n=. WDFKEY,WDBUTTON,WDCLOSE

mywin=: v casetable n

Similar case statements can be used in turn for creating the myfkey and mybutton verbs. For example, if there is a button b0, then if pressed, the Windows response will include the item:

'*id';'b0'

Therefore, the following case statement could be used to support two buttons, b0 and b1:

v=. button0`button1

n=. (<'*id'),.'b0';'b1'

mybutton=: v casetable n

The following example illustrates this. For more complex examples, see the applications in examples\demo and examples\memo.

A window dwin is created that contains two buttons, OK and Cancel. If  either button is pressed, or if a function key is pressed, a message box displays the Windows response. If the Cancel button is pressed, the window is then closed. wdml is used to handle the message loop (and therefore allows this window to co-exist with other windows):

OK=:    	wdinfo bind 'OK button pressed'

closebn=: 	wdinfo bind 'Close button pressed'

fkey=:  	wdinfo bind 'function key pressed'

closewin=: 	wd bind 'psel dwin;pclose;'

Close=: 	closewin @ closebn

button=: 	OK`Close casetable ((<'*id'),.'OK';'Close')

dwin=:  	button`fkey casetable (WDBUTTON,WDFKEY)

wd 'pcd dwin;'

wd 'xywh 20 10 40 12;cc OK button;'

wd 'xywh 20 30 40 12;cc Close button;'

wd 'pas 20 20;pcenter;pshow;'

wdml 1


Chapter 8 Window Controls
8:  Window Controls

Windows supports several types of graphic controls that can be included in the user interface. Additional controls (custom controls) are available through the VBX mechanism. All these controls are accessed using the Window Driver.

This chapter describes how to use Window controls, and includes details of each control. OLE and VBX controls are further described in Chapters 9 and 10.

All controls are displayed in a window called the parent window. The parent window is created first, and controls are then added to it. The controls in a parent window are referred to as child controls.

The parent window and child controls have names, referred to as their ids, that are set when created.  These start with an alphabetic character and consist of alphanumeric characters and the period. Ids are case-sensitive and can be up to 127 characters. For example, wd 'pc abc;' and wd 'pc abc.5;' create parent windows with ids abc and abc.5.

Several parent windows may be created at a time. Only one parent window and one of its child controls may be selected at a time. wd commands affect the selected parent or child.

Controls are selected when created and when the user selects them directly. The commands psel and csel can also be used to select a parent and child.


Parent Windows
8:  Parent Windows

The parent window is the display area for the menus and child windows required by a user interface. Three commands create a new parent window:

•	pc creates a standard parent window

•	pco creates a parent window that is owned by the currently active window. The owner is is disabled until the new parent is closed.

•	pcd creates a pco window that has a dialog box frame, that is, it cannot be resized.

Parent windows are initially not visible. They can be displayed in various ways using the pshow command, for example pshow sw_showmaximized shows the parent window maximized (to fit the available screen). Typically, a parent window and all its children are created, then the pshow command is given.


Location and Size
8:  Location and Size

The location and size of  controls  in a parent is set with the rectangle. The xywh command sets all values for the rectangle, while adj and other commands move the rectangle.

4 integers define the rectangle:

x	units from the left

y	units from the top

w	units in width (to the right)

h	units in height (to the bottom)

These units are in terms of the average character size of the current system font:

•	x and w values are 1/4 of the font width

•	y and h values are 1/8 of the font height

For example:

wd 'xywh 40 80 100 160;'

sets the rectangle to be 10 characters from the left edge of the parent; 10 lines down from the top edge of the parent; 25 characters wide; and 20 lines high.

Since location and size are defined relative to the size of the current system font, window definitions should display reasonably well on different screens at various resolutions.

The adj n commands adjust the rectangle. For example, if you are creating several controls, each of which is 2 units beneath the previous control, but is otherwise the same size, then instead of calculating new xywh values for each control, set the xywh for the first control, then use wd 'adjh 2;' to move the rectangle 2 units down.

The size of the system font can be obtained from the qm (query metrics) command.


Child Controls
8:  Child Controls

Child controls are created in the currently selected parent window. A parent window may have several child controls. wd commands affect the selected child control of the selected parent window.

Child controls are created with a given class and styles. The class defines the type of control, the styles customize the control. Some styles are specific to a particular type of control, other styles can be used with most or all controls. Style names reflect their use, for example es_multiline is a style applicable only to edit boxes. Styles whose names begin with the letters ws_ apply to any control. The group style groups the control with the previous control. Tab and Cursor keys recognize groups.

Commands cc and cci create child controls. cc creates a control with a given class and styles, and cci creates a control with the same class and initial style as the last cc command.  Typical syntax is:

cc id class style1 style2 ...;


Child Classes
8:  Child Classes

The class defines the appearance and behavior of the control. There are 10 standard classes:

button	pushbutton, checkbox, radiobutton

edit	edit box

listbox	list box

combobox	combination of edit and listbox

scrollbar	scrollbar

static	static text

vbx  	                VBX control

isigraph	graphics box

isipicture	picture from a BMP, WMF, or ICO file

isiole	presentation graphic of an OLE object

button

The appearance and behaviour of a button control depends on the styles it is created with. If none, the button simply initiates a Windows response when pushed. Possible styles are:

•	bs_autocheckbox 	a labelled button that can be checked

•	bs_autoradiobutton	a labelled button typically created as part of a group. 	Clicking one button in the group checks that button, 	and unchecks the previously checked button in the 	group.

•	bs_defpushbutton 	the default pushbutton. Pressing Enter has the same 	effect as clicking this button.

•	bs_groupbox 	a box used to visually group other buttons

•	bs_lefttext 	aligns the text to the left of the button

•	bs_ownerdraw 	a button with a picture from a graphics file

For example:

wd 0 : 0

pc buttons;

xywh 10 10 50 12;cc pressme button;

xywh 10 30 50 12;cc checkme button bs_autocheckbox;

xywh 70 10 60 55;cc grouping button bs_groupbox;

xywh 75 20 50 12;cc radio1 button bs_autoradiobutton;

xywh 75 35 50 12;cci radio2 group;

xywh 75 50 50 12;cci radio3 group;

csel checkme; ccheck 1;

csel radio2; ccheck 1;

pas 10 10;pcenter;pcloseok;pshow;wait;

)

edit

An edit control is a box in which text can be displayed and edited. Edit control styles are:

•	es_autohscroll 	use horizontal scroll bars if required

•	es_autovscroll 	use vertical scrollbars if required

•	es_center 	center text in control

•	es_lowercase  	use lowercase text only

•	es_multiline 	allow more than one line

•	es_password	 	allows hidden text to be entered

•	es_right 	right justify text in control

•	es_uppercase 	use uppercase text only

Windows commands beginning with the letters cf can set different fonts for edit controls, and commands beginning with the letters ced further customize and manipulate edit controls.

The command ctext writes text to an edit control. Typically, text is given within the delimiters " or EAV. The verb wdctext in file winlib.js creates the appropriate ctext command with a given text argument, for example

wd 'pc editbox;'

wd 'xywh 8 11 30 8;cc s0 static;cn "where to?";'

wd 'xywh 44 10 70 10;cc e0 edit ws_border;'

wd wdctext 'home alone'

wd 'pas 8 8;pcenter;pcloseok;pshow;wait;'

listbox

A listbox control displays a list of items, which can be selected by the user. Listbox control styles are:

•	lbs_multiplesel	allow multiple selections

•	lbs_notify 	allows a double click to end the wait (as a button 	event)

•	lbs_ownerdrawfixed  	creates an ownerdrawn listbox

•	lbs_sort	sort entries alphabetically

The ctext command puts items in the listbox. Items are delimited by LF.

In the response from Windows, multiple selections are delimited by LF. In the following example, the user makes two selections, then closes the listbox:

colors=:;:'black blue green red turquoise brown purple'

t=. 'pc listbox;xywh 5 5 60 60;'

t=. t,'cc l0 listbox lbs_multiplesel;'

t=. t,wdctext ;colors,&.>LF

wd  t,'pas 5 5;pcenter;pcloseok;pshow;wait;'

The result from Windows is:

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³*type  ³ 6 close                         ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*parent³listbox                          ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*id    ³sysclose                         ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*pinfo ³1 246 156 148 167 140 140 640 480³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³l0     ³green|turquoise                  ³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

combobox

A combobox is a combination of a listbox and an edit box. You can enter a response into the edit box, or select a response from the listbox. You may only select one item in a combobox. A dropdown combobox initially shows only the edit box, but allows the list box to appear when selected. Combobox styles are:

•	cbs_autohscroll 	allow horizontal scrolling of the edit box

•	cbs_dropdown 	shows list box only when selected

•	cbs_dropdownlist 	as cbs_dropdown, but the edit box is read only - 	you must select entries from the listbox

•	cbs_sort 	sort entries alphabetically

For example:

colors=: ;:'black blue green red turquoise brown purple'

t=. 'pc combobox;xywh 8 8 60 60;'

t=. t,'cc c0 combobox cbs_dropdownlist;'

t=. t,wdctext ;colors,&.>LF

t=. t,'pmove 0 0 76 40;pcenter;pcloseok;pshow;wait;'

wd t

scrollbar

A scrollbar control displays a horizontal or vertical scrollbar. Clicking a scrollbar ends the wait command with a button event. The value returned by Windows is the current position of the scrollbar.

There is only one scrollbar style: sbs_vert specifies a vertical scrollbar (default is horizontal).

The ctext command sets 4 values for the scrollbar: leftmost (or top) position, current position, rightmost (or bottom) position, and the size of change resulting from a click in the area between the thumbbox and either end of the scrollbar. For example:

wd 0 : 0

pc scroller;

xywh 10 10 100 12;

cc s1 scrollbar;

ctext 0 500 1000 50;

pas 10 10;pcloseok;pshow;wait;

)

The response from Windows has the form:

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³*type  ³ 5 button                  ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*parent³scroller                   ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*id    ³s1                         ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*pinfo ³1 0 0 248 91 240 64 640 480³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³s1     ³808                        ³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

static

A static control is used to display text, and can have various types of frames and backgrounds. It is never active. Static control styles are:

•	ss_blackframe  	black frame

•	ss_blackrect  	black rectangle

•	ss_center  	center text

•	ss_grayframe 	gray frame

•	ss_grayrect  	gray rectangle

•	ss_leftnowordwrap 	left justify, no word wrap

•	ss_noprefix    	allow & characters in control

•	ss_right 	right justify text

•	ss_simple         	static text control

•	ss_whiteframe 	white frame

•	ss_whiterect  	white rectangle

wd 0 : 0

pc wpstatic;pcloseok;

xywh  5 10 72 14;cc c0 static ss_blackframe;

adjh 5;cc c2 static ss_center ss_whiteframe;

adjh 5;cc c6 static ss_leftnowordwrap;

cn "left justified no word wrap in effect";

xywh 90 10 72 14;cc c7 static ss_noprefix ws_border;

cn "&No Prefix";

adjh 5;cc c8 static ss_right ws_border;cn Right;

adjh 5;cc cd static;cn Default;

pas 5 5;pcenter;pcloseok;pshow;

)

isigraph

An isigraph control is a window that can display graphics. First create an isigraph control, then use graphics commands to create and display the graphics. All graphics commands start with g. Graphics are displayed only when the gshow command is given.

The graphics window has coordinates running from (0,0) in the bottom left hand corner to (1000,1000) at the top right.

For example, the following displays a red pentagon:

wd 0 : 0

pc isigraph;

xywh 0 0 100 100;cc g0 isigraph;

grgb 255 0 0;gbrush;

gpolygon 1000 500 654 975 95 793 95 206 654 24;

gshow;pas 0 0;pcenter;pshow;

)

isipicture

An isipicture control displays an image from a file. The file may be a DIB (device independent bitmap), WMF (Windows metafile) or ICO (icon file).

DIB files usually have a file extension of BMP.

The ctext command sets the filename. For example, to display the aquarium bitmap in examples\data:

wd 'pc aquarium;'

wd 'cc i isipicture;'

wd 'ctext "examples\data\aquarium.bmp";'

wd 'pas 0 0;pscale;pcenter;pcloseok;'

wd 'pshow sw_showmaximized;'


Common Dialog Boxes
8:  Common Dialog Boxes

Windows provides several built-in dialog boxes called Common Dialog Boxes that perform useful functions.

The color dialog box allows selection of colors. The *data result is a list of the RGB values for 17 colors, of which the first is chosen in the standard color dialog box, and the rest in the custom color dialog box. Try:

_3[\ ". wddata 'mbcolor;'

This returns a matrix of the 17 values, one row per color.

The font dialog box allows selection of a logical font. The *data result describes the font chosen (in this case the font used in the J logo):

wddata 'mbfont;'

-32 0 0 0 600 0 0 0 0 3 2 1 18 "Bookman Old Style"

The message box dialog box displays a message and waits for a user response. For example:

wd 'mb title text;'

wd 'mb title text mb_iconstop mb_retrycancel;'

To list all message box styles:

list wddata 'qs mb;'

mb_abortretryignore mb_defbutton2       mb_defbutton3

mb_iconasterisk     mb_iconexclamation  mb_iconhand

mb_iconinformation  mb_iconquestion     mb_iconstop

mb_ok               mb_okcancel         mb_retrycancel

mb_yesno            mb_yesnocancel

The open filename dialog box allows the user to select a fully qualified file name:

wd 'mbopen;'

wd 'mbopen title "" "" Write(*.wri)|*.wri| Word(*.doc) 	|*.doc" ofn_filemustexist ;'

To list all open filename styles:

list wddata 'qs mbopen;'

ofn_createprompt    ofn_filemustexist...

ofn_overwriteprompt ofn_pathmustexist

The save filename dialog box is similar to the open filename dialog box:

wd 'mbsave;'


Fonts
8:  Fonts

A font can be chosen with the mbfont command. The result is a description of a font and is the current font. The result, either explicit or implicit, can be the argument to other commands.

A maximum of 20 fonts can be selected for use in controls. Destroying a control does not release the font resource. A wd reset command frees all font resources.

Several Window Driver commands determine fonts:

cfont [font] 	selects the current font, or the font described by theargument

cfoem 	selects the OEM fixed pitch font

cfsesm 	selects the current session manager font

cfsys	selects the system proportional pitch font (the initial default 	font)

fontdef [font] 	sets the default font for new controls as the current font,  or from 	the argument

fontcur font 	sets current font from the argument

mbfont [font] 	runs the common dialog box for choosing fonts

smfont [font] 	sets the session manager font as the current font, or from the argument


Accelerator Keys
8:  Accelerator Keys

& in the name of a button or menu item sets a keyboard accelerator. The & is not displayed and the next character is underlined. Pressing ALT + the character is the same as clicking on the button or menu item.


Parent Menus
8:  Parent Menus

Several Window Driver commands support menus:

menu id text  	add menu item

menucheck id  	check menu item

menudisable id  	disable menu item

menuenable id  	enable menu item

menupop text  	add popup menu item

menupopz 	ends popup menu and drops down a level

menusep  	add separator line in a popup menu

menuuncheck id  	uncheck menu item

To add a popup menu item pop1, displayed in the menu bar:

wd 'menupop pop1;'

To add individual items to the popup menu, displayed when the menu is selected:

wd 'menu item1 "item name";'

This displayes the text item name, and if selected, the Windows result contains the name item1.

To add a separator line:

wd 'menusep;'

To end the popup menu:

wd 'menupopz;'

For example, try

wd 0 : 0

pc menutest;

menupop "Options";

 menu newfile "&New File";

 menu openfile "&Open File";

 menusep;

 menu exit "&Exit";

menupopz;

menupop "Help";

 menu contents "&Contents";

 menu about "&About";

menupopz;

pshow;wait;

)

When the window is shown, select the about item. The Windows response is:

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³*type  ³ 4 menu                      ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*parent³menutest                     ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*id    ³about                        ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³*pinfo ³1 0 0 200 200 192 154 640 480³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ


Sendkeys
8:  Sendkeys

The command sendkeys sends keystrokes to the active window. This is similar to sendkeys in Visual Basic and other products.

+^%~()[]{} are special characters:

+ 	upshifts the next character (+a is the same as A)

^ 	control shift

% 	alt shift

~ 	Enter key

To send a special character as a normal character enclose it in {}. To send + , put {+} in text.

{key n} repeats key n times. For example: {a 5} or {left 3}.

Keys without an ASCII value are indicated by keywords in braces. {tab} is the tabkey.

For example:

wd 'qs sendkeys;'

wd 'winexec calc.exe;'

wd 'acttitle calculator; sendkeys "123{+}4~";'


Tab and Cursor Keys
8:  Tab and Cursor Keys

TAB and SHIFT+TAB keys cycle the focus through the children in the order they were created.

Cursor keys cycle through the controls in a group. By default, controls are created as part of a group consisting only of themselves.

The group style creates a control that is grouped with the previous control. For example:

wd 'cci b1 group;'


Ownerdraw
8:  Ownerdraw

A button created with the bs_ownerdraw style is an ownerdraw button. A listbox created with lbs_ownerdrawfixed style is an ownerdraw listbox.

A control with ownerdraw style displays a picture from a file. The files supported are the same types supported for the pictures in isipicture class windows.

The file name to display for an ownerdraw button is set with the cn command. The file names to display for each element in the listbox are set with the ctext command. The first parameter in the ctext command for an ownerdraw listbox is the height of each element.

For example, the following will display an ownerdraw button with the J icon:

wd ' pc a; xywh 10 10 30 30;'

wd 'cc b1 button bs_ownerdraw;'

wd 'cn "j2b.ico";'

wd 'pas 10 10; pshow;'


Chapter 9 DDE and OLE
9:  DDE and OLE

Dynamic Data Exchange (DDE) and Object Linking and Embedding (OLE) are  ways of allowing Windows programs to communicate with each other. Both methods allow one program to access data in another. With DDE, all you get is the data; with OLE you get the data and the services of the other application.


DDE
9:  DDE

DDE allows two Windows programs to exchange data by posting messages to each other using a standard protocol. J provides a comprehensive set of DDE commands so that you can communicate between J and any other Windows program supporting DDE, including another copy of J. You may have up to 20 DDE conversations at a time.

For example, with DDE you could set up J as a calculation server, so that another Windows program could send it a sentence for evaluation and receive back the result.

The DDE interface uses the Window Driver. Messages are sent with Window Driver commands, for example:

wd 'ddereq jserver calc res;'

Messages are  received when a wait loop terminates:

wd 'wait;'

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄ¿

³*type  ³15 ddestart³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄ´

³*parent³sysddestart³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄ´

³*topic ³mytopic    ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄ´

³*item  ³myitem     ³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÙ

Most Windows applications support DDE in some form or another. However, not all applications support the complete set of DDE commands, and in some cases the command usage is not standard. With J, you write programs to handle the DDE interface, and therefore you can tailor the J side of the protocol to fit the other applications requirements.

In this chapter we discuss general principles of DDE with examples of a J to J DDE link, and then discuss a link between J and Microsoft Word for Windows. Several other examples, including a link to Microsoft Visual Basic will be found in the directory: examples\dde.


Server and Client
9:  Server and Client

The two parties to a DDE conversation (connection or link) are known as the server and client. The server makes itself available by registering itself with Windows. The client initiates the conversation by sending a message to the server.

The DDE protocol is asymmetric: the client initiates the conversation, sends messages and instructions to the server, and terminates the conversation. The server cannot by itself initiate a conversation, or send messages except in response to a client request.


DDE conversations
9:  DDE Conversations

There are three types of DDE conversations, known as hot, warm and cold:

•	in a hot link, the client asks that whenever some data changes, the server send it the new data.

•	in a warm link, the client asks that whenever some data changes, the server send it an indication that the data has changed (but not the new data itself).

•	in a cold link, the server never notifies the client whenever data has changed. Programs to handle each of these will be slightly different, and you will need to know what type of conversation the other application supports.

Hot and warm links are also known as advise loops.

A warm link is essentially a combination of a hot and cold link - the hot link advises of a change in the data item, the cold link is used to send the data item.

A conversation uses three identifiers: service, topic and item. A conversation may also share data:

•	service 	identifies the server application, and is typically set by the server

•	topic 	is a high level identifier of the information being exchanged

•	item 	is a low level identifier of the information being exchanged

•	data 	is the data being exchanged (as character data)

Service, topic, and item names are case-insensitive.

Some applications require specific topic and item names be used; others do not care. A commonly used topic is the system topic, which may also have a sysitems item, both are used to provide information about a server application to a client. For example, Lotus 123 for Windows has a system topic:

wddata 'ddereq 123w system sysitems;'

SysItems	Topics Formats	RangeNames Selection Status

   wddata 'ddereq 123w system status;'

Ready

Some applications such as spreadsheets allow data to be exchanged in clipboard format. The utility clipfmt in script format.js will convert a list or table into clipboard format.

With spreadsheets, it is typical for the topic to be the worksheet name, and the item to be the cell or range name. For example, suppose data is a table of shape two by three, then this could be written to an Excel worksheet sheet1 as follows:

txt=. clipfmt data

txt=. EAV,txt,EAV

wd 'ddepoke excel sheet1 r1c1:r2c3 ',txt,';'

Some servers support a DDE execute command, allowing the client to use the servers command language directly. However, servers that support execute usually do so only in the system topic, and then only in a limited fashion, for example to run menu commands such as File/Open. For non-trivial tasks it is usually best to create a macro in the application and then use the execute command to run the macro. Most applications follow the conventions for execute expressions indicated in the following:

[open("sample.xlm")]

[run("r1c1")]

[connect][download(query1,results.txt)][disconnect]


J Commands and Events
9:  J Commands and Events

The following summarizes the Window Driver commands and event types. Here:

S	is the service name

T	is a topic

I	is an item

D	is some data

Server commands:

ddename S	set service name S

ddereqd D	provide data D to a ddereq event. It must be the first command given after a ddereq event is received.

ddeadvise T I D	provides data D to advise loops with given topic and item. It returns 0 if the loop is no longer active.

Server events:

11 ddepoke	data has been sent

12 ddeex	execute command string

13 ddereq	request for data

15 ddestart	request to start advise loop

Client commands:

ddecons	return conversation names (service and topic)

ddedis [S [T]]	disconnect

ddeex	S T D 	execute command in server

ddepoke S T I D	poke data to server

ddereq S T I 	request data from server

ddestart	S T I 	start advise loop

ddestop S T I	top advise loop

Client events:

10 result	answer to ddereq query

14 ddeadvise	new data from advise loop


Communications Protocol
9:  Communications Protocol

Opening the conversation:

The client always initiates the conversation by sending a message to the server. The server must be ready to respond. How the server does this depends on the application.

For J to act as a server, you must have first loaded J and set the service name using the ddename command. The server should also be in a wait loop, so that it can receive the clients message,  for example:

wd 'ddename jserver;wait;'

Client commands:

The client can send four types of messages:

•	a ddepoke message sends data to the server. The server does not respond. How the server treats this data depends on the application. If the server is a spreadsheet, the data may be written to the current worksheet; if the server is J, it may be treated as a sentence to be executed.

•	a ddeex message sends a command to the server. The server does not respond. How the server treats this depends on the application, but it would typically be used to invoke a macro command in the server. A J server need not recognise this message, as a ddepoke message can be used just as well.

•	a ddereq message sends a request for a data item to the server. The server responds with the data item.

•	a ddestart message sets up an advise loop, asking the server to advise the client whenever a specific data item has changed. The ddestop message terminates the advise loop. Once an advise loop has been initiated, the client must be prepared to accept messages from the server at any time.

Closing the conversation:

A conversation is closed whenever either application terminates. A client can also close the conversation by issuing a ddedis command (received by Windows, but not sent to the server).


DDE Examples
9:  DDE Examples

The following examples illustrate. First we set up a J to J connection manually:

Load two copies of J, and arrange the windows so that both are visible at the same time. You may find it helpful to minimize Program Manager to reduce screen clutter.

In one window (the server), define the service name as jserver, then enter a wait loop:

wd 'ddename jserver;'

wd 'wait;'

In the other window (the client), use the ddepoke command to send data to the server:

wd 'ddepoke jserver abc xyz mydata;'

The server wait loop will end, with the result:

ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿

³*type  ³11 ddepoke³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´

³*parent³sysddepoke³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´

³*topic ³abc       ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´

³*item  ³xyz       ³

ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´

³*data  ³mydata    ³

ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ

This indicates the character string mydata was sent to the J server, with topic abc and item xyz.

Now terminate the connection from the client:

wd 'ddedis;'

In practice, you will want to set up a protocol that will enable client and server to communicate back and forth. To illustrate this we describe typical hot and cold links that use J as an execution server.


J to J Hot Link
9:  J to J Hot Link

The script packages\dde\server1.js implements the server side of a DDE hot link. The protocol is as follows:

•	the server defines its service name to be:  jserver

•	the client issues a ddestart command, using any topic and item

•	the client issues a ddepoke for this topic and item, with the data being an executable J sentence

•	the server executes the sentence, and returns the result with a ddeadvise command

•	the client can issue a ddepoke repeatedly. If the data is close the topic and item are closed. If the data is exit the J server program is exited. If the data is off the J server task is terminated.

If you have not already done so, load 2 copies of J and minimize Program Manager to reduce screen clutter. In one copy of J (the server), enter:

load 'packages\dde\server1.js'

If you wish, you could load one copy of J, and enter the following command to load the second copy as a server (change the directory reference as appropriate):

wd 'winexec "jsm.exe packages\dde\server1.js";'

You could also create a new Program Manager item, which loads J with this script file as its profile file.

The server displays a Windows dialog box, which will be used to illustrate the conversation. If you wish, you can also minimize the server window.

In the other copy of J (the client), enter a request to start an advise loop with topic a and item x (or choose other names)

wd 'ddestart jserver a x;'

You can now send J sentences to be evaluated:

wddata 'ddepoke jserver a x "i. 4 5";wait;'

0	1	2	3	4

5	6	7	8	9

10	11	12	13	14

15	16	17	18	19

The server window shows the conversation:

Try other expressions,  for example, to create and use names:

wddata 'ddepoke jserver a x "mydata=: 2 3 5 7";wait'

2	3	5	7

wddata 'ddepoke jserver a x "#mydata";'

4

To close the server, enter:

wd 'ddepoke jserver a x "off";'

(The server does not respond.)


J to J Cold Link
9:  J to J  Cold Link

The script packages\dde\server2.js implements the server side of a DDE cold link. The protocol is as follows:

•	the server defines its service name to be:  jserver

•	the client issues a ddepoke for any topic and item, with the data being an executable J sentence

•	the server executes the sentence, and saves the result with the topic and item

•	the client issues a ddereq command for the topic and item

•	the server responds with the corresponding result

•	the client can issue a ddepoke and ddereq repeatedly. If the ddepoke data is exit the J server program is exited. If the data is off the J server task is terminated.

As before, load 2 copies of J and minimize Program Manager. In the server copy of J, enter:

load 'packages\dde\server2.js'

then minimize the server window.

In the client copy of J, enter a ddepoke command with a J sentence to be evaluated:

wd 'ddepoke jserver abc xyz "+/\*:i.7;'

To retrieve the result, send a ddereq message:

wddata 'ddereq jserver abc xyz;'

0 1 5 14 30 55 91

Try other expressions, then to close the server, send:

wd 'ddepoke jserver abc xyz "off";wait;'

(The server does not respond.)

Note that the hot link protocol is simpler than the cold link protocol, since once it is set up, the client need only issue one command to send a sentence and retrieve the result. Also, the ddereq command used with the cold link may time out if the server is not ready to send the data item requested.


Word for Windows to J Cold Link
9:  Word for Windows to J Cold Link

The next example is a cold link from Microsoft Word for Windows (WFW) as client, to a J server. The WFW macro language is essentially a fairly complete version of BASIC, and can be used for experimenting with DDE. Like many other applications, WFW only supports cold links.

First we look at a simple macro that sends a sentence to J and displays the result in a message box. First ensure the cold link J server is ready (run script packages\dde\server2.js). Then load WFW, and create a macro as follows:

Sub MAIN

cn = DDEInitiate("jserver", "mytopic")

DDEPoke cn, "myitem", "+/\i.7"

MsgBox DDERequest$(cn, "myitem")

DDETerminate(cn)

End Sub

When you run this macro,  it displays the message box:

The WFW macro instructions are as follows:

•	the DDEInitiate command initializes the connection between WFW and J, with the given topic name. This command returns a channel number, used by subsequent macro commands.

•	the DDEPoke command sends the sentence to the server

•	the DDERequest command requests the result

•	the MsgBox command displays the result in a message box

•	The DDETerminate command closes the conversation

The file examples\dde\wfwclien.txt contains the macro commands to build a more sophisticated version of this connection, in which WFW displays a dialog box in which you can enter sentences and display the results. Create a new macro, then copy in the example macro commands file. Run the macro and experiment by entering a sentence, and clicking the Run button:


OLE
9:  OLE

Your application can be an Object Linking and Embedding (OLE) client and can use the services of OLE servers. J supports the original version of OLE, but not yet OLE 2.0.

Applications like Microsoft Excel can be used as OLE servers. There are also several utility servers available such as MSGraph, MSDraw, and Equation. These utility servers often come as part of a main application. For example, MSGraph is a graphics OLE server that comes with Microsoft Excel, Microsoft Word for Windows and other applications. Excel graphics are provided by its use of MSGraph.

To find out which of your applications are OLE servers, you can run REGEDIT.EXE /V to browse through all applications that are registered in your system:

wd 'winexec "regedit /v";'

You can also retrieve this information with the qreg command:

txt=. wddata 'qreg;'

Applications listed with a protocol of StdFileEditing are OLE servers and can be accessed through OLE commands. Application names are not case sensitive:

txt=. <;._1 txt

b=. 1&e.@('StdFileEditing'&E.) &> txt

({.~ i.&LF) &> b#txt

MSDraw=Microsoft Draw

ExcelChart=Microsoft Excel Chart

ExcelWorksheet=Microsoft Excel Worksheet

123Worksheet=1-2-3 Worksheet

MSGraph=Graph

Package=Package                             PBrush=Paintbrush Picture

...

An OLE object is complete information about some data. It includes a graphical image of the data (presentation data). If it is an embedded object it includes the fundamental data (native data). If it is a linked object then it includes information that can be used to access the native data. It also includes the information to run an application to edit and process the native data as an OLE server.

J implements OLE commands using the Window Driver. Each OLE object has an id. To display an OLE object a child control must be created with the isiole class, and have the OLE object id set with the ctext command. An OLE object can be activated by double-clicking on it, or by pressing Enter when it has the focus.

The server of an OLE object does not have to be active, and the presentation data can be displayed without the server being active. The server can be activated and closed as required.

Paintbrush and Object Packager are OLE servers available on all systems and are used in the following examples.

First create a Paintbrush OLE object with id pbid:

wd 'olecreate pbid pbrush;'

Paint something, then close and update the embedded object.

List active OLE objects:

wddata 'qole;'

pbid

Create a parent window and display the object:

wd 'pc a;cc w isiole;ctext pbid;'

wd 'pas 0 0;pcenter;pscale;pcloseok;pshow;'

You can save the OLE object on file for later re-use.  Save in file pb.ole:

wd 'olesave pb.ole;'

Now delete it:

wd 'oledelete;'

Load the object from file and activate it. You can then edit and display it as before.

wd 'oleload pbid pb.ole;oleactivate;'


Object Packager
9:  Object Packager

The Object Packager is an OLE server that makes it easy to display an icon that can be used to run a command line. To create a new OLE object:

wd 'olecreate oid package;'

In the Object Package editor, select a new icon and enter a command line (in the same form as the Program Manager File/Run Command Line). Then close the editor.

You display the icon as before, for example:

wd 'pc abc;cc w isiole;ctext oid;pas 0 0;pshow;'

Once the icon is displayed, enter a wait loop to get the users response. If the icon is selected, you can run the command with:

wd 'oleactivate;'

To edit the contents of the package:

wd 'oleactivate 1;'


Graphics
9:  Graphics

MSGraph (or an equivalent graphics server) makes graphics very accessible. The following assumes you have MSGraph on your system.

Delete all OLE objects and free OLE resources:

wd 'olereset;'

Create an embedded msgraph object and activate the MSGraph server (it can be run invisibly if you use the olecinvisible command instead of olecreate):

wd 'olecreate oleid msgraph;'

Data is sent to MSGraph with the oledata command. The data is in clipboard format (utility clipfmt in script format.js converts J data to clipboard format).

dat=. clipfmt (i.6),.2+?6#10

txt=. 'OLE Demo',TAB,'Sales',CR,dat

wd 'oledata ',EAV,txt,EAV,';'

Return MSGraph result back in OLE object:

wd 'oleupdate;'

Now display the graph:

wd 'pc jgraph;'

wd 'xywh 0 0 150 100;cc w isiole;ctext oleid;'

wd 'pas 0 0;pcenter;pscale;pshow;'


Chapter 10 VBX Controls
10:  VBX Controls

VBX (Visual Basic eXtended) controls, also known as Microsoft Custom Controls, are application packages that can be accessed in a simple and consistent way from other Windows applications. They were originally designed for use with Visual Basic, but are also supported directly by J. They include graphics, spreadsheets, text editors, custom dialog box controls, gauges and database interfaces. They have become extremely popular and there is now a wide variety of such controls available from third party manufacturers.

Graph, spinbutton and spreadsheet controls are distributed with J. Utility programs for these controls are stored in directory packages\vbx, along with text files that give summary descriptions. Several demonstrations may be found under the examples directory. For example, to load a demo of the graph control:

load 'examples\graph\grafdemo.js'

For a spreadsheet demo:

load 'examples\ssbc\ssbcdemo.js'

Many Windows applications are distributed with VBX controls - to see the list on your own machine, change to the windows\system directory, and run:

 dir *.vbx

You can also buy VBX controls directly from third party manufacturers. Indeed,  the controls distributed with Windows applications are often subsets or earlier versions of the full systems obtainable from the original manufacturer. For serious use, we recommend you purchase the most recent versions of the controls, which will then include full documentation and support.


Accessing VBX controls
10:  Accessing VBX controls

J interacts with VBX controls using the Window Driver. You need a parent window to display the control, and you then create and use a VBX control in much the same way as for any other child control. You can use both standard and VBX controls on the same form, as in the controls demo (described in Chapter 2).

Each VBX control has a specific list of properties and events. The properties define the way the VBX control is set up. The events are the events that the VBX control can generate. When you create a VBX control, you typically set various properties, and register various events that you want to be notified of. When the VBX is in use, you retrieve information from the control by either reading the value of its properties, or by receiving event notifications (which end a wait loop).

Several Window Driver commands are specific to VBX controls:

qvbx 	query (returns the property and event list)

vbxenable	enable an event

vbxevent	register an event

vbxget	get the value of a property

vbxrefresh	redraw the control

vbxset	set the value of a property

The cc command opens the control. The class indicates it is a VBX control and includes the DOS filename and the control name (a VBX file can contain several controls) and optionally the title in the form below:

cc id vbx:dosfilename:controlname[:title];

Some controls require that a title be given. Controls that do not (such as the controls distributed with J), ignore any title that is given.

For example, to open the graph control:

cc v0 vbx:graph.vbx:graph;

To access a controls properties, the control must be created and be the currently selected child control. You create, select and access a VBX control in much the same way as any other Windows control. You use the qvbx command to return a list of all the controls properties and values, vbxset to set new property values, and vbxget to read specific property values.

To register a controls events, you use the vbxevent command to register the event with the Window Driver before you create the control, and then, after the control is opened and is the currently selected child control, use vbxenable to enable the events. Once enabled, these events cause a wait loop to end.


Using the Spinbutton Control
10:  Using the Spinbutton Control

To illustrate these commands, we use SPIN.VBX, a simple control that is ideal for experimentation. You may wish to enter the commands into a script window for easy editing and re-use.

Create a parent window with a spin control:

wd 'pc spin;'

wd 'xywh 20 20 12 12;'

wd 'cc s0 vbx:spin.vbx:spinbutton;'

wd 'pas 20 20;pcenter;pcloseok;pshow;ptop;'

Move to an execution window, and then list the property values:

a=. wd 'qvbx;'

   list '*properties' wdg a

ctlname         index           left...

width           height          enabled...

mousepointer    hwnd            dragmode...

tag             backcolor...

The events are:

list '*events' wdg a

dragdrop dragover spindown spinup

Note that events are not yet enabled. To see this, enter a wait loop:

wd 'wait;'

then click on the spinbutton. The wait loop does not end (press Ctrl-Break to end it).

Next we enable the spindown and spinup events, which should be triggered whenever the spin buttons are clicked. Re-edit and run the script as:

wd 'pc spin;'

wd 'xywh 20 20 12 12;'

wd 'vbxevent spindown spinup;'

wd 'cc s0 vbx:spin.vbx:spinbutton;'

wd 'vbxenable spindown spindown;'

wd 'pas 20 20;pcenter;pcloseok;pshow;ptop;'

Now when you enter a wait loop, the spin button triggers an event. In an execution window, enter the following, then click on the down spin button:

'*vbx' wdg wd'wait;'

 2 spindown

The result shows the event number and name. (The event numbers are taken from the order in which the event names occur in the result of qvbx). For the spin button to be useful, the windows message handler should take some action on these events. For example, in the controls demo, clicking a spin button toggles the display of the adjacent text box.

We now set a property value, spinorientation. While the VBX control is still active, enter:

wd 'vbxget spinorientation;'

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿

³*type          ³10 result ³

ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´

³*parent        ³sysresult ³

ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´

³*data          ³SpinButton³

ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´

³spinorientation³0         ³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ

This shows the spinorientation property set to 0, the default, which has the spin buttons aligned vertically. Set the property to 1 for horizontal alignment. In the script, enter:

wd 'vbxset spinorientation 1;'

after the cc command, and run the script to display:


Setting Property Values
10:  Setting Property Values

In general, setting the property values for a VBX control can be somewhat time consuming. Since these controls were designed for use with Visual Basic, there is little support for array definitions, so that properties that need a list of values usually must be given these values one by one. The graph control is a typical example. To draw a graph you usually need to enter a list of values to be graphed, and possibly also lists of labels, colors, shadings, and so on.

We use the graph control to illustrate. As before, you should create a script window for easy editing and re-use of the commands.

To create a graph control, enter:

wd 'pc graph;'

wd 'xywh 0 0 100 100;'

wd 'cc s0 vbx:graph.vbx:graph;'

wd 'pas 0 0;pcenter;pcloseok;pshow;ptop;'

Since you have not yet entered any data, the graph control is created with random data.

Now lets redraw the graph with specific data and labels. We use the thispoint command to specify the current point number, then enter values for the data and label text. First close the graph then enter:

wd 'pc graph;'

wd 'xywh 0 0 100 100;'

wd 'cc s0 vbx:graph.vbx:graph;'

wd 'vbxset thispoint 1 graphdata 5;'

wd 'vbxset thispoint 1 labeltext Jan;'

wd 'vbxset thispoint 2 graphdata 8;'

wd 'vbxset thispoint 2 labeltext Feb;'

wd 'vbxset thispoint 3 graphdata 13;'

wd 'vbxset thispoint 3 labeltext Mar;'

wd 'vbxset thispoint 4 graphdata 12;'

wd 'vbxset thispoint 4 labeltext Apr;'

wd 'vbxset thispoint 5 graphdata 9;'

wd 'vbxset thispoint 5 labeltext May;'

wd 'pas 0 0;pcenter;pcloseok;pshow;ptop;'

The graph control provides an alternative method of specifying each item, using indexing in parentheses:

wd 'pc graph;'

wd 'xywh 0 0 100 100;'

wd 'cc s0 vbx:graph.vbx:graph;'

wd 'vbxset data(1) 5 label(1) Jan;'

wd 'vbxset data(2) 8 label(2) Feb;'

wd 'vbxset data(3) 13 label(3) Mar;'

wd 'vbxset data(4) 12 label(4) Apr;'

wd 'vbxset data(5) 9 label(5) May;'

wd 'pas 0 0;pcenter;pcloseok;pshow;ptop;'

Finally, the VBX utilities provided with the system simplify data entry. The script file packages\vbx\vbxutil.js contains generic utilities, and the script file packages\vbx\graph.js contains definitions specific to the graph control. Load these by entering:

load 'graph'

The graph can now be drawn using:

wd 'pc graph;'

wd 'xywh 0 0 100 100;'

wd 'cc s0 vbx:graph.vbx:graph;'

GraphData 5 8 13 12 9

LabelText ;:'Jan Feb Mar Apr May'

wd 'pas 0 0;pcenter;pcloseok;pshow;ptop;'


Creating VBX command verbs
10:  Creating VBX command verbs

The verb LabelText defined in the graph.js script creates a list of VBX commands from its right argument. In fact, it calls a wd 'vbxset...' command for each item in its argument. For example:

LabelText ;:'one two three'

is the same as:

t=. 'vbxset labeltext ',EAV,'one',EAV,';'

t=. t,'vbxset labeltext ',EAV,'two',EAV,';'

t=. t,'vbxset labeltext ',EAV,'three',EAV,';'

wd t

How are such verbs defined? Clearly, it would not be difficult to create a verb to do this, but you may want to use a set of utilities that simplify their construction.

In graph.js, the definition reads:

LabelText=: 'labeltext' vbxclist

All the graph command verbs have similar definitions. vbxclist is an adverb whose argument is the property name being set, and the result is a verb that calls the vbxset property command for each item in its argument. vbxclist is one of several such verbs defined in the script vbxutil.js that will handle all standard VBX commands:

vbxchar	character string

'cmd' vbxchar 'abc'

is

wd 'vbxset cmd ',EAV,'abc',EAV,';'

vbxnum	single number

'cmd'  vbxnum 0

is

wd 'vbxset cmd 0;'

vbxindex	indexed number

'cmd' vbxindex 2 11

is

wd 'vbxset cmd(2) 11;'

vbxclist	character list

'cmd' vbxclist 'abc';'def'

is

wd 'vbxset cmd ',EAV,'abc',EAV,';',

'vbxset cmd ',EAV,'def',EAV,';'

vbnlist	numeric list

'cmd' vbnlist 1 2

is

wd 'vbxset cmd 1;vbxset cmd 2;'

vbxilist	indexed character list

'cmd' vbxilist 10 12

is

wd 'vbxset cmd(0) 10;vbxset cmd(1) 12;'

vbxdata	an array of rank 0, 1 or 2

'cmd' vbxdata >: i.2 2

is

wd 'vbxset cmd 1',TAB,'2',CR,'3',TAB,'4',CR,';'

When you create these command verbs, you will have to examine each one to determine the appropriate syntax. However, you can make a good start on this using the verb vbxcmds defined in vbxcmds.js. This will create command definitions for a VBX control (you should check the results before using them).

For example, for the graph control:

load 'vbxcmds'

5{. vbxcmds 'graph.vbx:graph'

autoinc=:        'autoinc' vbxnum

backdrop=:       'backdrop' vbxchar

backdropstyle=:  'backdropstyle' vbxnum

background=:     'background' vbxnum

borderstyle=:    'borderstyle' vbxnum


Chapter 11 ODBC Data Driver
11:  ODBC Data Driver Overview

The Open Database Connectivity (ODBC) interface allows applications to access data from database management systems (DBMS), using Structured Query Language (SQL) expressions.

The J/ODBC interface uses the Data Driver verbs, defined in script dd.js.

The processing required by the application is essentially independent of the DBMS. For example, if you have written programs to access dBase files using ODBC, then you can use similar programs to access Paradox, or indeed any other DBMS.

The application, and the driver programs that access the DBMS, are physically separate. To access a DBMS, you need only ensure a driver for that DBMS is available. There are ODBC drivers for virtually all commercial DBMS, and J itself is distributed with drivers for several popular systems, including Access, Btrieve, dBase, Excel, FoxPro, Oracle, Paradox and SQL Server.

Note that the DBMS need not itself support SQL, for example dBase does not. All that matters is that the ODBC DBMS driver supports SQL.

An ODBC DBMS driver, together with information on where its datasets are stored, is typically referred to as a data source.

Between the application and the data there are 3 layers, though they appear to the application as a single unit:

J application

Data Driver

ODBC Manager

Data Source	Data Source	Data Source
Data	Data	Data

The application sends requests to the Data Driver (using the verbs defined in script dd.js), which converts them into a standard format and sends them to the ODBC Manager. The ODBC Manager then sends them to the appropriate Data Source, and is also responsible for ensuring the required drivers are loaded. The Data Source drivers then handle the data access.


The SQL language
11:  The SQL language

SQL, or Structured Query Language, is a widely accepted protocol used for data access. It is an ANSI standard with SQL-92 being the most recent specification. A summary of the language appears in Appendix B.

The language is defined with various levels, listed in the appendix as minimum, core and extended. All SQL servers support at least the minimum level, some may also support core or extended levels, or extensions of their own. ODBC DBMS drivers are distributed with Help files that list the functionality of the driver, plus other useful information - when you install the drivers you should also print out the Help files for reference.


Installing ODBC
11:  Installing ODBC

The ODBC disks are distributed with the system, but are installed separately. The ODBC setup:

•	installs the ODBC Manager. If already installed, it updates any older files with new versions. It also creates a new Control Panel icon for ODBC (if there is not one already), from which you can configure the setup later.

•	installs individual DBMS drivers, as requested

You must first be running Windows. Insert the ODBC distribution disk 1 in drive a: (or other available drive). From the Program Manager, select the File/Run menu option. In the Command Line box, enter:

a:setup

and choose the OK button.

This presents a dialog box from which you can select the drivers to install. You need only install the drivers you require now. You can always add other drivers later by re-running the ODBC set up, which will prompt for the new drivers to be installed.

To follow the examples in this chapter, you should install the dBase driver, even if you do not intend to use it later. When you install this driver, or any other driver, you will be prompted to enter the data source name. The data source indicates the DBMS driver and where the data files are stored (on a PC, this is the DOS directory). Note that it is not the name of a specific data file as may be imagined.

The examples here use the dBase driver, and files stored in J subdirectory examples\data, and the data source name used is jdata. To set this up, in Program Manager, select the ODBC icon in Control Panel. Use Add or Setup to create a panel as shown:

Note that you should at least have one data source name as shown above, but you can set up multiple data source names, using the same driver but typically with a different DOS directory.

Although the data source name specifies a DOS directory, this is in fact used by the dBase driver as the default directory. You can override this default either by specifying another DOS directory when you connect to the dBase driver, or afterwards when you specify a file with its full DOS pathname. However, note this capability is provided by extensions to ODBC in the dBase driver, which are not necessarily found in other ODBC drivers.


ODBC Connection and Statement Handles
11:  ODBC Connection and Statement Handles

You start accessing a database by first opening a connection to the data source. The result is a number, called the connection handle. Subsequent requests to the data source use this connection handle.

When you send a request to select some data, the result is also a number, called the statement handle. Again, subsequent requests that reference this selection use the statement handle. There may be more than one statement handle associated with a connection handle. You may also have a statement handle not associated with a connection handle, where the request made was not specific to a particular data file.

In both cases, you should close the handle to free up resources when you are finished with it. For example, to read records from a file, you typically:

•	open a connection to the data source, returning a connection handle

•	make a selection on a specific file using the connection handle, returning a statement handle

•	read the records, using the statement handle

•	close the statement handle

•	close the connection handle

You must always close a connection handle explicitly. However, a statement handle may be closed if you have fetched all records selected - see the discussion of ddfet below. In any case, it is good practice to always close the statement handle explicitly, as there is no harm done if you try to close a handle that had already been closed.


Data Driver
11:  Data Driver

ODBC access is provided by the Data Driver verbs, that are defined in script dd.js. First load this file:

load 'dd'

The Data Driver verbs may be summarized as follows:

Here, ch refers to a connection handle, and sh a statement handle. Note that SQL commands are not case-sensitive.

ddcnm	r=. ddcnm sh

Column names of selected data

ddcol	r=. 'tdata' ddcol ch

Column names and atrributes in a database

ddcom	r=. ddcom ch

Commit a transaction (after a ddtrn)

ddcon	ch=. ddcon 'dsn=jdata'

Connect to ODBC data source name. The result is a connection handle. The argument can set several parameters. Some are supported by all databases, and others have a meaning only for specific databases. Parameters recognized by most database systems are:

dsn	ODBC data source name

dlg	dlg=1 prompts for a connection string with a dialog box with entries for User Id and Password (not supported by the distributed dBase driver)

uid	user name

pwd	user password

modifysql	set to 1 (the default) to use ODBC SQL grammer. Set to 0 to use 	native database grammer.

rereadafterupdate

set to 1 to force a re-read of a record after an update. This is useful for retrieving auto-updated values such as timestamps.

rereadafterinsert

set to 1 to force a re-read of a record after an insert

dddis	r=. dddis ch

Closes connection handle (disconnects from the data source)

ddend	r=. ddend sh

Closes statement handle

dderr	r=. dderr ''

Return error message on last command. An error message is given when a data driver verb returns _1.

ddfet	r=. ddfet sh,n

Fetch next record from selected data. Note that after you have read a record, the next fetch will not read it again. If you need to read it again, you must select it again. For example:

r=. ddfet sh 	fetch next record (same as ddfet sh,1)

r=. ddfet sh,5    	fetch next 5 records

r=. ddfet sh,_1  	fetch all remaining records.

If you fetch all remaining records using ddfet sh,_1,  or if your fetch returns fewer records that you requested (i.e. the fetch reads past the end of the file), then ddfet closes the statement handle. Otherwise, the statement handle remains open, and you should explicitly close it if you have finished reading the file.

ddrbk	r=. ddrbk ch

Discards (rollbacks) a transaction (after a ddtrn)

ddsel	sh=. 'select * from tdata' ddsel ch

Select data from a database, returning a statement handle

ddsql	r=. 'create table mydata' ddsql ch

Execute an SQL statement

ddsrc	sh=. ddsrc ''

Data source names available from the ODBC manager. Use ddfet to read them. 	These names can be used as the dsn= argument to ddcon.

ddtbl	sh=. ddtbl ch

Returns a statement handle for tables in the data source. Some ODBC drivers, including the distributed dBase driver, do not support this service and the result will be empty.

ddtrn	r=. ddtrn ch

Begin a transaction on a connection. Subsequent actions are not committed to the database until a ddcom is done. Actions since the ddtrn can be discarded by doing a ddrbk (rollback).


Listing the Data Sources
11:  Listing the Data Sources

The list of data sources that are specified in the ODBC set up dialog box can be retrieved under program control. The verb ddsrc requests this information, returning a statement handle:

ddsrc ''

1

Now use ddfet to fetch the data. The argument to ddfet has two numbers:  statement handle, number of records to be read (_1 for all records). To read all records:

ddfet 1 _1

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÂ¿

³MS Access Databases³*.mdb³0³³

ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÅ´

³Paradox Files      ³*.db ³0³³

ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÅ´

³jdata              ³*.dbf³0³³

ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÅ´

³pfxdata            ³*.dbf³0³³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÁÙ

The result will depend on the drivers you have set up. Note that you should see an entry for jdata, which is the data source name you assigned to the examples\data subdirectory.

The result has 4 items for each data source: the data source name; the DOS file extension; the connection handle (0 if none); and remarks (usually empty).

The function ddsources in script packages\files\ddutil.js returns the data source names.


ODBC error messages
11:  ODBC error messages

The data driver verbs that open and close connections, and send SQL statements, all return a number. Typically, if the number is positive, it is a handle. If the number is 0, it means the operation completed successfully (but the function returns no handle). If the number is _1, it means there was some error. You can get more information about the errror using dderr. For example, try closing a non-existent statement handle:

ddend 42

_1

dderr ''

ÚÄÄÄÄÂÄÂÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

³4101³0³0³The connection, statement, or query handle...

ÀÄÄÄÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

The result has 4 elements, of which the first 3 are internal numbers generated by the DBMS driver or the ODBC interface. The last element is the error message.

>{:dderr ''

The connection, statement, or query handle you provided is not valid.

The utility dderror defined in the ddutil.js script displays an error message if the last ODBC command resulted in an error, otherwise it does nothing. It is a handy way of testing your ODBC statements:

dderror ddend 42


Connecting to a data source
11:  Connecting to a data source

The ddcon command connects to a data source returning a connection handle, using the form:

[ch=. ddcon 'dsn=jdata'

1

If you want to use dderror to check the results, enter statements in the form:

dderror ch=. ddcon 'dsn=jdata'

We have now connected to a data source, but not yet to a data file. The file we will use is tdata, and the next statement uses ddcol to retrieve the column names and attributes for this file:

$cols=. 'tdata' ddcol ch

7 12

3 4 7 {"1 cols

ÚÄÄÄÄÄÄÂÄÄÄÄÂÄÄÄÄÄÄÄÄÄ¿

³Column³Type³Type_Name³

ÃÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´

³NAME  ³1   ³CHAR     ³

ÃÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´

³SEX   ³1   ³CHAR     ³

ÃÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´

³DEPT  ³1   ³CHAR     ³

ÃÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´

...


Selecting and reading data
11:  Selecting and reading data

To read data from a file, you first select the data you want to read using the ddsel verb, which returns a statement handle. You then use ddfet to fetch the records.

The left argument of ddsel is a SQL selection expression. Here are typical examples:

Select all records (* means all columns):

sh=. 'select * from tdata' ddsel ch

Fetch the first 3 records:

ddfet sh,3

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÂÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄ¿

³MACDONALD B   ³F³D101³1.95906e7³1.97805e7³26073³

ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄ´

³GENEREAUX S   ³F³D103³1.94503e7³1.96602e7³76332³

ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄ´

³KOEBEL R      ³M³D101³1.93711e7³1.98009e7³50699³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÙ

Fetch the next record:

ddfet sh

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÂÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄ¿

³KELLER J      ³F³D101³1.95105e7³1.97404e7³39119³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÙ

Close the statement handle:

ddend sh

You should always close the statement handle when you no longer need it. However to avoid repetition, the remaining examples do not show this.

Select males with salary exceeding 40000:

sel=.'select * from tdata where sex=''M'' and salary >= 40000'

sh=. sel ddsel ch

ddfet sh,4

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÂÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄ¿

³KOEBEL R      ³M³D101³1.93711e7³1.98009e7³50699³

ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄ´

³NEWTON R      ³M³D108³1.95601e7³1.97902e7³58694³

ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄ´

³ROGERSON G    ³M³D101³1.95712e7³1.98302e7³87021³

ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄ´

³ANCTIL J      ³M³D108³1.94606e7³1.97906e7³48779³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÙ

Select only the name, department and salary fields, where date of birth is before 1950:

sel=.'select name,dept,salary from tdata where dob<19500000'

Fetch the first such record:

ddfet sel ddsel ch

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÂÄÄÄÄÄ¿

³GENEREAUX S   ³D103³40653³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÙ


Updating a record
11:  Updating a record

To update a record, you process an SQL update statement. Here we update the salary field for ABBOTT K.

First read the record to see the current value (the salary is 40653):

sel=. 'select * from tdata where name=''ABBOTT K'''

ddfet sel ddsel ch

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÂÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄ¿

³ABBOTT K      ³M³D101³1.9631e7³1.98309e7³40653³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÙ

Next we process an update statement:

us=. 'update tdata set salary=45000 where name=''ABBOTT K'''

us ddsql ch

Finally, we read the record again, to ensure the update was successful:

sel=. 'select * from tdata where name=''ABBOTT K'''

ddfet sel ddsel ch

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÂÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄ¿

³ABBOTT K      ³M³D101³1.9631e7³1.98309e7³45000³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÙ


Creating a new file
11:  Creating a new file

To create a new file, use the SQL create command, with a list of the column names and attributes in the new data set. Here we create a new file test, with columns for name and salary.

First, drop test in case it already exists (the _1 result means the table was not found):

'drop table test' ddsql ch

_1

Now create the new file:

  'create table test (name char(12),sal numeric)' t ddsql ch

0

Add a record:

t=. 'insert into test (name,sal) values (''Neumann,  E'',40000)'

t ddsql ch

0

Add another record:

t=. 'insert into test (name,sal) values (''James, P'',42000)'

t ddsql ch

0

Now read the file:

ddfet _1,~ 'select * from test' ddsel ch

ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄ¿

³Neumann, E  ³40000³

ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄ´

³James, P    ³42000³

ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÙ


Chapter 12 Calling DLL Procedures
12:  Calling Procedures in DLLs

A DLL is a file (usually with extension .dll) that contains procedures. For example, file mmsystem.dll is a DLL of multimedia procedures. A J program can call DLL procedures.

Operating system facilities are provided by system DLLs such as kernel and user. Of perhaps greater interest are DLLs provided by software vendors. You can also write your own DLLs.

Note: calling procedures incorrectly can crash your system or corrupt memory. Ensure your work is saved first!

The function cd defined in dll.js calls a DLL procedure. The form is:

'filename procedure declaration' cd parameters

The left argument gives the DLL filename, procedure name, and a declaration of the result and parameter types.

•	The filename specifies the name of the DLL file. If it is already loaded it is found by matching the prefix part of the filename. If not already loaded and the name is not full qualified, Windows searches for it in the current directory, the windows directory, the windows\system directory, etc. Procedures specified by number rather than name have a # followed by the digits.

•	A procedure returns a scalar result and takes 0 or more parameters. Parameters are passed by value or by a pointer to values. Pointer parameters can be read and set.

•	The declaration is a set of blank delimited codes describing the result and parameter types:

c    	character

s    	short integer (2 byte)

i    	integer (4 byte)

f    	short float (4 byte IEEE)

d    	float (8 byte IEEE)

*    	pointer

n    	no result (only for result)

m    	memory address (only as *m)

The c i and d types are native J types. The s and f types are not native J types and are managed as character data.

The * type is a pointer to values. A J character, integer, or float vector can be the parameter for a * type. A J scalar integer, as a memory address, can also be a * type parameter. For example, the result of mema (see later section on Memory Management) could be a * type parameter. A * type can be followed by a modifier of  c s i f d or m. A scalar 0 is the NULL pointer.

The cd right argument is a list of enclosed parameters. The first declaration type describes the result and the remaining types describe the parameters in the cd right argument. An empty vector is treated as 0 enclosed values and a scalar is treated as a list with the enclosed scalar.

The cd result is the procedure result catenated with its possibly modified right argument.

For example, the Programmers Reference, Volume 2: Functions manual of the Microsoft Windows Software Developmnt Kit documents procedure getprofilestring in the kernel DLL. The procedure gets the value of a section keyword from the win.ini file.

'kernel getprofilestring s *c *c *c *c s' cd 'windows'; 'spooler'; 'default'; (32$'z');32

The first type s indicates that the procedure returns a short integer. The first pointer names a section. The second pointer names a keyword. The third pointer is the default if the keyword is not found. The fourth parameter is where the keyword text is put. The fifth parameter is the length of memory addressed by the fourth parameter.

If the getprofilestring declaration was wrong, say result type i instead of s, it would crash your system. If the fifth parameter was 64 and the keyword was longer than the 32 characters allocated by the fourth parameter, the extra data would overwrite memory causing unpredictable damage.

If you have multimedia sound support (refer to the Sound icon in Control Panel) then you could use the mmsystem DLL to play .wav files as follows:

'mmsystem sndplaysound s *c s'cd '\windows\chimes.wav';1

Procedures are usually documented with a C prototype or a Visual Basic declaration.

The C prototype for getprofilestring is:

UINT GetProfileString(LPCSTR, LPCSTR, LPCSTR, LPSTR, int)

The VB declaration for getprofilestring is:

Declare Function GetProfileString% Lib:kernel (ByVal r%, s$, k$, b$, k%)

J declaration types and some corresponding C and VB types are:

J    	C	    	Visual  Basic

c   	char, BYTE, BOOL

s   	int, short int, unsigned short int, UINT,	%	WORD, HANDLE, HWND, HGLOBAL

i	long int, unsigned long int, DWORD	&

f	float	!	d	 	double	#

*	char far *, LPSTR, LPCSTR	$

n	void

Return Codes

cd returns the following scalar integer error codes:

_1   library not found

_2   procedure not found

_3   too many DLLs loaded (limit of 20)

Type declaration or parameter errors are reported as the index of the type in error.


Memory Management
12:  Memory Management

Some DLL procedures return pointers to memory or require parameters of pointers to memory that cannot be provided by referencing a J array. The following foreign conjunctions are provided to allocate, free, read and write memory:

memr=. 15!:1

memw=. 15!:2

mema=. 15!:3

memf=. 15!:4

mema allocates memory. The result is an integer memory address that can be used as a parameter for a * type with cd or as the address for memf, memr, and memw. You can do address arithmetic (address+1000), but it should be avoided if possible. A 0 result indicates the allocation failed. For example:

address=. mema length

memf frees memory. The argument could be a mema result or pointer returned by a procedure. A 0 result is success and a 1 is failure. For example:

memf address

memr reads data from memory. Use an offset rather than adding to the address. A length of _1 reads data up to the first 0  (reading a C string). For example:

data=. memr address,offset,length

memw writes data to memory. data must be a character vector and length must match the length of the data, or be 1 greater, in which case a 0 is appended (writing a C string). For example:

data memw address,offset,length


Chapter 13 Packages and examples
13:  Packages and Examples

The subdirectories packages and examples contain various J programs.

•	The packages directory includes additional utilities that are either specific to a particular type of application, for example statistics and actuarial work, or specific to the computer configuration, for example LaserJet and VBX utilities. You may want to include these utilities in your own programs.

•	The examples directory includes a variety of code examples, and some standalone demos. These examples should help you understand various aspects of the system.

Each subdirectory of packages and examples includes a text file with the same name as the directory, that describes its contents. For example, the directory examples\graph includes a file graph.txt. If you want to make use of the code in any directory, you should print out the corresponding file.


Packages
13:  Packages

color

Scripts to support RGB color definitions.

dde

Scripts to support DDE.

•	server.js	set up J an execution/request server

•	server1.js	set up J as a hot-link server

•	server2.js	set up J as a cold-link server

The script server.js is the recommended general purpose J/DDE server. For example, it is used by the Visual Basic/J API in directory examples\dde\vb. For more details, refer to Write file examples\dde\vb\vb.wri.

files

Scripts to support access to files.

•	dbase.js 	contains utilities that provide direct access to dBase files

•	ddutil.js 	contains various Data Driver utilities

•	jfiles.js	J component file system (see description later in this chapter)

•	kfiles.js	keyed file system

•	nfiles.js	read and write files in various internal formats

finance

Financial and actuarial utilities. For example:

load 'act'

QX=. actable 'GAM83M'

Annuities-due for ages 60 and 61, guaranteed 5 years, payable monthly, interest 6.5% for 5 years, 5% thereafter:

annx 60 61;0 0 5 0 12;0.065 5 0.05;0;QX

11.6612 11.3912

isigraph

Scripts to support the isigraph control. For example:

load 'isigraph'

gshow 255 0 255 gpolygon gscale polygon 5 [ gopen''

print

Scripts to support printing, using the LaserJet directly, and via Windows Write.

The LaserJet functions allow printing to an attached LaserJet printer. For example, assuming your LaserJet is connected to LPT1, try:

load 'laserjet'

   ljprintfile2 'files'

This prints the script files.js in 2-up form (landscape mode with 2 columns per page) - a very convenient way to print script files.

stats

Various statistical routines. For example:

Discrete values for a poisson distribution with mean 2, frequencies from 0 to 5:

load 'stats'

poissondist 2 5

0.135335 0.270671 0.270671 0.180447 0.0902235 0.0360894

Summary statistics for some random numbers in a normal distribution with mean 0 and standard deviation 1:

dstat normalrand 10000

sample size:         10000

minimum:          _4.00425

maximum:           4.05703

median:       _0.001509861

mean:         _0.005932915

std devn:        0.9997345

skewness:      _0.01277013

kurtosis:          3.02423

util

Script uread.js provides a simple utility database for J functions. It is distributed with the utilities defined in subdirectory main, and you can add your own definitions if required. To include this in your start up profile, in myutil.js include the line:

'z' load 'packages\util\uread.js'

Once this is loaded, you can retrieve utilities by name, instead of having to load in the script where they were originally defined:

uread 'range ruler'

range ruler

   range 1 20 3

1 4 7 10 13 16 19

To read the directory:

   uread ''

assert     av         baserep    bx...

clean      clipfmt    colhdr     colsum...

dfh        diff       expand     expandn...

...

vbx

The subdirectory vbx provides support for VBX controls.

•	vbxutil.js 	generic utilities that can be used with any control.

•	vbxcmds.js 	functions to help set up specific VBX utilities.

•	graph.js and ssbc.js 	support the graph and spreadsheet controls distributed with 	the system.


Example Scripts
13:  Example Scripts

There are many scripts with examples. The directories are:

data    	data for the examples

dde    	DDE demos with J as client and as server

dde\vb	DDE demos specific to Visual Basic

demo    	various Window controls demos

graph   	graph VBX demos

isigraph	isigraph demos

math	mathematical functions

memo    	memomate application - a simple text database

ssbc    	spreadsheet VBX demos

wp	sample window programs


JFiles
13:  JFiles

Jfiles are component files for J data. A jfile can be thought of as a boxed list which is stored on file. An element of the boxed list is referred to as a component, and can store a noun of any type, shape or size. File components are numbered sequentially from 0 upwards.

To access the system (assuming you are using the standard profile):

load 'jfiles'

This populates a locale jfiles with utility functions, and defines the following verbs in the z locale:

jcreate

jerase

jappend

jread

jreplace

jdup

jsize

You create a file using jcreate.

jappend adds new items to the file. Each item added to the file is stored in a new component. Several items can be added to the file at a time.

jread reads items from file, and jreplace replaces items on file.

jdup duplicates a file, and jsize returns its size.

You can refer to a file either by its file name, or by its file handle. The default file extension is .jf - this is used if no file extension is given.

You cannot delete components once created. If you need to reclaim space no longer required, either replace the components with empties, or else duplicate the file, copying only the components required.

Create file

jcreate

create a file. The right argument is the filename. Any existing file is overwritten. The result is 1 if successful, else 0. For example:

jcreate 'mydata'

1

Note that since the file extension was not specified, this actually creates a DOS file named mydata.jf.

Read and write file

jappend

append to file. The left argument is a boxed list, with each item in the list stored in a new file component. An open noun is treated as a single boxed item. The right argument is the filename. The result is the new component numbers created. For example:

   (<'header') jappend 'mydata'

0

   ('rec1';'rec2') jappend 'mydata'

1 2

   (< <\1 2 3) jappend 'mydata'

3

   (2 2$10 20 30 40) jappend 'mydata'

4

jread

read file. The right argument is the filename, linked with one or more component

numbers. The result has the same shape as the component numbers. For example:

> jread 'mydata';4

10 20

30 40

jread 'mydata';i.5

ÚÄÄÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄ¿

³header³rec1³rec2³ÚÄÂÄÄÄÂÄÄÄÄÄ¿³10 20³

³      ³    ³    ³³1³1 2³1 2 3³³30 40³

³      ³    ³    ³ÀÄÁÄÄÄÁÄÄÄÄÄÙ³     ³

ÀÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÙ

jread 'mydata';i.2 2

ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

³header³rec1         ³

ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´

³rec2  ³ÚÄÂÄÄÄÂÄÄÄÄÄ¿³

³      ³³1³1 2³1 2 3³³

³      ³ÀÄÁÄÄÄÁÄÄÄÄÄÙ³

ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

jreplace

replace in file. The result is the components replaced. For example:

(1000;'abcde') jreplace 'mydata';1 2

1 2

jread 'mydata';i.3

ÚÄÄÄÄÄÄÂÄÄÄÄÂÄÄÄÄÄ¿

³header³1000³abcde³

ÀÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÙ

The left argument is reshaped if necessary to match the components in the right argument. For example, the following replaces components 1-3, each with the word 'reserved':

'reserved' jreplace 'mydata';1 2 3

1 2 3

Utilities

jdup

duplicate file. The left argument is the new filename; if elided, the file is duplicated in place. The right argument is the source filename, optionally linked with one or more component numbers to be copied to the new file, in the order given. By default, the entire file is duplicated. The result is the number of components written. For example:

'newdata' jdup 'mydata'

5

'newdata' jdup 'mydata';2 0 1

3

jsize

size of file, as 4 numbers:

starting component number (0)

number of components

length of file in bytes (same as result of 1!:4)

amount of free space that could be recovered by duplicating the file

For example:

jsize 'newdata'

0 5 1312 0

jerase

erase file, for example:

jerase 'newdata'

1

File handles

You can refer to a file either by its filename, or by its file handle if you have already opened the file. For most purposes we recommend using the filename. However, if you have a great deal of file activity, you may find it faster to open the file first, then use the file handle; this means the system does not have to open and close the file each time it is accessed. The utilities jopen and jclose in the jfiles locale can be used for this purpose. For example:

h=. jopen_jfiles_ 'mydata'

... process file using handle h...

jclose_jfiles_ h

1

File structure

Each file is structured as a header record, followed by data. The header record is as

follows:

[0]   version

[1]   starting component

[2]   number of components

[3]   file length

[4]   directory pointer

[5]   freelist pointer

Freelist

Each component is stored in its 3!:1 representation in a space that is a power of 2. This means that on average, the representation fills 75% of the space allocated, and allows some space for growing replaces. If the space required on replacement is less than half the space allocated, then the balance is freed up.

If you replace a component with a noun of smaller size, then this may result in some unused space. The system keeps track of this in the freelist, and attempts to reuse it where possible. The total free space available is given in the fourth element of the result of jsize, and this is the space that would be freed by duplicating the file using jdup.


Chapter 14 Runtime applications
14:  Runtime Applications

The Professional Edition of J includes a runtime system.

You can only develop and distribute runtime applications with the Professional Edition.

The files jrt.exe, j387.dll, and jemu.dll are required for your runtime applications. The file jsm.exe is not required for a runtime application, and may not be distributed.

If your application requires the VBX controls as distributed, or the ODBC drivers as distributed, you are also licensed to distribute the corresponding disks with your runtime applications. You may not distribute either of these disks separately, or other than as a required part of your runtime application.

A runtime application:

•	can be distributed royalty-free to run on other computers

•	does not use the J session manager for input and output

•	does not use js scripts, but instead uses jr scripts, which are encoded js scripts

•	does not use jsm.exe, but instead uses the runtime equivalent, jrt.exe

•	can be started from a Program Manager icon, so the J system is invisible to the user

The runtime executable jrt.exe is stored in compressed form on the runtime diskette. When you use Setup to install a runtime application, this file is automatically expanded. However, you may want to expand the file first, for testing purposes. To do so, put the runtime diskette in the a: drive (or other available drive), and enter:

expand  a:jrt.ex__  jrt.exe

To create a runtime application:

•	create a script file that loads the application.

•	use the Window Driver command makejr to convert this script file into a runtime script, with a suffix of jr. For example,

wd 'makejr examples\demo\runtime.js runtime.jr;'

•	Add an icon to a Program Group to run the application:

∗	open the Program Group where you want to add the application

∗	from the menu select File/New and press OK

∗	complete the Program Item Properties dialog box. The Command Line runs jrt.exe with a parameter of the jr file, e.g.

c:\j2\jrt.exe runtime.jr

∗	press Change Icon... and then Browse... to select an icon

∗	Press OK to accept the new definition.

Once set up, clicking the icon runs the application.

Packaging a Runtime Application

You can package your application professionally into a Windows Setup diskette. To do so:

•	Create an empty directory into which you will copy all the files required for your application. For example:

md \release

cd \release

•	Copy the J Runtime diskette that came with your J system to this directory:

copy a:*.*

•	Copy your application files to the release directory. There should be at least one .jr file and a related .ico file. The icon file can be any icon but must have the same name as the jr file. For example, if your application is statpack.jr then you must have a statpack.ico file. Both files must be copied to the release directory.

Example

To build a setup disk for the runtime example shown above, using the distributed j2y.ico:

copy runtime.jr \release

copy j2y.ico \release\runtime.ico

•	In J, customize Windows Setup for your application by loading the script main\makerel.js and executing makerel with an argument of your release directory:

load 'main\makerel.js'

makerel '\release'

•	In DOS, you can now copy the release directory to an empty diskette:

copy \release\*.*  a:

•	To install from this disk, from Program Manager run a:setup.

You can also test the installation from the hard disk, by running \release\setup from Program Manager.

An installation diskette can contain several applications, with each application installed in the program group with its own icon. The verb makerel assumes each .jr file in the release directory that has a matching .ico file, is a separate application, and will have setup create a Program Manager item for it.

Runtime Enquiry

Your application can determine if it is executing under the runtime system using the Window Driver command qrt, which returns a *data result of 1 if  so, otherwise 0, e.g. try:

   wddata 'qrt;'

0

You should ensure that the application exits from J when it has completed, e.g. calls

2!:55 ''

If you miss out this step, you will get an error message when your application has completed. You can test your application by ending it with a verb that terminates only if executing in the runtime version. The verb rtoff is defined in myutil.js as follows:

rtoff=: 3 : 0

if. '1'=>{:,wd 'qrt;' do. 2!:55'' end. 1

)

rtoff''

Creating Single Script Files

If your application requires more than one script file, each script file must be converted into a .jr file, since in the runtime version, the verbs that load scripts only recognise this type of file.

For convenience, you may want your application  to be in a single script file. This avoids the problem of having to convert references to .js files when loading in other script files, to references to .jr files.

The utilities save and scriptmake defined in the j locale can help you create a single script file.


Appendix B    SQL Statements

The following SQL statements define the base ODBC SQL grammar.

Statement	Min	Core	Ext
alter-table-statement ::=         ALTER TABLE base-table-name        {     ADD column-identifier data-type   |      ADD (column-identifier data-type [, column-identifier data-type]... )        }
create-index-statement ::=        CREATE [UNIQUE] INDEX index-name        ON base-table-name        ( column-identifier [ASC | DESC]        [, column-identifier [ASC | DESC] ]... )
create-table-statement ::=        CREATE TABLE base-table-name-1        (column-element [, column-element] ...)        column-element ::= column-definition | table-constraint-definition        column-definition ::=                column-identifier data-type                 DEFAULT default-value                [column-constraint-definition [,column-constraint-definition]...]        column-constraint-definition ::=                NOT NULL                | UNIQUE | PRIMARY KEY )                | REFERENCES base-table-name-2 referenced-columns                | CHECK (search-condition)               default-value ::= literal | NULL | USER        table-constraint-definition ::=                UNIQUE (column-identifier [, column-identifier] ...)                | PRIMARY KEY (column-identifier                       [, column-identifier] ...)                | CHECK (search-condition)                | FOREIGN KEY referencing-columns REFERENCES                       base-table-name-2 referenced-columns
create-view-statement ::=        CREATE VIEW viewed-table-name        [( column-identifier [, column-identifier]... )]        AS query-specification
delete-statement-positioned ::=        DELETE FROM table-name WHERE CURRENT OF cursor-name			(v2)
delete-statement-searched ::=        DELETE FROM table-name [WHERE search-condition]
drop-index-statement ::=        DROP INDEX index-name
drop-table-statement ::=        DROP TABLE base-table-name                [ CASCADE | RESTRICT ]
drop-view-statement ::=        DROP VIEW viewed-table-name                [ CASCADE | RESTRICT ]
grant-statement ::=        GRANT {ALL | grant-privilege [, grant-privilege]... }        ON table-name        TO {PUBLIC | user-name [, user-name]... }        grant-privilege ::=                DELETE                | INSERT                | SELECT                | UPDATE [( column-identifier [, column-identifier]... )]                | REFERENCES [( column-identifier                       [, column-identifier]... )]
insert-statement ::=        INSERT INTO table-name [( column-identifier [, column-identifier]...)]        VALUES (insert-value[,insert-value]... )
insert-statement ::=    INSERT INTO table-name [( column-identifier [, column-identifier]... )]        { query-specification | VALUES (insert-value [, insert-value]...}
ODBC-procedure-extension ::=        ODBC-std-esc-initiator [?=]call procedure ODBC-std-esc-terminator        | ODBC-ext-esc-initiator [?=]call procedure ODBC-ext-esc-terminator
revoke-statement ::=        REVOKE {ALL | revoke-privilege [, revoke-privilege]... }        ON table-name        FROM {PUBLIC | user-name [, user-name]... }        [ CASCADE | RESTRICT ]         revoke-privilege ::=                DELETE                | INSERT        | SELECT                | UPDATE | REFERENCES
select-statement ::=        SELECT [ALL | DISTINCT] select-list        FROM table-reference-list[        [WHERE  search-condition]        [order-by-clause]
select-statement ::=        SELECT [ALL | DISTINCT] select-list        FROM table-reference-list        [WHERE search-condition]        [GROUP BY column-name [, column-name]... ]        [HAVING search-condition]        [UNION select-statement]...        [order-by-clause]
select-for-update-statement ::=        SELECT [ALL | DISTINCT] select-list        FROM table-reference-list        [WHERE  search-condition]        FOR UPDATE OF [column-name [, column-name]...]		(v1)	(v2)
statement ::= create-table-statement        | delete-statement-searched     | drop-table-statement        | insert-statement     | select-statement        | update-statement-searched
statement ::= alter-table-statement        | create-index-statement        | create-table-statement        | create-view-statement        | delete-statement-positioned        | delete-statement-searched        | drop-index-statement        | drop-table-statement        | drop-view-statement        | grant-statement        | insert-statement        | revoke-statement        | select-statement        | select-for-update-statement        | update-statement-positioned        | update-statement-searched
statement ::= alter-table-statement        | create-index-statement        | create-table-statement        | create-view-statement        | delete-statement-positioned (continued)        | delete-statement-searched        | drop-index-statement        | drop-table-statement        | drop-view-statement        | grant-statement        | insert-statement        | ODBC-procedure-extension        | revoke-statement        | select-statement        | select-for-update-statement        | statement-list        | update-statement-positioned        | update-statement-searched
statement-list ::= statement | statement;statement-list
update-statement-positioned ::=        UPDATE table-name        SET column-identifier = {expression | NULL}                [, column-identifier = {expression | NULL}]...        WHERE CURRENT OF cursor-name		(v1)	(v2)
update-statement-searched        UPDATE table-name        SET column-identifier = {expression | NULL }               [, column-identifier = {expression | NULL}]...        [WHERE search-condition]


SQL Elements
Appendix B    SQL Elements

The following elements are used in the SQL statements listed previously .

Element	Min	Core	Ext
approximate-numeric-literal ::= mantissaEexponent        mantissa ::= exact-numeric-literal        exponent ::= [+|-] unsigned-integer
approximate-numeric-type ::=        FLOAT        | DOUBLE PRECISION        | REAL
argument-list ::= expression | expression, argument-list
base-table-identifier ::= user-defined-name
base-table-name ::= base-table-identifier
base-table-name ::= [user-name.]base-table-identifier
between-predicate ::= expression [NOT] BETWEEN expression AND        expression
binary-literal ::= {implementation defined}
binary-type ::=        BINARY (length)        | VARBINARY (length)        | LONG VARBINARY·
character ::= {any character in the implementor's character set}
character-string-literal :: = '{character}...'
character-string-type ::= CHARACTER(length) | CHAR(length)
character-string-type ::= CHARACTER(length) | CHAR(length) | CHARACTER VARYING(length) | VARCHAR(length)
character-string-type ::= CHARACTER(length) | CHAR(length) | CHARACTER VARYING(length) | VARCHAR(length) | LONG VARCHAR
column-identifier ::= user-defined-name
column-name ::= [table-name.]column-identifier
column-name ::= [{table-name | correlation-name}.]column-identifier
comparison-operator ::= < | > | <= | >= | = | <>
comparison-predicate ::=          expression comparison-operator expression
comparison-predicate ::= expression comparison-operator          {expression | (sub-query)}
correlation-name ::= user-defined-name
cursor-name ::= user-defined-name
data-type ::= character-string-type
data-type ::= character-string-type | exact-numeric-type | approximate-numeric-type
data-type ::= character-string-type | exact-numeric-type | approximate-numeric-type | binary-type | date-type | time-type | timestamp-type
date-literal ::= 'date-value'
date-separator ::= -
date-type ::= DATE
date-value ::= years-value date-separator months-value date-separator days-value
days-value ::= digit digit·
digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
dynamic-parameter ::= ?
exact-numeric-literal ::=          [+|-] { unsigned-integer [.unsigned-integer ]          | unsigned-integer.          | .unsigned-integer }
exact-numeric-type ::= DECIMAL(precision,scale) | NUMERIC(precision,scale) | SMALLINT | INTEGER
exact-numeric-type ::= DECIMAL(precision,scale) | NUMERIC(precision,scale) | BIT | SMALLINT | INTEGER |BIGINT
exists-predicate ::= EXISTS ( sub-query )
expression ::= term | expression {+|-} term term ::= factor | term {*|/} factor factor ::= [+|-]primary primary ::= column-name | dynamic-parameter | literal (continued) | ( expression ) primary ::= column-name                | dynamic-parameter                | literal                | set-function-reference                | USER                | ( expression ) primary ::= column-name                | dynamic-parameter                | literal                | ODBC-scalar-function-extension                | set-function-reference                | USER                | ( expression )
hours-value ::= digit digit
index-identifier ::= user-defined-name
index-name ::= [index-qualifier.]index-identifier
Index-qualifier ::= user-defined-name
in-predicate ::=        expression [NOT] IN {(value {, value}...) | (sub-query)}        value ::= literal | USER  | dynamic-parameter
insert-value ::=        dynamic-parameter        | literal        | NULL        | USER
keyword ::=        (see list of reserved keywords)
length ::= unsigned-integer
letter ::= lower-case-letter | upper-case-letter
like-predicate ::= column-name [NOT] LIKE pattern-value pattern-value ::= character-string-literal | dynamic-parameter | USER pattern-value ::= character-string-literal | dynamic-parameter(In a character-string-literal, the percent character ('%') matches 0 ormore of any character; the underscore character  ('_') matches 1character.)
literal ::= character-string-literal
literal ::= character-string-literal | numeric-literal
literal ::= character-string-literal | numeric-literal | binary-literal  ODBC-date-time-extension
lower-case-letter ::=        a | b | c | d | e | f | g | h | i | j | k | l | m |         n | o | p | q | r | s | t | u | v | w | x | y | z
minutes-value ::= digit digit
months-value ::= digit digit
null-predicate ::= column-name IS [NOT] NULL
numeric-literal ::= exact-numeric-literal | approximate-numeric-literal
ODBC-date-time-extension ::=        ODBC-std-esc-initiator d date-literal ODBC-std-esc-terminator        | ODBC-ext-esc-initiator d date-literal ODBC-ext-esc-terminator        | ODBC-std-esc-initiator t time-literal ODBC-std-esc-terminator        | ODBC-ext-esc-initiator t time-literal ODBC-ext-esc-terminator        | ODBC-std-esc-initiator ts timestamp-literal ODBC-std-esc-terminator        | ODBC-ext-esc-initiator ts timestamp-literal ODBC-ext-esc-terminator
ODBC-ext-esc-initiator ::= {
ODBC-ext-esc-terminator ::= }
ODBC-outer-join-extension ::=        ODBC-std-esc-initiator oj outer-join ODBC-std-esc-terminator        | ODBC-ext-esc-initiator oj outer-join ODBC-ext-esc-terminator
ODBC-scalar-function-extension ::=        ODBC-std-esc-initiator fn scalar-function ODBC-std-esc-terminator        | ODBC-ext-esc-initiator fn scalar-function ODBC-ext-esc-terminator
ODBC-std-esc-initiator ::= ODBC-std-esc-prefix SQL-esc-vendor-clause        SQL-esc-vendor-clause ::= VENDOR(Microsoft), PRODUCT(ODBC)        ODBC-std-esc-prefix ::= --(*
ODBC-std-esc-terminator ::= *)--
order-by-clause ::=  ORDER BY sort-specification [, sort-specification]...        sort-specification ::= {unsigned-integer | column-name } [ASC | DESC]
outer-join ::= table-name [correlation-name] LEFT OUTER JOIN         table-name [correlation-name] ON search-condition(For outer joins, search-condition must contain only the join condition between the specified table-references.)
precision ::= unsigned integer
predicate ::=        between-predicate | comparison-predicate | exists-predicate        | in-predicate | like-predicate | null-predicate | quantified-predicate
predicate ::=        comparison-predicate | like-predicate | null-predicate
procedure ::= procedure-name        | procedure-name (procedure-parameter-list)
procedure-identifier ::= user-defined-name
procedure-name ::= [user-name.]procedure-identifier
procedure-parameter-list ::= procedure-parameter        | procedure-parameter, procedure-parameter-lis
procedure-parameter ::= dynamic-parameter | literal
quantified-predicate ::= expression comparison-operator {ALL | ANY}                (sub-query)
query-specification ::=         SELECT [ALL | DISTINCT] select-list         FROM table-reference-list         [WHERE search-condition]         [GROUP BY column-name, [column-name]...]         [HAVING search-condition]
referenced-columns ::= ( column-identifier [, column-identifier]... )
referencing-columns ::= (column-identifier [, column-identifier]... )
scalar-function ::= function-name (argument-list)(The definitions for the non-terminals function-name and function-name (argument-list) are derived from the list of scalar functions in Appendix G, »Scalar Functions«.)
scale ::= unsigned-integer
search-condition ::=       boolean-term [OR search-condition]       boolean-term ::= boolean-factor [AND boolean-term]       boolean-factor ::= [NOT] boolean-primary       boolean-primary ::= predicate | ( search-condition )
seconds-fraction ::= unsigned-integer
seconds-value ::= digit digit
select-list ::= * | select-sublist [, select-sublist]...
select-sublist ::= expression select-sublist ::= expression | {table-name | correlation-name}.*
set-function-reference ::= COUNT(*) | distinct-function | all-function        distinct-function ::=                {AVG | COUNT | MAX |  MIN | SUM} (DISTINCT column-name)        all-function ::=               {AVG | MAX |  MIN | SUM} (expression)
sub-query ::=         SELECT [ALL | DISTINCT] select-list        FROM table-reference-list        [WHERE search-condition]        [GROUP BY column-name [, column-name]...]        [HAVING search-condition]
table-identifier ::= user-defined-name
table-name ::= table-identifier
table-name ::= [user-name.]table-identifier
table-reference ::= table-name
table-reference ::= table-name [correlation-name]
table-reference-list ::= table-reference [,table-reference]…
table-reference-list ::= table-reference [,table-reference]…        | ODBC-outer-join-extension
time-literal ::= 'time-value'
time-separator ::= :
time-type ::= TIME
time-value ::=         hours-value time-separator minutes-value time-separator         seconds-value
timestamp-literal ::= 'date-value timestamp-separator                 time-value[.seconds-fraction]'
timestamp-separator ::=          (The blank character.)
timestamp-type ::= TIMESTAMP
unsigned-integer ::= {digit}...
upper-case-letter ::=        A | B | C | D | E | F | G | H | I | J | K | L | M |         N | O | P | Q | R | S | T | U | V | W | X | Y | Z
user-defined-name ::=        letter[digit | letter | _]...
viewed-table-identifier ::= user-defined-name
viewed-table-name ::= [user-name.]viewed-table-identifier
years-value ::= digit digit digit digit


SQL Reserved Keywords
Appendix B    SQL Reserved Keywords

The following words are reserved for use in ODBC function calls.  These words do not constrain the minimum SQL grammar; however, to ensure compatibility with drivers that support the core SQL grammar, applications should avoid using any of these keywords.

ABSOLUTE

ADA

ADD

ALL

ALLOCATE

ALTER

AND

ANY

ARE

AS

ASC

ASSERTION

AT

AUTHORIZATION

AVG

BEGIN

BETWEEN

BIT

BIT_LENGTH

BY

CASCADE

CASCADED

CASE

CAST

CATALOG

CHAR

CHAR_LENGTH

CHARACTER

CHARACTER_LENGTH

CHECK

CLOSE

COALESCE

COBOL

COLLATE

COLLATION

COLUMN

COMMIT

CONNECT

CONNECTION

CONSTRAINT

CONSTRAINTS

CONTINUE

CONVERT

CORRESPONDING

COUNT

CREATE

CURRENT

CURRENT_DATE

CURRENT_TIME

CURRENT_TIMESTAM

CURSOR

DATE

DAY

DEALLOCATE

DEC

DECIMAL

DECLARE

DEFERRABLE

DEFERRED

DELETE

DESC

DESCRIBE

DESCRIPTOR

DIAGNOSTICS

DICTIONARY

DISCONNECT

DISPLACEMENT

DISTINCT

DOMAIN

DOUBLE

DROP

ELSE

END

END-EXEC

ESCAPE

EXCEPT

EXCEPTION

EXEC

EXECUTE

EXISTS

EXTERNAL

EXTRACT

FALSE

FETCH

FIRST

FLOAT

FOR

FOREIGN

FORTRAN

FOUND

FROM

FULL

GET

GLOBAL

GO

GOTO

GRANT

GROUP

HAVING

HOUR

IDENTITY

IGNORE

IMMEDIATE

IN

INCLUDE

INDEX

INDICATOR

INITIALLY

INNER

INPUT

INSENSITIVE

INSERT

INTEGER

INTERSECT

INTERVAL

INTO

IS

ISOLATION

JOIN

KEY

LANGUAGE

LAST

LEFT

LEVEL

LIKE

LOCAL

LOWER

MATCH

MAX

MIN

MINUTE

MODULE

MONTH

MUMPS

NAMES

NATIONAL

NCHAR

NEXT

NONE

NOT

NULL

NULLIF

NUMERIC

OCTET_LENGTH

OF

OFF

ON

ONLY

OPEN

OPTION

OR

ORDER

OUTER

OUTPUT

OVERLAPS

PARTIAL

PASCAL

PLI

POSITION

PRECISION

PREPARE

PRESERVE

PRIMARY

PRIOR

PRIVILEGES

PROCEDURE

PUBLIC

RESTRICT

REVOKE

RIGHT

ROLLBACK

ROWS

SCHEMA

SCROLL

SECOND

SECTION

SELECT

SEQUENCE

SET

SIZE

SMALLINT

SOME

SQL

SQLCA

SQLCODE

SQLERROR

SQLSTATE

SQLWARNING

SUBSTRING

SUM

SYSTEM

TABLE

TEMPORARY

THEN

TIME

TIMESTAMP

TIMEZONE_HOUR

TIMEZONE_MINUTE

TO

TRANSACTION

TRANSLATE

TRANSLATION

TRUE

UNION

UNIQUE

UNKNOWN

UPDATE

UPPER

USAGE

USER

USING

VALUE

VALUES

VARCHAR

VARYING

VIEW

WHEN

WHENEVER

WHERE

WITH

WORK

YEAR


Window Driver
Window Driver Reference

The Window Driver lets you program a graphical user interface and access Windows services.

Overview

Parent

Id

Child

Class

Style

Location and Size

Wait

Form Edit

Common Dialog Box

Fonts

Accelerators

Tab and Cursor Keys

CR and LF

Ownerdraw

Dynamic Data Exchange

Object Linking and Embedding

VBX Control

Commands


Window Driver Overview
Overview

A window program (wp) is a character vector of statements that create, manipulate, and interact with windows.

'pc abc; pshow;' has two statements. The first statement is the command pc with parameter abc and the second statement is command pshow.

Statements must end with semicolon.

Commands and parameters are separated by whitespace. Whitespace is 1 or more characters from the set (space, carriage return, line feed, tab, vertical tab, and form feed).

Simple parameters start with an alphanumeric or - and run to the ; or whitespace.

Delimited parameters start with ", EAV, or 197{a. and run to the matching delimiter. EAV is 255{a.. The 197{a. character is visible and can be entered with Alt+0197.

Function wd executes a window program. Try the following series of commands.

wd 'pc a; ptop; pshow; rem create parent, stay on top, and show it;'

wd 'pn "my window";'

wd 'cc pressme button; rem create child pushbutton;'

wd 'wait;'

wd 'reset; rem close all windows;'


Parent

The pc command creates a parent window that is initially not visible. It can be displayed in various ways with the pshow command. A parent window is the display area for the menus and child windows required by a user interface.

The pc command sets the id of the parent.

There can be more than one parent window. Commands affect the selected parent id. The pc command selects the new parent and the psel command can select any parent. An event for a parent that ends a wait command does a psel of that parent.

The pco command creates a parent window that is 'owned' by the currently selected parent. The owner is disabled until the new parent is closed.

The pcd command creates a parent that is owned by the current parent and has a dialog box frame.

wd 'pc a; pshow;'


Id

Ids identify parent windows, child windows, menu items, and OLE objects.

Ids start with an alphabetic and consist of alphanumeric characters and the period.

Ids are case-sensitive and can be up to 127 characters.

By convention, an id of abc.5 could be used as the id for the 5th instance of a parent or child. The prefix abc could be used to select the routine to run for events and the full id could be used to select that particular object.


Child

The cc command creates a child window that belongs to the selected parent.

A child window is often called a control.

The cc command sets the id of the control.

There can be more than one child for a parent. Commands affect the selected child id of the selected parent id.

cc selects the new child and the csel command can select any child of the selected parent. An event for a child that ends a wait command does a psel of the parent and a csel of the child.

cci creates a child window with the same class and initial style as the last cc command.

wd 'pc a; cc b button; pshow;'


Class

cc and cci create a child window with a class and style.

The class sets the basic appearance and behavior of the window.

There are 10 classes:

	button	pushbutton, checkbox, radiobutton..
	edit	a box for editing text
	listbox	list of items
	combobox	combination of an edit and a listbox
	scrollbar	vertical or horizontal scrollbar
	static	static text or box
	isigraph	a box in which graphics commands draw
	isipicture	picture from a BMP, WMF, or ICO file
	isiole	presentation graphic of an OLE object
	vbx	VBX control


button Class

A child with class button appears and acts differently depending on the styles it is created with.

wd'cc b1 button; rem create pushbutton;'

wd'cc b2 button bs_autocheckbox; rem create box with a label that can be checked;'

wd'cc b3 button bs_autoradiobutton; rem create circle with a label that can be checked;'

A radio button is usually created as part of a group. Clicking a button in the group checks that button and unchecks the previously checked button in the group.

Style bs_groupbox creates a box with a label that is used to visually group other buttons.

Style bs_ownerdraw creates an ownerdraw button.


edit Class

A child with class edit is a box in which text can be displayed and edited.

An edit control created with style es_multiline can contain multiple lines of text.

cf... commands can set different fonts for edit controls.

ced... commands further customize and manipulate edit controls.

wd 'cc e1 edit ws_border;'

wd 'cc e1 edit es_multiline ;'

wd 'cc e1 edit es_multiline ws_hscroll ws_vscroll ;'


listbox Class

A child with class listbox is a box which displays a list of items.

wd 'cc l1 listbox ;'

wd 'cc l2 listbox ws_vscroll ;'

wd 'cc l3 listbox lbs_sort ;'

wd 'cc l4 listbox lbs_multiplesel ;'

A listbox with style lbs_multiplesel allows the user to select more than one item.

A listbox with style lbs_multicolumn has multiple columns. Command clbcol sets the column width.

Style lbs_notify allows a double-click of a listbox item to be a button event and end the wait command.

The ctext command puts items in the listbox. Items are delimited by LF.

Items selected are returned in the result of a wait or qd command with the id of the listbox. Multiple selections are delimited by LF,

Style lbs_ownerdrawfixed creates an ownerdraw listbox.


combobox Class

A child with class combobox is a combination of a listbox and an edit box.

wd 'cc c1 combobox ;'

wd 'cc c2 combobox cbs_dropdown ;'

The cn command puts text in the edit box.

The ctext command puts items in the listbox. Items are delimited by LF.


scrollbar Class

A child with class scrollbar is similar to the scrollbars that scroll an edit control.

wd 'cc s1 scrollbar ;'

wd 'cc s2 scrollbar sbs_vert ;'

wd 'ctext 0 500 1000 50;'

Clicking a scrollbar ends the wait command with a button event.

The ctext command sets the values of the of the scroll bar leftmost position, current position, rightmost position, and the size of change from a click in the area between the thumbbox and either end of the scrollbar.


static Class

A control with class static creates a visual object that is not active.

A static control can contain text and can have various types of frames and backgrounds. The ss_ styles determine the appearance of a static control.

Static controls separate and label areas in a window.


isigraph Class

A control with class isigraph is a graphbox in which graphs can be drawn.

Coordinates: x is 0 to 1000 at the right; y is 0 to 1000 at the top.

Graphics commands start with g.

wd 'pc graph; cc g isigraph; gmove 50 50; gline 700 700; gshow; pas 0 0; pshow;'


isipicture Class

A control with class isipicture displays an image from a file.

The file is a DIB (device independent bitmap), WMF (Windows metafile) or ICO (icon file).

DIB files usually have a file extension of BMP.

The ctext command sets the filename.

wd 'pc picture; cc p isipicture; ctext examples\data\yacht.bmp; pas 0 0; pscale; pshow;'

wd 'pc picture; cc p isipicture; ctext examples\data\ship.bmp; pas 0 0; pscale; pshow;'

wd 'pc picture; cc p isipicture; ctext j2y.ico; pas 0 0; pscale; pshow;'


isiole Class

A control with class isiole displays an image from an OLE object.

See OLE for more information.

OLE objects are managed by commands starting with ole.

OLE objects have an id.

The ctext command sets the OLE object id into the child control.

Activate an ole object displayed in a window by double-clicking.

wd 'pc a; cc x isiole; ctext oid; pas 0 0; pshow; olecreate oid pbrush;'


vbx Class

A control with class vbx displays a VBX control.

See VBX Control for more information.


Style

The cc command creates a child window with a class and style.

Styles customize the appearance and behavior of the class.

Styles start with a class prefix. For example, bs_ for button styles.

Styles should only be used with their corresponding class.

ws_ styles can be used with all classes.

group style groups the control with the previous control. Tab and Cursor keys recognize groups.

wd 'rem return cc and cci styles; qs;'

wd 'pc a; cc e edit es_multiline ws_border; pshow;'


Location and Size

The location and size of a child in a parent is set with the rectangle.

The xywh command sets the rectangle;

adj and other commands adjust the values of the rectangle.

4 integers define the rectangle:

x	units from the left

y	units from the top

w	units in width (to the right)

h	units in height (to the bottom)

Units are in terms of the average character size in the system font.

x and w values are 1/4 of the width and y and h values are 1/8 of the height of the system font. For example, a control with xywh values of 40 80 100 160 would be: 10 characters from the left edge of the parent; 10 lines down from the top edge of the parent; 25 characters wide; and 20 lines high.

Location and size defined relative to the size of the system font allow window definitions to display reasonably on different screens at different resolutions.

wd 'rem return pixels in x and y units; qm;'

wd 'pc a;xywh 10 10 20 20;cc b button;pshow;'


Wait

The wait command waits for an event, for example, the press of a button. The wait command must be the last command.

The wd result is an n by 2 array of boxed character vectors. The first column is the id of the data.

The first row is *type and indicates which event ended the wait.

System ids start with *. *type is the type of event, *error is the error that occurred, *index is the 0 origin index in wp of the command in error, and *id is the id of the control that caused the event.

Additional system information is returned with ids in the first column that start with sys.

If the event is for a parent, the parent id is selected as the current parent (psel).

If the event is for a child, the parent is selected (psel) and the child is selected (csel).

If the event is for a parent, its location and size is returned in *pinfo and the data for all children is returned with their ids.

wd 'qt;'

wd 'qe;'

wd 'pc a ; cc b button; ptop; pshow; wait;'


Common Dialog Box

Windows provides several built in dialog boxes that perform common functions.

Color dialog box allows selection of RGB colors.

wd ' mbcolor ;'

Font dialog box allows selection of a logical font.

wd ' mbfont ;'

wd ' smfont; rem select last chosen font as the session manager font;'

Message box displays a message and waits for a user response.

wd ' mb title text ;'

wd ' mb title text mb_iconstop mb_retrycancel ;'

wd ' qs mb ;'

Open filename dialog box allows the user to specify a fully qualified file name.

wd ' mbopen;'

wd ' mbopen title "" "" "Write(*.wri)|*.wri|Word(*.doc)|*.doc" ofn_filemustexist ;'

wd ' qs mbopen ;'

Save filename dialog box is similar to the open filename dialog box.


Fonts

A font can be chosen with the mbfont command. The result is a description of a font and is the CURRENT font. The result, either explicit or implicit, can be the argument to other commands.

A maximum of 20 fonts can be selected for use in controls. Destroying a control does not release the font resource. A reset command frees all font resources.

cf... commands select a font for a child.

cfont [font] selects current font or font described by argument

cfoem selects OEM fixed pitch font

cfsesm selects current session manager font

cfsys selects system proportional pitch font (initial default font)

fontdef [font] sets default font for new controls as current font or from argument.

fontcur [font] sets current font from argument

mbfont [font] runs common dialog box for choosing fonts

smfont [font] selects current font or argument as the session manager font


Accelerators
Accelerator Keys

& in the name of a button or menu item sets a keyboard accelerator. The & is not displayed and the next character is underlined. ALT + the character is the same as clicking on the button or menu item.


Tab and Cursor Keys

TAB and SHIFT+TAB cycle the focus through the children in the order they were created.

Cursor keys cycle through the controls in a group. By default controls are created as part of a group consisting only of themselves.

The group style creates a control that is grouped with the previous control.

wd ' cci b1 group;'


CR and LF

Data read from a multiline edit control will contain CR,LF pairs.

ctext will expand LF or CR to CR,LF as is required in a multiline edit control.


ownderdraw
Ownerdraw

A button created with bs_ownerdraw is an ownerdraw button.

A listbox created with lbs_ownerdrawfixed is an ownerdraw listbox.

A control with ownerdraw style displays a picture from a file. The files supported are the same types supported for the pictures in isipicture class windows.

The file name to display for an ownerdraw button is set with the cn command.

The file names to display for each element in the listbox are set with the ctext command. The first parameter in the ctext command for an ownerdraw listbox is the height for each element.

wd ' pc a; xywh 10 10 30 30; cc b1 button bs_ownerdraw; cn yacht.wmf ; pas 10 10; pshow;'

wd 'pc a;xywh 5 5 50 150;cc l1 listbox lbs_ownerdrawfixed ws_border;pas 5 5;pshow;'

wd ' ctext 50 yacht.wmf ship.bmp j2y.ico ;'


DDE
Dynamic Data Exchange

You can use DDE to communicate with other applications as well as with other J tasks.

A CLIENT initiates a DDE conversation (link) with a SERVER.

If you are familiar with DDE in another application you can learn how to use it with that application, otherwise it might be easier to first play with it between two J tasks.

start first J task to be the server:

wd ' ddename imaserver ; rem register server name;'

wd ' rem wait for client requests; wait;'

start second J task to be the client:

wd ' ddeex imaserver system "[doit(now)]" ; rem send command to server;'

DDE conversation

A conversation is based on SERVICE and TOPIC. Service identifies the server application and topic is the high level identifier of the information being exchanged.

An exchange may involve an ITEM (low level information identifier) and DATA.

Service, topic, and item ids are case insensitive.

S|T refers to the conversation with service S on topic T.

S|T!I refers to conversation S|T on topic I and identifies the information that is exchanged.

wd ' ddecons ; rem return active S|T conversations;'

The number of conversations is limited to 20.

The ddedis command terminates conversations.

wd ' ddedis ; rem terminate all conversations;'

wd ' ddedis excel ; rem terminate excel conversations;'

wd ' ddedis excel system ; rem terminate excel|system;'

System Topic

Many servers support a topic and item of system|sysitems.

wd ' winexec c:\excel\excel.exe ;'

wd ' ddereq excel system sysitems ;'

wd ' ddereq excel system topics ;'

Advise loop

A client can request data for S|T!I when it wants it, or it can request an advise loop on S|T!I so the server will notify it when the data for S|T!I has changed. The wait command ends with *type of ddeadvise to indicate that data has changed.

Client Commands

ddecons	return S|T conversations (links)

ddedis	[s [t]]	disconnect

ddeex	s t d	execute command in partner

ddepoke	s t i d	poke data to partner

ddereq	s t i	request data from partner

ddestart	s t i	start advise loop on S|T!I

ddestop	s t i	stop advise loop on S|T!I

Client Events (*type in wait result)

ddeadvise	new data is available for S|T!I advise loop

Server Commands

To act as a server you must set a service name. The service name can only be set once. The service name can be set on the command line with /ddename= to allow a task to start J and establish links before the J application finishes initialization.

ddename	s	set service name

ddereqd	d	provide data to ddereq event. MUST be first command after event.

ddeadvise	t i d	provide data to advise loops. Returns 0 if loop no longer active.

Server Events (*type in wait result)

ddeex	execute command string

ddepoke	new data for S|T!I

ddereq	request for data. MUST issue ddereqd command immediately.

ddestart	request for advise loop

Execute

Servers that support execute usually support it only in the system topic.

Most applications follow the conventions for execute data indicated in the following:

[open("sample.xlm")]

[run("r1c1")]

[connect][download(query1,results.txt)][disconnect]

Server support of execute is usually limited. For non-trivial tasks it is best to use macro facilities in the application to build a macro and then use ddeex to run it.

run EXCEL and define a global macro called test that opens a new worksheet

wd ' ddeex excel system ',EAV,'[run("global.xlm!test")]',EAV,';'

run WORD for Windows and define a global macro called test that opens a new document

wd ' ddeex winword system "[test]" ;'

Data

Data is ascii text (sometimes referred to as cf_text data).

Some applications use TAB and CR to give structure to the data.

EXCEL uses TAB to separate columns and CR to separate rows.

Two rows by three columns of data could be set in EXCEL sheet1 if data was properly formed.

wd ' ddepoke excel sheet1 r1c3:r2c3 ',data,';'

Errors

*error 31 dde failed has additional information in *ddeerror. *ddeerror is the numeric error code returned by the low level dde function. *ddeerror 16386 contains text that explains that the error number indicates the dde function timed out.


OLE
Object Linking and Embedding

Your application can be an OLE client and can use the services of OLE servers.

Applications like EXCEL can be used as OLE servers. There are also several utility servers available such as MSGraph, MSDraw, and Equation. These utility servers often come as part of a main application.

MSGraph is a graphics OLE server that comes with EXCEL, WORD and other applications. EXCEL graphics are provided by its use of MSGraph.

You can run REGEDIT.EXE /V to list applications registered in your system. Those listed with a protocol of StdFileEditing are OLE servers and can be accessed through the OLE commands.

wd ' qreg ;'

An oleobject is complete information about some data. It includes a graphical image of the data (presentation data). If it is an embedded object it includes the fundamental data (native data). If it is a linked object then it includes information that can be used to access the native data. It also includes the information to run an application to edit and process the native data as an OLE server.

An oleobject has an id.

To display an oleobject a window must be created as an isiole class window and have the oleobject id set with the ctext command.

An oleobject displayed in an isiole window can be activated by double-clicking or by pressing ENTER when it has focus.

The server of an oleobject does not have to be active. The presentation data can be displayed without the server being active. The server can be activated and closed as required.

Paintbrush and Object Packager are OLE servers available on all systems and are used in the following examples.

wd ' olecreate pbid pbrush ;'

pbid is the id and pbrush is the name of the Paintbrush server. Paint something, then close and update the embedded object

wd ' qole ;'

wd ' olesave pb.ole ; rem save the oleobject in file pb.ole;'

wd ' oledelete ; rem delete current oleobject;'

wd ' oleload oleid pb.ole ; rem load object from file (not activated);'

wd ' oleactivate ;''

wd ' pc a;cc w isiole ; pas 0 0 ; pscale ; pcloseok ; pshow ; ctext oleid ;'

MSGraph (or an equivalent graphics server) makes good graphics very accessible.

wd ' olereset ; rem delete oleobjects and free ole resources;'

wd ' olecreate oleid msgraph ; rem create empty msgraph object and activate MSGraph server;'

Data is sent to MSGraph with the oledata command. The data has columns delimited by TAB and CR.

wd ' oledata ',data,'; rem data is text with TAB and CR defining the matrix;'

wd ' oleupdate ; rem get MSGraph result back in oleobject;'

Window from Paintbrush example will now display graph

MSGraph can be run invisibly if you use the olecinvisible command instead of olecreate.

The Object Packager is an OLE server that makes it easy to display an icon that can be used to run a command line.

wd ' olecreate oid package;'

wd ' oleactivate ; rem run the command line in the package;'

wd ' oleactivate 1; rem verb 1 edits the package;'


VBX Control

A control with class vbx displays a VBX control. A VBX control is created with the cc command. The class indicates it is a VBX control and gives the filename that contains the control, the name of the control (a vbx file can contain several controls) and an optional title for the control.

wd'cc g vbx:graph.vbx:graph:title;'

VBX properties and events are returned by qvbx.

wd'qvbx;'

Properties can be set and read.

wd'vbxget graphtype;'	get value of property graphtype

wd'vbxget graphtype graphstyle;'	get graphtype and graphstyle

wd'vbxset graphtype 2'	set graphtype to 2

wd'vbxset graphtype 2 graphstyle 4;'	set value of graphtype and graphstyle

Properties of type picture can only be set with the file name of a .bmp file.

wd'vbxset picture examples\data\aquarium.bmp'

Some properties are arrays and can have an index. The index is part of the name and must not be separated by blanks.

wd'vbxget extradata(3);'

wd'vbxset extradata(3) 1;

VBX events can end a wait if they are registered and are enabled. VBX events must be registered before the control is created.

wd'vbxevent keypress;'	register keypress event

wd'vbxevent click selchange;'	register click and selchange events

VBX events must be enabled after the control is created.

wd'vbxenable click;'

Some events can provide additional information. This information must be explicitly requested and the data type must be indicated. The Visual Basic symbols %&!# indicate respectively 2 byte integer, 4 byte integer, 4 byte floating point, and 8 byte floating point.

wd'vbxenable keypress %;'	key number as a 2 byte integer

wd'vbxenable click &&;'	ssbc.vbx click event with row and col


WD Command Reference
Window Driver Commands

The first letter(s) of a command usually indicates a general category:

p	parent window
c	child window
ced	child edit
cf	child font
g	graphics
q	queries that return information
sm	session manager
smp	session manager print commands
mb	common dialog boxes
dde	DDE
ole	OLE
vbx	VBX

Parameters are integer, id, text, or style.

-1 usually indicates the value is inherited from a previous value.

An id identifies a parent, child, menu item, or oleobject.

A style parameter is a keyword. A prefix usually indicates what it applies to. For example, bs_autoradiobutton is a button style.

qs command returns command styles.

wd ' qs;'

wd ' qs mb;'

COMMANDS

acttask taskhandle ;  activate task. winexec returns taskhandle

acttitle title ;  activate window with title bar that matches argument (case insensitive)

adj i j ;  adjust rectangle X and Y values by i and ,j

adjh i ;  adjust rectangle Y value by H and i

adjw i ;  adjust rectangle X value by W and i

args p0 p1...;  sets parameters p0 through p9. Parameters are referenced in later commands as %0 through %9.

wd 'args abc;  pc id; pn %0;'

beep i ;  beep i times

cc id class [styles] ;  create child. id identifies the child in results and is used to select the child as a target for other commands. class must be a valid class (e.g., button). 0 or more styles customize the control. id is used as initial name (see cn command).

ccheck b ;  check or uncheck button

cci id [styles] ;  create child with class and initial style inherited from last cc command.

cdir filespec [styles] ;  add file list to listbox or combobox. Styles are from the set (archives, directories, drives, exclusive, hidden, normal, readonly, system). exclusive excludes normal files and lists only those indicated.

cedgetsel ;  get selection information. *data result is start and end of selection.

cedrep text ;  replace selection with text

cedro ;  edit control set as readonly

cedrw ; edit control set as readwrite

cedsel start end ;  set selection. start and end are indexes into the edit control text. Caret is set at the end of the selection with the larger value. start of -1 clears selection. end of -1 selects up to end of data. Text is scrolled in the window so that the caret is visible.

cedtext n text ;  writes text to the edit box and scrolls so that line n is visible.

cenable bool ;  enable or disable child

cfocus ;  set input focus

cfoem ;  oem fixed pitch font (standard pc character set)

cfont ;  font chosen in mbfont command is set as child font

cfsesm ;  set session manager font as child font

cfsys ;  system variable pitch font

chide ;  hide child window (a hidden edit box can contain data)

clbcol i;  set column width for multi-column listbox

clipcopy text ;  puts text on the clipboard

clippaste ;  *data result is text from the clipboard

clscroll n ;  scroll edit text n lines. n can be signed.

cn text ;  child name set to text

csel id ;  select child id as target for commands

csendm i j k ;  *data set as result of sendmessage i, wParam j, lParam k

csendmstr i j text ;  *data set as result of sendmessage i, wParam j, lParam addressing text

csetsel i ;  set selection to item i in listbox or combobox. In a multiple select listbox the selection is added to any already selected. An argument of -1 clears all selections.

cshow ;  show child window (undoes chide)

ctext text ;  write new text in listbox, combobox, edit box. listbox and combobox items are LF delimited.

ctext filename ;  set filename for isipicture window of DIB (device independent bitmap), WMF (Windows Metafile), or ICO (icon) file to display.

ctext min, pos, max, size ;  set scrollbar minimum, position, maximum, and size of change

ddeadvise t i d ;  Send data to client in an advise loop. Client will get ddeadvise event.

ddecons ;  return s|t active conversations

ddedis [s [t]] ;  discontinue (terminate) conversations.

wd ' ddedis ;'	terminate all conversations with all servers

wd ' ddedis s ;'	terminate all conversations with server s

wd ' ddedis s t ;'	terminate conversation with server s on topic t

ddeex s t d ;  data d is sent to server s for topic t to execute.

ddename id ;  set dde service name (can only be done once). Command line /ddename= can also set dde service name.

ddepoke s t i d ;  send data to S|T!I

ddereq s t i ;  data for item i is requested from S|T

ddereqd d ;  send data in response to ddereq event (must be done immediately after ddereq event)

ddestart s t i ;  advise loop requested for S|T!I. New data signals ddeadvise event

ddestop s t i ;  stop advise loop on S|T!I

fontcur font ;  set current logical font. font is the information that describes a logical font and is the result of the mbfont command.

fontdef [font];  set default font used when a window is created to be the current chosen font or to the font defined by the font parameters.

garc i j k l xa ya xz yz;  draw arc on the ellipse defined by rectangle i,j,k,l. Arc starts at xa,ya and ends at xz,yz. Start and end points need not lie on the ellipse, they define a line from the center that intersects the ellipse.

gbkcolor ;  set current background color to color from last grgb command. Background color is used in the gaps in styled lines and as the background for text.

gbkmode bool ;  set background mode for gbkcolor to OPAQUE for 0, or TRANSPARENT for 1.

gbrush ;  select solid brush in color from last grgb command

gbrushnull ;  select null brush. The null brush leaves the area painted with it unchanged.

gchord  i j k l xa ya xz yz ;  same parameters as garc. The chord area is drawn with the pen and filled with the brush.

gclear ;  clear graphics box

gellipse i j k l ;  draws an ellipse in the rectangle i,j,k,l with the pen and fills it with the brush.

gflood i j r g b;  fills the area around point i,j with the current brush. The area is bounded by the color r,g,b.

gline i j ;  draw line from current position to point i,j and update current position

glines pts ;  draw connected lines. pts is 2 or points. NOTE: previous version required specifying the number of pts. If there an odd number of parameters, the first is assumed to be the number of points and is ignored.

gmark ;  set mark in graphics buffer and reset pens etc.

gmarkc ;  clear graphics buffer back to last gmark (does not undraw)

gmove i j ;  move current position to i,j

gpaint ;  complete redraw

gpen i [style] ;  select pen. pen is color from last grgb command and is i units wide. style is from the set (ps_solid, ps_dash, ps_dot, ps_dashdot, ps_dashdotdot, ps_null, ps_insideframe)

gpie i j k l xa ya xz yz ;  draw pie shaped wedge with pen and brush. Same parameters as garc.

gpixel i j;  draw pixel at i,j in current color

gpolygon pts ;  draws polygon in pen and brush.

gpolymode bool ;  0 selects ALTERNATE filling of polygon and 1 selects WINDING filling.

grect i j k l ;  draw rectangle at i,j,k,l with the current pen and brush.

grgb red green blue ;  	select color. values are from 0 to 255. 0 0 0 is black, 255 255 255 is white, 255 0 0 is red.

groundr i j k l w h ;  draw rectangle at i,j,k,l with rounded corners defined by ellipse with width w and height h

gshow ;  display graph data. graph data is not displayed as it is created

gtext i j text ;  draws text in graph box at point i,j

gtextcolor ;  current color is set as color of text drawn by gtext

makejr in.js out.jr ;  converts js input file to a J runtime jr file (Professional Edition only)

mb title text [styles] ;  messagebox with styles from set (mb_arbortretryignore, mb_defbutton2, mb_defbutton3, mb_iconasterisk, mb_iconexclamation, mb_iconhand, mb_iconinformation, mb_iconquestion, mb_iconstop, mb_ok, mb_okcancel, mb_retrycancel, mb_yesno, mb_yesnocancel)

mbcolor [colors] ;  choose color common dialog box. *data result is chosen color and 16 custom colors. Colors are 3 integers giving RGB values. The optional argument is sets initial chosen color and 16 custom colors (51 integer values in range 0 to 255).

mbfont ;  choose font common dialog. Start with last chosen font and sets new one if OK. The *data result is the information that defines the chosen font. The result can be used as the font argument in other commands.

mbopen title directory filename filterpairs [styles] ;  open file common dialog returns fully qualified file name selected by user. Filterpairs are delimited by |. Styles are from the set (ofn_createprompt, ofn_filemustexist, ofn_nochangedir, ofn_overwriteprompt, ofn_pathmustexist).

wd 'qs mbopen ;'

wd 'mbopen ;'

wd 'mbopen  mytitle  ""  ""  "Write(*.wri)|*.wri|(Word(*.doc)|*.doc"  ofn_filemustexist;'

mbsave title directory filename filerpairs [styles] ;  save file common dialog returns fully qualified file name (see mbopen).

menu id text ;  add menu item

menucheck id ;  check menu item

menudisable id ;  disable menu item

menuenable id ;  enable menu item

menupop text;  add popup menu item

menupopz ;  ends popup menu and drops down a level

menusep ;  separator line in a popup menu

menuuncheck id ;  uncheck menu item

oleactivate [verb];  activate server, make it visible, and execute default verb or specified verb.

wd ' oleactivate ;'	activate and execute default verb (usually edit)

wd ' oleactivate 1 ;'	activate and execute verb 1.

Many servers only support the default verb 0. The package server supports verb 0 to execute the command line in the package, and verb 1 to edit the contents of the package.

oleactivatei [verb];  same as oleactivate, except the activation is invisible

olecffile id oleclass filename;  creates embedded oleobject from a file. File must contain data that is understood by the server. Server is activated and visible.

wd ' oleccfile oid excelworksheet data.xls ;'

olecinvisible id oleclass ;  creates empty embedded oleobject. Server is activated, but is invisible.

wd ' olecinvisible oid pbrush;'

oleclffile id oleclass filename ;  creates linked oleobject from a file. File must contain data that is understood by the server. Server is activated and visible.

oleclose ;  close ole server

olecreate id oleclass ;  create default embedded oleobject. Server is activated and is visible.

wd ' olecreate oid pbrush;'

oledata text ;  send text data to oleobject server. Server activated invisibly if not already active.

oledelete [id] ;  delete oleobject. No error if object does not exist.

oleload id filename ;  load oleobject from file

olereset ;  delete all oleobjects and free all ole resources

olesave filename ;  save oleobject to file.

olesel id ;  select id as current oleobject as target of ole commands

oleupdate ;  update oleobject from the server. Gets changes in server not yet passed to the client.

pas i j ;  parent size adjusted to provide i and j margins beyond children

pbuttonx ;  attribute - checkbox and radiobutton presses cause button events

pc id ;  parent create. Initially hidden. id is caption (see pn command)

pcd id ;  parent create with dialog box frame and selected parent as owner. Previous parent is disabled to prevent user interaction until dialog with the new parent is finished. Closing enables the owner.

pcenter ;  center parent on screen

pclose ;  close parent. If there is no parent selected, nothing is done and there is no error.

pcloseok ;  attribute - window closes when user requests close. Otherwise the window must be explicitly closed with a pclose command.

pco id ;  parent create with selected parent as owner. Previous parent is disabled to prevent user interaction until dialog with the new parent is finished. Closing enables the owner.

pconno ;  attribute - the window will not cause events that end a wait command.

pconyes ;  attribute - the window will cause events that end a wait command.

penable bool ;  enable/disable parent

pescclose ;  attribute - ESC key is treated as system menu close.

phide;  hide parent, pshow can reshow

pmove x y w h ;  move and resize parent. Values are in logical units and are relative to the top left corner of the screen. Value of -1 inherits current value.

pn text ;  name for parent window caption

pscale ;  parent window sizing scales size of children

psel id ;  select parent id to be target for subsequent commands

psel ;  clear parent and child selection

pshow [style] ;  style is from the set (sw_hide, sw_minimize, sw_restore, sw_show, sw_showmaximized, sw_showminimized, sw_showminnoactive, sw_showna, sw_shownoactivate, sw_shownormal). sw_shownormal is the default.

wd ' rem return sw_ keywords; qs pshow;'

pshowx n... ;  argument is *pinfo data. Shows window as it was when *pinfo was set.

ptop ;  parent set as a TOPMOST window so it displays on top of other windows.

ptopnot ;  parent set as not TOPMOST window

qc ;  return child ids of current parent.

qd ;  return children ids and values for the selected parent

qe ;  return all error codes for *error

qhinst ;  return HINSTANCE of application

qhwndc ;  return HWND of current child

qhwndp ;  return HWND of current parent

qhwndx ;  return HWND of application

qm ;  return metrics in pixels: screen width, screen height, x logical unit, y logical unit. More elements may be added.

qole;  return OLE object ids.

qp ;  return parent ids.

qreg ;  return c:\windows\reg.dat registration data base. This is the information viewed with MS utility regedit.exe /v

qrt ;  return 1 if runtime version

qs [cmd] ;  return styles or keywords used in command. cmd can be: cc, cci, cdir, gpen, mb, mbopen, mbsave, pshow, sendkeys, smshow, or winexec

qsmact ;  return file name of active window

qsmall ;  return file names of all windows

qsmcsize ;  return size in characters of JX output window

qsmout ;  return file name of JX output window

qsmsize ; return size of smsel window (x y w h) in pixels

qsmwh ;  return size of main frame client area in pixels

qt ;  return all types for *type

qvbx ;  return information about properties and events of VBX control

rem text ;  remark

reset ;  close all windows and delete all OLE objects.

selno;  close does not reselect target parent and child  from when window was created

selrest;  select parent and child set by previous selsave

selsave;  save selected parent and child for subsequent restore by selrest

sendkeys text ;  Send keystrokes to active window. Similar to sendkeys in Visual Basic and other products.

+^%~()[]{} are special characters.

+ upshifts the next character (+a is the same as A)

^ control shift

% alt shift.

~ ENTER key.

To send a special character as a normal character enclose it in {}. To send + , put {+} in text.

{key n} repeats key n times. For example: {a 5} or {left 3}.

Keys without an ASCII value are indicated by keywords in braces. {tab} is the tabkey.

wd 'qs sendkeys ;'

wd 'winexec calc.exe;'

wd 'acttitle calculator; sendkeys "123{+}4~";'

smappend text ; appends text to smsel window

smcascade ;  menu Window/Cascade

smclose ;  close smsel window (does NOT save)

smfocus ;  set smsel window in focus

smfont ;  set session manger font from current font as set by dfont or fontcur

smove x y w y ;  move and size smsel window (pixels)

smopen ; open (if not already open) file set by smsel

smp ;  menu File/Print for smsel window (no print dialog)

A print file (smsel window or file) can contain print commands. There are 3 commands:

[print_command_init  "header"  "footer"  ]

[print_command_font  mbfont information  ]

[print_command_page]

Print commands must appear exactly as shown. They must start at the start of a line and the ] must be followed by the end of the line. Whitespace is allowed only in the parameter area. To be recognized as a print file, the first two lines of a file must be an init command and a font command.

The init gives the header and footer text and the font command gives the font for the header and footer and the initial font for the text. If the header or footer is empty ("") then it is not displayed. A &f is replace by the filename and a &p is replaced by the page number.

smpd ;  same as smp, but with print dialog

smpdf filename ;  same as smpf, but with print dialog

smpf filename ;  same as smp, but prints file

smpv ;  menu File/Print Preview, but for smsel

smpvf ;  same as smpv, but for file

smps ;  menu File/Print Setup

smread ;  return text from smsel window

smsave ;  save selected window (if modified)

smscroll i ;  scroll selected window

smsel filename ;  sets file name used to select window for other commands

smselact ;  selects (smsel) the active window

smselout ;  selects (smsel) the output window

smsetcmd n t name sentence help ;

n is 2 to 9 and indicates a function key

t is 0 for no definition, 1 for definition with display, 2 for definition with no display

name appears on Tool menu (include TAB to put Fn at right)

sentence is passed to J for execution when function key is pressed

help appears in status bar line at bottom of main window

smshow [style] ;  same style as for pshow

smtile ;  menu Window/Tile

smtilea ;  menu Window/Tile across

smwrite text ;  write new text to smsel

timer i ;  set interval timer to i milliseconds. Event systimer occurs when time has elapsed. The timer keeps triggering events until the timer is turned off. An argument of 0 turns the timer off. The systimer event may be delayed if J is busy and it is possible for several delayed events to be reported as a single event.

vbxenable eventname [parameter types]  ;  VBX Control

vbxevent eventname...  ;  VBX Control

vbxget propetry...  ;  VBX Control

vbxrefresh  ; request repaint of VBX control

vbxset property value...  ;  VBX Control

vedit ;  visual editing of the window defined by the commands that follow

wait ;  wait for user input

winexec text [style];  Execute DOS or Windows program. style is from the same set used in pshow.

The winexec result is the taskhandle of the new task. The task handle can be used as the argument to the acttask command.

wd ' winexec "write.exe text.wri" sw_maximize;'

xywh x y w h ;  sets rectangle. -1 value inherits the previous value.

xywhn ;  same as xywh, but not processed by vedit command


Form Edit

A form definition is the set of wd commands that define a parent window and its controls. The Form Editor takes a form definition from a form script file, displays the form, supports editing, and saves the new definition back in the script. The form script also contains the verbs that handle message loop events when the form is run. The Form Editor facilitates editing these verbs.

The best way to learn about this is to try it. Create a new script and run Edit/Form Edit. Run the Design New command to add controls. Drag controls with the mouse.

Controls can be marked with red or blue borders. The red control is the selection and all marked controls are the collection. The mouse can mark and unmark controls.

Hints	Mouse
Keyboard	Design
Control	Parent
Menu	Code
Tab Order	Test/Run
Defaults	Tech Notes


Form Edit Hints

Pick a good form id at outset, to avoid having to change it later.

Create a new script and save it as a permanent file. The form id might be a good name for the script.

Menu command Edit/Form Edit activates the form editor. It asks for the form id.

Use the Design Dialog to create, position, and size controls. The New command adds controls. Drag them with the mouse to where you want them.

Ctrl+C copies the collection to an internal clipboard and Ctrl+V, Ctrl+B, or Ctrl+N paste. For example, create a new radiobutton, move it, Ctrl+C, and do Ctrl+N several times.

You can open more than one form and copy and paste between forms.

Create the controls you want and position and size them roughly. Fine tune position, size, and alignment, after everything is on the form.

The Tab key can be used to find a control covered by another control.

Customize control styles, captions, and ids with the Control Dialog. Give descriptive ids to controls that cause events or will be used in wd commands.

Create a menu with the Menu Dialog.

Set the tab order after the form is pretty much complete. Moving, adding, or deleting controls require doing the tab order again. Radiobuttons are automatically grouped if they are in the right tab order.

Test the form with the Design Dialog File/Test command. This shows the form as it will look to the user. VBX controls are loaded and ownerdraw buttons are drawn. Check the tab order. Test runs verb wdtest which is normally defined by loading the standard profile.js script.

The Code Dialog shows which verbs are required to handle events and allows you to activate the form script and position the caret at the definition. Do not add handlers until the layout is settled.

Ctrl+click a control, a menu item, or the script to switch between the script and the form editor.

See Tech Notes for information on wd commands such as cci and adjh,


Form Edit Mouse Actions

click  --  select control (collection is maintained)

shift+click  --  toggle mark on control

ctrl+click  --  activate script (ctrl+click script to return)

double-click  --  show Control Dialog

drag move  --  drag collection. Ctrl+shift to move just the selection.

drag resize  --  just outside the red border shows a resizing cursor. Ctrl+shift to resize just the selection.

draw select  --  press the mouse outside any control and draw a box to select controls

A mouse action in a marked control affects that control. To select a control covered by a marked control, first unmark the control. The mouse selects the control with the nearest upper left corner.

The mouse displays the form menu. Select a menu item with ctrl to activate the script.

If tab order is displayed mouse actions are different.


Form Edit Keyboard Actions

The following keyboard actions are supported in the form.

Ctrl+X  --  cut collection (internal clipboard)

Ctrl+C  --  copy collection

Ctrl+V  --  paste

Ctrl+B  --  paste Beside collection

Ctrl+N  --  paste beNeath collection

Ctrl+T  --  toggle tab order display

Del  --  delete collection

Tab  --  select next in tab order

Shift+Tab  --  select previous


Form Edit Design Dialog

New adds a control to the form. VBX controls and ownerdraw buttons do not load the VBX or picture while designing the form.

Move collection with the cross direction buttons. The central button switches the move-grid between 1 and 4. The move is to the move-grid if not already on the grid.

Align collection with shift + a direction button.

Size collection with ctrl + a direction button.

The shift key causes the following buttons to act down rather than across.

Center  --  center collection

Size  --  size collection to the selection width

Space  --  space 3 or more controls across the form

Touch  --  space collection so they touch

Minus  --  remove space

Plus  --  add space


Form Edit Control Dialog

Double-click a control to show this dialog. Make changes and press OK or Run to recreate form.

The Styles and Class listboxes can have multiple items selected.

Dropdown comboboxes are not 3d when designing a form because of problems in moving them.

VBX controls are not loaded when designing a form. The vbx field defines the vbx file, the vbx name, and an optional title. The fields are separated by colons. A new VBX control is created with a caption of graph.vbx. Edit the caption to get a different control.

Ownerdraw buttons are not drawn when designing the form. The file name is in the caption. Edit the caption to be the name of the file with the graphic for the button.


Form Edit Parent Dialog

Design Window/Parent shows this dialog. Make changes and press OK or Run to recreate form.

A 'top level' parent is not owned by another window. An 'owned' parent is owned by the window that was selected (wd command psel) when the parent is created. The owner is disabled until the owned window closes. A 'dialog' parent has a solid frame and is owned.

Options do not affect the form during design.

pbuttonx  --  checkbox and radiobutton cause button event

pcenter  --  center form

pcloseok  --  close when close requested (otherwise explicit pclose command is required)

pesclose  --  Esc key treated as system menu close

pscale  --  resize of form resizes controls proportionally

ptop  --  display on top of other windows

The pmove button toggles use of a pmove command. When set, the current design location is shown to the right of the button. The form will be moved to that location when it is created.

The right and bottom margins set the margins used in creating the form.


Form Edit Menu Dialog

Design Window/Menu shows this dialog. Edit the definition and press OK or Run to recreate the form.

The following is an example of a menu definition:

&File
Open	Ctrl+O	idopen
Close		idclose
-
Quit		idquit
+
Help		idhelp

Popup menu items have no shortcut or id. Command menu items may have a shortcut and must have an id. At least 2 blanks must separate text, shortcut, and id. Left indents are unnecessary, but show the structure.

+ ends a popup menu, - is a separator. and & underlines the next character.

Use the mouse to show the menu on the form. Press the ctrl and select a menu item to go to the code in the script for that event.

You can also use the Code Dialog to define verbs for menu ids and shortcuts. A menu shortcut usually calls the verb defined for the menu id. For example, shortcut Ctrl+O could define a handler for fkey 'o ctrl' that called formid_menu_idopen.


Form Edit Code Dialog

Design Window/Code shows this dialog.

This dialog helps you define and edit verbs in the form script that handle events.

The button event type lists the ids of controls that cause button events. Checkbox and radiobutton controls are listed only if the parent option pbuttonx is on.

Items in the listbox are indented if a verb is not defined for that event.

Double-click an item in the listbox to activate the script with the caret located at the verb. If there is no definition, a default definition is added. Ctrl+click the script to return to the form editor.

The menu event type lists menu ids.

The fkey event type lists keys that cause events. Alphabetic and numeric keys with Ctrl or Ctrl+Shift as well as function keys cause events. Fkey events Ctrl+Z,X,C, or V are not supported. Menu shortcuts are handled as fkey events.

The other event type lists general form events. init is the verb run to initialize and show the form. catch is the verb run for any event that does not have a handler defined.

The orphan event type lists verbs defined in the form script for which there is no event. For example, create a button and create a handler verb in the script, then delete the button.

Ctrl+click a control, a menu item, or the script to switch between the script and the form editor.


Form Edit Tab Order

Ctrl+T in the form toggles display of the tab order.

The tab order determines how the user moves around on the form with the tab key.

Mouse actions with the tab order displayed are as follows:

click  --  select control (red border)

shift+click  --  put new selection after previous selection in the tab order

ctrl+click  --  put new selection as first in tab order


Form Edit Test and Run

Design File/Test saves the form back in the script, saves the script, runs the script, and runs verb wdtest a right argument of the form name. Verb wdtest is defined by profile.js. It runs the form init verb to initialize and show the form, and runs a message loop that displays events.

Design File/Run saves the form back in the script, saves the script, runs the script, and executes the form run verb with a right argument of the form name. The Code Dialog other event type with listbox entry run takes you to the form run verb definition.


Form Edit Defaults

Design Dialog File/Defaults displays the sizes used for controls created with New. The defaults can be changed and can be recorded in the jsm.ini file.

The default form font can be set by the main J menu with View/Set Form Font. Use File/Save jsm.ini to save a new form font as the default in the ini file.


Form Edit Tech Notes

A form definition in a script begins with a line that starts with a pc, pcd, or pco command and ends with the line <rem form end>.

Script main\forminit.js is used as a template for new forms. If there is no form definition in the script and forminit.js contains a form, then forminit.js is added to the end of the script. If neither the script nor forminit.js contain a form, then a simple form is added to the end of the script. You can edit forminit.js to add controls and handlers that you frequently require.

The form editor creates forms that contain xywh and cc commands. It does not create cci commands or any rectangle adjustment commands such as adjh. It will load a form definition with cci and adjustment commands but those commands are not retained by the editor. Unsupported commands in the original form may cause problems and will not be saved when the form is saved by the editor. The cci and rectangle adjustment commands are still useful in creating certain types of forms. Edit those commands directly in the script and run them from the init verb after creating the form and before showing the form.