ClearWin+ Browser Program Version 5.0

This program is written using ClearWin+ and is available as a sample program. By browsing the text which follows you can explore many of the features of ClearWin+ (especially some new features, not yet found in the manual) simply by clicking on highlighted text describing items of interest to you. Some of the icons and bitmaps also respond to a click. Please note that the use of this program is no substitute for reading the manual - it is designed to give you a taste of what is possible using ClearWin+.

This program is under active development. Some sections are incomplete and will be updated in later releases of ClearWin+. A more up-to-date version of this program may be available on the bulletin board. If you have obtained this program from the bulletin board, it may well describe features of ClearWin+ which are not yet built into our current software release. If you feel you have a need for such a feature, contact someone at Salford Software for an intermediate (at your own risk!) version of the library WINLIB.LIB or SALFLIBC.DLL for WIN32.

The ClearWin+ Browser is built around hyper-text windows using the %HT format. We believe that the %HT format offers a way to construct a GUI interface which is much more informative and convenient for your users. In effect, you supply a help script which also contains the controls needed to operate your program.


The program illustrates some of the effects that you can achieve using ClearWin+. Example code can be shown in C or Fortran, selectable using the language selection menu at the top of this window, and can be executed by pressing the button. The following topics are covered: Hypertext

Building programs with hyper-text

Hypertext windows provide an way of building very easy-to-use GUI applications. A hypertext window contains text with hypertext links, which enable your users to flip between pages by clicking on highlighted text or images, or initiate program execution. A hypertext window is created using %HT, and can be surrounded by other controls as required. The text itself is supplied as an ASCII file containing a subset of the HTML markup codes, commonly used to create documents for the World Wide Web.

For example, the format %70.20HT[introduction] would create a hypertext window of a width sufficient to display 70 average width characters and 20 rows. The text would be supplied by a prior call to ADD_HYPERTEXT_RESOURCE@ add_hypertext_resource with the name of a hypertext resource, say 'start', containing a document called 'introduction'. This would be defined as a resource thus:

start HYPERTEXT "myfile.htm"
The Salford resource compiler, SRC version 1.95 or later must be used (the Microsoft RC compiler will not work for this). The file BROWSE.HTM, which is built into the ClearWin+ browser program which you are currently running (and which is available as an example program) is an excellent example of a hypertext file. Note that hypertext resources are stored in a compressed format, which is not therefore accessible to your users by binary dumping your program file.

Windows containing hypertext have certain special properties, see Hypertext Windows.

The HTML text is displayed in the window left and right justified with scroll bars if necessary. The %HT format may be preceded by a pivot format (%PV) so that the text area changes size as the window is adjusted by the user. For further details of the variant of HTML markup codes used by %HT, see Hypertext Markup Codes.

Hypertext markup codes

Hypertext markup codes

Markup codes are contained within diamond brackets <>. For example, a paragraph end is marked using <P>. Markup codes are case insensitive. Some codes define a condition which pertains until cancelled by a corresponding markup starting with a '/' character. For example, bold face text is preceded by <B> and followed by </B>. Special characters (such as the diamond brackets used to define markup codes) are encoded as follows:
&LT;       <
&GT;       >
&AMP;       &
Hypertext files may contain portions of text which are included conditionally, under program control, see Conditional Hypertext. This program uses this feature to change the text depending on the programming language selection menu. The following HTML codes are currently available:

<TITLE> ... </TITLE> - This supplies a title to a document. This will be placed in the caption of the window using the %HT format. To supply a title as part of the text use <H1>

<H1> ... </H1> - This defines a principle heading to a document. The text will be enlarged and centred. Although the other heading styles (H2 .. H6) can be used, they currently operate the same way as H1. In future versions of the software this will change.

<HTML> ... </HTML> - In standard HTML these codes are almost redundant - they simply enclose the entire text. However they are vital for ClearWin+ hypertext as they are used to delimit separate documents. Each document should be surrounded by these tags and contain a DOC tag (see below).

<DOC name="doc_name"> - This defines the document name, and has no analog in HTML. Each document should have a distinct name enclosed in double quotation marks as shown.

<a HREF="name"> ...</a> - This is an HTML anchor which encloses text (or an image) which will be highlighted in blue and will react to a left mouse click. Note that standard HTML anchors have a somewhat more general syntax. The name should either be another document name (defined by DOC), or alternatively if the %HT format supplied a call-back function, that function will be called. The function can determine the textual value on the anchor by calling clearwin_info. In this way, it is possible to execute code in response to a mouse click.

<P> - End of paragraph. Subsequent text will start on a fresh line with a small gap separating it from the previous text. The markup <BR> on the other hand, will force a line break with no extra gap.

<HR> - Rules a horizontal line across the screen.

<B> ... </B> - Applies bold face to text.

<U> ... </U> - Underlines text.

<I> ... </I> - Creates italic text.

<RED> ... </RED> - Sets the text colour. Other available colours are BLUE, BLACK, GREEN, WHITE, and YELLOW. Because hypertext links are coloured blue by default, you may want to avoid the use of this text colour (although the colour of a link may be modified by nesting a colour change inside the link). These are not standard HTML markups.

<IMG SRC="name" ALIGN="align_option"> - Using this markup you can insert a bitmap into your text. "name" should be the name of a BITMAP resource (quotation marks are required), and align_option should be one of TOP, MIDDLE, BOTTOM. The alignment specification is optional, the default is BOTTOM. This determines the way in which the image is aligned with the surrounding text. By embedding an image in an anchor construct you can display an image which responds to mouse clicks.

<equation> ... </equation> - Using this markup you can insert a mathematical equation (see mathematical equations for details.

<UL> ... </UL> - Text embedded between these markup codes is considered to form an unordered list. Each list item is preceded by a <LI> markup and will start on a fresh line and a bullet mark. Lists embedded in lists will nest to the right. The codes <OL> ... </OL> will produce an ordered list numbered from 1.

<IF name> ... </IF> - See Conditional Hypertext Hypertext Windows

Hypertext Windows

A window may contain at most 1 hypertext control. It may also contain other controls, menus, etc. as desired. It is however possible to embed several child windows, each containing hypertext, within a single parent window. The reason why a window may only contain one hypertext control is that the window automatically provides certain services to the hypertext control. Thus the containing window will be displayed with vertical scroll bars if the hypertext is too long for the space provided. Note that this happens entirely automatically, it is an error to attempt to attach vertical scroll-bars (%VS) to a window containing hypertext. Horizontal scroll bars are never needed, since hypertext is always adjusted to fit the width available.

Special call-back functions are available within a window containing hypertext, thus:

"PREVIOUS_TEXT" Causes the hypertext window to 'go back' one link. A menu item attached to this call-back will be automatically greyed if the hypertext is at the top level.

By default, hypertext windows are given a grey background, although this can be changed using %`BG. In most cases it is desirable to give the parent window a matching grey background using %BG[GREY]

The title of a window containing hypertext will consist of any explicit title (%CA) followed by the title of the current hypertext document (as supplied by the <TITLE> markup, see Hypertext markup codes), separated by a '-'. Conditional Hypertext

Conditional Hypertext

The ClearWin+ browser program itself uses conditional hypertext to display different information depending on the programming language selected. For example,
Call the <if fortran> WINIO@ <else> winio </if> function to display a window.
This uses an integer parameter, "fortran", set up using the SET_CLEARWIN_INFO@ set_clearwin_info function. The first case is selected if the parameter is non-zero. The else clause is optional. Conditional constructs can be nested, and may contain arbitrary amounts of other markup codes and text.

If a call-back function changes the value of a parameter referenced in a conditional construction, it should either return 1 (to cause all controls in the window to be updated) all use WINDOW_UPDATE@ window_update to ensure that the hypertext is updated. Buttons

Various types of buttons

The simplest types of buttons are created using the %BT format. By default a button responds to being pressed by closing its associated window and returning the number of the button pressed. This makes it very easy to write simple message/dialog boxes. Try running the following example several times. First try closing the window using the OK button, then try the CANCEL button, and finally close the window using the system menu. Notice the different return values.

     ANS=WINIO@('This is a test message%nl%nl%CN%`BT[Ok]    %BT[Cancel]');

       winio("This is a test message\n\n%CN%`BT[Ok]    %BT[Cancel]");

.

Notice how in this example the OK button has been made default by using the grave accent character after the percent. This means that you can also close the window by pressing ENTER, and it will be as if you pressed the OK button.

You may have noticed in the last example that the OK and cancel buttons were a different size, because each was sized to fit its text. Alternatively you can specify the button width (in units of average-width characters). For example:


     ANS=WINIO@('This is a test message%nl%nl%CN%`6BT[Ok]    %6BT[Cancel]');

       winio("This is a test message\n\n%CN%`6BT[Ok]    %6BT[Cancel]");

.

Menus

Menus

The following types of menu can be controled by ClearWin+: All three menu types can contain sub-menus which are activated from the main menu. Each format takes a similar string of text following it. This string defines a tree of possibilities. Some menu items invoke sub-menus, others actually initiate action, and must be associated with a call-back function in the argument list. The following code produces a well known menu. Each of the call-back functions (except exit) has been attached to a "TEXT" call-back function. As you can see, this call-back function offers a very convenient way of testing menus before the code they are meant to invoke has been developed.

     ANS=WINIO@('%mn[&File[&New,&Open,&Save,|,E&xit]'
    +     //',&Edit[&Copy,C&ut,&Paste]]',
    +       'TEXT','New',
    +       'TEXT','Open',
    +       'TEXT','Save',
    +       'EXIT',
    +       'TEXT','Copy',
    +       'TEXT','Cut',
    +       'TEXT','Paste')

    winio("%mn[&File[&New,&Open,&Save,|,E&xit]"
            ",&Edit[&Copy,C&ut,&Paste]]",
            "TEXT","New",
            "TEXT","Open",
            "TEXT","Save",
            "EXIT",
            "TEXT","Copy",
            "TEXT","Cut",
            "TEXT","Paste");

.

Menu items can also be given certain special properties. Preceding a menu item with a tilde (~) will cause it to be greyed if a corresponding integer argument (passed as an int* by C programmers) is zero. Likewise, preceding a menu item by a hash character (#) will cause a tick (check mark) to be placed in front of the menu item if the corresponding argument is set to 1. This is often used to display menu items which toggle each time they are selected. The following example illustrates a three-item menu. Each item is checked when it is selected. The third item is de-selected and greyed if the 'C' menu item is selected:


       WINAPP 1000000,1000000
       OPTIONS(INTL)
       INCLUDE <WINDOWS.INS>
       EXTERNAL USE_FORTRAN,USE_C,USE_F90_EXTENSIONS
       INTEGER FORTRAN_MODE,C_MODE,F90_EXTENSIONS
       COMMON FORTRAN_MODE,C_MODE,F90_EXTENSIONS
       INTEGER ANS
       FORTRAN_MODE=1
       F90_EXTENSIONS=0
       C_MODE=0
C
      ANS=WINIO@('%mn[Language[#Fortran,#C,~#F90-extensions]]',
     + FORTRAN_MODE,USE_FORTRAN,
     + C_MODE,USE_C,
     + FORTRAN_MODE,F90_EXTENSIONS,USE_F90_EXTENSIONS)
       END

      INTEGER FUNCTION USE_FORTRAN()
       INTEGER FORTRAN_MODE,C_MODE,F90_EXTENSIONS
       COMMON FORTRAN_MODE,C_MODE,F90_EXTENSIONS
       FORTRAN_MODE=1
       C_MODE=0
       USE_FORTRAN=1
       END
      INTEGER FUNCTION USE_C()
       INTEGER FORTRAN_MODE,C_MODE,F90_EXTENSIONS
       COMMON FORTRAN_MODE,C_MODE,F90_EXTENSIONS
       FORTRAN_MODE=0
       F90_EXTENSIONS=0
       C_MODE=1
       USE_C=1
       END
      INTEGER FUNCTION USE_F90_EXTENSIONS()
       INTEGER FORTRAN_MODE,C_MODE,F90_EXTENSIONS
       COMMON FORTRAN_MODE,C_MODE,F90_EXTENSIONS
       F90_EXTENSIONS=1-F90_EXTENSIONS
       USE_F90_EXTENSIONS=1
       END

int fortran_mode=1;
int f90_extensions=0;
int c_mode=0;

int use_fortran()
{
       fortran_mode=1;
       c_mode=0;
       return 1;
}

int use_c()
{
       fortran_mode=0;
       f90_extensions=0;
       c_mode=1;
       return 1;
}

int use_f90_extensions()
{
       f90_extensions=(1-f90_extensions);
       return 1;
}
main()
{
    winio("%mn[Language[#Fortran,#C,~#F90-extensions]]",
            &fortran_mode,use_fortran,
            &c_mode,use_c,
            &fortran_mode,&f90_extensions,use_f90_extensions);
    }

.

Because menus are complex objects with many arguments it is often desirable to construct them in sections across several calls to WINIO@. winio. The rule for combining the results of several menu formats of the same kind is best illustrated by a few examples. Thus %MN[alpha,beta] followed by %MN[gamma,delta] would yield a menu equivalent to %MN[alpha,beta,gamma,delta]. The menu %MN[file[open,save]] followed by %MN[[exit],help] would be equivalent to %MN[file[open,save,exit],help]. The general rule is that the two menu strings are placed together (after removing the second format code) and back-to-back square brackets(][) are repeatedly removed from the join. Finally a comma is inserted at the join. Note that the square brackets in a menu format always pair, even if a continuation is pending. Note also that a menu can only start with more than one opening square bracket if it is a continuation. Invalid menu continuations, such as %MN[alpha] followed by %MN[[beta]] will cause an immediate fault.

An asterisk following any opening square bracket has special significance. An INTEGER int* argument is used to return an integer identifier (actually the Windows menu handle) of the individual menu or sub-menu. For example %MN[*file[open,save,exit],help] would return an identifier for the sub-menu containing the items open, save, and exit. This identifier can be used to dynamically modify the menu after the window has been created. Dynamic menus

Dynamic menus

Usually an application displays each window with a fixed set of menus. Menu items which are not available in particular circumstances are greyed as necessary using the '~' feature (see menus). However, sometimes a menu item can only be computed on the fly. Consider for example a word processing application which can process several documents at once. Such an application might require a menu containing the names of currently open files to provide a method to switch between documents.

To create a menu which can be modified you must first obtain the menu identifier of the piece of menu which you wish to manipulate. For example, to modify the list 'open, save, exit' you would associate the asterisk in %MN[*file[open,save,exit],help] with an integer variable, say 'menuvar'. Using this variable it is possible to add additional items to the end of the menu (or sub-menu), or to remove the last item. Thus in general the entire menu can be re-written if required. The following two subroutines functions are used:


       SUBROUTINE REMOVE_MENU_ITEM@(MENUVAR)
       INTEGER MENUVAR

       SUBROUTINE ADD_MENU_ITEM@(MENUVAR,NAME,GREYC,CHECKC,FN)
       INTEGER MENUVAR
       INTEGER GREYC
       INTEGER CHECKC
       EXTERNAL FN

void remove_menu_item(int menuvar);

void add_menu_item(int menuvar,char* name,int* greyc,int* checkc,int(*)(fn));

Notice that each new menu item has a grey control and check control variable. If these are not needed they should be tied to integers with the values 1, and 0 respectively (i.e. enabled and not checked). If the menu item is invoked the function 'fn' will be called in just the same way as for ordinary static menu items.

These subroutines functions can operate on parts of window menus (%MN), system menus (%SM) or pop-up menus (%PM). Attempting to remove an item from an already empty (sub)menu is not an error, although if the menuvar parameter is invalid an error will be generated.

If possible you should avoid altering the top level of the window menu (%MN) with these functions. This is because a changing menu display may be disconcerting for your users. Also, if you do extend the window menu you must ensure that the window is wide enough to receive it, otherwise Windows will continue the menu on another line, which is fairly ugly! The CLEARWIN_INFO@ function The clearwin_info function

The CLEARWIN_INFO@ and CLEARWIN_STRING@ clearwin_info and clearwin_string functions

The CLEARWIN_INFO@ clearwin_info function can return a wide variety of information, selectable by a case-insensitive character string argument. Three types of information are provided:

Parameters can have integer values, accessed by CLEARWIN_INFO@, clearwin_info, or string values, accessed by CLEARWIN_STRING@. clearwin_string. It is an error to attempt to access a non-existent parameter or to access a string parameter as if it were an integer, or vice-versa.

The following parameters are currently defined. Except where otherwise noted they have integer values.

USER DEFINED PARAMETERS

USER DEFINED CLEARWIN_INFO PARAMETERS

In addition to the list of pre-defined clearwin_info parameters , it is possible to set the values of any number of other named parameters. These are useful for communication between call-back functions, and to provide parameters for use with the <if> conditional text-inclusion facility in hypertexts (see %HT format).

For example, the parameter MY_PARAM could be set to the value 45 using the following call:


    CALL SET_CLEARWIN_INFO@('MY_PARAM',45)

    set_clearwin_info("MY_PARAM",45);

Note that clearwin parameters can be effectively WINDOWS MESSAGE INTERCEPTION

WINDOWS MESSAGE INTERCEPTION

Much of the interaction between Windows and an application is by means of messages. Under ClearWin+, programmers need not normally concern themselves with these messages, which are handled entirely within the ClearWin+ library. Very rarely it is useful to intercept one of these messages to achieve some special effect. Before resorting to this technique it is worth calling Salford Software support for advice about possible alternative solutions. Software which uses %MG shuold be tested very thoroughly whenever you update the ClearWin+ library. Use %MG only as a last resort!

The %MG format takes an integer message number (e.g. WM_SETFOCUS) and a call-back function. The function is called each time that particular message is processed. The return value from the function should have one of the following values:

  • 0 Close the window
  • 1 Leave the window open and update all controls
  • 2 Leave the window open, but do not update the controls.
  • 3 Continue to process this message normally

The safest way to use %MG is to return 3 after simply setting flags within your program. It is particularly dangerous to make calls to winio from within a %MG call-back, as the process of creating the new window may cause additional messages to be trapped by the parent window, causing a recursive loop. USING THE CLIPBOARD

USING THE CLIPBOARD

Early versions of ClearWin+ allowed clipboard interaction with one edit control (%EB). This has now been greatly enhanced.

When making your program use the clipboard it is important to ensure that you do so in a standard fashion. In particular, your program should never write information into the clipboard unless your user has explicitly activated a control telling it to do so.

Full cut/copy/paste of text is now available from edit boxes (%EB), and variable entry boxes (%RD, %RF, %RS, %DP, %FP, %TP). Also text can be selected and copied from embedded ClearWin windows (%CW).

These facilities are accessed by using the pre-defined call-back functions 'COPY', 'CUT', 'PASTE'."COPY", "CUT", "PASTE". These functions operate entirely automatically, and if attached to a menu or button, will disable (gray) the control when not available. For example, the PASTE option will be disabled if there is no text in the clipboard.

It is also possible to copy text or other information to/from the clipboard using the functions


INTEGER*4 FUNCTION COPY_TO_CLIPBOARD@(DATA,LENGTH,TYPE)
INTEGER*4 FUNCTION COPY_FROM_CLIPBOARD@(DATA,LENGTH,TYPE)

int copy_to_clipboard(void& data,int length,int type);
int copy_from_clipboard(void& data,int length,int type);

The type parameter should be one of the Windows CF_ parameters (e.g. CF_TEXT). The INTEGER*4 length parameter determines the length of the information. Textual data should be terminated by a null character, which should be included in the length. Graphics

Graphics

If you have DBOS code which uses the Salford graphics routines (DRAW_LINE@, TRAW_TEXT@, etc.) (found in the header <dbos\graphics.h>) , or if you have DBOS code which uses a third-party library which uses these functions, then you should have to do very little if anything to make this code work inside a window.

In the same way as text output destined for the screen is diverted to a window under ClearWin+, so a program outputing graphical information destined for the screen will produce that output in a window of the apropriate size. Thus a call to VGA@ will produce a 640 x 480 graphics area in a slightly larger window, which will also contain a button to close it. However, just as few finished applications would use the raw ClearWin+ output to a window, so Windows graphics can be improved by embedding them in a formatted window. This is achieved using the %GR format. This takes two integer arguments defining the width and depth (in pixels) of the graphics area. This format usually uses a call-back function (indicated as usual by the circumflex ^) to handle mouse action, and/or to respond to re-sizing events, as described below.

Using this format the graphics area can be embedded in a window with other controls. For example:


A=WINIO@('%GR&',300,200)

a=winio@("%GR&",300,200);

The %GR format can also take a grave accent, in wich case it takes an additional INTEGER int* argument which can be used as a handle to the graphics area. This handle (which is set by the winio call) is only needed if you plan to have several graphical areas active at the same time.

The %GR format can take the following options (enclosed in sqare brackets as usual):

  • RGB_COLOURS - By default graphics routines such as DRAW_LINE@ which take a colour argument use colours which correspond to those under DBOS. However, by specifying RGB_COLOURS the colour argument becomes an RGB value, which can be created using RGB@ the standard Windows RGB macro . This is option is recommended for new code.
  • RED - Specifies the default background colour.
  • GREEN - Specifies the default background colour.
  • BLUE - Specifies the default background colour.
  • YELLOW - Specifies the default background colour.
  • WHITE - Specifies the default background colour.
  • GRAY - Specifies the default background colour.
  • GREY - Specifies the default background colour.
  • BLACK - Specifies the default background colour.
  • FULL_MOUSE_INPUT - Causes the call-back function to be called on all mouse movements, rather than just mouse key presses.
  • METAFILE_RESIZE - This should be used in conjunction with the pivot format (%PV). It causes the graphics output to the window to be copied to a Windows structure called a metafile. If the window is re-sized, the graphics are played back at the new resolution. While this is extremely effective for some types of applications, the re-scaling may cause unpleasant aliasing effects. Also, care should be taken to ensure that excessive amounts of graphics information are not sent to the metafile, otherwise memory may become exhausted.
  • USER_RESIZE - This represents another way of arranging to re-size a graphics area that has been subject to a pivot. In this case the call-back function is invoked each time the are is re-sized. The clearwin_info parameters GRAPHICS_RESIZING, GRAPHICS_WIDTH, and GRAPHICS_DEPTH can be used to detect the re-size and obtain the new dimensions. Using this option, a program can respond to size changes in any way it chooses. The graphics area is blanked to its background colour before the call-back function is called. Note that a re-size event is deemed to occur when the window is first displayed. This means that the drawing code need only be placed inside the call-back function.
  • BOX_SELECTION - Indicates that the graphics area should start with box selection enabled. This means that dragging the mouse with the left button depressed will produce a box drawn X-ored onto the graphics area. The coordinates of this box can be subsequently retrieved using the GET_GRAPHICS_SELECTION@ subroutine. get_graphics_selected_area function. The graphics selection mode can also be set using the SET_GRAPHICS_SELECTION@ subroutine. set_graphics_selection function. This takes an integer argument, 0 is the default with no mouse drawing action, 1 enables box drawing, 2 enables line drawing (see below). Note that it is possible to achieve a much smoother effect using the graphics selection method than by explicitly drawing in XOR mode, the technique used by DOS programs. This is because the lines can be drawn directly to the screen rather than the bitmap graphics buffer. Calling SET_GRAPHICS_SELECTION@ set_graphics_selection has the useful side-effect of removing any existing selection, even if the mode does not change.
  • LINE_SELECTION - Like BOX_SELECTION, except that a straight line is drawn as the mouse is moved. Typically this could be used by a drawing program by retrieving the end points when the mouse was released and drawing a permanent line between the points.
Obviously, any graphics code using %GR must be adjusted to use the 'screen' width and depth specified in the arguments to the format. Fortunately, most DBOS graphics code is written to exploit the super-vga modes on the various graphics adapters. As a result, such code is usually constructed so as to work at different resolutions. Furthermore, applications should examine the clearwin_info parameters SCREEN_WIDTH and SCREEN_DEPTH to determine suitable dimensions for the graphics area. Remember that screen resolutions can vary from 640 x 480 (or even less) up to 1280 x 1024 or more.

If it is desired to create several graphics areas simultaneously (either embedded in the same window or in different windows) then the SELECT_GRAPHICS_OBJECT@ select_graphics_object function should be used. The argument is the integer returned by %`GR (as described above). This function will return 1 if it succeeds. Note that this function will fail if the graphics area has been closed by the user. It is very important to test for this condition if it is a possibility before proceeding to draw in the area. ClearWin Windows

Traditional input/output

Most conventional DOS programs communicate with the user by reading from the keyboard and writing to the scrolling screen using high level language features such as PRINT*. the printf function.

While this form of input/output is inappropriate for most Windows applications, it still has useful applications. Programs which perform long calculations often use PRINT statements to communicate useful information about their progress. Also many programmers use screen I/O to debug their code. As soon as a ClearWin program encounters one of these statements, it creates a large window covering the whole screen and uses it like a 'dumb terminal'. Users can scroll the text using scroll bars. A caret will be placed in the window if the program attempts to read from the 'screen'. All this was present in very early versions of ClearWin+ which contained non of the modern formatted window facilities. As a result a variety of functions were supplied to customise these windows somewhat, for example it was (and is) possible to attach a menu to a ClearWin window. However, while this functionality is retained in ClearWin+ for existing programs, we recommend that new programs should embed any ClearWin windows in a formatted window using %n.mCW.

%n.mCW (e.g. %10.6CW) creates a ClearWin window n average character widths across and m lines deep. One integer argument must be supplied to indicate the FORTRAN unit number to be associated with the window. If zero is passed the window is created as the default screen (i.e. it will capture PRINT*, READ*, etc.). One FILE** argument must be supplied. This should point to a FILE* object which is set up by the winio call and can be used by subsequnt calls to fprintf etc. A null argument creates the window as the default screen for printf etc.

Using %CW traditional output can be elegantly embedded inside a larger Windows application with menus , toolbars , etc. Text from the window can also be selected with the mouse and copied to the clipboard using the COPY standard call-back. Note that PASTE and CUT are not supported. It is often useful to precede %CW with a pivot (%PV) so that the window expands as the main window in which it is embedded is re-sized by the user.

In general, it is not recommended that ClearWin windows should be used for input in completed applications because the interface will feel very non-standard to someone familiar with other Windows applications. GIF Animation

GIF Animation

The splash screen for this program illustrates a recent addition to ClearWin+ - the use of animated GIF resources. As most Internet users will have realised, many of the images on the WEB are encoded in GIF format. This format compresses images and caters for animations. An animated GIF file is constructed out of a number of still images, and contains information to specify how many times the image sequence should be played (or to specify an indefinite loop) together with the duration for which each image will be displayed.

In addition, a GIF image can contain a colour nominated as transparent. This means that such an image can act very much like an icon in that it can have an arbitrary shape, however, unlike an icon, the format imposes no size restrictions.

Many image processing and paint tools will create simple (non-animated) GIF files, and these can be assembled into animated GIFs using a variety of tools, such as the Microsoft GIF Animator, available from the Microsoft Web site.

GIF (animated or otherwise) images can be incorporated in you program as a GIF resource. For example:

my_button GIF c:\gifs\gif1.gif

This resource is then used in the %GI format thus:

%GI[my_button]

A callback can be supplied to receive single and double clicks. The callback function can interrogate the CLEARWIN_INFO@ clearwin_info parameters GIF_MOUSE_X and GIF_MOUSE_Y to determine where within the image the click occured. This means that a medium to large image can contain regions which respond in different ways to mouse clicks. Coordinates are in pixels relative to the top left of the image. Note that if the GIF image is displayed at another screen resolution, these pixel coordinates will consistently refer to the same point in the image.

Note that a GIF image contains size information, so none is required with the format.

Animations require memory and processing time, so it might be unwise to use a large and complex animation on a 'please wait' screen displayed while a lengthy operation is being performed. Obviously, slower animations are less expensive than rapid ones. Also, for the animation to be maintained, it is important that very lengthy calculations are broken up with calls to TEMPORARY_YIELD@temporary_yield() (of course this is desirable for many other reasons as well).

One way to reduce the performance cost of many animations is to exploit the fact that much of an image may remain the same from frame to frame. Consider for example an animated ballot paper. It might be that only the region to contain the cross would actually need to change. It is possible to assemble a GIF consisting of one full image and a series of patches, which will obviously require less memory and processing resources than the corresponding set of full images. If you decide to procede this way your program will remain unchanged, it will simply require more work with the image processing tools.

On 16 or 256 colour systems GIF images are displayed without the use of a palette. This is to avoid some of the problems with Windows when two or more processes compete for the use of the palette. Gif images are best viewed in a high colour mode. If in doubt it is worth switching your screen to 256 colour mode to ensure that your graphic looks acceptable. You can, of course, read the CLEARWIN_INFO@ clearwin_info parameter, 'SCREEN_NUM_COLOURS' do determine what to do at run time.

GIF images may be used to provide fancy buttons that attract attention because of their animation, front cover screens for programs, and add colour and interest to your programs. Larger images can even be used as image maps by reading the click coordinates, as explained above.

In order to comply with our contractual obligations, the GIF resources are decompressed by the resource compiler and recompressed by a different method. This means that none of your executables or SALFLIBC.DLL contain any code related to the processing of the GIF format.

For the above reasons we have supplied no routines to enable you to export graphics to GIF files. However, if you want to incorporate your graphics in animated GIFs this is still possible. Simply create a series of still images as BMP files, convert them to GIFS using any of a large number of shareware image processing programs, and assemble the result as an animated GIF.

The mouse cursor

The mouse cursor

By default the mouse cursor is represented by an arrow except in graphics regions, where it is represented by a cross. Two formats are supplied to change the mouse cursor representation. %DC sets the default cursor for the window as a whole, and %CU sets the cursor for the next control in the window. Each is followed by a standard string (i.e. a string in square brackets or an @ character indicating that a suitable string is supplied in the arguments. The string should be the name of a CURSOR resource. By using a grave accent, you can use the numbers representing the standard Windows cursors. For example:

       A=WINIO('%`DC%OB%`CU%GR%CB%FF%NL%CN%`BT[OK]',IDC_IBEAM,
     +IDC_WAIT,100,100)

    winio("%`dc%ob%`cu%gr%cb\f\n%cn%`bt[OK]",
                 IDC_IBEAM,IDC_WAIT,100,100);

.

These two formats also have a more complex form in which several alternative cursors are supplied together with an integer used to select which one to use. The integer should be in the range 1 to the number of cursors. For example:


       INTEGER*4 K
       K=1
       A=WINIO('%3DC[CURSOR_1][CURSOR_2][CURSOR_3]',K)

       int k=1;
    winio("%3dc[cursor_1][cursor_2][cursor_3]",&k);

Whenever the cursor is in the main window, its shape will be governed by the current value of k. The %CU format can be used in a similar way. For example, using this mechanism, a graphics region can arrange to change its cursor when it changes its selection mode. Selection boxes of various types

Selection boxes of various types

Selection boxes alow the user to select items from a list. The simplest method is to use %LS. This takes a CHARACTER array followed by an integer item count NULL-terminated array of char* pointers followed by an integer variable. a pointer to an integer variable. This variable should be set to a value 1 - N to supply an initial selection, or zero for no selection. The variable will be updated each time the user changes the selection. %LS can take a call-back function.

By using a grave accent on %LS you can produce a drop-down list. Such a list occupies minimal space until the user clicks on it, when it 'drops down', covering other information.

If there are too many items to display simultaneously you can supply parameters to %LS. For example, %10.5LS will create a list box of width ten average chacters and five items deep. If necessary scroll bars will be supplied to roll the items.

Sometimes it is required to select more than one item at once. This can be done using %MS. This is analogous to %LS except that the result variable is replaced by an integer array. The elements of this array should be initialised to zero for initially de-selected items and one for selected items. The array is updated as the user changes the selection.

Note that the format %LB can also be used to create list boxes. It is the same as %LS except that its n and m parameters are the 'wrong' way round. It has been retained for compatibility with existing code.

The following program illustrates some typical cases:


      winapp 1000000,1000000
       options(intl)
      include <windows.ins>
      integer k,ans
       integer ivec(7)
       character*10 things(7)
       data things/'Apples','Bananas','Cherries','Grapes',
     +'Oranges','Pears','Rasberies'/
       ivec(1)=0
       ivec(2)=1
       ivec(3)=0
       ivec(4)=0
       ivec(5)=1
       ivec(6)=1
       ivec(7)=0
       ans=winio@('%ca[Selecting things]%3tl&',15,30,45)
       ans=winio@('%tc[red]Simple%taDrop-down%taScrolling%ta'//
     +'Multiple selection%nl%tc[black]&')
       ans=winio@('%ls%ta&',things,7,k)
       ans=winio@('%`ls%ta&',things,7,k)
       ans=winio@('%10.3ls%ta&',things,7,k)
       ans=winio@('%ms&',things,7,ivec)
       ans=winio@('%ff%nlNote that the first three boxes are '//
     +'coupled together%nl&')
       ans=winio@('because they share the result variable k')
       end
 
#pragma windows 1000000 1000000
#include <windows.h>

int k;
char* things[]={"Apples","Bananas","Cherries",
               "Grapes","Oranges","Pears","Rasberies",NULL};
int ivec[7]={0,0,0,0,0,0,0};
main()
{
    ivec[1]=1;
    ivec[4]=1;
    ivec[5]=1;
    winio("%ca[Selecting things]%3tl&",15,30,45);
    winio("%tc[red]Simple\tDrop-down\t"
            "Scrolling\tMultiple selection\n%tc[black]&");
    winio("%ls\t&",things,&k);
    winio("%`ls\t&",things,&k);
    winio("%10.3ls\t&",things,&k);
    winio("%ms&",things,ivec);
    winio("\f\nNote that the first three boxes are coupled together\n&");
    winio("because they share the result variable k");
    }

 
.

Laying out a window

Laying out a window

Much of the burden of laying out controls in a window is handled by ClearWin+ automatically. Each time you specify a control the system works out the area that it will occupy and searches from left to right looking for a free place large enought to take it. As the format(s) that specify the window are processed a map of which regions of window are occupied is maintained. This is used to prevent one control being placed on top of another. Controls can be spaced out using actual spaces within the format. For example:

       a=WINIO@('%6BT[OK]     %6BT[CANCEL]')

       winio("%6BT[OK]     %6BT[CANCEL]");

.

Notice how we have specified the button width explicitly in this example so that the buttons will have the same size.

Now consider the more typical case where we want to place a message above the closure buttons. In this case the text will probably be longer that the buttons and we need to get the buttons centred to look good. We also need a spare blank line between the text and the buttons. We generate newlines using %NL \n thus:


       a=WINIO@('This is a vital message%nl%nl%CN%6BT[OK]     %6BT[CANCEL]')

       winio("This is a vital message\n\n%CN%6BT[OK]     %6BT[CANCEL]");

.

In this case we have used the %CN format to centre the buttons in the window. To get an even more pleasing effect we can position a standard icon to the left of the text using %SI. This takes a parameter indicating the number of lines of text which will follow it. This enables ClearWin+ to centre the icon correctly. For example:


       a=WINIO@('%1SI!This is a vital message%nl%nl%CN%6BT[OK]     %6BT[CANCEL]')

       winio("%1SI!This is a vital message\n\n%CN%6BT[OK]     %6BT[CANCEL]");

.

It is important to distinguish between the action of the newline, %NL \n and the form-feed, %FF \f . In simple examples these have the same effect. However, consider the following example in which we place a large control on the left of the window:


       a=WINIO@('%OB%10.5CW%CB line 1%NL line 2%NL line3%FF line 4',0)

       winio("%OB%10.5CW%CB line 1\n line 2\n line3\f line 4",0);

.

Whereas the newlines have continued to use up the space to the right of the (unused) embedded ClearWin window, the form feed explicitly moves beneath everything in the window.

By default a window is created as a dialog box. The system automatically places a blank border around the window contents, since for simple examples this always looks good. In more complex windows, esspecially those which have a toolbar at the top, it is often desirable to remove this border using the no_border option to %WW - i.e. %WW[no_border].

Controls may also be layed out horizontally using the tab, %TA \t . By default this tabs to columns separated by the width of eight average characters. Tab positions may also be specified explicitly using %TL. For example %4TL would take four integer arguments specifying the first four tab positions as multiples of the width of an average character . Subsequent tab positions would follow the default scheme. A complicated window layout may contain several %TL formats. Each %TL format takes effect for subsequent controls and cancels any previous one.

As explained above, tab positions are based on the width of an average character (before any changes in font size). While this is fine enough for most purposes, it is occasionaly useful to specify tab positions more precisely. To this end, if you used the grave accent modifier, then the tab positions are specified as REAL*8 double quantities and can be fractional. Character widths

Character widths

Most Windows fonts, including the default font, are proportional. This means that some characters are wider than others. The exact variation may vary from font to font, but the '@' character and some capital letters, such as 'M', as wide characters, whereas 'i' is obviously a narrow character. Sometimes the width of a character may even vary depending on its neighbours, for example a pair of adjacent lower-case 'f' characters will be pushed a little closer together. Proportional fonts are generally much more pleasing to read.

Because of this complication, you have to be rather careful about specifying character widths. Drag and drop

Drag and drop

With the advent of Windows 95, the drag and drop interface is likely to become more important. It is important that your application can respond to files which are dragged from the desktop (or elsewhere) onto your application.

Files dragged into a file-open box under Windows 95 will cause the box to close and return the file in question, however applications which open files should be able to respond to files dragged onto their window(s). To achieve this, simply use the %DR format in your window. This format takes a call-back function as argument. This function should retrieve the clearwin_string DROPPED_FILE to obtain the full path name of the dropped file. The ACTION_X and ACTION_Y parameters will reflect the location of the drop (so you may want to use %`SP with 0,0 as arguments if you need to display a dialog box at the drop point).

Remember that users will often drag totally unsuitable files onto your window, possibly by mistake, so it is important to validate that the file is suitable for your application (at least by checking its file suffix) before starting to use it. If in your application opening another file implicitly destroys previous work, it would also be sensible to check that the user actually wants to do this. Mathematical equations

Mathematical equations

Using the %EQ format it is possible to draw mathematical equations, such as V={divide 4;3}{pi}R{sup 3} (with Greek symbols etc.) and other objects with a similar appearance, such as chemical formulae. Equations may also be embedded in hypertext (see below).

The %EQ format is followed by a standard string (i.e. a string in square brackets, or an '@' sign and a string as an argument), followed by the width and depth of the equation in pixels. If the contents of the equation are not going to change, the width and depth can be set to zero, forcing the size of the region to be defined by the equation.

Equations are strings with the three characters {;} reserved. The following symbols can be included in strings:

  • {alpha}
  • {beta}
  • {gamma}
  • {delta}
  • {epsilon}
  • {phi}
  • {pi}
  • {zeta}
  • {psi}
  • {sigma}
  • {theta}
  • {kappa}
  • {lambda}
  • {ita}
  • {rho}
  • {mu}
  • {nu}
  • {omega}
  • {chi}
  • {tau}
  • {infinity}
  • {plus_minus}
  • {ge}
  • {proportional}
  • {curly_d}
  • {le}
  • {ne}
  • {identically_eq}
  • {approximately_eq}
  • {such_that}
  • {vector_sum}
  • {empty_set}
  • {set_intersection}
  • {set_union}
  • {proper_subset}
  • {subset}
  • {belongs_to}
  • {not_belongs_to}
  • {for_all}
  • {there_exists}
  • {del}
  • {sqrt}
  • {semicolon}
  • {curly_bra}
  • {curly_ket}
The names of these special symbols are case sensitive, and the Greek characters also exist as upper case characters, for example, {Pi} will produce an upper case pi. In addition, a number of more complex constructions are supplied. In what follows * stands for any equation string:

  • {sup *} Superscript or exponent
  • {sub *} Subscript
  • {divide *;*} Division writen with a horizontal bar
  • {sum *} Summation without upper limit
  • {sum *;*} Summation with both limits
  • {integral } Indefinite integral
  • {integral *} Integral with lower limit only
  • (integral *;*} Full definite integral. Note that the body of the sum or integral will be placed after the closing curly brace. Spaces are important in the above constructions.

    Badly formed equations will normally cause a clearwin error, however if a grave accent is specified on the %EQ, the error will be suppressed.

    Excessive nesting of constructs such as sup or sub, which reduce the font size, may result in unreadable equations.

    Here are a few well known equations and chemical formulae as examples:

    • H{sub 2}SO{sub 4}
    • E=MC{sup 2}
    • {del}.B=0
    • {sum n=1;{infinity}}{divide 1;n{sup 2}}={divide {pi}{sup 2};6}
    .

    These same equation strings may be used in hypertext (%HT) embedded between <equation> and </equation>. The string between these delimiters is treated as a pure equation - no markup codes are recognised - so, for example, the '<' symbol should be written as is.

    Spare section

    Not used

    Junk Treeview controls

    Treeview controls

    Usint the %TV format you can construct a tree-structured (hierarchical) list box, analogous to the type of display sometimes used to display a directory structure. This takes a CHARACTER array followed by an integer indicating the size of the array CHAR* array of strings terminated by a NULL pointer (c.f. the listbox controls). The final argument is an INTEGER int* to receive the index of the chosen item. The control operates similarly to the listbox except that the first two characters of each string have a special meaning. The first character should be a capital letter (A - Z) indicating the level of the item within the hierarchy. The second letter should be a 'C' if the item is to be displayed compactly (i.e. not displaying any children) and 'E' if the item is to be displayed expanded with any children. Consider the following list of things:
    
                   AEFood
                   BEFruit
                   CCApples
                   CCPears
                   BCNuts
                   CCHazel nuts
                   CCBrazil nuts
                   AEDrink
                   BCAlcoholic
                   BCNon-alcoholic
    
    As you can see, the children of a node (together with any of their children) are placed immediately beneath the object. In the example shown the types of nuts would not immediately be shown because of the C in BCNuts. Nodes can be expanded and contracted by your user by double clicking on the item. Usually you would code 'C' for the second charater of each string. This will produce an initial display of only the top level. As nodes get expanded and contracted the information is stored in the strings. This means that if the strings are used to display the hierarchy a second time the display will seem to start from where it left off. You could even store the strings in a file so that the display would persist in appearance from run to run. Items with a lower case letter or a blank in the first position are ignored and never displayed. This provides a means to hide elements, or to provide space for the display to grow dynamically. Empty strings in C have the same effect. If a node has no children you can code 'E' or 'C' - there is no difference.

    Notice that it makes no sense for a level 2 item (say) to be followed immediately by a level 4 item. An item cannot be followed immediately by its 'grandchildren'. This condition will be detected as an error. Conversely, a level may fall by any amount.

    %TV can take a call-back function. This can look at the result variable and also interrogate the CLEARWIN_INFO@ clearwin_info variable TREEVIEW_ITEM_SELECTED. Tis will be one if and only if the call-back is responding to a double click event.

    By default the treeview display uses bullet marks to the left of the labels. These can be replaced by icons of your own choosing. Icons should be.

    C/C++ programmers please notice that because the strings are updated to reflect user actions, it is vital not to use original compiler- generated constants for the strings. It is also vital that the same string (in the sense of address) does not appear at more than one place in the list. Use strdup or other means to ensure your strings are writable and distinct. The NULL string ("") used to indicate omitted items does not need to be writable or distinct.

    By default the treeview (%TV) control uses bullet marks to the left of each label. By using a grave accent on the format these can be replaced by user-selectable icons. If a grave accent is used, then a third character is removed from the string and is interpreted as an index ('A' - 'Z') into a list of icons. This list is supplied as an extra argument, and should consist of a list of icon resources separated by commas (e.g. 'ICON1,ICON2,ICON3'). Because only small images are required, you should construct icons in which the image is confined to the top left 16 x 16 corner. The rest of the icon must be transparent. Note that these icons mimick the small icons which are available under Windows 95. However, this code will work equally well under Windows 3.1 or Windows NT.

    By providing a call back which examines the expansion indicator (character two of each string) it is possible to change the icon index to reflect whether the icon is expanded or not. If you perform a change of this sort you should pass the main array to WINDOW_UPDATE@ window_update to force the control to be updated.

    The following (informative, but rather boring!) example illustrates the use of textview controls:

    
           WINAPP 500000,500000
           OPTIONS(INTL)
           BLOCK DATA
           CHARACTER*30 CONTENTS(56)
           INTEGER ITEM
           COMMON/C/CONTENTS
           COMMON/I/ITEM
           DATA CONTENTS/
         +'ACABook',
         +'BCAChapter 1',
         +'CCASection 1.1',
         +'CCASection 1.2',
         +'CCASection 1.3',
         +'CCASection 1.4',
         +'BCAChapter 2',
         +'CCASection 2.1',
         +'CCASection 2.2',
         +'CCASection 2.3',
         +'CCASection 2.4',
         +'BCAChapter 3',
         +'CCASection 3.1',
         +'CCASection 3.2',
         +'CCASection 3.3',
         +'CCASection 3.4',
         +'BCAChapter 4',
         +'CCASection 4.1',
         +'CCASection 4.2',
         +'CCASection 4.3',
         +'CCASection 4.4',
         +'BCAChapter 5',
         +'CCASection 5.1',
         +'CCASection 5.2',
         +'CCASection 5.3',
         +'CCASection 5.4',
         +'BCAChapter 6',
         +'CCASection 6.1',
         +'CCASection 6.2',
         +'CCASection 6.3',
         +'CCASection 6.4',
         +'BCAChapter 7',
         +'CCASection 7.1',
         +'CCASection 7.2',
         +'CCASection 7.3',
         +'CCASection 7.4',
         +'BCAChapter 8',
         +'CCASection 8.1',
         +'CCASection 8.2',
         +'CCASection 8.3',
         +'CCASection 8.4',
         +'BCAChapter 9',
         +'CCASection 9.1',
         +'CCASection 9.2',
         +'CCASection 9.3',
         +'CCASection 9.4',
         +'BCAChapter 10',
         +'CCASection 10.1',
         +'CCASection 10.2',
         +'CCASection 10.3',
         +'CCASection 10.4',
         +'BCAChapter 11',
         +'CCASection 11.1',
         +'CCASection 11.2',
         +'CCASection 11.3',
         +'CCASection 11.4'/
           END
    
           INTEGER FUNCTION TEST()
    C********************************************************************
    C                                                                   *
    C      Call-back function sets the icon for each object according   *
    C      to whether it is expanded or not                             *
    C                                                                   *
    C********************************************************************
           CHARACTER*30 CONTENTS(56)
           INTEGER ITEM
           COMMON/C/CONTENTS
           COMMON/I/ITEM
           CHARACTER*30 STRING
           STRING=CONTENTS(ITEM)
           IF(STRING(2:2).EQ.'E')THEN
           STRING(3:3)='B'
           ELSE
           STRING(3:3)='A'
           ENDIF
           CALL WINDOW_UPDATE@(CONTENTS)
           TEST=2
           END
    C
    C     ******************************************
    C     *                                        *
    C     *    Main program - just call WINIO@     *
    C     *                                        *
    C     ******************************************
    C
           INCLUDE <WINDOWS.INS>
           EXTERNAL TEST
           CHARACTER*30 CONTENTS(56)
           INTEGER ITEM
           COMMON/C/CONTENTS
           COMMON/I/ITEM
           INTEGER ANS
           ANS=WINIO@('%WW%OB%PV%^`20.15TV%CB%FF%NL%CN%`BT[OK]',
         +CONTENTS,56,ITEM,'CLOSED_BOOK,OPEN_BOOK',TEST)
           END
    
    
    #pragma windows 500000 500000
    #include <windows.h>
    #include <string.h>
    
    char* contents[]={
    strdup("ACABook"),
    strdup("BCAChapter 1"),
    strdup("CCASection 1.1"),
    strdup("CCASection 1.2"),
    strdup("CCASection 1.3"),
    strdup("CCASection 1.4"),
    strdup("BCAChapter 2"),
    strdup("CCASection 2.1"),
    strdup("CCASection 2.2"),
    strdup("CCASection 2.3"),
    strdup("CCASection 2.4"),
    strdup("BCAChapter 3"),
    strdup("CCASection 3.1"),
    strdup("CCASection 3.2"),
    strdup("CCASection 3.3"),
    strdup("CCASection 3.4"),
    strdup("BCAChapter 4"),
    strdup("CCASection 4.1"),
    strdup("CCASection 4.2"),
    strdup("CCASection 4.3"),
    strdup("CCASection 4.4"),
    strdup("BCAChapter 5"),
    strdup("CCASection 5.1"),
    strdup("CCASection 5.2"),
    strdup("CCASection 5.3"),
    strdup("CCASection 5.4"),
    strdup("BCAChapter 6"),
    strdup("CCASection 6.1"),
    strdup("CCASection 6.2"),
    strdup("CCASection 6.3"),
    strdup("CCASection 6.4"),
    strdup("BCAChapter 7"),
    strdup("CCASection 7.1"),
    strdup("CCASection 7.2"),
    strdup("CCASection 7.3"),
    strdup("CCASection 7.4"),
    strdup("BCAChapter 8"),
    strdup("CCASection 8.1"),
    strdup("CCASection 8.2"),
    strdup("CCASection 8.3"),
    strdup("CCASection 8.4"),
    strdup("BCAChapter 9"),
    strdup("CCASection 9.1"),
    strdup("CCASection 9.2"),
    strdup("CCASection 9.3"),
    strdup("CCASection 9.4"),
    strdup("BCAChapter 10"),
    strdup("CCASection 10.1"),
    strdup("CCASection 10.2"),
    strdup("CCASection 10.3"),
    strdup("CCASection 10.4"),
    strdup("BCAChapter 11"),
    strdup("CCASection 11.1"),
    strdup("CCASection 11.2"),
    strdup("CCASection 11.3"),
    strdup("CCASection 11.4"),
    NULL};
    int item=6;
    
    int test()
    {
    /*******************************************************************/
    /*                                                                 */
    /*    Call-back function sets the icon for each object according   */
    /*    to whether it is expanded or not                             */
    /*                                                                 */
    /*******************************************************************/
           char* str=contents[item-1];
           if(*(str+1)=='E')
           *(str+2)='B';
           else
           *(str+2)='A';
           window_update(contents);
        return 2;
        }
    
    main()
    {
           winio("%ww%ob%pv%^`20.15tv%cb\f\n%cn%`bt[OK]",
                   contents,&item,"closed_book,open_book",test);
    }
    #pragma resource
    closed_book icon book1.ico
    open_book icon book2.ico
    
    
    
    Link this with a resource file containing the following:
    
    CLOSED_BOOK ICON BOOK1.ICO
    OPEN_BOOK ICON BOOK2.ICO
    
    Because this program is actually part of BROWSE.EXE, the array will not be re-initialised between runs. Therefore if you run the example a second time you will to return to the expansion state at which you left it. If you do not want this in your application, simply re-initialise the first three characters of each string.

    .

    Toolbars

    Toolbars

    Simple toolbars are constructed using %TB. For example, %3.4TB will produce a small block of 12 tools - 3 across and 4 deep. The arguments for each component of the toolbar are as follows:
    • Name of resource for OFF bitmap
    • Name of resource for ON bitmap
    • Name of resource to use while bitmap is depressed
    • If '~' used name of resource for INACTIVE bitmap
    • VariablePointer to variable which is toggled 1=on,0=off.
    • If '~' used VariablePointer to variable which controls if button is active
    • Call-back function if '^' is used.
    If ? is used, the appropriate number (one per button) of help strings must be supplied immediately after the %TB as standard strings. For example, %3TB[Button 1][Button 2][Button 3].

    Often a window has a slightly more general toolbar placed immediately beneath the menu bar. This bar may contain bitmap buttons, small gaps, and certain other controls such as drop-down list boxes. To produce such a tool bar use %ww[no_border] to eliminate the blank border round your window (otherwise your toolbar will hang in space!), and string the tools across the top of the window, followed by %BX. This format will create a strip of suitable size to contain the toolbar. %BX takes one DOUBLE PRECISION double argument which specifies the amount of additional space (in units of standard character depths) to add (vertically centering the toolbar). This should be adjusted to produce a pleasing effect. Adjacent bitmap buttoms should be placed on one %TB (e.g. %3TB) to ensure that the bitmaps are exactly adjacent. Where required small gaps can be introduced using spaces.

    To produce a vertical floating toolbar, place a suitable %TB in another window, which the user can move about. You will probably need to use %LW in the window to allow it to remain open while other things happen.

    Care should be taken that adjacent bitmaps in a %TB have the same dimensions on the shared edge. Typically this is achieved by making all the biotmaps of the same size.

    Here is a simple example of a toolbar:

            options(intl)
            winapp 500000,500000,'resource.rc'
            include <windows.ins>
            character*12 options(3)
            data options/'Active','Passive','Interactive'/
            kopt=1
            k1=0
            k2=0
            k3=0
            ans=winio@('%ww[no_border,maximise]%2.1tb %`ls %tb&',
         +'one_1','one_2','one_d',k1,
         +'two_1','two_2','two_d',k2,
    
         +options,3,kopt,
         +'query_1','query_2','query_1',k3)
          ans=winio@('%bxPress Alt-F4 to close this window',0.5d0)
          end
    
    The file RESOURCE.RC should contain:
    one_1 BITMAP one_1.bmp
    one_2 BITMAP one_2.bmp
    one_d BITMAP one_d.bmp
    two_1 BITMAP two_1.bmp
    two_2 BITMAP two_2.bmp
    two_d BITMAP two_d.bmp
    query_1 BITMAP query_1.bmp
    query_2 BITMAP query_2.bmp
    
    #pragma windows 500000 500000
    #include <windows.h>
    
    char* options[]={"Active","Passive","Interactive",NULL};
    int main()
    {
        int k1=0,k2=0,k3=0,kopt=1;
        int ans=winio("%ww[no_border,maximise]%2.1tb %`ls %tb&",
                       "one_1","one_2","one_d",&k1,
                       "two_1","two_2","two_d",&k2,
                       options,&kopt,
                       "query_1","query_2","query_1",&k3);
            ans=winio("%bxPress Alt-F4 to close this window",0.5);
        }
    
    #pragma resource
    one_1 BITMAP one_1.bmp
    one_2 BITMAP one_2.bmp
    one_d BITMAP one_d.bmp
    two_1 BITMAP two_1.bmp
    two_2 BITMAP two_2.bmp
    two_d BITMAP two_d.bmp
    query_1 BITMAP query_1.bmp
    query_2 BITMAP query_2.bmp
    
    .

    Summary of ClearWin+ format codes

    Summary of ClearWin+ format codes

    The following table provides a list of the special format codes together with an outline of their use.

    %AC
    Accelerator format

    %AP
    Absolute positioning format.

    %AW
    Attach window format.

    %BC
    Button colour format.

    %BF
    Use bold font.

    %BG
    Background colour format.

    %BH
    Bubble help format.

    %BI
    Button icon format.

    %BM
    Similar to the icon format %ic but the picture is supplied as a simple bitmap.

    %BR
    Bar format draws a horizontal or vertical bar which is partially filled with a user-selected colour.

    %BT
    Button format - defines a button with text.

    %CA
    Caption format defines the title of a dialog box.

    %CB
    Box close format closes a box opened by %ob.

    %CC
    Closure control format provides a link to a call-back function by which the user controls the action to be taken when a window is closed.

    %CH
    Child window format inserts a child window.

    %CL
    Colour palette format

    %CN
    Centering format forces everything which follows it, up to the next new line or form-feed character, to be centred in the window.

    %CO
    Supplies defaults for subsequent rd/rf/rs boxes

    %CU
    Establishes a cursor for the next control in a format.

    %CV
    Control variable format.

    %CW
    Embeds a ClearWin+ window. (See traditional input/output )

    %DC
    Establishes a default cursor for the window.

    %DD
    Supplies an increment for next %RD, which acquires a spin control.

    %DF
    Supplies an increment for next %RF, which acquires a spin control.

    %DP
    Adds a decimal parameter to last parameter block (%PB) (See Parameter blocks. )

    %DW
    Owner draw box format provides owner draw boxes.

    %EB
    Edit box format presents a edit box in which a text file can be displayed and modified.

    %EP
    Adds an enumerated parameter to last parameter block (See Parameter blocks. ).

    %FF
    Form feed. Move down to below any existing controls. Equivalent to \f.

    %FL
    Floating point limit format specifies the lower and upper limits for subsequent %rf formats.

    %fn
    Font name format - selects a font for subsequent text.

    %FP
    Adds a floating point parameter to the last parameter block. (See Parameter blocks. )

    %FR
    MDI frame format - defines a frame to contain child windows attached by %aw
    .

    %FS
    File selection format specifies the working directory and file filter for subsequent file open call-backs.

    %FT
    File filter format specifies filter information for subsequent file open call-backs.

    %GA
    Gang format enables radio buttons and/or bitmap buttons to be ganged together so that if one is switch on the others are switched off.

    %GD
    Programmer's grid format supplies a temporary grid to help with the positioning of controls.

    %GF
    Returns a handle to the current font.

    %GP
    Get window position format used to get the current co-ordinates of the window position.

    %GR
    Create a sub-window to contain Salford graphics.(See graphics windows )

    %HE
    Help format specifies the location of help information.

    %HS
    Horizontal scroll bar format.

    %HT
    Hypertext format. (See Hypertext windows)

    %IC
    Icon format - draws an icon.

    %IF
    Initial focus - sets initial window focus to the next control. %IL
    Integer limit format - specifies the lower and upper limits for subsequent %rd formats.

    %IT
    Use italic font.

    %LB
    List box format supplies a simple list-box facility.

    %LS
    New list box format. Like %LB but the n and m parameters are reversed.

    %lw
    Leave window open format allows window_printf to return without closing the window that it creates.

    %MG
    Message interception format.

    %MI
    Minimise icon format supplies the name of an icon resource to be used if the window is minimised.

    %MN
    Menu format used to attach a menu to the window.

    %MS
    Multiple selection box.

    %ND
    Sets or resets never down mode.

    %NL
    New line, equivalent to \n.

    %NR
    Sets or resets never right mode.

    %OB
    Box open format defines the top left hand corner of a rectangular box into which subsequent objects are to be placed until a corresponding %cb format is encountered.

    %PB
    Parameter block format.(See Parameter blocks. )

    %PD
    Produces a pound currency symbol.

    %PM
    Defines (or extends) a pop-up menu tied to the right mouse button.

    %PS
    Property sheet (tabbed dialog) format

    %PV
    Pivot format used to create a pivotal point for any subsequent re-sizing of the window.

    %RB
    Radio button format defines a radio button with button text supplied directly.

    %RD
    Integer input format creates an edit box and displays an integer that can be updated.

    %RF
    Floating point input format creates an edit box and displays an floating point value that can be updated.

    %RJ
    Right justifying format forces everything which follows it, up to the next new line or form-feed character, to be right justified in the window. A window margin, if any, is still applied.

    %RS
    String input format creates an edit box and displays a a string that can be updated. Maximum string length is supplied as a separate argument.

    %SC
    Startup callback function.

    %SD
    Enters or leaves subscript mode.

    %SF
    Standard font format - resets to default text attributes after use of any combination of %bf, %it, %ul, %fn, and %ts.

    %SH
    Makes this window a component of a property sheet.

    %SI
    Standard icon format defines a standard icon that is to be placed to the left of the block of text that follows the descriptor.

    %SL
    Slider format.

    %SM
    System menu format.

    %SP
    Set window position format used to initialise the position of the window on the screen.

    %SS
    Save settings in .INI file.

    %ST
    Variable string format lays a string out in a field of n characters. The string is re-drawn each time the window is renewed.

    %SU
    Enter or leave superscript mode.

    %SZ
    Window size format.

    %TA
    Tab; 8-character intervals. Equivalent to \t.

    %TB
    Bitmap button and toolbar format defines a bit mapped button or a whole tool-bar.

    %TC
    Sets the colour of subsequent text.

    %TL
    Defines tabstop settings for window.

    %TP
    Supply textual (string) parameter for prior parameter block (%PB) (See Parameter blocks. )

    %TS
    Text size format - used to scale the text font size either up or down.

    %TT
    Thin button format - used to make textual tool bars.

    %TX
    Textual array

    %TY
    Defines attribute for text array (%TX)

    %UL
    Underline text.

    %UP
    Supply user parameter for prior parameter block(%PB) (See Parameter blocks. )

    %VP[Property list]
    Add another property to a previously defined VBX control

    %VB[VB_Class name][Property list]
    Insert a VBX control (not yet fully operational).

    %WC
    Character output.

    %WD
    Integer output.

    %WE
    Floating point output in exponent form.

    %WF
    Floating point output in decimal form.

    %WG
    Floating point output in decimal or exponent form.

    %WP
    Supplies the name of a wallpaper bitmap which is used as a back drop to its contents.

    %WS
    Character string output.

    %WW
    Window control format causes the resultant window to look like a normal application window, rather than a dialog window.

    %WX
    Hexadecimal integer output.

    Parameter blocks

    Parameter blocks

    A parameter block is a control which has been designed for use in complex simulation programs where your users may wish to browse a large set of parameter names and values, with the option to select a value and modify it. A parameter block is defined using %n.mPB where n is the width of the block in average characters, and m is the number of lines in the control. The control will scroll if necessary to display all the parameters. %PB can take the option 'SORTED' to cause the parameters to be alphabetically sorted by name. After a parameter block has been defined parameters can be attached by subsequent formats thus:
    1. %DP - Integer parameter
    2. %FP - Floating point parameter
    3. %EP - Enumerated parameter (a set of named alternatives)
    4. %UP - User parameter (just activates a call-back)
    One use for the user parameter is to activate another parameter block to achieve a hierarchical effect.

    The various parameter types are illustrated by the following example:

    
          WINAPP 500000, 500000
           OPTIONS(INTL)
           INCLUDE <WINDOWS.INS>
           EXTERNAL ACTION
           INTEGER ANS,TEXTURE_TYPE
           REAL*8 V,P,A
           CHARACTER*8 TEXTURES(6)
           CHARACTER*20 NAME
           DATA TEXTURES/'Sticky','Messy','Dirty','Greasy','Slimy',
         +'Very slippery'/
          K1=1
          K2=2
          K4=4
          K5=5
          V=4.5
           TEXTURE_TYPE=4
           A=35.4
           P=120.6
           NAME='This and Sticky'
            ANS=WINIO@(
         +'Double click on the parameter you wish to change:%nl%nl&')
          ANS=WINIO@('%ww[casts_shaddow]%ca[Parameter setting]&')
          ANS=WINIO@('%30.8pb[sorted]&')
          ANS=WINIO@('%dp[test1]&',k1)
          ANS=WINIO@('%dp[test2]&',k2)
          ANS=WINIO@('%ep[Oil texture]&',textures,6,texture_type)
          ANS=WINIO@('%dp[Temperature (Deg C)]&',k4)
          ANS=WINIO@('%dp[Carbon monoxide (%)]&',k5)
          ANS=WINIO@('%fp[Curent (Amps)test6]&',a)
          ANS=WINIO@('%10.3fp[Voltage]&',v)
          ANS=WINIO@('%fp[Oil pressure (PSI)]&',p)
          ANS=WINIO@(
         +'%?tp[Oil name][What is the official name of this oil?]&',
         +name)
          ANS=WINIO@('%up[Special action]&',action)
           ANS=WINIO@(' ')
           END
           INTEGER*4 FUNCTION ACTION()
           INCLUDE <WINDOWS.INS>
           K=WINIO@('No special action available yet%nl%nl%cn%bt[Continue]')
           ACTION=1
           END
    
    #include <windows.h>
    int kh=0,kv=0;
    
    char* textures[]={"Sticky","Messy","Dirty","Greasy","Slimy","Very slippery",NULL};
    int action()
    {
           winio("No action today\n\n%cn%bt[Thank you]");
           return 2;
    }
    main()
    {
        char name[20]="Thick and Sticky";
        int k1=1,k2=2,k4=4,k5=5;
           int texture_type=4;
           double v=4.5,p=200,a=25.2;
        winio("%ww[casts_shaddow]Double click on an item to change it\n\n&");
        winio("%30.8pb[sorted]&");
        winio("%dp[test1]&",&k1);
        winio("%dp[test2]&",&k2);
        winio("%ep[Oil texture]&",textures,&texture_type);
        winio("%dp[Temperature (Deg C)]&",&k4);
        winio("%dp[Carbon monoxide (%)]&",&k5);
        winio("%fp[Curent (Amps)]&",&a);
        winio("%10.3fp[Voltage]&",&v);
        winio("%fp[Oil pressure (PSI)]&",&p);
        winio("%?tp[Oil name][What is the official name of this oil?]&",name,20);
        winio("%up[Special action]&",action);
           winio("");
        }
    
    
    
    .

    Text arrays

    Text arrays

    Text arrays, created using the %TX format, provide a convenient way to display a grid of characters together with 'attributes' to achieve effects analogous to those achieved under DOS by writing to the screen buffer. A text array can respond to keyboard and mouse input via its call-back function, updating the array as necessary.

    The text array format %n.mTX[options] takes two character strings and two integer arguments n, and m. For example:

    
    character*800 text,attr
    k=winio@('%60.8TX',text,attr,80,10)
    
    char text[800],attr[800];
    winio("%60.8TX",text,attr,80,10);
    
    
    The text array 'text' is displayed in the box as an 80 x 10 array of which initially only 60 x 8 is visible. The size of the control can be variable if it is preceded by a pivot in a variable sized window. The attr array contains attribute numbers stored as integers (i.e. CHAR(i) in Fortran). Zero is the default attribute, others are defined by subsequent %TY[colour] formats. The first ty defines attribute 1, etc. The colour is the background colour of the text, and may be specified as an RGB value in the argument list if the colour in brackets is omitted. The foreground colour, may be varied with %TC, however changes in font, underlining, etc are not permitted Format %TX may have a call-back, which can use the following clearwin_info strings:
    • TEXT_ARRAY_RESIZING
    • TEXT_ARRAY_WIDTH
    • TEXT_ARRAY_DEPTH
    • TEXT_ARRAY_X
    • TEXT_ARRAY_Y
    • TEXT_ARRAY_MOUSE_FLAGS
    • TEXT_ARRAY_CHAR
    The TEXT_ARRAY_RESIZING parameter is set to 1 only in a call-back responding to a re-sizing event. The next two parameters only have meaning in this context. They are widths in characters.

    The X and Y parameters give the mouse position in characters from the top left corner, and are zero based. The mouse flags, which contain information about which mouse button (if any) is depressed, are defined as in %DW. The option FULL_MOUSE_INPUT can be specified to force call backs whenever the mouse moves over the control.

    By default the call-back function is called when a keyboard character is sent while the control is in focus. The character is placed in the parameter TEXT_ARRAY_CHAR. If the option FULL_CHAR_INPUT is specified, the call-back function receives each keystroke using the Microsoft VK_ parameters (defined in our insert files). The call-back is invoked for each key press and each key release. In the latter case TEXT_ARRAY_CHAR parameter has the top bit set. The parameter TEXT_ARRAY_CHAR will be zero when not in use. To respond to alt key combinations you should use the %AC facility rather than tracking the alt key with FULL_CHAR_INPUT. This is because messages associated with the release of the ALT key can be delayed until the next key is pressed. The option USE_TABS may be used to cause the tab key to be passed to the call-back rather than performing its normal Windows function of moving between controls.

    Unless an explicit font has been selected prior to %TX, the SYSTEM FIXED FONT is used, since a text array is supposed to be textually aligned both vertically and horizontally. You can select an explicit font for the array, but you must select a fixed pitch font.

    Note carefully that the text array is not re-dimensioned if the control is re-sized, re-sizing simply changes the region which is made visible. Property Sheets

    Property Sheets

    Property sheets represent a way of presenting two or more 'sheets' of data in a format which resembles a card index. Each sheet is set up as a separate window using winio and the %SH format. This produces a child window which is hidden from view until connected to a property sheet control using %PS.

    In the following example, notice how the caption text of each sheet is used to name the corresponding card index 'tab'.

    
           OPTIONS(INTL)
           INCLUDE <WINDOWS.INS>
           INTEGER K1,K2,K3,ANS
           INTEGER MALE,FEMALE
           INTEGER ALIVE,CONSCIOUS,COMFORTABLE,AGE
           CHARACTER*20 NAME
           CHARACTER*200 REPORT
           DATA NAME/'Fred Bloggs'/
           report='Mr. Bloggs has a large wart'//char(13)//char(10)//
         +'on his left buttock which'//char(13)//char(10)//
         +'should be removed with caustic soda'//char(13)//char(10)
           MALE=1
           FEMALE=0
           ALIVE=1
           CONSCIOUS=1
           COMFORTABLE=0
           AGE=75
    C
    C     Sheet 1
    C
           ANS=WINIO@('%ca[Personal]Personal information:%nl%nl&')
           ANS=WINIO@('%obName:%ta%rs%nlAge:%ta%rd%nlSex: %rb[Male]   '//
         +'%rb[Female]%2ga%cb%sh',NAME,AGE,MALE,FEMALE,MALE,FEMALE,K1)
    C
    C     Sheet 2
    C
           ANS=WINIO@('%ca[Medical]General patient condition%nl%nl&')
           ANS=WINIO@('%ob%rb[Alive]%nl%rb[Conscious]%nl%rb[Comfortable]'//
         +'%cb%sh',ALIVE,CONSCIOUS,COMFORTABLE,K2)
    C
    C     Sheet 3
    C
           ANS=WINIO@('%ca[Report]Doctor''s report%nl%nl&')
           ANS=WINIO@('%30.4eb[hscrollbar,vscrollbar]%sh',REPORT,200,K3)
    C
    C     The main window
    C
           ANS=WINIO@('%bg[grey]%ca[Patient status]%3ps',K1,K2,K3)
          END
    
    main()
    {
           int k1,k2,k3;
           int male=1,female=0;
           int alive=1,conscious=1,comfortable=0;
           char report[200]="Mr. Bloggs has a large wart\r\non his left buttock which\r\nshould be removed with caustic soda\r\n";
           int age=75;
           char name[20];
           strcpy(name,"Fred Bloggs");
    //
    //     Sheet 1
    //
           winio("%ca[Personal]Personal information:\n\n&");
           winio("%obName:\t%rs\nAge:\t%rd\nSex: %rb[Male]   %rb[Female]%2ga%cb%sh",
                name,20,&age,&male,&female,&male,&female,&k1);
    //
    //     Sheet 2
    //
           winio("%ca[Medical]General patient condition\n\n&");
           winio("%ob%rb[Alive]\n%rb[Conscious]\n%rb[Comfortable]%cb%sh",
                &alive,&conscious,&comfortable,&k2);
    //
    //     Sheet 3
    //
           winio("%ca[Report]Doctor's report\n\n&");
           winio("%30.4eb[hscrollbar,vscrollbar]%sh",report,200,&k3);
    //
    //     The main window
    //
           winio("%ca[Patient status]%bg[grey]%3ps",&k1,&k2,&k3);
        }
    
    
    .

    Note that property sheets are coloured grey by default, and therefore the main window in the above example has been explicitly coloured to match.