WO1995022104A1 - Use of multiple applications and allocation of memory or other resources in a gui environment - Google Patents

Use of multiple applications and allocation of memory or other resources in a gui environment

Info

Publication number
WO1995022104A1
WO1995022104A1 PCT/AU1995/000068 AU9500068W WO1995022104A1 WO 1995022104 A1 WO1995022104 A1 WO 1995022104A1 AU 9500068 W AU9500068 W AU 9500068W WO 1995022104 A1 WO1995022104 A1 WO 1995022104A1
Authority
WO
Grant status
Application
Patent type
Prior art keywords
rom
application
windows
die
name
Prior art date
Application number
PCT/AU1995/000068
Other languages
French (fr)
Inventor
Bruce Peter Parker
Original Assignee
Ni-Tech Pty. Limited
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F17/00Digital computing or data processing equipment or methods, specially adapted for specific functions
    • G06F17/30Information retrieval; Database structures therefor ; File system structures therefor
    • G06F17/30011Document retrieval systems
    • G06F17/30014Hypermedia
    • GPHYSICS
    • G06COMPUTING; CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F12/00Accessing, addressing or allocating within memory systems or architectures
    • G06F12/02Addressing or allocation; Relocation
    • G06F12/08Addressing or allocation; Relocation in hierarchically structured memory systems, e.g. virtual memory systems
    • G06F12/10Address translation

Abstract

A number of GUI applications, and related data files, can be run and used at the same time. A first GUI application with a first data file or record is run. One or more primary symbols (26, 28, 30, 32) representing one or more further GUI applications are displayed. Actuation of one of the primary symbols (26, 28, 30, 32) by a user causes a search for a second data file or record associated with the first data file or record. If an associated second data file or record exists, the further GUI application runs with the associated second data file or record automatically loaded. On request for allocation of virtual memory or 'Windows' resources in a Microsoft Windows environment, memory or resources greater than that requested are actually allocated.

Description

USE OF MULTIPLE APPLICATIONS AND ALLOCATION OF MEMORY OR OTHER RESOURCES IN A GUI ENVIRONMENT

Technical Field

The invention relates to a method of facilitating the use of a plurality of G.U.I. applications, and to a device for putting this method into effect. The invention is particularly useful in the field of legal work, and especially in litigation, but has uses in many other fields. A second aspect of the invention relates to a method of allocating virtual memory and resouces in a G.U.I, or Windows environment.

Rack-ground Art

The term G.U.I, is derived from the words "graphical user interface". However, for the purpose of this specification a more generalised meaning is required.

Thus, in this specification, a G.U.I, application is defined to be a program for performing a particular task, such as word processing or image manipulation, in which options and commands available to the user are displayed in graphical form, and in which options and commands are represented by symbols which can be actuated by the user. The words "symbol" and "actuate" are defined below.

For the purposes of this specification, a symbol includes any symbol, whether alphanumeric, pictorial, or a combination of both. For example, the so called "icons" which are commonly used in many G.U.I, applications can be regarded as symbols.

In this specification, the word "actuate" when used in relation to a symbol should be taken to include any form of actuation, including "clicking" on a symbol using a mouse, selecting a symbol using a keyboard, pressing a symbol on a touch sensitive screen, and even using a voice actuation program to actuate a symbol by speaking into a microphone.

A file is defined to be a named set of data stored in machine readable form, for example on magnetic media or in RAM, for use with a G.U.I, application.

A data file is defined to be a file containing data which has been input by a user, manually or otherwise. A data file is created and saved by a G.U.I, application once the required data has been entered by the user of the G.U.I, application. If the user then needs to view or edit the data in a particular data file, he must first instruct the G.U.I, application to load the data file. Most G.U.I, applications allow the user to allocate names to data files and records (defined below) so as to allow the user to identify and select a particular data file or record at a later date.

A record is defined to be a group of related items of data in a data file. For example, a business can decide to store the names and addresses of its customers and suppliers using a database. In this case, the names and addresses can be stored in two separate data files called, for example, CUSTOMERS and SUPPLIERS, and each individual customer or client can occupy a separate record within each file. However, in this specification the word "record" is not limited solely to databases. Also, in this specification, when a data file has been loaded and a particular record in that data file has been selected, that record is referred to as "loaded".

It is well known that many operating systems nowadays are multi-tasking and allow a G.U.I, application to run while one or more other G.U.I, applications are running in the background. However, in this specification, the use of the word "run" in relation to a G.U.I, application should be taken to indicate that the G.U.I, application is running in the foreground, ie. as d e main application, and not in the background. This does not, of course, preclude the possibility that other G.U.I, applications are running in the background. Normally, when a G.U.I, application is running in the foreground information relating to the application is displayed to the user.

As has been stated above, the invention is particularly useful in the field of litigation. When a legal practitioner is involved in litigation on behalf of a client, it is often necessary for the legal practitioner to store a whole range of different types of information relating to the case. If a computer is used to store the information then it can be necessary to make use of a range of different software applications. For example, written documents can be recorded and edited using a word processor, images can be stored and displayed using a graphics package, general information relating to the case can be stored using a database, and financial information can be recorded using a spreadsheet. Each application, of course, makes use of its own data files, and, in order to keep track of the locations of files, it is usually necessary to store the files relating to different applications in separate directories. For example, all the word processing files can be stored in a directory called WORD, all the image files can be stored in a directory called IMAGE, and so on.

Furthermore, it can be necessary to further subdivide the data files within each directory. For example, the practitioner may want to keep all files relating to a particular client together, and may therefore wish to subdivide each directory into a number of subdirectories, each relating to a separate client. Still more subdivisions can be necessary for a variety of other reasons. For example, the practitioner can be dealing with a number of separate cases relating to the same client, and can wish to form a separate subdirectory for each case. This can result in a large and complex directory tree structure.

In litigation, it often happens that two data files relating to different applications are closely related to each other. For example, a written document, stored in a word processing data file, can make reference to a picture which is stored as an image data file. In order to read the written document the practitioner must run the word processing application and then load the data file corresponding to the written document. If he then wishes to view the picture referred to by the document, he must then run the appropriate image processing application and load the image data file corresponding to the picture. In order to do this he must first identify the file name of the image data file. A considerable amount of time can be wasted by the practitioner in finding the file name of the image data file. Furthermore, even when the file name has been found, more time can be wasted by the practitioner in locating the data file on his computer system. It will be appreciated that the problem of locating the data file on the computer system can be particularly acute in a case where the data files of the different applications available to the practitioner are spread over a complex directory tree structure.

The invention has arisen from an attempt to overcome the above difficulties, but is applicable to a wide range of fields in addition to litigation. Disclosure of the Tnvention

According to the invention there is provided a method of facilitating the use of a plurality of G.U.I, applications, the method comprising running a first G.U.I, application with a first data file or record loaded and at the same time displaying one or more primary symbols representing one or more further G.U.I, applications, and, on acmation of one of the primary symbols by a user, searching for a second data file or record associated with said first data file or record and, if such an associated second data file or record exists, causing the further G.U.I, application represented by said one of the primary symbols to be run with the associated second data file or record automatically loaded. It will be appreciated that, in the example of litigation discussed above, such a metfiod saves the practitioner both the time involved in searching for the file name of the image file associated with his word processing file, and the time involved in locating on the computer the image file to be loaded into the graphics package.

Preferably, if no such associated second data file or record exists then, on actuation of said one of the primary symbols by a user, the method includes the step of informing the user of this fact.

In such a case, the method can include the step of, on actuation of said one of the primary symbols by a user, causing the further G.U.I, application represented by that primary symbol to be run with no data file automatically loaded. Clearly, the user must have some way of specifying which data files and records are to be considered as associated with each other. Conveniently, two data files or records are considered to be associated when their names are the same, or when designated parts, for example the first parts, of their names are the same.

Preferably, the method also includes, while the first G.U.I, application is running, displaying one or more secondary symbols representing said one or more further G.U.I, applications, and, on acmation of one of said secondary symbols by a user, running the G.U.I, application associated with that secondary symbol with no data file or record automatically loaded. It will be appreciated that this feature allows the user to switch from the first G.U.I. application to one of the further G.U.I, applications regardless of whether the two applications have associated data files or records.

Preferably, the method further includes the step of, when one of the further G.U.I. applications is running, displaying a return symbol representing the first G.U.I. application, and, on actuation of the return symbol by a user, running the first G.U.I. application.

In this case, the first G.U.I. application is preferably run with a third data file or record automatically loaded if, when the return symbol is actuated, said one of the further G.U.I. applications is running with a fourth data file or record loaded and die third and fourth data files or records are associated with each other.

Clearly, the first and third data files or records can be one and the same thing, and the second and fourth data files or records can also be one and the same thing, but this need not necessarily be the case since, after running said one of the further G.U.I. applications with the second data file or record preloaded, the user can switch to a different data file or record (ie. the fourth data file or record) before returning to the first G.U.I. application by actuating the return symbol.

In a more sophisticated embodiment of the invention, if there is more than one further G.U.I. application, the method also includes, when one of the further G.U.I. applications is running with a particular data file or record loaded, displaying one or more further application symbols representing the other further applications, and, on actuation of one of the further application symbols by a user, causing the further G.U.I. application represented by said one of the further application symbols to be run with a data file or record automatically loaded which is associated with said particular data file or record.

It will be appreciated that this feature allows the user to "hop" directly between the various different further G.U.I. applications in order to view and/or edit a complete set of related data files or records.

Ideally, the user is able to specify, at any stage during the method, the default directories to be used by the G.U.I. applications (including the first G.U.I. application) when the G.U.I. applications are caused to be run by acmation of a relevant symbol.

In the example of the legal practitioner given above, this feature allows a practitioner who happened to be working on a document in a word processing application, to switch to his graphics package and create an image data file without worrying about which directory the image data file should be saved in.

As a corollary, a further feature only allows two data files or records to be associated with each other, for example by virtue of their names, when each of the data files or records is located in a respective default directory. It will be appreciated that this feature helps to ensure that unrelated data files and records are not accidentally associated with each other.

Conveniently, the method further includes displaying a number generating symbol and, on acmation of the number generating symbol, and input of start and finish values, by the user, generating a sequence of numbers, or alphanumeric strings, between the start and finish values.

The method can also include generating a bar code corresponding to each number or string, and/or printing a label corresponding to each number or string, and/or creating a data file or record having a name corresponding to each string. This feature has the advantage of ensuring that human error does not arise in the creation of a sequence of bar codes, labels, or data files or records.

In the example of the legal practitioner given above, this feature can be used to create labels for a series of consecutively numbered case files, together with associated bar codes and data files or records. The invention also provides a device for carrying out the above method, comprising computing means for running the G.U.I. applications, display means for displaying said symbols and information relating to the G.U.I. applications, first input means for allowing the user to operate the G.U.I. applications, and second input means for allowing the user to actuate said symbols. The first and second input means can, of course, be combined with each other to form a single input means, or combined with the display means, as in the case of a touch sensitive screen.

According to a further aspect of the invention, there is provided a method of - allocating virtual memory in a GUI environment, said method comprising the steps of: providing an allocation request for virtual memory; increasing said allocation request to define an extra virtual memory space for storing GUI objects; and allocating an increased virtual memory space in response to said increased allocation request when said increased allocation request is less than or equal to the amount of free virtual memory available.

According to a further aspect of the invention, there is provided a method of allocating windows resources in the Microsoft Windows® environment, said method comprising the steps of: providing an allocation request for windows resources; increasing said allocation request to define a buffer for storing GUI objects; and allocating an increased portion of said windows resources in response to said increased allocation request when said increased allocation request is less than or equal to the amount of free windows resources available. According to a further aspect of the invention, there is provided a method of managing windows resources in the Microsoft Windows® environment, said method comprising the steps of: allocating an increased percentage of windows resources for an application displayed in a main window, said increased percentage of windows resources comprising a nominal portion of windows resources for said application and a buffer which are contiguously arranged in relation to one another; and storing windows resources of one or more child windows of said main window in said buffer. Brief Description of Drawings

The preferred embodiment of the present invention will now be more particularly described, by way of example only, with reference to the accompanying drawings, in which:

Fig. 1 shows the main menu of a program for facilitating the use of a number of G.U.I. applications;

Fig. 2 shows the screen layout for a database application, when run with the program;

Fig. 3 shows the screen layout for a graphics application, when run with the program; Fig. 4 shows the program's Utilities Menu;

Fig. 5 shows the screen layout for the program's Change Paths utility;

Fig. 6 shows the screen layout for the program's Numbering utility;

Figs 7A and 7B show allocation of windows resources in Microsoft Windows;

Figs. 8 A and 8B show allocation of windows resources according to an embodiment of the invention;

Fig. 9 is a flow diagram illustrating the method of allocating free windows resources according to an embodiment of the invention;

Fig. 10 is a flow diagram illustrating step 190 of Fig. 9 in detail; and

Fig. 11 is a flow diagram illustrating the method of freeing windows resources according to an embodiment of the invention. Modes for Carrying Out the Invention

The appendix contains program listings for implementing preferred embodiments. For me sake of keeping the number of pages in the specification to a manageable size, the code in the appendix has been compressed by replacing each hard return by the symbol "Λ".

The preferred embodiment is implemented by means of a program, which will be referred to simply as the program, which can be run on a conventional computer (not shown) connected to a VDU having a screen 2. When the program is started a copyright warning message (not shown) is displayed on die screen 2. Once the user has read and accepted the copyright warning message, the program's main menu is displayed on me screen 2, as shown in Fig. 1. The main menu comprises eight symbols which can be actuated by die user by means of clicking on the appropriate symbol using a mouse (not shown). The "DB" symbol 4 represents the first, or central, application, which, in the present example, is a database application. The four symbols 6, 8, 10 and 12 on the right hand side of die main menu represent four additional applications, which will be referred to simply as the further applications for consistency with the terminology used earlier in this specification. These four symbols are labelled "WP", "GRAPH", "SS" and "FLOW", and represent a word processing application, a graphics application, a spread sheet application, and a flowchart application respectively. For reasons which will become clear below, the four symbols 6, 8, 10 and 12 will be referred to as secondary symbols. Acmation by a user of one of the secondary symbols causes me further application represented by that secondary symbol to be run. Furthermore, when a further application is run by actuating a secondary symbol, the further application is run with no data file or record automatically loaded.

When die DB symbol 4 is actuated, the central application, namely the database application, is caused to be run, and die screen shown in Fig. 2 is displayed. This screen is essentially the same as the screen which would be displayed if d e database application were running normally, i.e. without the use of the program of the preferred embodiment, except mat five symbols are displayed in a strip 14 across the top of the screen 2. The rest of the screen 2, outside die strip 14, is laid out in the same way as when the database is run normally. For example, the normal pull-down menus, file 16, edit 18 and help 20, are available at me top of the screen 2, and the database field names 22 are displayed down me left hand side of die data area 24 of the screen 2. The user can enter appropriate data adjacent each field name 22 in order to create a database comprising a number of records. Each record has a unique record number which is displayed at me top of the data area 24, adjacent the label "Record No.". The database application allows d e user to store information in a number of different records, with each record being divided into a number of different fields. The five symbols 26, 28, 30, 32 and 34 in me strip 14 are labelled "WP", "GRAPH", "SS", "FLOW" and "MENU", and d eir operation will now be described. Acmation of the MENU symbol 34 simply returns the user to die main menu shown in Fig. 1. The remaining four symbols 26, 28, 30 and 32 will be referred to as primary symbols, and represent me same four further applications as the secondary symbols 6, 8, 10 and 12. The difference between die primary and secondary symbols is that acmation of a primary symbol allows the user to run the further application represented by diat primary symbol with a data file automatically loaded. When a primary symbol is actuated die program looks to see whether there is a data file for the relevant further application having a file name (excluding the file name extension, e.g. DOC, TXT, TIF) which is identical to die record number of the record which is currendy displayed by die database application. If such a data file (referred to as an associated data file) exists, the further application is caused to be run with die associated data file automatically loaded. If no such associated data file exists, a message is displayed on die screen 2 informing die user of tiiis fact. The user is then given (in a dialogue box which is not shown in die drawings) the following three choices: to return to the screen layout of Fig. 2; to run die further application widi no data file automatically loaded; or to automatically create an associated data file and run die further application widi die automatically created data file automatically loaded.

As an example, me user may select record no. 1234 while using die database application shown in Fig. 2, and dien click on die "GRAPH" symbol 28. The program men looks, in die default directory (explained below) of die graphics application, to see whe ier an image data file named 1234 exists. If an image file named 1234 exists, the graphics application will be run wi i the image data file 1234 automatically loaded, and me screen of Fig. 3 will be displayed. The image corresponding to the image data file 1234 will be displayed in window 36, and all me normal pull-down menus 38 of die graphics application will be available to die user. It will be seen, dierefore, that the user can jump straight from a database record to die image associated widi that database record, displayed in the graphics application. The program also provides a RETURN symbol 40, acmation of which returns die user to die screen view of Fig. 2. If die image data file 1234 is displayed in die graphics application when die return symbol 40 is actuated, d e user is returned to database record no. 1234, i.e. die original record from which the user moved to the graphics application. However, if the user switches to a different image data file before actuating die return symbol 40, the user is given me option of returning to the database record associated widi that different image data file, assuming such an associated record exists, or of returning to die original database record, i.e. record no. 1234. If no such associated record exists, the user is returned to die original database record, i.e. record no. 1234. Although this example has been given in relation to the graphics application, d e same process applies for the remaining further applications.

It will be seen, dierefore, that if die user wishes to associate a data file with a particular database record, all diat die user has to do is to save die data file widi a file name which corresponds to die record number of me database record.

When die utilities symbol 42 of die main menu (shown in Fig. 1) is actuated, die utilities menu screen shown in Fig. 4 is displayed. The utilities menu screen has ten symbols which allow the user to make use of various utilities provided by the program, and described below. Actuation of the "Change Paths" symbol 44 displays die Patiis screen shown in Fig. 5. The Paths screen allows the user to enter, in die boxes 46, die default directory padi to be used by each of die four further applications. The default directory paths perform two useful functions. Firstiy, when a further application is run by actuation of a primary or secondary symbol, the default directory for tiiat further application is the default directory specified in the relevant box 46. Alternatively a default area of a file, such as a database file, can be specified. The user can, of course, change directory while using die further application, but if he does not change directory then die further application will save files and look for existing files only in me default directory.

Secondly, when a primary symbol is actuated, and die program is searching for an associated data file, d e program will search for the associated data file only in me relevant default directory, or the associated record only in die relevant default area of die relevant file. This is particularly useful, since it allows a number of copies of the program to be run on die same computer (not necessarily simultaneously), with each copy of the program being allocated a different set of default directories. It will be seen diat it is, for example, possible to have two different image data files bod named 1234 residing in different directories, for use by different copies of die program.

When the "Numbering" symbol 48 on die Utilities Menu is actuated by die user, die screen layout shown in Fig. 6 is displayed on die screen 2. The numbering utility is used to generate a sequence of consecutive labels, bar codes and/or database records. The user can enter a starting number of up to seven digits in die "Starting No." box 50, and an ending number of up to seven digits in me "Ending No. " box 52/ When die "Generater" symbol 54 is actuated, a sequence of numbers between the starting and ending values is generated. It is also possible to give die numbers a fixed prefix by entering a letter or number in die "Prefix" box 56. In addition, a letter can be entered in the "From" box 58, and anodier letter entered in die "To" box 60, in order to provide each number with a sequence of extensions between die "From" and "To" letters. In this context, an extension is a letter which is placed at die end of die number. If the "Bar Codes" option 62 is selected by die user, a bar code will be generated corresponding to each of die generated numbers. If the "Database Records" option 64 is selected, tiien database records will be generated having record numbers corresponding to the generated numbers. The "View" symbol 66 simply allows the user to view d e generated numbers on die screen 2, before database records, bar codes, or labels are generated. The "Print" symbol 68 is used to activate a print run which actually prints die labels and bar codes. The "Cancel" symbol 70 returns die user to die utilities menu of Fig. 4 wimout generating any labels, bar codes or database records.

The remaining options on me utilities menu of Fig. 4 will be discussed briefly below. Actuation of the "Resource Calculator" symbol 72 displays a calculator on die screen 2 which can be used for a variety of purposes, including calculating die total amount to be charged to a client for performing a particular task.

The "OCR Capture" symbol 74 allows die user to scan documents into the word processing application, and perform optical character recogmtion on die text of tiiose documents.

The "Convert File" symbol 76 allows the user to convert word processing documents from one format to anotiier, and die "Join Files" symbol 78 allows die user to join a number of different word processing files togetiier. The "Audio Read Back" symbol 80 initiates any standard program for reading die text of a document aloud, and die "Voice Control" symbol 82 initiates any standard program which allows me computer to be controlled by means of me user speaking commands into a microphone (not shown).

The "Image Capture" symbol 84 initiates die graphics application, and allows the user to scan in new images.

The "MENU" symbol 86 returns die user to die main menu of Fig. 1. Returning to the main menu of Fig. 1, die "Print Reports" symbol 88 is used to print a number of predefined database reports. For example, the "Print Reports" symbol 88 can be used to print out all database records between two particular dates. The "Print Reports" symbol 88 can also be used to print out information relating to the program itself, for example, a list of the default directories used by die various applications.

Acmation of die "EXIT" symbol 90 causes me program to close all open data' files, stop running all applications, and terminate die program itself. If die program comes across a data file of any one of d e applications which has been amended and not saved, known as a "dirty" data file, tiien, as a safety measure, die program asks the user whether die dirty data file is to be saved before being closed. In addition, die user is also given die option of saving dirty files, if any, whenever die RETURN symbol 40 is actuated. In a further, non-illustrated embodiment of die invention, die primary symbols

26, 28, 30 and 32, and die MENU symbol 34 are displayed not only in the database application as shown in Fig. 2, but also on die screen layouts of all of die further applications. In tiiis case, die five symbols 26 to 34 operate in exactiy die same way as has been described above, in order to allow die user to jump directiy from a data file in one further application to die associated data file in anotiier further application. As above, two data files are considered to be associated if tiiey have the same file name and are both located in the default directories which are specified by die user in the screen layout of Fig. 5. Although die invention has been described above in relation to a database application, being the central application, and a number of further applications d e data' files of which may be associated widi records of die database, other arrangements are possible. For example, in otiier embodiments of die invention, data files of die central application can be associated widi data files of the further applications, or with records of die further applications. Alternatively, records of the central application can be associated widi records of die further applications.

It is commonly known tiiat many G.U.I.s, such as Windows, suffer from problems known by such terms as General Protection Faults (GPFs) or Terminal Application errors, for example. One particular form of such faults is a memory access fault. In die Windows environment, memory access is controlled by die memory manager files such as KRNL386.EXE, EMM386.EXE and SMARTDRV.EXE for example.

Windows environment applications programs, when run (launched), grab a portion of available virtual memory space which can be any combination of RAM and disk space. Thus various applications occupy contiguous blocks of virtual memory. Memory GPFs occur where an applications program attempts to read or write data (i.e. such as a data file) outside of d e allocated virtual memory space, and a collision widi data already residing at tiiat location occurs, else a virtual memory address cannot be found to which to write the data.

The technique adopted in the prior art that seeks to resolve memory access faults is to reserve a proportion of die total available virtual memory space and prohibit applications programs to reside in that space. As a rule of thumb, at least 30%, and ' often as much as 50% of me available memory space is held in reserve. The embodiment described in me appended program listing achieves a result where near zero memory GPFs occur. The tiiree files, Romulus.exe, Romlinkd.dll and Romulus.dll, have effect over the memory manager file (such as KRNL386.EXE in the Windows environment). During me assignment of virtual memory space these files cause extra virtual memory space to be allocated for each applications program. The extra space is for the purposes of storing (again in die Windows environment) the window name, window class, desk class (if any) and child class. A further approximate 10% margin also is included. This extra space is sufficient such tiiat any 'overflow' data sought to be written within die nominal virtual memory space can be accommodated, tiius memory GPFs rarely if ever occur. A further advantage, dierefore, is tiiat the prior art practice of reserving a significant portion of tiie available virtual memory space need not be continued, tiius the full available virtual memory space can be effectively utilised.

A further beneficial aspect of the preferred embodiment is tiiat in die instance of a Windows applications program being consigned to die 'background1, die invention functions to release the virtual memory space previously occupied by die applications program, in distinction to die prior art practices of merely closing (i.e. stop die running of) me ".exe" file. This has particular advantage of avoiding the effect of "memory leakage' . Memory leakage can be described as die phenomenon whereby if die same applications program is continually opened tiien closed, die total available system resources will unavoidably reduce widi each opening and closing instance. This is so even tiiough the applications program seeks only to occupy the same virtual memory space each time it is opened.

A number of operating systems and environments currentiy exist which utilise a G.U.I. Examples of such G.U.I. environments include Microsoft Windows®, OS/2 ® , X-Windows, and d e Apple operating system, all of which are well known in die art.

An embodiment of me invention is utilised in me MS Windows environment as will be described below. The MS Windows environment incorporates a memory management system in which both random access memory (RAM) and hard drive disk space can be utilised as a single, contiguous addressable memory space for storing applications and data. The usage of a portion of available hard drive disk space in this manner is commonly referred to as virtual memory. Ideally,' using tins arrangement of virtual memory space, a G.U.I. environment such as MS Windows should be able to store more applications and data, as well as larger size applications and data, in memory man would be die case if only RAM were utilised.

For example, the amount of free memory available immediately after loading - MS Windows witiiout using virtual memory might be 4 MB. However, by utilising a 10 MB swapfile (that is, virtual memory), the total free memory available after loading MS Windows is increased to nearly 14 MB. Thus, a total of 14 MB of addressable memory, rather than 4 MB, is available for loading and executing botii applications and data.

The size of the virtual memory space can be adjusted dependent upon available free hard drive disk space, as is well known in the art. Thus, for example, a 1 GB hard drive having 800 MB of free disk space available can be utilised under the MS Windows environment to provide virtual memory up to an upper limit.

In MS Windows, each application currentiy loaded in memory is displayed witiiin a window. Similarly, each instance of a data file loaded into memory for such an application is displayed witiiin a window as well. A region of memory known as die Windows Resources is also maintained for storing information such as the name, size, position, font, etc., of each and every graphical windows object active in die MS Windows environment, as is well known in the art. The structure known as die Windows Resources of MS Windows will be denoted by capitalisation, whereas the windows resources, which the Windows Resources is comprised of, will not be capitalised.

The total addressable memory space, which includes both RAM and virtual memory, and die Windows Resources are controlled by a memory manager such as KRNL386.EXE. The Windows Resources itself comprises one or more fixed portions of die total addressable memory space, which each are 64 KB in size, for storing windows resources.

Thus, each application and data file loaded into die MS Windows environment is stored in a region(s) of the total addressable memory space and d e corresponding window, which the application or data files are displayed in, has windows resources stored in die Windows Resources. That is, in order for an application or a data file to be loaded into die MS Windows environment, bom a portion of the total addressable memory and a portion of me Windows Resources must be allocated for each application or data file. When the MS Windows environment is launched, it grabs a portion of the

Windows Resources for its own configuration. Each application when launched also attempts to grab the largest possible slot available of Windows Resources to meet its allocation requirement.

In the MS Windows environment, d e primary restriction limiting die number of applications and/or data files tiiat can be opened and operated safely and in a stable environment is not typically limited by die size of the total addressable memory space, since tiiis can be enlarged dependent upon die available free hard drive disk space, but by die Windows Resources as will be described below.

Using virtual memory space, it would appear mat a large number of applications and data files could be maintained in memory in the MS Windows environment by utilising virtual memory. However, this in fact is not die case as die MS Windows environment becomes increasingly unstable as more and more applications and data files are loaded into memory. That is, it is commonly known that many G.U.I. 's, such as MS Windows, suffer from problems known as General Protection Faults (GPFs). General Protection Faults are produced by a memory access fault and are strongly influenced in tiieir likelihood of occurring by die amount of free Windows Resources available rather than by die size of the total addressable memory available.

In early versions of the MS Windows environment, the total size of the Windows Resources was limited to 64 KB. The size of the Windows Resources was dierefore one factor affecting the likelihood of a GPF occurring.

However, using current computer technology, tiiis problem of the fixed size Windows Resources is partially alleviated by die usage of hardware and software memory caching and virtual memory. Computer systems using such caching allow filled blocks or portions of die Windows Resources to be "swapped out" of memory and onto die disk space of a hard drive temporarily until the particular portion of cache memory is again required. An empty block is swapped into me Windows Resources accordingly. Nonetiieless, GPFs continue to be a primary limitation of me number of applications and data files that can be loaded into memory and have die MS Windows environment operate in a stable manner.

In fact, GPFs continue to occur widi little or no reduction in tiieir rate of occurrence and are generated by improper memory accesses into die Windows Resources in which one application attempts to access a portion of the Windows Resources allocated to anotiier application or data file, tiiereby generating a GPF which not only causes the currently executing application to fail but also makes the MS Windows environment unstable. A user must therefore restart the entire MS Windows environment after a GPF occurs.

Fig. 7 A is a diagram illustrating die allocation of Windows Resources 100 in the MS Windows environment for several applications and data files in accordance with die prior art.

A first application (APP1) is initiated in block 105 by double-clicking on the application icon, for example, and tiien opened and loaded into memory as shown in block 106. A block (or portion) 120 of the Windows Resources 100 is tiien allocated for first application.

The block 120 is located between addresses A0 and A2 of die Windows Resources 100 for storing die main window of die first application. As is well known in the art, the amount of windows resources required by an application is typically expressed as a percentage of the Windows Resources 100, and die percentage required by any particular application is heavily dependent upon die application. Thus, for example, an application for displaying computer animations may require 25 % of Windows Resources 100, whereas a word processing application may only require 15% of Windows Resources 100.

Another disadvantage of die prior art allocation of Windows Resources 100 is a phenomenon known as memory leakage in which the entire block allocated for an application is not freed when it is closed. For example, if the first application is closed, die block 120 of Windows Resources 100 between addresses A0 and A2 should be freed for other applications to use, however, a leakage memory 130 between addresses A0 and Al in Fig. 7A (the upper address of die memory leakage block 130 as indicated by a dashed line) is not freed and dierefore is not available for otiier applications to use. Thus, for example, an application allocated 25% of Windows Resources 100 when it is initially loaded only releases 23% of Windows Resources 100 when it closes, thereby reducing die total amount of Windows Resources available for other applications. Frequent opening and closing of applications leads to a considerable reduction in the amount of free Windows Resources 100 available due to die existence of these leakage memory blocks (130-134).

A first document (DOC1) is opened by die first application shown in block 107, and a portion 121 of the Windows Resources 100 between addresses A2 and A4 is allocated for the first document. While block 121 of the Windows Resources for the first document is shown contiguous with die block 120 of Windows Resources 100 for the first application, it will be apparent to a person skilled in die art tiiat the prior art allocation method for Windows Resources 100 does not require tiiis to be the case, In fact, Windows Resources 100 are allocated in a manner in which the largest available slot of the free Windows Resources 100 is allocated when die application or the data file is loaded and die remainder of die request is stored in otiier blocks if the request is not wholly satisfied. Thus, an application requiring 25% of the Windows Resources 100 can be allocated in several non-contiguous regions of the Windows Resources 100. For example, three non-contiguous portions of the Windows Resources 100 having sizes of 15 % , 6 % , and 4 % , respectively, can be allocated for the application.

When die block 121 of d e Windows Resources 100 for the first document is freed by closing die window containing the first document, tiiis block is also subject to memory leakage as shown by the memory leakage block 131 between addresses A2 and A3. A second application (APP2) is initiated as shown in the block 113, and is opened as shown in block 114. A portion 125 of die Windows Resources 100 is allocated between memory addresses A4 and A6 for the second application. Again, it will be apparent to a person skilled in the art that, while the allocation 125 of Windows Resources 100 for the second application is shown as a single contiguous block to simplify the diagram, the allocation 125 could consist of several smaller, non¬ contiguous portions of the Windows Resources 100.

The first application opened in block 106 opens a second data file (DOC2) in block 108, such as a document for a word processor, and is allocated a portion 122 the free Windows Resources 100 located between addresses A6 and A8. A first chart (CHART1) opened by die second application shown in block 115 is allocated a portion 126 of die Windows Resources 100 between addresses A8 and A10. Botii portions 122 and 126 are subject to having a leakage memory 133 and 134, respectively.

A region 127 of free Windows Resources 100 (indicated by hatching) remains available between addresses A10 and All as shown in Fig. 7A.

It will be apparent to a person skilled in die art tiiat Fig. 7A does not necessarily represent a chronological allocation of memory since a window or child window is allocated on die basis of die largest slot of Windows Resources 100 available when an application or a data file is opened. Allocation of die percentage of Windows Resources 100 requested by an application or file is allocated on basis of the largest slots available. Thus, the windows resources for a window or a child window are typically allocated throughout the Windows Resources 100 in non-contiguous blocks. That is, the requested windows resources are allocated by "hopping" tiirough the Windows Resources and grabbing the largest blocks available. This method of allocating Windows Resources 100 leads to, and results in, general protection faults occurring by its very nature. Thus, while 60% of Windows Resources 100 might be free (that is, only 40% of die Windows Resources 100 are used), die MS Windows, environment becomes increasingly unstable as more windows for applications and data files are opened and is prone to general protection faults occurring as the free Windows Resources 100 decreases.

Many general protection faults occur because an application attempts to overwrite die Windows Resources 100 allocated for anotiier application. This is illustrated in Fig. 7B in which an application APP3 is allocated a block 137 of Windows Resources 100 up to address A12 and anotiier application APP4 is allocated block 138 which starts at address A12. A general protection fault will occur in die MS Windows environment when the application APP3 attempts to increase its allocation of Windows Resources 100 by writing into me block 139 (indicated by hatching) between addresses A12 and A13, which was allocated to die application APP4 as part of its block 138. The overwriting of the windows resources of die application APP4 by the application APP3 will produce a GPF.

Thus, die method of allocating Windows Resources 100 by "hopping around" to allocate resources is a severe limitation affecting die total number of windows, and " therefore die number of applications and data files, tiiat can be opened at any given time. Many users of the MS Windows environment therefore find it necessary to close down applications to free up Windows Resources 100 in order to load otiier applications and data files. Thus, die total available addressable memory space comprising RAM and virtual memory does not limit the number of applications tiiat can be loaded, but instead it is die method of allocating Windows Resources that does tins. A user is generally alerted to a general protection fault by a dialog box appearing on me screen. The user is men required to eitiier click an OK button to exit out of die application or click an IGNORE button to continue. Regardless of die choice, many applications frequently fail at tiiis point. The general protection fault effectively kills the application which is currentiy in the foreground of die MS Windows environment, although it may not have been the application that generated die GPF. While no longer useable, the .DLL module of die application remains in memory and die allocated portion of the Windows Resources 100 is not freed. This is another problem of the prior art which is distinct from the problem of memory leakage. Subsequent execution of the application generally fails since the .DLL module of die application already exists in memory, which is detected by die application, but which cannot be communicated with.

Thus, the memory manager of the MS Windows environment has a number of longstanding disadvantages. The method of allocating Windows Resources 100 on the largest-slot-available basis and "hopping around" as each and every window is opened leads to fragmented allocation of Windows Resources 100. In this connection, child windows of an application are allocated according to tins method, leading to further fragmentation of Windows Resources and consequently to general protection faults. Thus, the prior art method of allocating Windows Resources 100 limits the number of applications and data files tiiat can be opened. Furthermore, the problem of memory leakage is exacerbated by die opening and closing of windows allocated in tiiis manner in response to users attempting to keep the MS Windows environment stable by freeing Windows Resources 100 so that other applications to be loaded.

Thus, d e most serious disadvantage affecting the number of applications and data files tiiat can be opened in windows into d e MS Windows environment is not dependent on the total addressable memory space or die size of the Windows Resources, since the Windows Resources can be swapped out using caching hardware and software, but by the prior art method of allocating Windows Resources 100 which produces memory access faults and otiier GPFs. The effect of using virtual memory in the MS Windows environment is that it effectively increases the running of applications so that they operate faster, but it does not allow more applications to be loaded.

An embodiment of the invention for allocating Windows Resources 100 to dramatically reduce die occurrences of GPFs will now be described widi reference to - Figs. 8A and 8B. A first application (APP1) is initiated in block 140 shown in Fig. 8A and is opened in block 141. A portion 155 of die Windows Resources 100 is allocated between addresses A0 and A2 for the first application.

The portion 155 of the Windows Resources 100 allocated for the first application APP1 includes a nominal portion 155A and a buffer 155B shown in Fig. 8B for storing child windows, diereby dramatically reducing die occurrences of GPFs and more fully utilising the entire Windows Resources 100, as described below. The buffer region 155B of die portion 155 of die Windows Resources 155 is indicated at me upper end of die block 155 by a dashed-dotted line. Subsequently opened data files shown in blocks 142 and 143 are provided Windows Resources 100 for their corresponding windows from the buffer 155B of the block 155 of die Windows Resources 100 allocated for the first application. This is in contrast to die separate, non-contiguous portions 121 and 122 of die Windows Resources 100 of die first and second data files of blocks 107 and 108 as shown in Fig. 7A. The likelihood of general protection faults is dramatically reduced since die child windows do not have blocks of windows resources allocated by "hopping" around. Thus, by providing a buffer 155B in the allocation of Windows Resources 100 for an application to store window objects, the occurrences of GPFs can be greatly reduced and die Windows Resources can be utilised down to 0% in contrast to the prior art in which the MS Windows environment tends to become unstable when less than 40%-60% of free Windows Resources are available. In addition, only a single leakage memory 160 occurs for the portion 155 of the Windows Resources 100 shown in Fig. 8A in comparison to the tiiree leakage memory blocks 130, 131 and 133 for the main and child windows of die first application in Fig. 7A.

A second application (APP2) is initiated as shown in block 148 in Fig. 8A and is opened in block 149. A portion 156 of die Windows Resources 100 is then allocated for the second application. A child window of the second application containing a first chart (CHART 1) shown in block 150 opened by die second application is provided an allocation of Windows Resources 100 witiiin die buffer (not shown) of die portion 156 allocated to second application. A free portion 157 (indicated by hatching) of die Windows Resources 100 remains between memory addresses A4 and A5 in Fig. 8A. It will be apparent to a person skilled in the art that, while portions 155 and 156 of die Windows Resources 100 are illustrated as memory blocks stored in contiguous memory addresses, tiiey can in fact comprise several non-contiguous regions.

In this embodiment, die windows resources requested by each application are increased by 10% generally to provide such a buffer for storing the windows resources of the child windows. Typically, child windows require half of a percent of free Windows Resources 100. However, as mentioned above, applications require varying amounts of Windows Resources 100 and tiius various size buffers (typically expressed as a percentage of die free Windows Resources) can be allocated for each main window. The buffer allocation of Windows Resources 100 for each application can be independently hard coded into die memory manager, or optionally can be independently configured using an initialisation file (.INI file) or other predetermined means for storing such data including a database record, etc., stored on a hard disk, a floppy disk, or other storage means such as a ROM, or can be a combination tiiereof. Preferably, the Windows Resources is defragmented by die memory manager when die memory manager is loaded die first time. This can be done using conventional memory defragmentation techniques.

In this manner, die occurrences of general protection faults are dramatically reduced by providing buffers in the allocation of free Windows Resources 100 for each main window. Thus, when child windows are opened for data files and subsequent launchings of applications, die windows resources for the child windows are allocated in a region that is typically contiguous with the windows resources allocated for the main window. Utilising this embodiment of the invention, it has been possible to launch 6 or 7 resource hungry applications in me MS Windows, which reduced die free Windows Resources 100 down to nearly 0%, yet the MS Windows environment operates in a stable manner. This is in marked contrast to the prior art in which the MS Windows environment becomes unstable and prone to general protection faults and otiier terminal application errors when four resource hungry applications are opened, and die free Windows Resources is reduced by 40%-60% (that is, 60% to 40% is still free, respectively), for example.

An embodiment of the invention is shown in Fig. 9 for allocating the Windows Resources 100 in accordance widi Fig. 8A and 8B. In step 180, an instruction is received to open an application. This can be done by providing an acmation signal to open die application (for example, double-clicking on the application icon using a pointing device). In step 181, the memory manager of this embodiment is loaded into memory. In step 182, die memory manager obtains die memory parameters for the application. That is, in step 182, tiie percentage of free Windows Resources required by die particular application is determined by die memory manager. This value expressed as a percentage of the free Windows Resources can be stored in a data file. In step 183, die memory manager finds or otiierwise locates the application. This is done by identifying the window handle of d e application. In decision block 184, a check is made to determine if die particular application is already loaded into the total addressable memory space. When decision block 184 returns true (yes), execution continues at step 186 in which a the child window is initiated for the application. In step 187, the memory manager assigns a portion of the buffer (e.g. a portion of buffer 155B of Fig. 8B) to the child window from me allocation of Windows Resources 100 (e.g. block 155) for the application. Execution then returns to die calling procedure. Otherwise, when decision block 184 returns false (no), execution continues at step 185 in which the parent window of die application is initiated. In step 188, die application issues a system resource request for the main window. In step 189, the memory manager intercepts the system resource request. That is, the system resource request is not delivered to die memory allocation routine of the system library of the MS Windows environment. In step 190, die memory manager provides a buffer witiiin the portion of windows resources allocated for the application.

Thus, die first time that an application is executed, a buffer is allocated in the applications allocated portion of Windows Resources 100 to store windows resources of any child windows of die application. The child windows of die application can be generated by subsequently loading die application and/or by opening one or more data files within the application. When a child window is initiated, die memory manager intercepts the system resource request and assigns a portion of die buffer to the child window. Thus, fragmentation of the Windows Resources 100 shown in Fig. 7 A is dramatically reduced.

The substeps comprising step 190 of Fig. 9 are shown in detail in Fig. 10. In step 195, the memory manager finds the request for Windows Resources 100. In step 196, the memory manager identifies the particular application. This includes identifying the percentage of free Windows Resources required by d e application. In step 197, the request for Windows Resources 100 is increased by a known factor (that is, the percentage of free Windows Resources is increased) to provide a buffer for the storage of child windows of die application. In decision block 198, a check is made to determine if tiiere is sufficient free space available in the Windows Resources to allocate die increased portion of Windows Resources 100 that includes the buffer for the application. When decision block 198 returns faults (no), execution continues at step 199 in which a message is displayed alerting die user that the application cannot be loaded. Otiierwise, when decision block 198 returns true (yes), execution continues at step 200 in which the requested Windows Resources 100 are allocated.

As previously described above, die requested windows resources for die application are allocated in die largest contiguous block(s) of free Windows Resources 100 available. Execution then returns to the main procedure illustrated in Fig. 9. The procedure for freeing windows resources is illustrated in Fig. 11. In step

210, d e closure of a window is initiated, which can be done by clicking on an icon or button. In step 211, the memory manager intercepts the request for closing me window that is sent to the MS Windows system library. In step 212, the memory manager closes the window. This includes shutting down die application and causing die .DLL module associated widi die window, if necessary, to be closed.

In decision block 213, a check is made to determine if die window to be closed is die last remaining window of die application. When decision block 213 returns false (no), execution continues at step 214 in which the portion of the buffer allocated for die storing child window is freed, however, die buffer itself remains allocated to die windows resources assigned to the application. Otherwise, when decision block returns true (yes), execution continues at step 215 in which the entire windows resources allocation for the application is freed, except for the amount of windows resources frozen in the stack (i.e. leakage memory), if any. After steps 214 or 215, execution returns to the calling procedure. Furthermore, when an application terminates due to a general protection fault, the whole block of windows resources allocated to d e application, including the child windows, is closed by die memory manager. This is in contrast to the prior art in which the .DLL module of die application stays in memory. That is, when die application closes, the embodiment of me invention sends a kill command to the .DLL module in memory, if it still exists.

The memory manager of the present invention continuously monitors resource allocation for child windows to ensure that resources are available within die buffer of the corresponding application for the child windows.

In tiiis embodiment, the methods illustrated in Figs. 8-11 are carried out by tiiree modules which are described in detail in the appended source code. In particular, die Romlinkd.DLL controls the usage and closing of child windows in an application. That is, the Romlinkd.DLL module monitors the allocation and availability of free Windows Resources that each child window has in the buffer allocated for the particular application. The Romulus.DLL module controls the handling of files between applications. Finally, the Romlink.EXE program handles all applications and operations that are directed to an application. As described above the Romlink.EXE program displays a floating button either in the top of the current window or in a tool bar. Thus, the Romlink.EXE program provides the buttons for initiating and closing applications. The Romlink.EXE program is continuously monitoring when a user clicks a button, attempts to close the application, or switches amongst applications using die task list of the MS Windows environment. When any of tiiese events occurs die Romlink.EXE program closes all child windows in die application one at a time. If the child windows are dirty, it provides a SAVE prompt to save the contents of die window. When the Romlink.EXE program ends it removes the floating Romlink button. In this embodiment, the Romulus.INI file contains the full path and file names of the applications.

The program listing contained in the appendix is die subject of copyright owned by the applicant, and may not be reproduced in any way, except for me purposes of reproduction of this specification, without the express prior written authority of die applicant.

APPENDIX

ROMULUS.DLL" ROMULUS. AK" t Microsoft Visual C++ generated build script - Do not modify" PROJ = ROMULUS" DEBUG = 0" PROGTYPE = 1" CALLER = ARGS = " DLLS = " D_RCDEFINES = -d_DEBUG" R_RCDEFINES = -dNDEBUG" ORIGIN = MSVC" ORIGIN_VER = 1.00" PROJPATH = USEMFC = 0" CC = cl" CPP = cl" CXX -= cl" CCREATEPCHFLAG = " CPPCREATEPCHFLAG - " CUSEPCHFLAG = " CPPUSEPCHFLAG = " FIRSTC = ROMULUS.C " FIRSTCPP = " RC = rc" CFLAGS_D_WDLL = /nologo /G2 /W3 /Zi /AMw /θd /D "_DEBUG" /FR /GD /Fd"ROMULUS.PDB"" CFLAGS_R_WDLL = /nologo /W3 /AMw /Ol /D "NDEBUG" /FR /GD " LFLAGS_D_WDLL = /NOLOGO /ONERROR:NOEXE /NOD /PACKC:61440 /CO /NOE /ALIGN:16 /MAP:FULL" LFLAGS_R_WDLL = /NOLOGO /ONERROR:NOEXE /NOD /PACKC:61440 /NOE /ALIGN:16 /MAP: ULL" LIBS_D_WDLL = oldnames libw commdlg shell olecli olesvr mdllcew" LIBS_R_WDLL = oldnames libw commdlg shell olecli olesvr mdllcew" RCFLAGS = /nologo" RESFLAGS = /nologo" RUNFLAGS = ~ DEFFILE = ROMULUS.DEF" OBJS_EXT = " LIBS_EXT = " Jif "$(DEBUG)" == "1"" CFLAGS = $(CFLAGS_D_WDLL)" LFLAGS = $(LFLAGS_D_WDLL)" LIBS = $(LIBS_D_WDLL)" MAPFILE = nul" RCDEFINES = $(D_RCDEFINES)" 'else" CFLAGS = $(CFLAGS_R_WDLL)" LFLAGS = $(LFLAGS_R_WDLL)" LIBS = $(LIBS_R_WDLL)" MAPFILE = nul" RCDEFINES = $(R_RCDEFINES)" lendif" !if [if exist MSVC.BND del MSVC.BND]" lendif" SBRS = ROMULUS.SBR" all: $(PROJ) .DLL $(PROJ) .BSC" ROMULUS.OBJ: ROMULUS.C $(ROMULUS_DEP)" $(CC) $(CFLAGS) $(CCREATEPCHFLAG) /c ROMULUS.C" ROMULUS.RES: ROMULUS.RC $(ROMULUS_RCDEP)" $(RC) $( CFLAGS) $(RCDEFINES) -r ROMULUS.RC" $(PROJ) .DLL: : ROMULUS.RES" $(PROJ) .DLL: : ROMULUS.OBJ $(OBJS_EXT) $(DEFFILE)" echo >NUL @«$(PROJ) .CRF" ROMULUS.OBJ +" $(OBJS_EXT)" $(PROJ).DLL" $(MAPFILE)" c:\msvc\lib\+" c:\msvc\mfc\lib\+" c:\vb\cdk\+" $(LIBS)" $(DEFFILE);" «" link $(LFLAGS) @$(PROJ) .CRF" $(RC) $(RESFLAGS) ROMULUS.RES $@" @copy $(PROJ).CRF MSVC.BND" implib /nowep $(PROJ).LIB $(PROJ).DLL" $(PROJ) .DLL: : ROMULUS. ES" if not exist MSVC.BND $(RC) $(RESFLAGS) ROMULUS.RES $@" run: $(PROJ).DLL" $(PROJ) $(RUNFLAGS)" $(PROJ).BSC: $(SBRS)" bscmake <§«" /o$@ $(SBRS)" «" ROMUlius.C" tinclude <windows.h>" tinclude <string.h>" tinclude <stdio.h>" tinclude <stdlib.h>" tinclude <commdlg.h>" tinclude <direct.h>" tinclude <dlgs.h>" tinclude <dos.h>" tinclude "resource.h"" typedef struct {" LPSTR lpszClassName;" LPSTR IpszWindow;" HWND hWnd;" } FUZZYPARAMS;" typedef struct {" LPARAM lParam;" WPARAM wParam;" UINT msg;" HWND hWnd;" } HOOKINFO;" tdefine STARTMARK_LEN 4" tdefine ENDMARK_LEN 5" tdefine MAX_FILENAME_LEN 128 + 1" tdefine BUFFER_SIZE 10000" tdefine MAX_STRING_LEN 256" tdefine MAX_ITEMS_SEL 100" /* GLOBAL VARIABLES */" HINSTANCE ghlnst;" OPENFILENAME

SUBSTTTUTE SHEET (Rule 26) ofn;" char JoinedFileName[MAX_FILENAME_LEN] ;" char

RetTempName[MAX_FILENAME_LEN];" char SaveFileName[MAX_FILENAME_LEN];" char TempString[MAX_STRING_LEN];" char TempStorage[MAX_STRING_LEN];" HHOOK hHook = NULL;" FARPROC OldHook = NULL;" HWND ghCurrentWnd, ghRomlinkWnd, ghChildWnd;"

/* FUNCTION DECLARATIONS */" int export CALLBACK LibMain(HINSTANCE, WORD,

WORD, LPSTR);" int export CALLBACK WEP(int);" LPSTR export CALLBACK

RomJoinFiles(HWND);" UINT export CALLBACK Open_Proc(HWND, UINT, WPARAM,

LPARAM);" BOOL export CALLBACK RomUnJoinFiles(HWND, LPSTR);" LPSTR export

CALLBACK RomTempName(LPSTR, LPSTR);" LPSTR export CALLBACK RomSaveAs(HWND);" void FindFiles(HWND) ;" void AddFile(HWND) ;" BOOL Joinlt(HWND) ;" void

DisplayMessage(HWND, WORD, WORD);" HWND export CALLBACK

FuzzyFindWindow(LPSTR, LPSTR);" BOOL export CALLBACK Fuzzy_Proc(HWND,

FUZZYPARAMS FAR *);" BOOL export CALLBACK RomKillFile(HWND, LPSTR);" /*

LibMain */" int export CALLBACK LibMain(HINSTANCE hinst, WORD wDataSeg, WORD cbHeapSize," LPSTR IpszCmdLine)" {" ghlnst = hinst;" if(cbHeapSize i= 0)

UnlockData(O);" return 1;" }" int export CALLBACK WEP(int nParameter)" {" return 1;" }" LPSTR export CALLBACK RomJoinFiles(HWND hWordWnd)" {" UINT i, cbString;" char chReplace;" char szFilter[256];" /* load file filters */" if ((cbString = LoadString(ghlnst, FILTERSTRINGS," szFilter, sizeof(szFilter) ) ) 1= 0) {" chReplace = szFilter[cbString - 1];" for (i = 0; szFilter[i] != '\0'» i++) {" if (szFilter[i] == chReplace)" szFilter[i] = '\°'? Λ }" }" ofn.lStructSize = sizeof(OPENFILENAME) ;" ofn.hwndOwner = hWordWnd;" ofn.hlnstance = ghlnst;" ofn.lpstrFilter = szFilter;" ofn.lpstrCustomFilter = NULL;" ofn.nMaxCustFilter = 0;" ofn.nFilterlndex = 1;" ofn.lpstrFile= NULL; ofn.nMaxFile = 0;" ofn.lpstrFileTi le = NULL;" ofn.nMaxFileTitle = 0;" ofn.lpstrlnitialDir = NULL;" ofn.lpstrTitle = "Select files to join";" ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST |" OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY | OFN_ENABLETEMPLATE |" OFN_ENABLEHOOK;" ofn.nFileOffset = NULL;" ofn.nFileExtension = NULL;" ofn.lpstrDefExt = NULL;" ofn.lCustData = NULL;" ofn.lpfnHook = θpen_Proc;" ofn.lpTemplateName =- MAKEINTRESOURCE(OPENFILE_DB) ;" if(GetOpenFileName(fiofn)

== NULL)" JoinedFileName[0] = 0;" return(JoinedFileName);" }" UINT export

CALLBACK Open_Proc(HWND hDlg, UINT msg, WPARAM wParam," LPARAM IParam)" {" int Selected[MAX_ITEMS_SEL];" int NumSel, i;" char Buffer[128];" switch(msg) {" case WM_INITDIALOG:" return TRUE;" case WM_COMMAND:" switch(wParam) {" case ID_FILELIST:" if(HIWORD(IParam) == LBN_DBLCLK) {" AddFile(hDlg);" return TRUE;" }" break;" case OPENBUTID_ADD:" AddFile(hDlg);" return TRUE;" case OPENBUTID_REMOVE:" NumSel = (int) SendDlgItemMessage(hDlg, OPENCNTID_JOINLIST," LB_GETSELITEMS, MAX_ITEMS_SEL," (LPARAM) (int FAR *) Selected);" if(NumSel == 0) DisplayMessage(hDlg, NO_FILES_TOREMOVE,* JOIN_APP_NAME);" else {" for(i = NumSel - 1; i >= 0; i—) {" SendDlgItemMessage(hDlg, OPENCNTID_JOINLIST, LBJ3ELETESTRING," Selectedfi], 0);" }" }" return TRUE;" case OPENBUTID_JOIN:" if(Joinlt(hDlg) == TRUE)" PostMessage(hDlg, WM_COMMAND, IDABORT, (LONG) TRUE);" return TRUE;- case IDOK:" GetDlgItemText(hDlg, ID_FILENAME, Buffer, sizeof(Buffer) );" for(i = 0; i < lstrlen(Buffer); i++)" if( (Buffer[i] == '*') || (Buffer[i] == '?')) return FALSE;" return TRUE;" case pshHelp:" WinHelp(hDlg, "winhelp.hlp", HELP_CONTENTS, 0);" return TRUE;" }" return FALSE; /* Allow standard processing. */" }" /* Allow standard processing. */" return FALSE;" }" void AddFile(HWND hDlg)" {" char Buffer[256] ;" char FileNm[256] ;" char Directory[256];" int Selecte [MAX_ITEMS_SEL] ;" int NumSel, i;" GetDlgItemText(hDlg, ID_DIRECTORYNAME, Directory, sizeof(Directory) ) ;" if(Directory[lstrlen(Directory) - 1] 1= '\\')~ lstrcat(Directory, "\\");" NumSel = (int) SendDlgItemMessage(hDlg, ID_FILELIST, LB_GETSELITEMS," MAX_ITEMS_SEL, (LPARAM) (int FAR*) Selected);" if(NumSel == 0) DisplayMessage(hDlg, NO_FILES_TOADD," JOIN_APP_NAME) ;" else {" for(i = 0; i

< NumSel; i++) {" SendDlgItemMessage(hDlg, ID_FILELIST, LB_GETTEXT," Selectedfi], (LPARAM) (LPSTR) FileNm);" lstrcpy(Buffer, Directory);" lstrcat(Buffer, FileNm);" AnsiLower(Buffer) ;" if(SendDlgItemMessage(hDlg, OPENCNTID_JOINLIST, LB_FINDSTRINGEXACT," (WPARAM) -1, (LPARAM) (LPSTR) Buffer) == LB_ERR)" SendDlgItemMessage(hDlg, OPENCNTID_JOINLIST, LB_ADDSTRING," 0, (LPARAM) (LPSTR) Buffer);" }" }" }" BOOL JoinIt(HWND hDlg)" {" HGLOBAL hBuff;" LPSTR Buffer;" HFILE InFile, OutFile;" int NumSel, i;" unsigned readin;" char FileName[128] ;" LPSTR TempName;" NumSel = (int) SendDlgItemMessage(hDlg, OPENCNTID_JOINLIST, LB_GETCOUNT," 0, 0);" if(NumSel

< 2) {" DisplayMessage(hDlg, AT_LEAST_TWO, JOIN_APP_NAME) ;" return FALSE;" }" if(( (hBuff = GlobalAlloc(GPTR, BUFFER_SIZE) ) == NULL) ||" ((Buffer = GlobalLoc (hBuff)) == NULL)) {" DisplayMessage(hDlg, NO_BUFFER, JOIN_APP_NAME) ;" Return FALSE;" >" /*TempPath = getenv("TEMP") ;" if(TempPath == NULL)" TempPath = _getcwd(NULL, NULL);" TempName = _tempnam(TempPath, "JOIN");" lstrcat(TempName, ".TXT");*/" TempName = RomTempName("JOIN", "TXT");" if((OutFile = _lcreat(TempName, 0)) == HFILE_ERROR) {" DisplayMessage(hDlg, NO_TEMP_JOIN, JOIN_APP_NAME) ;" GlobalUnlock(hBuff) ;" GlobalFree(hBuff) ;" return FALSE;" }" for(i = 0 ; i < NumSel; i++) {" SendDlgItemMessage(hDlg, OPENCNTID_JOINLIST, LB GETTEXT," i, (LPARAM) (LPSTR) FileName);" if((InFile = _lopen(FileName, READ)) == HFILE_ERROR) {" LoadString(ghlnst, NO_OPEN_FILE, Buffer, MAX_STRING_LEN);" lstrcat(Buffer, FileName);" /* using FileName to store the dialog title */" LoadString(ghlnst, JOIN_APP_NAME, FileName, MAX_STRING_LEN) ;" MessageBox(hDlg, Buffer, FileName, MB_OK I MB_ICONEXCLAMATION) ;" GlobalUnlock(hBuff) ;" GlobalFree(hBuff);" return FALSE;" }" _lwrite(OutFile, »[-*—, 4);" _lwrite(OutFile, FileName, lstrlen(FileName));" _lwrite(OutFile, "~*~]\n", 5);" while(TRUE) {" readin = _lread(InFile, Buffer, BUFFER_SI2E) ;" if(readin 1= 0) _l rite(OutFile, Buffer, readin);" if(readin < BUFFER_SI2E) break;" }" _lclose(InFile) ;" }" _l rite(OutFile, "[~*~END-*-]\n", 12);" _lclose(OutFile) ;" /* free up the buffer */" GlobalUnlock(hBuff);" GlobalFree(hBuff);" lstrcρy( oinedFileName,

TempName);" return TRUE;" }" BOOL export CALLBACK RomUnJoinFiles(HWND hWordWnd, LPSTR JoinedFileName)" {" HGLOBAL hBuff;" LPSTR Buffer;" HFILE InFile, OutFile;" unsigned readin, i, MarkerPos, StartPos, FileNamePos;" char DestFileName[MAX_FILENAME_LEN + ENDMARK_LEN];" char BeginMark[STARTMARK_LEN + 1] = ..[-*-...- B00L nFileName;" if(( (hBuff = GlobalAlloc(GPTR, BUFFΞR_SIZE) ) == NULL) ||" ((Buffer = GlobalLock(hBuff) ) == NULL)) {" DisplayMessage(hWordWnd, NO_BUFFER, JOIN_APP_NAME) ;" return FALSE;" }" if((InFile = _lopen(JoinedFileName, READ)) == HFILE_ERROR) {" DisplayMessage(hWordWnd, NO_OPEN_JOIN, JOIN_APP_NAME) ;" GlobalUnlock(hBuff) ;" GlobalFree(hBuff);" return FALSE;" }" MarkerPos = 0;" InFileName = FALSE;" OutFile = HFILE_ERROR;" hile(TRUE) {" readin = _lread(InFile, Buffer, BUFFER_SIZE);" for(i = 0; i < readin; i++) {" if(InFileName) {" if(Buffer[i] == 0x0a) {" DestFileName[FileNamePos - ENDMARK_LEN + 1] = 0;" if(lstrcmp(DestFileName, "END") == 0) {" OutFile = HFILE_ERROR;" readin = 0;" break;" }" else {" if((OutFile = _lcrea (DestFileName, 0)) == HFILE_ERROR) {" LoadString(ghlnst, NO_OPEN_FILE, Buffer, MAX_STRING_LEN);" lstrca (Buffer, DestFileName) ;" LoadString(ghlnst, JOIN_APP_NAME, DestFileName," MAX_STRING_LEN) ;" MessageBox(hWordWnd, Buffer, DestFileName," MB_OK | MB_ICONEXCLAMATION);" GlobalUnlock(hBuff);" GlobalFree(hBuff) ;" return FALSE;" }" StartPos = i + 1;" InFileName = FALSE;" }" }" else {" DestFileName[FileNamePos] = Buffer[i];" FileNamePos++;" if(FileNamePos >= sizeof(DestFileName) )" FileNamePos = sizeof(DestFileName) - 1;" }" }" else <" if(Buffer[i] == BeginMark[MarkerPos]) {" if( (MarkerPos == 0) ____ ((i + STARTMARK_LEN) > BUFFER_SIZE) ) {" _llseek(InFile, (i - BUFFER_SIZE), 1);" break;" }" MarkerPos++;" }" else MarkerPos = 0;" if(MarkerPos == STARTMARK LEN) {" MarkerPos = 0;" InFileName = TRUE;" FileNamePos = 0;" if((OutFile 1= HFILE_ERROR) && ((i - STARTMARK_LE ) > StartPos))" _lwrite(OutFile, &Buffer[StartPos]," i - STARTMARK_LEN - StartPos + 1);" _lclose(OutFile) ;" }" }" }" if((llnFileName) && (OutFile 1= HFILE_ERROR) S& (i > StartPos))" _lwrite(OutFile, fiBuffer[StartPos], i - StartPos);" StartPos = 0;" if(readin < BUFFER_SIZE) break;" }" _lclose(OutFile) ;" _lclose(InFile) ;"

GlobalUnlock(hBuff);" GlobalFree(hBuff) ;" return TRUE;" }" LPSTR export

CALLBACK RomSaveAs(HWND hWordWnd)" {" UINT i, cbString;" char chReplace;" char szFilter[256] ;" if ((cbString = LoadString(ghlns , FILTERSTRINGS," szFilter, sizeof(szFilter) ) ) != 0) {" chReplace = szFilter[cbString - 1];" for (i = 0; szFilter[i] != '\0'; i++) {" if (szFilter[i] == chReplace)" szFilter[i] =

'\0';" }" }" ofn.lStructSize = sizeof(OPENFILENAME);" ofn.hwndOwner = hWordWnd;" ofn.hlnstance = ghlnst;" ofn.lpstrFilter = szFilter;" ofn.IpstrCustomFilter = NULL;" ofn.nMaxCustFilter = 0;" ofn.nFilterlndex = 1;" ofn.lpstrFile= SaveFileName;" ofn.nMaxFile = sizeof(SaveFileName) ;" ofn.lpstrFileTi le = NULL;" ofn.nMaxFileTitle = 0;" ofn.lpstrlnitialDir =

NULL;" ofn.lpstrTitle = "Save As";" ofn.Flags = OFN_SHOWHELP |

OFN_PATHMUSTEXIST | OFN_HIDEREADONLY |" OFN_OVERWRITEPROMPT;" ofn.nFileOffset = NULL;" ofn.nFileExtension = NULL;" ofn.lpstrDefExt = NULL;" ofn.lCustData = NULL;" ofn.lpfnHook = NULL;" ofn.lpTemplateName = NULL;" if(GetSaveFileName(Sofn) == NULL)" SaveFileName[0] = 0;" return(SaveFileName);" }" void DisplayMessage(HWND hWnd, WORD wID, WORD tID)"

{" char Message[MAX_STRING_LEN];" char Title[MAX_STRING_LEN] ;"

LoadString(ghlnst, wID, Message, MAX_STRING_LEN);" LoadString(ghlnst, tID,

Title, MAX_STRING_LEN);" MessageBox(hWnd, Message, Title, MB_OK |

MB_ICONEXCLAMATION) ;" }" HWND export CALLBACK FuzzyFindWindow(LPSTR lpszClassName, LPSTR IpszWindow)" {" FUZZYPARAMS FuzzyParams;" FuzzyParams.lpszClassName = (lpszClassNamefO] == 0)? NULL : lpszClassName;" FuzzyParams.IpszWindow = (IpszWindow[0] == 0)? NULL : IpszWindow;" FuzzyParams.hWnd -= NULL;" EnumWindows(Fuzzy_Proc, (DWORD) ((FUZZYPARAMS FAR

*)£FuzzyParams) );" return FuzzyParams.hWnd;" }" BOOL export CALLBACK

Fuzzy_Proc(HWND hWnd, FUZZYPARAMS FAR *lpFuzzyParams)" {" char Buffer[MAX_STRING LEN];" if(lpFuzzyParams->lpszClassName 1= NULL) {" GetClassName(hWnd, Buffer, MAX_STRING_LEN);" if(lstrcmp(Buffer, lpFuzzyParams- >lpszClassName) 1= 0)" return (1);" }" if(lpFuzzyParams->lpszWindow 1= NULL) {" GetWindowText(hWnd, Buffer, sizeof(Buffer) );" if(_fstrstr(Buffer, lpFuzzyParams->lpszWindow) == NULL) " return (1);" }" lpFuzzyParams->hWnd = hWnd; " return(O); " }" /*" BOOL export CALLBACK RomKillFile(HWND hWnd,

LPSTR FileName)" {" Istrcpy(TempStorage, FileName);" while(IsWindow(hWnd))" Yield();" if(remove(TempStorage) == 0)" return TRUE;" return FALSE;" }*/" LPSTR export CALLBACK RomTempName(LPSTR Prefix, LPSTR Ext)" {" char

*TempPath, TempPrefix[6] ;" int Num, i, NumPos;" TempPath = getenv("TEMP") ;" if(TempPath =•= NULL)" TempPath = getcwd(NULL, NULL);" lstrcpyn(TerapPrefix, Prefix, 5) ;" Istrcpy(TempString, TempPath) ;" if(TempString[lstrlen(TempString) - 1] 1= '\\')" lstrca (TempString, "\\");" lstrcat(TempString, TempPrefix);" NumPos = lstrlen(TempString) ;" lstrcat(TempString, "0000.");" lstrcat(TempString, Ext);" for(Num = 0; Num < 10000; Num++) {" wsprintf(TempStorage, "%04d", Num);" for(i = 0; i < 4; i++)" TempString[NumPos + i] = TempStorage[i];~ if(_dos_findfirst(TempString, _A_ARCH | _A_HIDDEN | _A_NORMAL I" _A_RDONLY | _A_SUBDIR j _A_SYSTEM | _A_VOLID, NULL) != 0) break;" }" if(Num == 10000) {" TempString[0] = NULL;" }" return TempString;" }" ROMULUS.DEF" LIBRARY Romulus" DESCRIPTION 'Romulus DLL - extra functionality for Romulus'" EXETYPE WINDOWS" STUB 'WINSTUB.EXE'" CODE PRELOAD MOVEABLE DISCARDABLE" DATA PRELOAD MOVEABLE SINGLE" HEAPSIZE 4096" EXPORTS" WEP @1 RESIDENTNAME" RomJoinFiles @2" Open_Proc @3" RomUnJoinFiles @4" RomTempName @5" RomSaveAs @6" FuzzyFindWindow <7" Fuzzy_Proc @8" RomKillFile @9" JOINRC.H" tdefine OPENFILE_DB 10" tdefine FILTERSTRINGS 100" tdefine JOIN_APP_NAME 110" tdefine CONV_APP_NAME 111" tdefine JOIN TITLE 112" tdefine SAVEAS_TITLE 113" tdefine NO_FILES_TOREMOVE 120" tdefine NO_FILES_TOADD 121" tdefine AT_LEAST_TWO 122" tdefine NO_BUFFER 123" tdefine NO_TEMP_JOIN 124" tdefine NO_OPEN_JOIN 125" tdefine NO_OPEN_FILE 126" tdefine TEMP_ENV_VAR 130" tdefine TEMP_FILE_MASK 131" tdefine START_MARK 132" tdefine END_MARK 133" tdefine COMPLETED_MARK 134" tdefine ID_FILΞLIST 1120" tdefine ID_DIRECTORYNAME 1088" tdefine ID_FILENAME 1152" tdefine OPENCNTID_JOINLIST 100" tdefine OPENBUTID_ADD 101" tdefine OPENBUTID_REMOVE 102" tdefine OPENBUTID_JOIN 103" ROMLINKD.DLL" ROMLINKD.MAK" t Microsoft Visual C++ generated build script - Do not modify" PROJ = ROMLINKD" DEBUG = 0" PROGTYPE = 1" CALLER = " ARGS = " DLLS = " D_RCDEFINES ~~ -d_DEBUG" R_RCDEFINES = -dNDEBUG" ORIGIN = MSVC" ORIGIN_VER = 1.00" PROJPATH = USEMFC = 0" CC = cl" CPP = cl" CXX = Cl" CCREATEPCHFLAG = " CPPCREATEPCHFLAG = " CUSEPCHFLAG = " CPPUSEPCHFLAG = " FIRSTC = ROMLINKD.C " FIRSTCPP = " RC = re" CFLAGS_D_WDLL = /nologo /G2 /W3 /Zi /ALw /Od /D "_DEBUG" /FR /GD /Fd"ROMLINKD.PDB"" CFLAGS_R_WDLL = /nologo /W3 /AMw /Ol /D "NDEBUG" /FR /GD " LFLAGS_D_WDLL = /NOLOGO /ONERRO :NOEXE /NOD /PACKC:61440 /CO /NOE /ALIGN:16 /MAP:FULL" LFLAGS_R_WDLL = /NOLOGO /ONERROR:NOEXE /NOD /PACKC:61440 /NOE /ALIGN:16 /MAP:FULL" LIBS_D_WDLL = oldnames libw commdlg shell olecli olesvr ldllcew" LIBS R WDLL = oldnames libw commdlg shell olecli olesvr mdllcew" RCFLAGS = /nologo" RESFLAGS = /nologo" RUNFLAGS = " DEFFILE = ROMLINKD.DEF" OBJS_EXT = " LIBS_EXT = " lif "S(DEBUG)" __ nl «~ CFLAGS = $(CFLAGS_D_WDLL)" LFLAGS = $(LFLAGS_D_WDLL)" LIBS = $(LIBS_D_WDLL)" MAPFILE = nul" RCDEFINES = $(D_RCDEFINES)" lelse" CFLAGS = $(CFLAGS_R_WDLL)" LFLAGS = $(LFLAGS_R_WDLL)" LIBS = $(LIBS_R_WDLL)" MAPFILE = nul" RCDEFINES = $(R_RCDEFINES)" lendif" lif [if exist MSVC.BND del MSVC.BND]" lendif" SBRS = ROMLINKD.SBR" ROMLINKD_DEP = " all: $(PROJ).DLL $(PROJ).BSC" ROMLINKD.OBJ: ROMLINKD.C $(ROMLINKD_DEP)" $(CC) $(CFLAGS) $(CCREATEPCHFLAG) /c ROMLINKD.C" $(PROJ) .DLL: : ROMLINKD.OBJ $(OBJS_EXT) $(DEFFILE)" echo >NUL @«$(PROJ).CRF" ROMLINKD.OBJ +" $(OBJS_EXT)" $(PROJ).DLL" $(MAPFILE)" c:\msvc\lib\+" c:\msvc\mfc\lib\+" $(LIBS)" $(DEFFILE);" «" link $(LFLAGS) @$(PROJ).CRF" $(RC) $(RESFLAGS) $@" implib /nowep S(PROJ).LIB $(PROJ).DLL" run: $(PROJ).DLL" $(PROJ) $(RUNFLAGS)" $(PROJ).BSC: $(SBRS)" bscmake @«" /o$@ $(SBRS)" «" ROMLINKD.C" tinclude <windows.h>" tinclude <string.h>" tinclude <stdio.h>" tinclude <stdlib.h>" tinclude <commdlg.h>" tinclude <direct.h>" tinclude <dlgs.h>" tinclude <dos.h>" /* GLOBAL VARIABLES */" HINSTANCE ghlnst;" HHOOK hHook = NULL;" HWND ghCurrentWnd, ghRomlinkWnd, ghChildWnd;" HWND ghFTParent;" HHOOK hHookCBT = NULL;" /* FUNCTION

DECLARATIONS */" int export CALLBACK LibMain(HINSTANCE, WORD, WORD, LPSTR);" int export CALLBACK WEP(int);" BOOL export CALLBACK RomSet(HWND, HWND);"

BOOL export CALLBACK RomExtraSet(HWND);" void export CALLBACK

RomFree(void) ;" void export CALLBACK ItFunc(int, WORD, DWORD);" void export CALLBACK RomSetChildWindow(HWND) ;" int export CALLBACK UsFunc(int,

WORD, DWORD);" /* LibMain */" int export CALLBACK LibMain(HINSTANCE hinst,

WORD wDataSeg, WORD cbHeapSize," LPSTR IpszCmdLine)" {" ghlnst = hinst;" if(cbHeapSize 1= 0) UnlockData(O) ;" return 1;" }" int export CALLBACK

WEP(int nParameter)" {" return 1;" }" BOOL export CALLBACK RomSet(HWND hWnd,

HWND hRWnd)" {" ghCurrentWnd = hWnd;" ghRomlinkWnd = hRWnd;" ghChildWnd = NULL;" hHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)(FARPROC)ItFunc," ghlnst, NULL/*GetWindowTask(hWnd)*/);" if(hHook) return TRUE;" return FALSE;"

}" BOOL export CALLBACK RomExtraSet(HWND hWnd)" {" ghFTParent = hWnd;" if((hHookCBT = SetWindowsHookEx(WH_CBT, " (HOOKPROC) (FARPROC)UsFunσ, ghlnst,

NULL)) == NULL)" return FALSE;" return TRUE;" }" void export CALLBACK

RomFree()" {" if(hHook) UnhookWindowsHookEx(hHook);" if(hHookCBT)

UnhookWindowsHookEx(hHookCBT);" hHook = NULL;" }" void export CALLBACK

ItFunc(int nCode, WORD wParam, DWORD IParam)" {" /* structure used for CallWpnProc */" struct tempStruct {" LONG IParam;" WORD wParam;" WORD message;" HWND hwnd;" } FAR * lptsParamStruct;" if( nCode >= 0 ) {" lptsParamStruct = (struct tempStruct FAR *) IParam;" if(lptsParamStruct- >message == WM_NCDESTROY) {" if(lptsParamStruct->hwnd == ghCurrentWnd)" PostMessage(ghRomlinkWnd, WM_USER + 50, 0, 0);" else if(lptsParamStruct->hwnd == ghChildWnd) {" PostMessage(ghRomlinkWnd, WM_USER + 51, 0, 0);" ghChildWnd = NULL;" >" ~" }" CallNextHookEx(hHook, nCode, wParam, IParam);" return;" }" void export CALLBACK RomSetChildWindow(HWND hWnd)" {" ghChildWnd = hWnd;" }" int export CALLBACK UsFunc(int nCode, WORD wParam, DWORD IParam)" {"

LPCBT_CREATEWND CreateWndParam;" HWND hWndApp;" if(nCode •== HCBT_CREATEWND) {" CreateWndParam = (LPCBT_CREATEWND) IParam;" if(CreateWndParam->lpcs- >hwndParent •== ghFTParent) {" hWndApp = GetParent(ghFTParent);" PostMessage(ghFTParent, WM_MDIMAXIMIZE, wParam, 0);" PostMessage(hWndApp, WM_COMMAND, 0x13b, 0);" PostMessage(hWndApp, WM_COMMAND, 0x133, 0);" } " }" return (int) CallNextHookE (hHookCBT, nCode, wParam, IParam);" }" ROMLINKD.DEF" LIBRARY romlinkd" DESCRIPTION 'Romulus DLL. Copyright (c) 1993 - 1994 Ni-Tech Pty Limited. Patent Pending.'" EXETYPE WINDOWS" STUB 'WINSTUB.EXE'" CODE PRELOAD MOVEABLE DISCARDABLE" DATA PRELOAD MOVEABLE SINGLE" HEAPSIZE 4096" EXPORTS" WEP @1 RESIDENTNAME" RomSet @2" RomExtraSet @3" RomFree @4" ItFunc @5" RomSetChildWindow @6" UsFunc @7" " ROMLINK.EXE" ROMLINK.MAK" t Microsoft Visual C++ generated build script - Do not modify" PROJ = ROMLINK" DEBUG = 1" PROGTYPE = 0" CALLER = " ARGS = " DLLS = " D_RCDEFINES = -d_DEBUG" R_RCDEFINES = -dNDEBUG" ORIGIN = MSVC" ORIGIN_VER = 1.00" PROJPATH = C:\A_FILES\ROMLINK\" USEMFC = 1" CC = cl" CPP = cl" CXX = cl" CCREATEPCHFLAG = " CPPCREATEPCHFLAG = " CUSEPCHFLAG = " CPPUSEPCHFLAG = " FIRSTC = ROMLINK.C " FIRSTCPP = " RC = rc" CFLAGS_D_WEXE = /nologo /W3 /FR /G2 /Zi /D_DEBUG /θd /AM /GA /Fd"ROMLINK.PDB"" CFLAGS_R_WEXE = /nologo /W3 /FR /θl /DNDEBUG /AM /GA" LFLAGS_D_WEXE = /NOLOGO /ONERROR:NOEXE /NOD /PACKC:61440 /CO /ALIGN:16 /STACK:10240" LFLAGS_R_WEXE = /NOLOGO /ONERROR:NOEXE /NOD /PACKC:61440 /ALIGN:16 /STACK:10240" LIBS_D_WEXE = mafxcwd oldnames libw commdlg shell olecli olesvr mlibcew" LIBS_R_WEXE = mafxcw oldnames libw commdlg shell olecli olesvr mlibcew" R FLAGS = /nologo" RESFLAGS = /nologo" RUNFLAGS = " DEFFILE = ROMLINK.DEF" OBJS_EXT = " LIBS_EXT = ROMLINKD.LIB " lif "$(DEBUG)" == "1"" CFLAGS = $(CFLAGS_D_WEXE)" LFLAGS = $(LFLAGS_D_WEXE)" LIBS = $(LIBS_D_WEXE)" MAPFILE = nul" RCDEFINES = $(D_RCDEFINES)" lelse" CFLAGS = $(CFLAGS_R_WEXE)" LFLAGS = $(LFLAGS_R_WEXE)" LIBS = $(LIBS_R_WEXE)" MAPFILE = nul" RCDEFINES = $(R_RCDEFINES)" lendif" lif [if exist MSVC.BND del MSVC.BND]" lendif" SBRS = ROMLINK.SBR" ROMLINK_DEP = c:\a_files\romlink\romlink.h \" ROMLINKD_DEP = " all: $(PROJ).EXE S(PROJ).BSC" ROMLINK.OBJ: ROMLINK.C $(ROMLINK_DEP)" $(CC) $(CFLAGS) $(CCREATEPCHFLAG) /c ROMLINK.C" $(PROJ) .EXE:: ROMLINK.OBJ $(OBJS_EXT) $(DEFFILE)" echo >NUL @«$(PROJ).CRF" ROMLINK.OBJ +" $(OBJS_EXT)" $(PROJ) .EXE" $(MAPFILE)" σ:\msvc\lib\+" c:\msvc\mfc\lib\+" ROMLINKD.LIB+" $(LIBS)" $(DEFFILE);" «" link $(LFLAGS) @$(PROJ) .CRF" $(RC) $(RESFLAGS) $@" run: $(PROJ).EXE" S(PROJ) $(RUNFLAGS)" $(PROJ).BSC: $(SBRS)" bscmake @«" /o$@ $(SBRS)" «" ROMLINK.C" tinclude "Romlink.h"" HANDLE ghlnst;" HWND ghWnd, ButWnd, ghAppWnd;" char AppName[200] ;" char MainClass[MAX_CLASS_LEN] ;" char DeskClass[MAX_CLASS_LEN];" char ChildClass[MAX_CLASS_LEN] ;" BOOL SpecialClose;" BOOL HookSet = FALSE, FTHookSet = FALSE;" int gAppID;" BOOL gLeaveOpen;" int PASCAL WinMain(HANDLE hlnstance, HANDLE hPrevInstance," LPSTR IpszCmdLine, int nCmdShow)" {" WNDCLASS Class;" MSG msg;" RECT re; " if(hPrevInstance) {" GetInstanceData(hPrevInstance, (BYTE *) SButWnd, sizeof(HWND) ) ;" SetFocus(ButWnd);" return FALSE;" }" ghlnst = hlnstance;" LoadString(ghlnst, APP_NAME, AppName, sizeof(AppName) ) ;" Class.style = NULL;" Class.lpfnWndProc = (WNDPROC) Main_Proc;" Class.cbClsExtra = 0;" Class.cbWndExtra = 0;" Class.hlnstance = ghlnst;" Class.hlcon = NULL;" Class.hCursor = LoadCursor( UL , IDC_ARROW);" Class.hbrBackground = NULL;" Class.IpszMenuName = NULL;" Class.lpszClassName = "RomlinklO";" if( IRegisterClass(SClass) ) return FALSE;" GetWindowRect(GetDesktopWindow( ) , &rc);" ghWnd = CreateWindow(" "RomlinklO"," "Romulus"," WS_POPUP," re.right - ROM_WIN_WIDTH, re.bottom - ROM_WIN_HEIGHT," ROM_WIN_WIDTH, ROM_WIN_HEIGHT," NULL," NULL," ghlnst," NULL); " if(ghWnd == NULL)" return FALSE; " if(lpszCmdLine[0] == NULL)" return FALSE;" if(HookSetup(IpszCmdLine) == FALSE)" return FALSE;" ButWnd = CreateWindow("BUTTON", "Romulus"," BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP,~ 0, -1, ROM_BUT_WIDTH, ROM_BUT_HEIGHT, ghWnd," ROM_BUTTON_ID, ghlnst, NULL);" SetWindowPos(ghWnd, HWND_TOPMOST, 532, 0, 70, 20, /*SWP_NOMOVE|*/ SWP_NOSIZE /*SWP_DRAWFRAME)*/) ;" ShowWindow(ghWnd, SW_SHOWNOACTIVATE);" UpdateWindow(ghWnd) ;" while(GetMessage(&msg, NULL, 0, 0)) {" TranslateMessa e(&msg);" DispatchMessage(Smsg) ;" }" return msg.wParam;" }" BOOL HookSetup(LPSTR AppWindowName)" {" char Buffer[200] = { NULL };" HWND DeskWnd;" FARPROC Proc;" ghAppWnd = NULL;" if(lstrcmp(AppWindowName, WORD_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(WORD_MAIN_CLASS, AppWindowName);" gAppID = WORD_ID;" Istrcpy(MainClass, WORD_MAIN_CLASS) ;" Istrcpy(DeskClass, WORD_DESK_CLASS) ;" Istrcpy(ChildClass, WORD_CHILD_CLASS) ;" GetPrivateProfileString(LEAVEAPPSOPEN_SECTION, WP_INI_ENTRY, ""," Buffer, sizeof(Buffer) , INI_NAME);" SpecialClose = FALSE;" } " else if(lstrcmp(AppWindowName, WORDPERFECT_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(WORDPERFECT_MAIN_CLASS, AppWindowName);" gAppID = WORDPERFECT_ID;" Istrcpy(MainClass, WORDPERFECT_MAIN_CLASS) ;" Istrcpy(DeskClass, WORDPERFECT_DESK_CLASS) ;" Istrcpy(ChildClass, WOHDPERFECT_CHILD_CLASS) ;" GetPrivateProfileString(LEAVEAPPSOPEN_SECTION, WP_INI_ENTRY, ""," Buffer, sizeof(Buffer) , INI_NAME);" SpecialClose = FALSE;" }" else if(lstrcmp(AppWindowName, AMIPRO_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(AMIPRO_MAIN_CLASS, AppWindowName);" gAppID = AMIPRO_ID;" Istrcpy(MainClass, AMIPRO_MAIN_CLASS) ;" Istrcpy(DeskClass, AMIPRO_DESK_CLASS) ;" Istrcpy(ChildClass, AMIPRO_CHILD_CLASS) ;" GetPrivateProfileString(LEAVEAPPSOPEN_SECTION, WP_INI_ENTRY, ""," Buffer, sizeof(Buffer) , INI_NAME);" SpecialClose = FALSE;" }" else if(lstrcmp(AppWindowName, EXCEL_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(EXCEL_MAIN_CLASS, AppWindowName);" gAppID = EXCEL_ID;" Istrcpy(MainClass, EXCEL_MAIN_CLASS) ;" Istrcpy(DeskClass, EXCEL_DΞSK_CLASS) ;" Istrcpy(ChildClass, EXCEL_CHILD_CLASS) ;"

GetPrivateProfileString(LEAVEAPPSOPEN_SECTION, SPREAD_INI_ENTRY, "", " Buffer, sizeof(Buffer) , INI_NAME);" SpecialClose = FALSE;" } " else if(lstrcmp(AppWindowName, LOTUS123_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(LOTUS123_MAIN_CLASS, AppWindowName);" gAppID = LOTUS123_ID;" Istrcpy(MainClass, LOTUS123_MAIN_CLASS) ;" Istrcpy(DeskClass, LOTUS123_DESK_CLASS) ;" Istrcpy(ChildClass, LOTUS123_CHILD_CLASS) ;" GetPrivateProfileString(LEAVEAPPSOPEN_SECTION, SPREAD_INI_ENTRY, ""," Buffer, sizeof(Buffer) , INI_NAME);" SpecialClose = FALSE;" } " else if(lstrcmp(AppWindowName, QPRO_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(QPRO_MAIN_CLASS, AppWindowName);" gAppID = QPR0_ID;" Istrcpy(MainClass, QPRO_MAIN_CLASS) ;" lstrcpy(DeskClass, QPRO_DESK_CLASS) ;" Istrcpy(ChildClass, QPRO_CHILD_CLASS);"

GetPrivateProfileString(LEAVEAPPSOPEN_SECTION, SPREAD_INI_ENTRY, ""," Buffer, sizeof(Buffer), INI_NAME);" SpecialClose = FALSE;" }" else if(lstrcmp(AppWindowName, ABC_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(ABC_MAIN_CLASS, AppWindowName);" gAppID = ABC_ID;" Istrcpy(MainClass, ABC_MAIN_CLASS) ;" Istrcpy(DeskClass, ABC_DESK_CLASS) ;" Istrcpy(ChildClass, ABC_CHILD_CLASS);"

GetPrivateProfileString(LEAVEAPPSOPEN_SECTION, CHART_INI_ENTRY, ""," Buffer, sizeof(Buffer), INI_NAME);" SpecialClose = TRUE;" }" else if(lstrcmp(AppWindowName, PSTYLER_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(PSTYLER_MAIN_CLASS, AppWindowName);" gAppID = PSTYLER_ID;" Istrcpy(MainClass, PSTYLER_MAIN_CLASS) ;" Istrcpy(DeskClass, PSTYLER_DESK_CLASS) ;" Istrcpy(ChildClass, PSTYLER_CHILD_CLASS) ;" GetPrivateProfileString(LEAVEAPPSOPEN_SECTION, VIEWER_INI_ENTRY, ""," Buffer, sizeof(Buffer), INI_NAME);" SpecialClose = TRUE;" }" else if(lstrcmp(AppWindowName, FTCOLOR_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(FTCOLOR_MAIN_CLASS, AppWindowName);" gAppID = FTCOLOR_ID;" Istrcpy(MainClass, FTCOLOR_MAIN_CLASS) ;" Istrcpy(DeskClass, FTCOLOR_DESK_CLASS) ;" Istrcpy(ChildClass, FTCOLOR_CHILD_CLASS) ;" GetPrivateProfileString(LEAVEAPPSOPEN_SECTION, VIEWER_INI_ENTRY, ""," Buffer, sizeof(Buffer) , INI_NAME);" SpecialClose = TRUE;" /* start special hook for FT Color */" DeskWnd = NULL;" Proc = MakeProcInstance(Desk_Proc, ghlnst);" EnumChildWindows(ghAppWnd, Proc, (DWORD) ((HWND FAR *)&DeskWnd) ) ;" FreeProcInstance(Proc) ;" if((DeskWnd =-= NULL) || ( (FTHookSet = RomExtraSe (DeskWnd) ) == FALSE))" return FALSE; " }" else if(lstrcmp(AppWindowName, WORDSCAN_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(WORDSCAN_MAIN_CLASS, AppWindowName);" gAppID = WORDSCAN_ID;" Istrcpy(MainClass, WORDSCAN_MAIN_CLASS) ;" /*Istrcpy(DeskClass, WORDSCAN_DESK_CLASS) ;*/" Istrcpy(ChildClass, WORDSCAN_CHILD_CLASS) ;" GetPrivateProfileString(LEAVEAPPSOPEN_SECTION, VIEWER_INI_ENTRY, *"*," Buffer, sizeof(Buffer) , INI_NAME);" SpecialClose = FALSE;" }" else if(lstrcmp(AppWindowName, OPENIMAGE_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(OPENIMAGE_MAIN_CLASS, AppWindowName);" gAppID = OPENIMAGE_ID;" Istrcpy(MainClass, OPENIMAGE_MAIN_CLASS) ;" Istrcpy(DeskClass, OPENIMAGE_DESK_CLASS) ;" Istrcpy(ChildClass, OPENIMAGE_CHILD_CLASS) ;" GetPrivateProfileString(LEAVEAPPSOPEN_SECTION, VIEWER_INI_ENTRY, ""," Buffer, sizeof(Buffer) , INI_NAME);" SpecialClose = FALSE; " }" else if(lstrcmp(AppWindowName, ISYS_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(ISYS_MAIN_CLASS, AppWindowName);" gAppID = ISYS_ID;" Istrcpy(MainClass, ISYS_MAIN_CLASS) ;"

GetPrivateProfileString(LEAVEAPPSOPEN_SECTION, TR_INI_ENTRY, ""," Buffer, sizeof(Buffer), It*fI_NAME) ;" }" else if(lstrcm (AppWindowName, ISYSUTILS_WINDOW_NAME) == 0) {" ghAppWnd =

FuzzyFindWindow(ISYSUTILS_MAIN_CLASS, AppWindowName);" gAppID = ISYSUTILS_ID;' /* this app is always closed */" }~ else if(lstrcmp(AppWindowName, AVERY_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(NULL, AppWindowName);" gAppID = AVERY_ID;" /* this app is always closed */" }" else if(lstrcmp(AppWindowName, ROMCALC_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(ROMCALC_MAIN_CLASS, AppWindowName);" gAppID = ROMCALC_ID;" /* this app is always closed */" }" else if(lstrcmp(AppWindowName, LOTUSORG_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(LOTUSORG_MAIN_CLASS, AppWindowName);" gAppID = LOTUSORG_ID;" /* this app is always closed */" }" else if(lstrcmp(AppWindowName, DOSBACKUP_WINDOW_NAME) == 0) {" ghAppWnd = FuzzyFindWindow(DOSBACKUP_MAIN_CLASS, AppWindowName);" gAppID = DOSBACKϋP_ID;" /* this app is always closed */" }" gLeaveOpen = (lstrcm (AnsiLower(Buffer), TROE_STRING) == 0)? TRUE : FALSE;" if(ghAppWnd == NULL)" return FALSE;" HookSet = RomSet(ghAppWnd, ghWnd);" if(HookSet == 0)" return FALSE; " return TRUE;" }" long FAR PASCAL _export Main_Proc(HWND hWnd, unsigned Message," WORD wParam, LONG IParam) " {" switch (Message)" {" case WM_USER + 50:" case WM_DESTROY:" if((HookSet) || (FTHookSet) )" RomFree();" hWnd = FindWindow("OMain", NULL);" if(hWnd) " if( HsZoomed(hWnd) ) ShowWindow(hWnd, SW_SHOWMAXIMIZED);" else SetActiveWindow(hWnd) ;" else {" MessageBox(ghWnd, "The Romulus MS Access Database has been closed."," AppName, MB_OK);" }" PostQuitMessage(O) ;" break;" case WM_USER + 51:" CloseAndSwitch();" break;" case WM_COMMAND:" switch(wParam) {" case ROM_BUTTON_ID:" CloseAndSwitch();" break;" }" break;" default:" return DefWindowProc(hWnd, Message, wParam, IParam);" }" return(O);" }" void CloseAndSwitch()" {"

SetActiveWindow(ghAppWnd) ;" if((gAppID == AVERY_ID) || (gAppID == ROMCALC_ID) I I " (gAppID == ISYSUTILS_ID) | | (gAppID == LOTUSORG_ID) | | (gAppID == DOSBACKUP_ID) ) " {" if(IsWindow(ghAppWnd) ) " PostMessage(ghAppWnd, WM_CLOSE, 0, 0);" else " /* close romlink */" DestroyWindow(ghWnd) ;" }" else if (gAppID == ISYS_ID) {" if(gLeaveOpen) {" EnumWindows(ISYS_Proc, NULL);" }" else {" PostMessage(ghAppWnd, WM_CLOSE, 0, 0);" }" DestroyWindow(ghWnd) ;" } " if(CloseChildWindows() == FALSE) {" if(gLeaveOpen == FALSE)"

PostMessage(ghAppWnd, WM_CLOSE, 0, 0);" DestroyWindow(ghWnd) ;" }" } " }" BOOL CloseChildWindows()" {" HWND MainWnd, DeskWnd;" BOOL Result = FALSE;" FARPROC Proc;" MainWnd = FindWindow(MainClass, NULL);" if(MainWnd) {" DeskWnd = NULL;" Proc = MakeProcInstance(Desk_Proc, ghlnst);" EnumChildWindows(MainWnd, Proc, (DWORD) ((HWND FAR *)SDeskWnd) );" FreeProcInstance(Proc);" if(DeskWnd) {" Proc = MakeProdnstance(Child_Proc, ghlnst);" EnumChildWindows(MainWnd, Proc, (DWORD) (BOOL FAR *)&Result);" FreeProcInstance(Proc) ;" }" }" return(Result);" }" BOOL CALLBACK _export Desk_Proc(HWND hWndChild, HWND FAR *DeskWnd)" {" char szClass[MAX_CLASS_LEN] = { NULL };" GetClassName(hWndChild, szClass, MAX_CLASS_LEN) ;." if(lstrcmp(szClass, DeskClass) == 0) {" *DeskWnd = hWndChild;" return(O);" }" return(1); " }" BOOL CALLBACK _export Child_Proc(HWND hWndChild, BOOL FAR *Result)" {" char szClass[MAX_CLASS_LEN] = { NULL };" GetClassName( WndChild, szClass, MAX_CLASS_LEN) ;" if(lstrcmp(szClass, ChildClass) == 0) {" RomSetChildWindow(hWndChild) ;" if(SpecialClose)" PostMessage(hWndChild, WM_SYSCOMMAND, SC_CLOSE, 0);" else" PostMessage(hWndChild, WM_CLOSE, 0, 0);" *Result = TRUE;" return(O);" } " return(l); " }" BOOL CALLBACK _export ISYS_Proc(HWND hWnd, LPARAM IParam)" {" char Buffer[MAX_STRING_LEN] ;" GetClassName(hWnd, Buffer, MAX_STRING_LEN) ;" if(lstrcmp(Buffer, ISYS_MAIN_CLASS) == 0) {" GetWindowText(hWnd, Buffer, lstrlen(ISYS_WINDOW_NAME) + 1);" if( (lstrcmp(Buffer, ISYS_WINDOW_NAME) 1= 0) &&" (IsWindowVisible(hWnd)) )" SendMessage(hWnd, WM_CLOSE, 0, 0);" }" return(l); " }" HWND FuzzyFindWindow(LPSTR lpszClassName, LPSTR IpszWindow)" {" FUZZYPARAMS FuzzyParams;" FARPROC Proc;" FuzzyParams.lpszClassName = lpszClassName;" FuzzyParams.IpszWindow = IpszWindow;" FuzzyParams.hWnd = NULL;" Proc = MakeProcInstance(Fuzzy_Proc, ghlnst);" EnumWindows(Proc, (DWORD) ((FUZZYPARAMS FAR *)SFuzzyParams) ) ;" FreeProcInstance(Proc) ;" return FuzzyParams.hWnd;" }" BOOL CALLBACK _export Fuzzy_Proc(HWND hWnd, FUZZYPARAMS FAR *lpFuzzyParams)" {" char Buffer[MAX_STRING_LEN] ;" if(lpFuzzyParams- >lpszClassName 1= NULL) {" GetClassName(hWnd, Buffer, MAX_STRING_LEN) ;" if(lstrcmp(Buffer, lpFuzzyParams->lρszClassName) 1= 0)" return (1);" }" if(lpFuzzyParams->lpszWindow 1= NULL) {" GetWindowText(hWnd, Buffer, sizeof(Buffer) ) ;" if(_fstrstr(Buffer, lpFuzzyParams->lpszWindow) == NULL)" return (1);" }" lpFuzzyParams->hWnd = hWnd; " return(O); " }" ROMLINK.H" tinclude <windows.h>" tinclude <string.h>" tinclude "romlrc.h"" typedef struct {" LPSTR lpszClassName;" LPSTR IpszWindow;" HWND hWnd;" } FUZZYPARAMS;" typedef unsigned int near* NPUINT;" typedef unsigned int far* LPUINT;" typedef unsigned long near* NPULONG;" typedef unsigned long far* LPULONG;" typedef long NEAR* NPLONG;" tdefine ROM_BUTTON_ID 17" tdefine ROM_WIN_WIDTH 70" tdefine ROM_WIN_HEIGHT 20" tdefine ROM_BUT_WIDTH 70" tdefine ROM_BUT_HEIGHT 20" tdefine MAX_CLASS_LEN 30" tdefine MAX_STRING_LEN 256" tdefine INI_NAME "romulus.ini" " tdefine LEAVEAPPSOPEN_SECTION "LeaveApplicationsOpen"" tdefine WP_INI_ENTRY "WordProcessor"" tdefine VIEWER_INI_ENTRY "Viewer"" tdefine TR_INI_ENTRY "TextRetrieval"" tdefine SPREAD_INI_ENTRY * "Spreadsheet"" tdefine CHART_INI_ENTRY "Chart"" tdefine TRUE_STRING "true"" /*tdefine WORD_NAME "Winword"*/" tdefine WORD_WINDOW_NAME "Microsoft Word"" tdefine WORD_MAIN_CLASS "OpusApp"" tdefine WORD_DESK_CLASS "OpusDesk"" tdefine WORD_CHILD_CLASS "OpusMwd"" tdefine WORD_ID 1" Λtdefine ABC_NAME "abc 2"*/" tdefine ABC_WINDOW_NAME "ABC Flowcharter"" tdefine ABC_MAIN_CLASS "Ren & Stimpy"" tdefine ABC_DESK_CLASS "MDIClient"" tdefine ABC_CHILD_CLASS "Ren Hoek"" tdefine ABC_ID 2 " Λtdefine ABC NAME "abc 3"*/" tdefine ABC_WINDOW_NAME "Micrografx ABC Flowcharter"" tdefine ABC_MAIN_CLASS "ABCFrame"" tdefine ABC_DESK_CLASS "MDIClient"" tdefine ABC_CHILD_CLASS "ABCChart"" tdefine ABC_ID 2" /*tdefine EXCEL_4_NAME "excel"*/" tdefine EXCEL_WINDOW_NAME "Microsoft Excel"" tdefine EXCEL_MAIN_CLASS "XLMAIN"" tdefine EXCEL_DESK_CLASS "XLDESK"" tdefine EXCEL_CHILD_CLASS "EXCELS"" tdefine EXCEL_ID 3" Λtdefine EXCEL_5_NAME "excel"*/" tdefine EXCEL_WINDOW_NAME "Microsoft Excel"" tdefine EXCEL_MAIN_CLASS "XLMAIN"" tdefine EXCEL_DESK_CLASS "XLDESK"" tdefine EXCEL_CHILD_CLASS "EXCEL9"" tdefine EXCEL_ID 3" Λtdefine PSTYLER_NAME "pstyler"*/" tdefine PSTYLER_WINDOW_NAME "PhotoStyler Special Edition"" tdefine PSTYLER_MAIN_CLASS "Frame"" tdefine PSTYLER_DESK_CLASS "MDIClient"" tdefine PSTYLER_CHILD_CLASS "MDIChild"" tdefine PSTYLER_ID 4" Λtdefine FTCOLOR_NAME 1.0 "ftcolor"*/" tdefine FTCOLOR_WINDOW_NAME "FotoTouch Color"" tdefine FTCOLOR_MAIN_CLASS "appwindow"" tdefine FTCOLOR_DESK_CLASS "MDIClient"" tdefine FTCOLOR_CHILD_CLASS "mdichildwindow"" tdefine FTCOLOR_ID 5 " Λtdefine FTCOLOR_NAME 1.0a "ftcolor"*/" tdefine FTCOLOR_WINDOW_NAME "FotoTouch Color"" tdefine FTCOLOR_MAIN_CLASS "FTColor"" tdefine FTCOLOR_DESK_CLASS "MDIClient"" tdefine FTCOLOR_CHILD_CLASS "mdichildwindow"" tdefine FTCOLOR_ID 5 " Λtdefine ISYS_NAME "iq"*/" tdefine ISYS_WINDOW_NAME "ISYS Query"" tdefine ISYS_MAIN_CLASS "ThunderForm"" tdefine ISYS_ID 6" Λtdefine ISYSUTILS_NAME "idbw"*/" tdefine ISYSUTILS_WINDOW_NAME "ISYS Utilities"" tdefine ISYSUTILS_MAIN_CLASS "ThunderForm"" tdefine ISYSUTILS_ID 7" /*tdefine AVERY_NAME "lpwin"*/" tdefine AVERY_WINDOW_NAME "LabelPro"" tdefine AVERY_ID 8" /*tdefine ROMCALC_NAME "romcalc"*/" tdefine ROMCALC_MAIN_CLASS "RomCalclO"" tdefine ROMCALC_WINDOW_NAME "Romulus Resource Calculator"" tdefine ROMCALC_ID 9" Λtdefine ORGANISER_NAME "organize"*/" tdefine LOTUSORG_MAIN_CLASS "TZ_PORG"" tdefine LOTUSORG_WINDOW_NAME "Lotus Organizer"" tdefine LOTUSORG_ID 10" /*tdefine WORDSCAN_NAME "wordscan 2"*/" tdefine WORDSCAN_WINDOW_NAME "WordScan Plus - JOB01"" tdefine WORDSCAN_MAIN_CLASS "Calera.WordScan" '" tdefine WORDSCAN_CHILD_CLASS "Calera.WordScan.Viewer"" tdefine WORDSCAN_ID 11 " /*tdefine WORDPERFECT_NAME "wordperfect 6.0"*/" tdefine WORDPERFECT_WINDOW_NAME "WordPerfect"" tdefine WORDPERFECT_MAIN_CLASS "WordPerfect"" tdefine WORDPERFECT_DESK_CLASS "MDIClient"" tdefine WORDPERFECT_CHILD_CLASS "WPDocFrame"" tdefine WORDPERFECT ED 12" /*#define AMIPRO_NAME "Ami Pro 3.0"*/" tdefine AMIPRO_WINDOW_NAME "Ami Pro"" tdefine AMIPRO_MAIN_CLASS "AmiProWndA"" tdefine AMIPRO DESK CLASS "MDIClient"" tdefine AMIPRO CHILD CLASS "MDICHILD"" tdefine AMIPRO_ID 13" Λtdefine lotusl23_NAME "lotus 123 4.01"*/" tdefine LOTUS123_WINDOW_NAME "Lotus 1-2-3 Release 4"" tdefine LOTUS123_MAIN_CLASS "123WParent"" tdefine LOTUS123_DESK_CLASS "123WMDIClient"" tdefine LOTUS123_CHILD_CLASS "123WSheet"" tdefine LOTUS123_ID 14" /*tdefine QPRO_NAME "Quattro pro 5.0"*/" tdefine QPRO_WINDOW_NAME "Quattro Pro for Windows"" tdefine QPRO_MAIN_CLASS "QPWBaseWdw"" tdefine QPRO_DESK_CLASS "MDIClient"" tdefine QPRO_CHILD_CLASS "QPWChildWdw"" tdefine QPRO_ID 15" Λtdefine DOSBACKUP_NAME "Backup v6"*/" tdefine DOSBACKUP_WINDOW_NAME "Microsoft Backup -"" tdefine DOSBACKUP_MAIN_CLASS "MWBACKUP"" tdefine DOSBACKUP_ID 16" Λtdefine OPENIMAGE_NAME "OPEN/image"*/" tdefine OPENIMAGE_WINDOW_NAME "OPEN/image Cabinet"" tdefine OPENIMAGE_MAIN_CLASS "WIISDisplay" " tdefine OPENIMAGE_DESK_CLASS "ImageWindow"" tdefine OPENIMAGΞ_CHILD_CLASS "ImageWindow"" tdefine OPENIMAGE_ID 17" /* FUNCTION DECLARATIONS */" int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);" BOOL HookSetup(LPSTR) ;" long export FAR PASCAL Main_Proc(HWND, unsigned, WORD, LONG); " void

CloseAndSwitch(void) ;" BOOL CloseAppFile(void) ;" BOOL

CloseChildWindows(void) ;" BOOL export CALLBACK Desk_Proc(HWND, HWND FAR *);"

BOOL export CALLBACK Child_Proc(HWND, BOOL FAR *);" BOOL export CALLBACK

ISYS_Proc(HWND, LPARAM);" HWND FuzzyFindWindow(LPSTR, LPSTR);" BOOL export

CALLBACK Fuzzy_Proc(HWND, FUZZYPARAMS FAR *);" long export FAR PASCAL

SubClass_Proc(HWND, unsigned, WORD, LONG);" extern HANDLE ghlnst;" extern HWND ghWnd, ButWnd;" extern char AppName[200] ;" BOOL export CALLBACK RomSet(HWND,

HWND);" BOOL export CALLBACK RomExtraSet(HWND) ;" void export CALLBACK

RomFree(void);" void export CALLBACK RomSetChildWindow(HWND) ;" EXTERNAL.H" int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);" long FAR PASCAL _export Main_Proc(HWND, unsigned, WORD, LONG); " void CloseAndSwitch(void) ;" BOOL CloseAppFile(void);" BOOL CloseChildWindows(void) ;" BOOL CALLBACK _export Desk_Proc(HWND, HWND FAR *);" BOOL CALLBACK _export Child_Proc(HWND, BOOL FAR *);" BOOL CALLBACK _export ISYS_Proc(HWND, LPARAM);" HWND FuzzyFindWindow(LPSTR, LPSTR);" BOOL CALLBACK _export Fuzzy_Proc(HWND, FUZZYPARAMS FAR *);" extern HANDLE ghlnst;" extern HWND ghWnd, ButWnd;" extern char AppName[200] ;" ROMLINK.DEF" NAME RomLink" DESCRIPTION 'Romulus RomLink. Copyright (c) 1993 - 1995 Ni-Tech Pty Limited. Patent Pending.'" EXETYPE WINDOWS" STUB 'WINSTUB.EXE'" CODE MOVEABLE PRELOAD" DATA MOVEABLE MULTIPLE PRELOAD" HEAPSIZE 8192" INITIATING FILES" '*" '* Romulus - Global Module" '* Copyright 1993 Romulus Software" '*" Option Compare Database 'Use database order for string comparisons" Option Explicit" ' * Global document and image paths" Global Rom_DocumentPath As String" Global Rom_ImagePath As String" Global ROM_ISYSTEXTPATH As String" Global Rom_SpreadSheetPath As String" Global Rom_ChartPath As String" ' * this name will be used in all dialog boxes *" Global Const ROMϋLUS_APP_NAME - "Romulus"" ' * some ini names *" Global Const ROM_INI_NAME = "romulus.ini"" Global Const ROM_APP_INI_SECTI0N = "Applications"" Global Const ROMLINK_INI_ENTRY = "Romulus ink"" Global Const ROM_WP_INI_ENTRY = "WordProcessor"" Global Const ROM_WP2_INI_ENTRY = "WordProcessor2"" Global Const ROM_WP3_INI_ENTRY = "WordProcessor3"" Global Const ROM_VIE ER_INI_ENTRY = "Viewer"" Global Const ROM_VIEWER2_INI_ENTRY = "Viewer2"" Global Const ROM_VIEWER3_INI_ENTRY = "Viewer3"" Global Const ROM_TR_INI_ENTRY = "TextRetrieval"" Global Const ROM_TRUTILS_INI_ENTRY = "TextRetrievalϋtilities"" Global Const ROM_SPREAD_INI_ENTRY = "Spreadsheet"" Global Const ROM_SPREAD2_INI_ENTRY = "SpreadSheet2"" Global Const ROM_SPREAD3_INI_ENTRY = "SpreadSheet3"" Global Const ROM_CHART_INI_ENTRY = "Chart"" Global Const ROM_LABEL_INI_ENTRY = "Labels"" Global Const ROMCALC_INI_ENTRY = "RomulusCalc"" Global Const ROM_VOICE_INI_ENTRY = "VoiceControl"" Global Const ROM_READBAC _INI_E TRY = "AudioReadBack"" Global Const ROM_JOIN_INI_ENTRY = "JoinTemplate"" Global const ROM_CONVERT_INI_ENTRY = "ConvertTemplate"" Global Const ROM_TEXTSAVE_INI_ENTRY = "TextSaveTemplate"" Global Const ROM_ORG_INI_ENTRY = "Organizer"" Global Const

ROM_BACKUP_INI_ENTRY = "Backup"" Global Const ROM_MAX_STRINGLEN = 256" ' * application main window classes *" Global Const ROM_WORD_WINDOWCLASS = "OpusApp"" Global Const ROM_PSTYLER_WINDOWCLASS -= "Frame"" Global Const ROM_WORDPERFECT_WINDOWCLASS = "WordPerfect"" Global Const

ROM_AMIPRO_WINDOWCLASS = "AmiProWndA"" Global Const ROM_FTCOLOR_WINDOWCLASS = "FTColor"" Global Const ROM_EXCEL_WINDOWCLASS = "XLMAIN"" Global Const ROM_LOTUS123_WINDOWCLASS = "123WParent"" Global Const ROM_QPRO_WIND0WCLASS = "QPWBaseWdw"" Global Const ROM_ABC_WINDOWCLASS = "ABCFrame"" Global Const ROM_ISYS_WINDOWCLASS = "ThunderForm"" Global Const ROM_AVERY_WIND0WCLASS = """ Global Const ROMCALC_WINDOW_CLASS = "RomCalclO"" Global Const ROM_ISYSϋTILS_WINDOWCLASS = "ThunderForm"" Global Const ROM_ORG_WINDOWCLASS = -TZ_PORG"" Global Const ROM_WORDSCAN_WINDOWCLASS = "Calera. ordScan"" Global Const ROM_OPENIMAGE_WINDOWCLASS = "WIISDisplay"" Global Const ROM_BACKUP_WINDOWCLASS = "MWBACKUP"" Global Const ROM_WORD_WINDOWNAME = "Microsoft Word"" Global Const ROM_PSTYLER_WINDOWNAME = "PhotoStyler Special Edition"" Global Const ROM_WPRDPERFECT_WINDOWNAME = "WordPerfect"" Global Const ROM_AMIPRO_WINDOWNAME = "Ami Pro"" Global Const ROM_FTCOLOR_WINDOWNAME = "FotoTouch Color"" Global Const ROM EXCEL WINDOWNAME = "Microsoft Excel"" Global Const RGM_LOTUS123_WINDOWNAME = "Lotus 1-2-3 Release 4"" Global Const ROM_QPRO_WINDOWNAME = "Quattro Pro for Windows"* Global Const ROM_ABC_WINDOWNAME = "Micrografx ABC Flowcharter"" Global Const ROM_ISYS_WINDOWNAME = "ISYS Query"" Global Const ROM_AVERY_WINDOWNAME = "LabelPro"" Global Const ROMCALC_WINDOW_NAME = "Romulus Resource Calculator"" Global Const ROM_ISYSUTILS_WINDOWNAME = "ISYS Utilities'"* Global Const ROM_ORG_WINDOWNAME = "Lotus Organizer"" Global Const ROM_WORDSCAN_WINDOWNAME = "WordScan Plus - JOB01"" Global Const ROM_OPENIMAGE_WINDOWNAME = "OPEN/image Cabinet"" Global Const ROM_BACKUP_WINDOWNAME = "Microsoft Backup -"" Global Const ROM_ISYS_AINDEX = "ISYS.IXA"" ' * Windows API ShowWindow() defines *" Global Const ROM_SW_SHOWMAXIMIZED = 3" ' * message box defines * msgbox" Global Const ROM_MB_OK = 0" Global Const ROM_MB_YESNO = 4" Global Const ROM_MB_ICONEXCLAMATION = 48" Global Const ROM_MB_IC0NINFORMATION = 64" Global Const ROM_MB_ICONQOESTION = 32" Global Const MB_DEFBUTTON2 = 256, IDYES = 6, IDNO = 7" ' * ini entries to hold the file name to store numbers in" Global Const ROM_NUMFILE_INI_SECTION = "Numbers"" Global Const ROM_NUMFILE_INI_ENTRY = "TextFile"" Global Const ROM_BARFILE_INI_ENTRY = "BarFile"" Global Const ROM_PLAINFILE_INI_ENTRY = "PlainFile"" ' * ini entry in avery labels of the last loaded label form" Global Const ROM_AVERY_LAYOUT_SECTION = "Layout Editor"" Global Const ROM_AVERY_LASTFILE_ENTRY = "LastSavedLayout"" Global Const ROM_AVERY_INI_NAME = "lpwin.ini"" ' * Windows API WM_CLOSE" Global Const ROM_WM_CLOSE = 16" 'Global Const ROM_WM_SYSCOMMAND = 274" 'Global Const ROM_SC_CLOSE = -4000" ' * DLL function declarations" 'Declare Function Rom_FindWindow Lib "user" Alias "FindWindow" (ByVal ClassName As String, ByVal Title As Long) As Integer" Declare Function Rom_ShowWindow Lib "user" Aliaβ "ShowWindow" (ByVal WindowHand As Integer, ByVal ShowType As Integer) As Integer" Declare Function Rom_SetActiveWindow Lib "user" Alias "SetActiveWindow" (ByVal WindowHand As Integer) As Integer" 'Declare Function Rom_GetActiveWindow Lib "user" Alias "GetActiveWindow" ( ) As Integer" Declare Function Rom_GetModuleHandle Lib "kernel" Alias "GetModuleHandle" (ByVal lpAppName As String)" As Integer" Declare Function Rom_IsZoomed Lib "user" Alias "IsZooraed" (ByVal WindowHand As Integer) As Integer" Declare Sub Rom_Yield Lib "kernel" Alias "Yield" ( )" Declare Function Rom_GetPrivateProfileString Lib "Kernel" Alias "GetPrivateProfileString" (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Integer, ByVal lpFileName As String) As Integer" Declare Function Rom_PostMessage Lib "user" Alias "PostMessage" (ByVal hWnd As Integer, ByVal msg As Integer, ByVal wParam As Integer, IParam As Long) As Integer". 'Declare Function Rom_SendMessage Lib "user" Alias "SendMesBage" (ByVal hWnd As Integer, ByVal msg As Integer, ByVal wParam As Integer, IParam As Long) As Integer" Declare Function Rom_WritePrivateProfileString Lib "Kernel" Alias "WritePrivateProfileString" (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal SentString As String, ByVal lpFileName As String) As Integer" Declare Function Rom_FuzzyFindWindow Lib romulus.dll" Alias "FuzzyFindWindow" (ByVal lpszClassName As String, ByVal IpszWindow As String) As Integer" Function RomJReturnlniString (Section As String, Entry As String) As String" On Error GoTo NoString_Err" Dim lpIniRetString As String" Dim ret As Integer" 'Create a buffer for the returned ini string" lpIniRetString -

Space$(ROM_MAX_STRINGLEN)" ret = Rom_GetPrivateProfileString(Section, Entry, "", lpIniRetString, ROM_MAX_STRINGLEN, ROM_INI_NAME)" 'Truncate the fixed- length string to the left of the Null terminator" lpIniRetString = Left$(lpIniRetString, (InStr(lpIniRetString, Chr$(0)) - 1))"

Rom_ReturnIniString = lpIniRetString" RIS_Exit:" Exit Function" NoString_Err:" Rom_ReturnIniString = """ Resume RIS_Exit" End Function" '*" '* Romulus - OpenFileRoutines Module" '* Copyright 1993 Romulus Software" '*" Option Compare Database 'Use database order for string comparisons" Option Explicit" Function Rom_OpenABC ()" On Error GoTo NoOpenABC_Err" Dim ret As Integer" ret = Rom_OpenApp(ROM_CHART_INI_ENTRY, ROM_ABC_WINDOWCLASS, ROM_.ABC_WINDOWNAME)" ABC_Exit:" Exit Function" NoOpenABC_Err:" MsgBox "Cannot open ABC Flowcharter. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROM0LUS_APP_NAME" Resume ABC_Exit" End Function" Function Rom_OpenABCFile (Filename As String)" On Error GoTo ABCFile_Err" Dim ret As Integer" ' * see if the filename is valid" Filename *= Rom_ChartPath & Filename" If Dir$(Filename) = "" Then" ret = MsgBox("There is no associated flowchart. Would you like to create a flowchart?", ROM_MB_YESNO + MB_DEFBUTTON2 + ROM_MB_ICONQUESTION, ROMULUS_APP_NAME)" If ret = 7 Then GoTo ABCFile_Exit" DoCmd RunMacro "Indicator"" ret = Rom_OpenApp(ROM_CHART_INI_ENTRY, ROM_ABC_WINDOWCLASS, ROM_ABC_WINDOWNAME)" SendKeys "%fs" & Filename & "{ENTER}"" Exit Function" End If" ' * open ABC or make it the active window" ret =

Rom_OpenApp(ROM_CHART_INI_ENTRY, ROM_ABC_WINDOWCLASS, ROM_ABC_WINDOWNAME)" ' * open the filename" If ret = True Then" SendKeys "%fo" & Filename & "{ENTER}"" End If" ABCFile_Exit:" Exit Function" ABCFile_Err:" MsgBox "Cannot open ABC flowchart. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMDLUS_APP_NAME" Resume ABCFile_Exit" End Function" Function Rom_OpenAmiPro ()" On Error GoTo NoOpenAmiPro_Err" Dim ret As Integer" ret = Rom_OpenApp(ROM_WP3_INI_ENTRY, ROM_AMIPRO_ INDOWCLASS, ROM_AMIPRO_WINDO NAME)" AmiPro_Exit:" Exit Function" NoOpenAmiPro_Err:" MsgBox "Cannot open Ami Pro. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATI0N, ROMULUS_APP_NAME" Resume AmiPro_Exit" End Function" Function Rom_OρenAmiProFile (Filename As String)" On Error GoTo APFile_Err" Dim ret As Integer" ' * see if the filename is valid" Filename = Rom_DocumentPath & Filename" If Dir$(Filename) = "" Then" ret = MsgBox("There is no associated document. Would you like to create a document?", ROM_MB_YESNO + MB_DEFBUTTON2 + ROM_MB_ICONINFORMATION, ROMULUS_APP_NAME)" If ret = 7 Then GoTo APFile_Exit" DoCmd RunMacro "Indicator"" ret = Rom_OpenApp(ROM_WP3_INI_ENTRY, ROM_AMIPRO_WINDOWCLASS, ROM_AMIPRO_WINDOWNAME)" SendKeys "%fn" & "{ENTER}"" SendKeys "%fa" & Filename & "{ENTER}"" Exit Function" End If" ' * open Word or make it the active window" ret = Rora_OpenApp(ROM_WP3_INI_ENTRY, ROM_AMIPRO_WINDOWCLASS, ROM_AMIPRO_WINDOWNAME)" ' * open the filename" If ret = True Then" SendKeys "%fo" & Filename & "{ENTER}"" End If" APFile_Exit:" Exit Function" APFile_Err:" MsgBox "Cannot open Ami Pro document. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME" Resume APFile_Exit" End Function" Function Rom_OpenApp (AppIniEntry As String, AppClass As String, AppWindow As String) As Integer" On Error GoTo Open_Err ' Set up error handler." Rom_OpenApp = True" Dim WindowHandle As Integer" Dim ret As Integer" Dim lpIniRetString As String" Dim AppName As string" Dim RomName As String" Dim AppModuleName As String" Dim ParamPos As Integer" ' * find the filename of the app from the ini_file" AppName = Rom_ReturnIniString(ROM_APP_INI_SECTION, AppIniEntry)" If (AppName = "") Then" MsgBox "There is no filename listed for " & AppWindow & "in the ROMULUS.INI file.", ROM_MB_OK +

ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME" Rom DpenApp = False" GoTo Open_Exit" End If" ' * load the app if it is not already loaded" ' * to find the module ignore any command line parameters in the name" ParamPos = InStr(AppName, " ")" If (ParamPos) Then" AppModuleName = Left$(AppName, ParamPos - 1)" Else" AppModuleName = AppName" End If" If (Rom_GetModuleHandle(AppModuleName) = 0) Then 'App is riot loaded" ret = Shell(AppName, 1) 'start App" If ret = 0 Then GoTo Oρen_Err" ' * wait until the main window of the app has been displayed" ' ???? if it does not start up correctly we get stuck here forever" While (Rom_FuzzyFindWindow(AppClass, AppWindow) = 0)" Rom_Yield" Wend" End If" ' * make sure we can find the window handle before we open Rom link" WindowHandle = Rom_FuzzyFindWindow(AppClass, AppWindow)" If WindowHandle = 0 Then" MsgBox "Cannot Access " & AppWindow, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME" Rom_OpenApp = False" GoTo Open_Exit" End If" ' * Start the Romulus floating top button window" ' * If it doesn't start we still let them go ahead" RomName = Rom_ReturnIniString(ROM_APP_INI_SECTION, ROMLINK_INI_ENTRY)" RomName = RomName & " " & AppWindow" If (RomName = "") Then" MsgBox "There is no filename listed for the Romulus link program in the ROMULUS.INI file.", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME" Else" ret = Shell(RomName, 8) 'start Romulus floating top window." End If" ' * maximize the window and make it the active window" If

(Rom_IsZoomed(WindowHandle) = 0) Then" ret = Rom_ShowWindow(WindowHandle, ROM_SW_SHOWMAXIMIZED)" Else" ret = Rom_SetActiveWindow(WindowHandle)" End If" Open_Exit:" Exit Function" Open_Err:" MsgBox "Cannot open " & AppWindow & ". Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME" Rom_OpenApp = False" Resume Open_Exit" End Function" Function Rom_OpenExcel ( )" On Error GoTo NoOpenExcel_Err" Dim ret As Integer" ret = Rom_OpenApp(ROM_SPREAD_INI_ENTRY, ROM_EXCEL_WINDOWCLASS,

ROM_EXCEL_WINDOWNAME)" Excel_Exit:" Exit Function" NoOpenExcel_Err:" MsgBox "Cannot open Excel. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME" Resume Excel_Exit" End Function" Function Rom_OpenExcelFile (Filename As String)" On Error GoTo ExcelFile_Err" Dim ret As Integer" ' * see if the filename is valid" Filename = Rom_SpreadSheetPath & Filename" If Dir$(Filename) = "" Then" ret = MsgBox("There is no associated spreadsheet. Would you like to create a spreadsheet?", ROM_MB_YESNO + MB_DEFBUTTON2 + ROM_MB_ICONQUESTION, ROMULUS_APP_NAME)" If ret = 7 Then GoTo ExcelFile_Exit" DoCmd RunMacro "Indicator"" ret = Rom_OpenApp(ROM_SPREAD_INI_ENTRY, ROM_EXCEL_WINDOWCLASS, ROM_EXCEL_WINDOWNAME)" SendKeys "%fa" & Filename & "{ENTER}"" Exit Function" End If" ' * open Excel or make it the active window" ret = Rom_OpenApp(ROM_SPREAD_INI_ENTRY, ROM_EXCEL_WINDOWCLASS, ROM_EXCEL_WINDOWNAME)" ' * open the filename" If ret = True Then" SendKeys "%fo" & Filename & "{ENTER}"" End If" ExcelFile_Exit:" Exit Function" ExcelFile_Err:" MsgBox "Cannot open Excel spreadsheet. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME" Resume ExcelFile_Exit" End Function" Function Rom_OpenFTColor ( )" On Error GoTo NoOpenFTC_Err" Dim ret As Integer" ret = Rom_OpenApp(ROM_VIEWER3_INI_ENTRY,

ROM_FTCOLOR_WINDOWCLASS, ROM_FTCOLOR_WINDOWNAME)" FTC_Exit:" Exit Function" NoOpenFTC_Err:" MsgBox "Cannot open FotoTouch Color. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME" Resume FTC_Exit" End Function" Function Rom_OpenFTColorFile (Filename As String)" On Error GoTo FTCFile_Err" Dim ret As Integer" ' * see if the filename is valid" Filename = Rom_ImagePath & Filename" If Dir$(Filename) = "" Then" ret - MsgBox("There is no associated image. Would you like to create an image?", ROM_MB_YESNO + MB_DEFBDTTON2 + ROM_MB_ICONQDESTION, ROMULUS_APP_NAME)* If ret = 7 Then GOTO FTCFile_Exit* DoCmd RunMacro "Indicator"* ret = Rom_OpenApp(ROM_VIEWER3_INI_ENTRY, ROM_FTCOLOR_WINDOWCLASS, ROM_FTCOLOR_WINDOWNAME)* SendKeys "%fnil" S "{ENTER}"* SendKeys "%fa" & Filename & "{ENTER}"* SendKeys "%fq"* Exit Function* End If* ' * open FT Color or make it the active window* ret = Rom_OpenApp(ROM_VIEWER3_INI_ENTRY, ROM_FTCOLOR_WINDOWCLASS, ROM_FTCOLOR_WINDOWNAME)* ' * open the filename* If ret = True Then* SendKeys "%fo" & Filename & "{ENTER}"* End If* FTCFile_Exit:* Exit Function* FTCFile_Err:* MsgBox "Cannot open FotoTouch image. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMϋLUS_APP_NAME* Resume FTCFile_Exit* End Function* Function Rom_OpenISYS (AppIniEntry As String, AppClass As String, AppWindow As String) As Integer* On Error GoTo ISYS_Err ' Set up error handler.* Rom_OpenISYS = True* Dim WindowHandle As Integer* Dim ret As Integer* Dim lpIniRetString As String* Dim AppName As String* Dijn RomName As String* Dim AppModuleName As String* Dim ParamPos As Integer* ' * find the filename of the app from the ini_file* AppName =

Rom_ReturnIniString(ROM_APP_INI_SECTION, AppIniEntry)* If (AppName = "") Then* MsgBox "There is no filename listed for " & AppWindow fi "in the ROMOLUS.INI file.", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Rom_OpenISYS = False* GoTo ISYS_Exit* End If* ' * load the app if it is not already loaded* ' * to find the module ignore any command line parameters in the name* ParamPos = InStr(AppName, " ")* If (ParamPos) Then* AppModuleName = Left$(AppName, ParamPos - 1)* Else* AppModuleName = AppName* End If* If (Rom_GetModuleHandle(AppModuleName) = 0) Then 'App is not loaded* ret = Shell(AppName, 1) 'start App* If ret = 0 Then GoTo ISYS_Err* ' * wait until the main window of the app has been displayed* ' ???? if it does not start up correctly we get stuck here forever* While (Rom_FuzzyFindWindow(AppClass, AppWindow) = 0)* Rom_Yield* Wend* SendKeys "%fc%ff" ε "{DEL}" S "{ENTER}"* SendKeys "%fd" & "{TAB}" & "{TAB}"* SendKeys "+{END}"* SendKeys "{DEL}" & Rom_ISYSTextPath £? "-{ENTER}"* End If* ' * make βure we can find the window handle before we open Rom link* WindowHandle = Rom_FuzzyFindWindow(AppClass, AppWindow)* If WindowHandle = 0 Then* MsgBox "Cannot Access " & AppWindow, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Rora_OpenISYS = False* GoTo ISYS_Exit* End If* ' * Start the Romulus floating top button window* ' * If it doesn't start we still let them go ahead* RomName =

Rom_ReturnIniString(ROM_APP_INI_SECTION, ROMLINK_INI_ENTRY)* RomName = RomName & " " & AppWindow* If (RomName = ••••) Then* MsgBox "There is no filename listed for the Romulus link program in the ROMULUS.INI file.", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMDLUS_APP_NAME* Else* ret = Shell(RomName, 8) 'start Romulus floating top window.* End If* ' * maximize the window and make it the active window* If (Rom_IsZoomed(WindowHandle) = 0) Then* ret = Rom_ShowWindow(WindowHandle, ROM_SW_SHOWMAXIMIZED)* Else* ret = Rom_SetActiveWindow(WindowHandle)* End If* ISYS_Exit:* Exit Function* ISYS_Err:* MsgBox "Cannot open " & AppWindow & ". Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Rom_OpenISYS ~~ False* Resume ISYS_Exit* End Function* Function Rom_OpenISYSAllFiles ()* On Error GoTo NoOpenISYSAll_Err* Dim ret As Integer* Dim DBFileName As String* Dim DBName As String* Dim ISYSFirst As Integer* Dim Paath As String* ' * see if there is an ISYS database in the Rom_ISYSTextPath* DBFileName = Rom_ISYSTextPath & ROM_ISYS_AINDEX* If Dir$(DBFileName) = "" Then* MsgBox "There is no Full Text database.", ROM_MB_OK + ROM_MB_ICONINFORMATION, ROMULUS_APP_NAME* GoTo ISYSAll_Exit* End If* ' * open ISYS or make it the active window* ret = Rom_OpenISYS(ROM_TR_INI_ENTRY, ROM_ISYS_WINDOWCLASS, Rom_ISYS_Windowname)* ' * clear the last search and make sure there is no filter set* DBName = Rom_ISYSTextPath* If ret Then* SendKeys "%fc%ff" & "{DEL}" & "{ENTER}"* 'SendKeys "%fd" & "{TAB}" ε -{TAB}"* 'SendKeys "+{END}"* 'SendKeys "{DEL}" & DBName S "{TAB}" & "{ENTER}"* End If* ' SendKeys "%fd" & "{TAB}" & "{TAB}"* ' SendKeys "+{END}"* ' If Paath - DbName Then* ' SendKeys "{TAB}" & "{ENTER}"* ' SendKeys "%fc%ff" & "{DEL}" & "{ENTER}"* ' GoTo ISYSAll_Exit* ' End If* '* ' If Paath <> DbName Then* ' SendKeys "+{END}"* ' SendKeys "{DEL}" & DbName & "{TAB}" & "{ENTER}"* ' SendKeys "%fc%ff" & "{DEL}" & "{ENTER}"* ' End If* ISYSAll_Exit:* Exit Function* NoOpenISYSAll_Err:* MsgBox "Cannot open ISYS. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATIO , ROMULUS_APP_NAME* Resume ISYSAll_Exit* End Function* Function Rom OpenlSYSFile (Filename As String)* On Error GoTo ISYSFile_Err* Dim ret As Integer* Dim FullFileName As String* Dim DBFileName As String* Dim DBName As String* ' * see if there is an ISYS database in the Rom_ISYSTextPath* DBFileName = Rom_ISYSTextPath & ROM_ISYS_AINDEX* ff "Dir$(DBFileName) = "" Then* MsgBox "There is no Full Text database.", ROM_MB_OK + ROM_MB_ICONINFORMATION, ROMULUS_APP_NAME* GoTo ISYSFile_Exit* End If* ' * see if the filename is valid* FullFileName = Rom_ISYSTextPath & Filename* If Dir$(FullFileName) = "" Then* MsgBox "There is no associated Full Text file", ROM_MB_OK + ROM_MB_ICONINFORMATION, ROMULUS_APP_NAME* GoTo ISYSFile_Exit* End If* ' * open ISYS or make it the active window* ret = Rom_OpenISYS(ROM_TR_INI_ENTRY, ROM_ISYS_WINDOWCLASS, Rom_ISYS_Windowname)* ' * clear last search and open filename* DBName = Rom_ISYSTextPath* If ret Then* SendKeys "%fc%ff" & Filename & "{ENTER}"* SendKeys "%q"* End If* ISYSFile_Exi :* Exit Function* ISYSFile_Err:* MsgBox "Cannot open ISYS text file. Error: " + Error$, ROM_MB_OK +

ROM_MB_ICONEXCLAMATION, RθMϋLUS_APP_NAME* Resume ISYSFile_Exit* End Function* Function Rom_OpenLotusl23 ()* On Error GoTo NoOpenLotusl23_Err* Dim ret As Integer* ret = Rom_OpenApp(ROM_SPREAD2_INI_ENTRY, ROM_LOTUS123_WINDOWCLASS, ROM_LOTUS123_ INDOWNAME)* Lotusl23_Exit:* Exit Function* NoOpenLotusl23_Err:* MsgBox "Cannot open Lotus 123. Error: " + Error$, ROM_MB_OK +

ROM_MB_ICONEXCLAMATION, ROMDLUS_APP_NAME* Resume Lotusl23_Exit* End Function* Function Rom_OpenLotusl23File (Filename As String)* On Error GoTo Lotusl23File_Err* D.im ret As Integer* ' * see if the filename is valid* Filename = Rom_SpreadSheetPath & Filename* If Dir$(Filename) = "" Then* ret = MsgBox("There is no associated spreadsheet. Would you like to create a spreadsheet?", ROM_MB_YESNO + MB_DEFBUTTON2 + ROM_MB_ICONINFORMATIO , ROMDLUS_APP_NAME)* If ret = 7 Then GoTo Lotusl23File_Exit* DoCmd RunMacro "Indicator"* ret = Rom_OpenApp(ROM_SPREAD2_INI_ENTRY,

ROM_LOTUS123_WINDOWCLASS, ROM_LOTUS123_WINDOWNAME)* SendKeys "%fa" & Filename & "{ENTER}"* Exit Function* End If* ' * open Lotus 123 or make it the active window* ret = Rom_OpenApp(ROM_SPREAD2_INI_ENTRY, ROM_LOTUS123_WINDOWCLASS, ROM_LOTUS123_WINDOWNAME)* ' * open the filename* If ret = True Then* SendKeys "%fo" & Filename & "{ENTER}"* End If* Lotusl23File_Exit:* Exit Function* Lotusl23File_Err:* MsgBox "Cannot open Lotus 123 spreadsheet. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMOLϋS_APP_NAME* Resume Lotus123File_Exit* End Function* Function Rom_OpenOI (AppIniEntry As String, AppClass As String, AppWindow As String) As Integer* On Error GoTo OpenOI_Err ' Set up error handler.* Rom_OpenOI = True* Dim WindowHandle As Integer* Dim ret As Integer* Dim lpIniRetString As String* Dim AppName As String* Dim RomName As String* Dim AppModuleName As String* Dim ParamPos As Integer* ' * find the filename of the app from the ini_file* AppName =

Rom_ReturnIniString(ROM_APP_INI_SECTION, AppIniEntry)* If (AppName = "") Then* MsgBox "There is rib "filename listed for " & AppWindow & "in the ROMOLUS.INI file.", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMOLUS_APP_NAME* Rom_OpenOI = False* GoTo OpenOI_Exit* End If* ' * load the app if it is not already loaded* ' * to find the module ignore any command line parameters in the name* ParamPos = InStr(AppName, " ")* If (ParamPos) Then* AppModuleName = Lefts(AppName, ParamPos - 1)* Else* AppModuleName = AppName* End If* If (Rom_GetModuleHandle(AppModuleName) = 0) Then 'App is not loaded* ret = Shell(AppName, 1) 'start App* If ret = 0 Then GoTo OpenOI_Err* ' * wait until the main window of the app has been displayed* ' ???? if it does not start up correctly we get stuck here forever* While (Rom_FuzzyFindWindow(AppClass, AppWindow) = 0)* Rom_Yield* Wend* End If* ' * make sure we can find the window handle before we open Rom link* WindowHandle = Rom_FuzzyFindWindow(AppClass, AppWindow)* If WindowHandle = 0 Then* MsgBox "Cannot Access " & AppWindow, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* RomJDpenOI = False* GoTo OpenOI_Exit* End If* ' * Start the Romulus floating top button window* ' * If it doesn't start we still let them go ahead* RomName =

Rom_ReturnIniString(ROM_APP_INI_SECTION, ROMLINK_INI_ENTRY)* RomName = RomName & " " & AppWindow* If (RomName = "") Then* MsgBox "There is no filename listed for the Romulus link program in the ROMULUS.INI file.", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Else* ret = Shell(RomName, 8) 'start Romulus floating top window.* End If* ' * maximize the window and make it the active window* If (Rom_IsZoomed(WindowHandle) = 0) Then* ' ret = Rom_ShowWindow(WindowHandle, ROM_SW_SHOWMAXIMIZED)* 'Else* ret = Rom_SetActiveWindow(WindowHandle)* End If* OpenOI_Exit:* Exit Function* OpenOI_Err:* MsgBox "Cannot open " & AppWindow & ". Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Rom_OpenOI = False* Resume OpenOI_Exit* End Function* Function Rom_OpenOIDFile (Filename As String)* On Error GoTo OIDFile_Err* Dim ret As Integer* SendKeys "%fs" S Filename & "{ENTER}"* ' * open OPEN/image or make it the active window* ret = Rom_OpenApp(ROM_VIEWER2_INI_ENTRY, ROM_OPENIMAGE_WINDOWCLASS,

ROM_OPENIMAGE_WINDOWNAME)* ' * open the filename* If ret = True Then* SendKeys "%do" & Filename & "{ENTER}"* End If* OIDFile_Exit:* Exit Function* OIDFile_Err:* MsgBox "Cannot open OPEN/image image document. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume OIDFile_Exit* End Function* Function Rom_OpenOIFFile (Filename As String)* On Error GoTo OIFFile_Err* Dim ret As Integer* ' * see if the filename is valid* Filename = Rom_ImagePath & Filename* If Dir$(Filename) = "" Then* ret = MsgBo ("There is no associated image. Would you like to create an image?", ROM_MB_YESNO + MBJT3EFBUTTON2 + ROM_MB_ICONQUESTION, ROMULUS_APP_NAME)* If ret = 7 Then GoTo OIFFile_Exit* DoCmd RunMacro "Indicator"* ret = Rom_OpenApp(ROM_VIEWER2_INI_ENTRY, ROM_OPENIMAGE_WINDOWCLASS, ROM_OPENIMAGE_WINDOWNAME)* * * ret = Rom_OpenApp(ROM_VIEWER3_INI_ENTRY, ROM_FTCOLOR_WINDOWCLASS, ROM_FTCOLOR_WINDOWNAME)* ' * SendKeys "%fnil" δ "{ENTER}"* ' * SendKeys "%fa" & Filename & "{ENTER}"* ' * SendKeys "%fq"* Exit Function* End If* SendKeys "%fs" & Filename & "{ENTER}"* ' * open OPEN/image or make it the active window* ret = Rom_OpenApp(ROM_VIEWER2_INI_ENTRY, ROM_OPENIMAGE_ INDO CLASS, ROM_OPENIMAGE_WINDOWNAME)* ' * open the filename* If ret = True Then* SendKeys "%fo" fi Filename & "{ENTER}"* End If* OIFFile_Exit:* Exit Function* OIFFile_Err:* MsgBox "Cannot open OPEN/image image document. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume OIFFile_Exit* End Function* Function Rom_OpenOpenImage ()* On Error GoTo NoOpenOI_Err* Dim ret As Integer* ret = Rom_OpenApp(ROM_VIE ER2_INI_ENTRY, ROM_OPENIMAGE_WINDOWCLASS, ROM_OPENIMAGE_ INDOWNAME)* OI_Exit:* Exit Function* NoOpenOI_Err:* MsgBox "Cannot open OPEN/image. Error: " + Error$, ROM_MB_OK +

ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume OI_Exit* End Function* Function Rom_OpenORG ()* On Error GoTo NoOρenORG_Err* Dim ret As Integer* ret = Rom_OpenApp(ROM_ORG_INI_ENTRY, ROM_ORG_ INDO CLASS, ROM_ORG_ INDOWNAME)* ORG_Exit:* Exit Function* NoOpenORG_Err:* MsgBox "Cannot open Organizer. Error: " + Error?, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume ORG_Exit* End Function* Function Rom_OρenPStyler ()* On Error GoTo NoOpenPStyler_Err* Dim ret As Integer* ret =

Rom_OpenApp(ROM_VIE ER2_INI_ENTRY, ROM_PSTYLER_WINDOWCLASS, ROM_PSTYLER_WINDOWNAME)* PStyler_Exit:* Exit Function* NoOpenPStyler_Err:* MsgBox "Cannot open Photo Styler. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCXAMATION, ROMULUS_APP_NAME* Resume PStyler_Exit* End Function* Function Rom_OpenPStylerFile (Filename As String)* On Error GoTo PStylerFile_Err* Dim ret As Integer* ' * see if the filename is valid* Filename = Rom_ImagePath & Filename* If Dir$(Filename) = "" Then* ret = MsgBox("There is no associated image. Would you like to create an image?", ROM_MB_YESNO + MB_DEFBUTTON2 + ROM_MB_ICONINFORMATION, ROMULUS_APP_NAME)* If ret = 7 Then GoTo PStylerFile_Exit* DoCmd RunMacro "Indicator"* ret = Rom_OpenApp(ROM_VIEWER3_INI_ENTRY, ROM_FTCOLOR_WINDOWCLASS, ROM_FTC0LOR_WINDOWNAME)* SendKeys "%fnil" S "{ENTER}"* SendKeys "%fa" & Filename & "{ENTER}"* SendKeys "%fq"* Exit Function* GoTo PStylerFile_Exit* End If* ' * open PStyler or make it the active window* ret = RomjDpenApp(ROM_vffcwER2_INI_ENTRY, ROM_PSTYLER_WINDOWCLASS,

ROM_PSTYLER_WINDOWNAME)~ ' * open the filename* If ret = True Then* SendKeys "%fo" & Filename & "{ENTER}"* End If* PStylerFile_Exit:* Exit Function* PStylerFile_Err:* MsgBox "Cannot open Photo Styler image. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume PStylerFile_Exit* End Function* Function Rom_OpenQpro ()* On Error GoTo NoOpenQpro_Err* Dim ret As Integer* ret = Rom_OpenApp(ROM_SPREAD3_INI_ENTRY, ROM_QPRO_WINDOWCLASS, ROM_QPRO_ INDOWNAME)* Qpro_Exit:* Exit Function* NoOpenQpro Err:* MsgBox "Cannot open Quattro Pro. Error: " + Error$, ROM_MB_OK +

ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume Qpro_Exit* End Function* Function Rom_OpenQproFile (Filename As String)* On Error GoTo QproFile_Err* Dim ret As Integer* ' * see if the filename is valid* Filename = Rom_SpreadSheetPath & Filename* If Dir$(Filename) = "" Then* ret = MsgBo ("There is no associated spreadsheet. Would you like to create a spreadsheet?", ROM_MB_YESNO + MB_DEFBUTTON2 + ROM_MB_ICONINFORMATION, ROMULUS_APP_NAME)* If ret = 7 Then GoTo QproFile_Exit* DoCmd RunMacro "Indicator"* ret = Rora_OpenApp(ROM_SPREAD3_INI_ENTRY, ROM_QPRO_WINDOWCLASS, ROM_QPRO_WINDOWNAME)* SendKeys "%fa" & Filename & "{ENTER}"* Exit Function* End If* ' * open Quattro Pro or make it the active window* ret = Rom_OpenApp(ROM_SPREAD3_INI_ENTRY, ROM_QPRO_WINDOWCLASS, ROM_QPRO_WINDOWNAME)* ' * open the filename* If ret = True Then* SendKeys "%fo" S Filename & "{ENTER}"* End If* QproFile_Exit:* Exit Function* QproFile_Err:* MsgBox "Cannot open Quattro Pro spreadsheet. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume QproFile_Exit* End Function* Function Rom_OpenWord ()* On Error GoTo NoOpenWord_Err* Dim ret As Integer* ret = Rom_OpenApp(ROM_WP_INI_ENTRY, ROM_WORD_WINDOWCLASS, ROM_WORD_WINDOWNAME)* Word_Exit:* Exit Function* NoOpenWord_Err:* MsgBox "Cannot open Word for Windows. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume Word_Exit* End Function* Function Rom_OpenWord6File (Filename As String)* On Error GoTo Word6File_Err* Dim ret As Integer* ' * see if the filename is valid* Filename = Rom_DocumentPath & Filename* If Dir$(Filename) = "" Then* ret = MsgBo ("There is no associated document. Would you like to create a document?", ROM_MB_YESNO + MB_DEFBUTTON2 + ROM_MB_ICONINFORMATION, ROMULUS_APP_NAME)* If ret = 7 Then GoTo Word6File_Exit* DoCmd RunMacro "Indicator"* ret =

Rom_OpenApp(ROM_WP_INI_ENTRY, ROM_WORD_WINDOWCLASS, ROM_WORD_WINDOWNAME)* SendKeys "%fn" & "{ENTER}"* SendKeys "%fa" & Filename & "{ENTER}"* Exit Function* End If* ' * open Word or make it the active window* ret = Rom_OpenApp(ROM_W^_INI_ENTRY, ROM_WORD_WINDOWCLASS, ROM_WORD_WINDOWNAME)* ' * open the filename* If ret = True Then* SendKeys "%fo" & Filename S_ "{ENTER}"* End If* Word6File_Exit:* Exit Function* Word6File_Err:* MsgBox "Cannot open Word for Windows document. Error: " + Error$, ROM_MB_OK +

ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume Word6File_Exit* End Function* Function Rom_OpenWordFile (Docnum As String)* On Error GoTo WordFile_Err* Dim ret As Integer* Dim Imagename As String* Dim Filename As String* ' * see if the filename is valid* Filename = Rom DocumentPath & Docnum £ ".doc"* Imagename = Rom_ImagePath & Docnum & ".tif"* If Dir$(Filename) = "" Then* ret = MsgBox("There is no associated document. Would you like to create a document?", ROM_MB_YESNO + MB_DEFBUTTON2 + ROM_MB_ICONQUΞSTION, ROMULUS_APP_NAME)* If ret = 7 Then GoTo WordFile_Exit* DoCmd RunMacro "Indicator"* If Dir$(Imagename) <> "" Then Else GoTo WordFile_Next* ret = MsgBox("Would you like to OCR the related image?", ROM_MB_YESNO + MB_DEFBUTTON2 + ROM_MB_ICONQUESTION, ROMULUS_APP_NAME)* If ret = 7 Then GoTo WordFile_Next* ret = Rom_OpenApp(ROM_WP_INI_ENTRY, ROM_WORD_WINDOWCLASS, ROM_WORD_WINDOWNAME)* SendKeys "%fn" & "{ENTER}"* SendKeys "%fa" £ Filename & "{ENTER}"* SendKeys "%fq", True* SendKeys "{RIGHT 500}", True* SendKeys "{LEFT 500}", True* SendKeys "{RIGHT 500}", True* SendKeys "{LEFT 500}", True* SendKeys "%d" & "{ENTER}"* SendKeys Imagename & "{ENTER}"* Exit Function* End If* ' * open Word or make it the active window* ret =

Rom_OpenApp(ROM_WP_INI_ENTRY, ROM_WORD_WINDOWCLASS, ROM_WORD_WINDOWNAME)* ' * open the filename* If ret = True Then* SendKeys "%fo" & Filename & "{ENTER}"* Exit Function* End If* WordFile_Nex :* ret = Rom_OpenApp(ROM_WP_INI_ENTRY, ROM_WORD_WINDOWCLASS, ROM_WORD_WINDOWNAME)* SendKeys "%fn" & "{ENTER}"* SendKeys "%fa" & Filename & "{ENTER}"* Exit Function* WordFile_Exit:* Exit Function* WordFile_Err:* MsgBox "Cannot open Word for Windows document. Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume WordFile_Exit* End Function* Function Rom_OpenWordPerfect ()* On Error GoTo NoOpenWordPerfect_Err* Dim ret As Integer* ret = Rom_OpenApp( PM_WP2_INI_ENTRY, RPM_WPRDPERFECT_WINDCWCLASS, ROM_WORDPERFECT_WINDOWNAME)* WordPerfeσt_Exi :* Exit Function* NoOpenWordPerfect_Err:* MsgBox "Cannot open Word Perfect. Error: " + Error$, ROM_MB_OK + RPM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume WordPerfect_Exit* End Function* Function Rom_OpenWordPerfectFile (Filename As String)* On Error GoTo WPFile_Err* Dim ret As Integer* ' * see if the filename is valid* Filename = Rom_DocumentPath & Filename* If Dir$(Filename) = "" Then* ret = MsgBox("There is no associated document. Would you like to create a document?", ROM_Mff_YESNO + MB_DEFBUTTON2 + ROM_MB_ICONINFORMATION, ROMULUS_APP_NAME)* If ret = 7 Then GoTo WPFile_Exit* DoCmd RunMacro "Indicator"* ret = Rom_OpenApp(ROM_WP2_INI_ENTRY, ROM_WORDPERFECT_WINDOWCLASS, ROM_WORDPERFECT_WINDOWNAME)* While

(Rom_FuzzyFindWindow(ROM_WORDPERFECT_WINDOWCLASS, ROM_WORDPERFECT_WINDOWNAME) = 0)* Rom_Yield* Wend* SendKeys "%fn" & "{ENTER}"* SendKeys "%fa" £ Filename & "{ENTER}"* Exit Function* End If* ' * open Word or make it the active window* ret -= Rom_OpenApp(ROM_WP2_INI_ENTRY, ROM WORDPERFECT WINDOWCLASS, ROM_WCRDPERFECT_WINDOWNAME)* ' * open the filename* If ret = True Then* SendKeys "%fo" & Filename & "{ENTER}"* End If* WPFile_Exit:* Exit Function* WPFile_Err:* MsgBox "Cannot open Word Perfect document. Error: " + Error$, RPM_MB_PK + RPM_MB_ICPNEXCLAMATIPN, RPMDLUS_APP_NAME* Resume WPFile_Exit* End Function* Function Rom_PpenWordScan ()* Pn Error GoTo NoCpenWSC_Err* Dim ret As Integer* ret = Rom_CpenApp(RCM_VIEWER_INI_ENTRY, RPM_WPRDSCAN_WINDOWCLASS, RPM_WΩRDSCAN_WINDPWNAME)* WSC_Exit:* Exit Function* NoΩpenWSC_Err:* MsgBox "Cannot open Word Scan. Error: " + Error$, RPM_MB_OK + RCM_MB_ICCNEXCLAMATICN, RPMDI.US_APP_NAME* Resume WSC_Exit* End Function* Function Rom_ΩpenWordScanFile (Filename As String)* Pn Error GoTo WSCFile_Err* Dim ret As Integer* ' * see if the filename is valid* Filename = Rom_ImagePath S Filename* If Dir$(Filename) = "" Then* ret = MsgBox("There is no associated image. Would you like to create an image?", ROM_MB_YESNO + MB_DEFBUTT0N2 +

RCM_MB_ICPNINFCRMATICN, RPMULUS_APP_NAME)* If ret = 7 Then GoTo WSCFile_Exit* DoCmd RunMacro "Indicator"* ret = Rom_CpenApp(RPM_VIEWER3_INI_ENTRY, RPM_FTCCLCR_WINDPWCLASS, ROM_FTCC PR_WINDPWNAME)* SendKeys "%fnil" S "{ENTER}"* SendKeys "%fa" & Filename & "{ENTER}"* SendKeys "%fq"* Exit Function* GoTo WSCFile_Exit* End If* ' * open Word Scan or make it the active window* ret = Rom_CpenApp(RCM_VIEWER_INI_ENTRY, ROM_WORDSCAN_WINDΩWCLASS, RCM_WPRDSCAN_WINDPWNAME)* ' * open the filename* If ret = True Then* SendKeys "%fnd" & Filename S. "{ENTER}"* End If* WSCFile_Exit:* Exit Function* WSCFile_Err:* MsgBox "Cannot open Word Scan image. Error: " + Error$, RCM_MB_CK + RCM_MB_ICCNEXCLAMATICN, RCMULUS_APP_NAME* Resume WSCFile_Exit* End Function* '** '* Romulus - Path Module* '* Copyright 1993 Romulus Software* '** Cption Compare Database 'Use database order for string comparisons* Pption Explicit* Function Rom_SavePaths ()* Pn Error GoTo SavePath_Err* Dim DB As Database* Dim PathsDyna As Dynaset* Dim ret As Integer* Set DB = CurrentDB()* Set PathsDyna = DB.CreateDynaset("Romulus Paths")* PathsDyna.Edit* Rom_DocumentPath = forms("Romulus Paths Form") .form("DocPath")* If Right$(Rom_DocumentPath, 1) <> "\" Then Rom_DocumentPath = Rom_DocumentPath + "\"* PathsDyna("Document Path") = Rom_DocumentPath* Rom_ImagePath = forms("Romulus Paths Form") .form("ImagePath")* If Right$(Rom_ImagePath, 1) <> "\" Then Rom_ImagePath = Rom_ImagePath + "\"* PathsDyna("Image Path") = Rom_ImagePath* Rom__ISYSTextPath = forms("Romulus Paths Form").form("TextPath")* If Right$(Rom_ISYSTextPath, 1) <> "\" Then ' Rom_ISYSTextPath = Rom_ISYSTextPath + "\"* PathsDyna("ISYSText Path") - Rom ESYSTextPath* Rom_SpreadSheetPath = forms("Romulus Paths Forπrj.forraC'SpreadPath")* If Right$(Rom_SpreadSheetPath, 1) <> "\" Then Rom_SpreadSheetPath = Rom_SpreadSheetPath + "\"* PathsDyna("Spreadsheet Path") = Rom_SpreadSheetPath* Rom_ChartPath = forms("Romulus Paths Form").form("ChartPath")* If Right$(Rom_ChartPath, 1) <> "\" Then Rom_ChartPath = Rom_ChartPath + "\"* PathsDyna("Chart Path") = Rom_ChartPath* PathsDyna.Update* DB.Close* PathsDyna.Close* ret = Rom_ClosePathForm()* SavePath_Exit:* Exit Function* SavePath_Err:* MsgBox "Error: " + Error$* ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume SavePath_Exit* End Function* Function Rom_InitPathForm ()* On Error GoTo InitPathJErr* Dim DB As Database* Dim PathsDyna As Dynaset* Set DB = CurrentDB()* Set PathsDyna = DB.CreateDynaset("Romulus Paths")* forms("Romulus Paths Form") .form("DocPath") = PathsDyna("Document Path")* forms("Romulus Paths Form") .form("ImagePath") = PathsDyna("Image Path")* forms("Romulus Paths Form") .form("TextPath") = PathsDyna("ISYSText Path")* forms("Romulus Paths Form") .form("SpreadPath") = PathsDyna("Spreadsheet Path")* forms("Romulus Paths Form") .for ("ChartPath") = PathsDyna("Chart Path")* DB.Close* PathsDyna.Close* InitPath_Exit:* Exit Function* InitPath_Err:* MsgBox "Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume InitPath_Exit* End Function* * '* Romulus - Utilities Module* '* Copyright 1993 Romulus Software* '** Option Compare Database 'Use database order for string comparisons* Option Explicit* Function Rom_Backup ()* On Error GoTo Backup_Err* D.im ret As Integer* Dim FileName As String* Dim RomName As String* ' * find the filename of the app from the ini_file* FileName =

Rom_RetumIniString(RPM_.APP_INI_SECTION, ROM_BACKUP_INI_ENTRY)* If (FileName = "'-) Then* MsgBox "There is no filename listed for the Backup program in the ROMULUS.INI file.", ROM_MB_O + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* GoTo Backup_Exit* End If* ' * open Backup or make it the active window* ret = Shell(FileName, 1)* Backup_Exit:* Exit Function* Backup_Err:* MsgBox "Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume Backup_Exit* End Function* Function Rom_Word6Convert ()* On Error GoTo ord6Convert_Err* Dim ret As Integer* Dim FileName As String* ' * find the convert template rfame from the ini_file* FileName =

Rom_ReturnIniString(ROM_APP_INI_SECTION, ROM_CONVERT_INI_ENTRY)* If (FileName = "") Then* MsgBox "The Convert template is not listed in the ROMULUS.INI file.", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* GoTo Word6Convert_Exit* End If* ' * open Word or make it the active window* ret ~~ Rom_OpenApp(ROM_WP_INI_ENTRY, ROM_WORD_WINDOWCLASS, ROM_WORD_WINDOWNAME)* ' * open the filename* If ret = True Then* SendKeys "%fn" & FileName £ "{ENTER}"* End If* Word6Convert_Exit:* Exit Function* Word6Convert_Err:* MsgBox "Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume Word6Convert_Exit* End Function* Function Rom_Wσrd6ISYSCapture ()* On Error GoTo Word6Capture_Err* Dim ret As Integer* Dim FileName As String* ' * find the text edit template name from the ini_file* FileName =

Rom_ReturnIniString(ROM_APP_INI_SECTION, ROM_TEXTSAVE_INI_ENTRY)* If (FileName = "") Then* MsgBox "The ISYS Capture template is not listed in the ROMULUS.INI file.", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* GoTo Word6Capture_Exit* End If* ' * open Word or make it the active window* ret = Rom_OpenApp(ROM_WP_INI_ENTRY, ROM_WORD_WINDOWCLASS, ROM_WORD_WINDOWNAME)* ' * open the filename* If ret = True Then* SendKeys "%fn" & FileName & "{ENTER}"* SendKeys "%fq"* End If* Word6Capture_Exit:* Exit Function* Word6Caρture_Err:* MsgBox "Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume Word6Capture_Exit* End Function* Function Rom_Word6Join ()* On Error GoTo Word6Join_Err* D.im ret As Integer* Dim FileName As String* ' shut the utilities form first so that we don't lock up when romlink sets Access as the active window* 'DoCmd Close A^_FORM, "Romulus Utilities"* ' * find the join template name from the ini_file* FileName = Rom_ReturnIniString(ROM_APP_INI_SECTION, RPM_JPIN_INI_ENTRY)* If (FileName = "") Then* MsgBox "The Join template is not listed in the RPMULUS.INI file.", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* GoTo Word6Join_Exit* End If* ' * open Word or make it the active window* ret =

Rom_OpenApp(ROM_WP_INI_ENTRY, ROM_WORD_WINDOWCLASS, ROM_WORD_WINDOWNAME)* ' * open the filename* If ret = True Then* SendKeys "%fn" & FileName & "{ENTER}"* End If* Word6 oin_Exit:* Exit Function* Word6Join_Err:* MsgBox "Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume Word6Join_Exit* End Function* Function Rom_WordOCRCapture ()* On Error GoTo WordOCR_Err* Dim ret As Integer* ret = Rom_OpenApp(ROM_WP_INI_ENTRY, ROM_WORD_WINDOWCLASS, ROM_WORD_WINDOWNAME)* SendKeys "%fn{ENTER}"* WordOCR_Exit:* Exit Function* WordOCR_Err:* MsgBox "Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME* Resume WordOCR_Exit* End Function* '** '* Romulus - Menus Module* '* Copyright 1993 Romulus Software* '** Option Compare Database 'Use database order for string comparisons* Option Explicit* Function Rom_Exit ()* On Error GoTo RomExit_Err* Dim hWnd As Integer* Dim ret As Integer* ' * confirm they really want to exit* ret = MsgBox("Are you sure you wish to exit?" + Error$, ROM_MB_YESNO + MB_DEFBUTTON2 + ROM_MB_ICONQUESTION, ROMULUS_APP_NAME)* If (ret = 7) Or (ret = 2) Then GoTo RomExit_Exit* hWnd = Rom_FuzzyFindWindow(ROM_WORD_WINDOWCLASS , ROM_WORD_WINDOWNAME)* If hWnd Then* ret = Rom_PostMessage(hWnd, ROM_WM__CLOSE, 0, 0)* End If* hWnd = Rom_FuzzyFindWindow(ROM_EXCEL_WINDOWCLASS, ROM_EXCEL_WINDOWNAME)* If hWnd Then* ret = Rom_PostMessage(hWnd, ROM_WM_CLOSE, 0, 0)* End If* hWnd = Rom_FuzzyFindWindow(ROM_ISYS_WINDOWCLASS, ROM_ISYS_WINDOWNAME)* If hWnd Then* ret = Rom_PostMessage(hWnd, ROM_WM_CLOSE, 0, 0)* End If* hWnd = Rom_FuzzyFindWindow(ROM_PSTYLER_WINDOWCLASS, ROM_PSTYLER_WINDOWNAME)* If hWnd Then* ret = Rom_PostMessage(hWnd, ROM_WM_CLOSE, 0, 0)* End If* hWnd =

Rom_FuzzyFindWindow(ROM_FTCOLOR_WINDOWCLASS, ROM_FTCOLOR_WINDOWNAME)* If hWnd Then* ret = Rom_PostMessage(hWnd, ROM_WM_CLOSE, 0, 0)* End If* hWnd = Rom_FuzzyFindWindow(ROM_ABC_WINDOWCLASS, ROM_ABC_WINDOWNAME)* If hWnd Then* ret = Rom_PostMessage(hWnd, ROM_WM_CLOSE, 0, 0)* End If* hWnd = Rom_FuzzyFindWindo (ROM_WORDPERFECT_WINDOWCLASS, ROM_WORDPERFECT_WINDOWNAME)* If hWnd Then* ret = Rom_PostMessage(hWndr ROM_WM_CLOSE, 0, 0)* End If* hWnd = Rom_FuzzyFindWindow(ROM_AMIPRO_WINDOWCLASS, ROM_AMIPRO_WINDOWNAME)* If hWnd Then* ret = Rom_PostMessage(hWnd, ROM_WM_CLOSE, 0, 0)* End If* hWnd = Rom_FuzzyFindWindow(ROM_LOTUS123_WINDOWCLASS, ROM_LOTUS123_WINDOWNAME)* If hWnd Then* ret = Rom_PostMessage(hWnd, ROM_WM_CLOSE, 0, 0)* End If* hWnd = Rom_FuzzyFindWindow(ROM_QPRO_WINDOWCLASS, ROM_QPRO_WINDOWNAME)* If hWnd Then* ret = Rom_PostMessage(hWnd, ROM_WM_CLOSE, 0, 0)* End If* hWnd = Rom_FuzzyFindWindow(ROM_WORDSCAN_WINDOWCLASS, ROM_WORDSCAN_WINDOWNAME)* If hWnd Then* ret = Rom_PostMessage(hWnd, ROM_WM_CLOSE, 0, 0)* End If* hWnd = Rom_FuzzyFindWindow(ROM_OPENIMAGE_WINDOWCLASS, ROM_OPENIMAGE_WINDOWNAME)* If hWnd Then* ret = Rom_PostMessage(hWnd, ROM_WM_CLOSE, 0, 0)* End If* ' *????? label package and audio and voice and resource calc and isys update* ' * shut down Access* DoCmd Quit A_PROMPT* RomExit_Exit:* Exit Function* RomExit_Err:* MsgBox "Error: " + Error?, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMOLUS_APP_NAME* Resume RomExit_Exit* End Function*'* Romulus - Numbering Module Copyright 1993 Romulus Software'**Option Compare Database 'Use database order for string comparisons*Option Explicit*' * set module variable*Dim gRom_NumsDirty As Integer*Function Rom_AddNumbers ()*On Error GoTo AddNums_Err*Rom_AddNumbers = False*Dim Prefix As String*Dim StartNum As String*Dim EndNum As String*Dim StartExt As String*Dim EndExt As String*Dim PrefixVar As Variant*Dim StartNumVar As Variant*Dim EndNumVar As Variant*D.im StartExtVar As Variant*Dim EndExtVar As Variant*Dim PrefixLen As Integer*Dim StartNumLen As Integer*Dim EndNumLen As Integer*Dim StartExtLen As Integer*Dim EndExtLen As Integer*Dim Num As Integer*Dim Ext As Integer*Dim Buffer As String*D.im FileName As String*D.im FormatLine As String*Dim MaxWidth As Integer*' * get the values of the text controls*PrefixVar = UCase(forms("Romulus Numbering") .form("Prefix"j )*If IsNull(PrefixVar) Then*Prefix = ""*PrefixLen = 0*Else*Prefix = PrefixVar*PrefixLen = Len(PrefixVar)*End If*StartNumVar = forms("Romulus Numbering") .for ("Starting Number")*If IsNull(StartNumVar) Then*StartNum = ""'StartNumLen = 0*Else*StartNum = StartNumVar*StartNumLen = Len(StartNumVar)*End If*EndNumVar = forms("Romulus Numbering") .form("Ending Number")*If IsNull(EndNumVar) Then*EndNum = ""*EndNumLen = 0*Else*EndNum = EndNumVar*EndNumLen = Len(EndNumVar)*End If*StartExtVar = UCase(forms("Romulus

Numbering").form("From Extension"))*If IsNull(StartExtVar) Then*StartExt = ""*StartExtLen = 0*Else*StartExt = StartExtVar*StartExtLen =

Len(StartExtVar)*End If*EndExtVar = UCase(forms("Romulus Numbering") .form("To Extension") )*If IsNull(EndExtVar) Then*EndExt = ""*EndExtLen = 0*Else*EndExt = EndExtVar*EndExtLen = Len(EndExtVar)*End If*' * validate the start and end strings*If (IsNumeric(StartNum) = False) Or (Val(StartNum) < 1) Then*MsgBox "The 'Starting Number' must be a positive number (with optional leading zeroes)", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME*DoCmd GoToControl "Starting Number"*GoTo AddNums_Exit*End If*If (EndNum <> "") And ( (IsNumeric(EndNum) = False) Or (Val(EndNum) < 1)) Then*MsgBox "The 'Ending Number' must be a positive Number (with optional leading zeroes)", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME*DoCmd GoToControl "Starting Number"*GoTo AddNums_Exit*End If*' * validate that startnum is greater than end num if they are both there*If (EndNum <> "") And (Val(EndNum) < Val(StartNum) ) Then*MsgBox "The 'Ending Number' must must be greater than the 'Starting Number'.", ROM_MB_OK + ROM_MB_ICONEXCLAMATION,

ROMULUS_APP_NAME*DoCmd GoToControl "Ending Number"*GoTo AddNums_Exit*End If*' * validate total lengths*If ((StartNumLen + PrefixLen) > 7) Gr ( (EndNumLen + PrefixLen) > 7) Then*MsgBox "The total number of digits in the Prefix and the number cannot exceed 7.", RPM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME*DoCmd GoToControl "Prefix"*GoTo AddNums_Exit*End If*' * validate the extensions*If StartExtLen > 1 Or (StartExt <> "" And (StartExt < "A" Or StartExt > "Z")) Then*MsgBox "The 'From Extension' must be a single letter between 'A' and 'Z'.", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME*DoCmd GoToControl "From Extension"*GoTo AddNums_Exit*End If*If EndExtLen > 1 Or (EndExt <> "" And (EndExt < "A" Pr EndExt > "Z")) Then*MsgBox "The 'To Extension' must be a single letter between 'A' and 'Z'.", RPM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME*DoCmd GoToControl "To Extension"*GoTo AddNums_Exit*End If*If EndExt <> '" And StartExt = "" Then*MsgBox "There must be a 'From Extension' if you enter a 'To Extension'.", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMDLUS_APP_NAME*DoCmd GoToControl "From Extension"*GoTo AddNums_Exit*End If*If (EndExt <> "") And (EndExt < StartExt) Then*MsgBox "The 'To Extension' must must be a letter that occurs after the 'From Extension'.", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME*DoCmd GoToControl "To Extension"*GoTo AddNums_Exit*End If*' * if the end number is blank set it equal to the start*If EndNum ~~ "" Then EndNum = StartNuπTIf EndExt = "" Then EndExt ~~ StartExt*' * determine the number of leading zeroes (if any)*If Left$(StartNum, 1) = "0" Or Left$(EndNum, 1) = "0" Then*If StartNumLen > EndNumLen Then*MaxWidth = StartNumLen*Else*MaxWidth = EndNumLen*End If*Else*MaxWidth = l*End If*FormatLine = String$(MaxWidth, "0")*' * show hourglass*DoCmd Hourglass True*' * add the requested numbers to the file*FileName = Rom_ReturnIniString(ROM_NUMFILE_INI_SECTION, ROM_NUMFILE_INI_ENTRY)*Open FileName For Append As #l*If StartExt = "" Then*For Num = Val(StartNum) To Val(EndNum)*Print #1, Chr$(34) & Prefix & Formats(Num, FormatLine) & Chr$(34)*Next*Else*For Num = Val(StartNum) To Val(EndNum)*For Ext = Asc(StartEx ) To Asc(EndExt)"Print #1, Chr$(34) & Prefix & Format$(Num, FormatLine) & Chr$(Ext); Chr$(34)*Next*Next*End If*' * set module variable to indicate we are now dirty*gRom_NumsDirty = True*' * make the print and view buttons active*forms("Romulus

Numbering") .form("Disabled_ViewNumbers") .Visible = False*forms("Romulus Numbering") .form("Disabled_PrintNumbers") .Visible = False*forms("Romulus Numbering") .form("View Numbers").Enabled = True*forms("Romulus Numbering") .form("Print Numbers").Enabled = True*' * clear all the edit controls*forms("Romulus Numbering") .form("Prefix") = Null*forms("Romulus Numbering") .form("Starting Number") = Null*forms("Romulus

Numbering") .form("Ending Number") = Null*forms("Romulus Numbering") .form("From Extension") = Null*forms("Romulus Numbering") .form("To Extension") = Null*DoCmd GoToControl "Prefix"*Rom_AddNumbers = True*AddNums_Exit:*DoCmd Hourglass False*Close*Exit Function*AddNums_Err:*MsgBox "Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME*Resume AddNums_Exit*End Function*Function Rom_CloseNums ()*On Error GoTo CloseNums_Err*Dim ExtraText As String*Dim ret As lnteger*lf forms("Romulus Numbering") .form("Generate Records") -= True Then*ExtraText = " and use them to generate database records"*Else*ExtraText = ""*End If*If gRom_NumsDirty = True Then*ret = MsgBox("You have created a list of numbers. Do you want to print them" & ExtraText & "?", ROM_MB_ICONEXCLAMATION + 3, ROMULUS_APP_NAME)*If ret = 6 Then '* Yes selected*ret = Rom_PrintNums()*GoTo ClθBeNums_Exit*End If*If ret = 2 Then '* Cancel selected*GoTo CloseNums_Exit*End If*End If '* No selected it drops out*DoCmd Close A_FORM, "Romulus Numbering"*CloseNums_Exit:*Exit Function*CloseNums_Err:*MsgBox "Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME*Resume CloseNums_Exit*End Function*Function Rom_OpenNumbering ()*On Error GoTo OpenNum_Err*DoCmd OpenFor "Romulus Numbering"*OpenNum_Exit:*Exit Function*OpenNum_Err:*MsgBox "Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION,

ROMULUS_APP_NAME*Resume OpenNum_Exit*End Function*Function Rom_PrintNums ()*On Error GoTo PrintNums_Err*Dim ret As Integer*Dim FileName As String*Dim DB As Database*Dim MainDyna As Dynaset*Dim DocNum As String*' * No longer needed - I disable the buttons instead*' If gRom_NumsDirty = False Then*' MsgBox "You have not created any numbers yet", ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME*' GoTo PrintNums_Exit*' End If*If Not IsNull(forms("Romulus Numbering") .form("Starting Number")) Then*ret = Rom_AddNumbers()*If ret = 0 Then GoTo PrintNums_Exit*End If*' * create the database records if requested*If forms("Romulus Numbering") .form("Generate Records") = True Then*FileName = Rom_ReturnIniString(ROM_NUMFILE_INI_SECTION,

ROM_NUMFILE_INI_ENTRY)*Open FileName For Input As #l*Set DB = CurrentDB()*Set MainDyna = DB.CreateDynase ("Romulus Database")~BeginTrans*On Error Resume Next*Input #1, DocNum*While Err = 0*MainDyna.AddNew*MainDyna("Doc Number") = DocNum*MainDyna.Update*Err = 0 '* so that if there is a duplicate key error we keep going*Input #1, DocNum*Wend*CommitTrans*DB.Close*MainDyna.Close*On Error GoTo PrintNums_Err*Close*End If*' * according to selection set Avery labels up to open correct file*If forms("Romulus Numbering") .form("Bar Codes") = True Then*FileName = Rom_ReturnIniString(ROM_NUMFILE_INI_SECTION, ROM_BARFILE_INI_ENTRY)*Else*FileName =

Rom_ReturnIniString(ROM_NUMFILE_INI_SECTION, ROM_PLAINFILE_INI_ENTRY)*End If*ret = Rom_WritePrivateProfileString(ROM_AVERY_LAYOUT_SECTION, ROM_AVERY_LASTFILE_ENTRY, FileName, ROM_AVERY_INI_NAME)*' * open Avery Labels or make it the active window*ret = Rom_OpenApp(ROM_LABEL_INI_ENTRY, ROM_AVERY_WINDOWCLASS, ROM_AVERY_WINDOWNAME)*'**' * update display of the linked item - needed' if already open*' * open the filename*' * ???? problem getting the list to link on first opening - so will rely on a label that is already linked opening automatically*'FileName =

Rom_ReturnIniString(ROM_NUMFILE_INI_SECTION, ROM_NUMFILE_INI_ENTRY)*'If ret = True Then*'SendKeys "%ml" & FileName &

"{TAB}{TAB}{TAB}{DOWN}{UP}{UP}{UP}{UP}{UP}{UP}{UP}{UP}{DOWN}{ENTER}{ENTER}%ml{ ENTER}"*'Else*'GoTo PrintNums_Exit*'End If*'**DoCmd Close A_FORM, "Romulus Numbering"*PrintNums_Exit:*Close*Exit Function*PrintNums_Err:*MsgBox "Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_.NAME*Resume PrintNums_Exit*End Function*Function Rom_SetupNumbering ()*On Error GoTo SetupNum_Err** * set module variable to indicate we are now clean*gRom_NumsDirty = False*Dim FileName As String*'* set up the numbering file as empty*FileName = Rom_ReturnIniString(ROM_NUMFILE_INI_SECTION, ROM_NUMFILE_INI_ENTRY)*Open FileName For Output As

#l*SetupNum_Exit:*Close*Exit Function*SetupNum_Err:*MsgBox "Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, ROMULUS_APP_NAME*Resume SetupNum_Exit*End FunctionFunction Rom_ViewNums ()*On Error GoTo ViewNum_Err*D.im ret As Integer*Dim FileName As String*' * No longer needed - I disable the buttons instead*' If gRom_NumsDirty = False Then*' MsgBox "You have not created any numbers yet", ROM_MB_OK, ROMULUS_APP_NAME*' GoTo ViewNum_Exit*' End If*FileName = Rom_ReturnIniString(ROM_NUMFILE_INI_SECTION, ROM_NUMFILE_INI_ENTRY)*ret = Shell("notepad " & FileName, l)*ViewNum_Exit:*Exit Function*ViewNum_Err:*MsgBox "Error: " + Error$, ROM_MB_OK + ROM_MB_ICONEXCLAMATION, RPMULUS_APP_NAME*Resume ViewNum_Exit*End Function***

SUBS 26

Claims

Clai s 1. A method of facilitating the use of a plurality of G.U.I. applications, the method comprising running a first G.U.I. application with a first data file or record loaded and at the same time displaying one or more primary symbols representing one or more further G.U.I. applications, and, on actuation of one of the primary symbols by a user, searching for a second data file or record associated widi said first data file or record and, if such an associated second data file or record exists, causing the further G.U.I. application represented by said one of the primary symbols to be run with the associated second data file or record automatically loaded.
2. A method as claimed in Claim 1, wherein two data files or records are considered to be associated when their names are the same, or when designated parts, for example the first parts, of their names are the same.
3. A method as claimed in Claim 1 or 2, which further includes, while the first G.U.I. application is running, displaying one or more secondary symbols representing said one or more further G.U.I. applications, and, on acmation of one of said secondary symbols by a user, running the G.U.I. application associated with that secondary symbol with no data file or record automatically loaded.
4. A method as claimed in any preceding claim, which further includes the step of, when one of the further G.U.I. applications is running, displaying a return symbol representing the first G.U.I. application, and, on actuation of the return symbol by a user, running the first G.U.I. application.
5. A method as claimed in Claim 4, wherein the first G.U.I. application is run with a third data file or record automatically loaded if, when me return symbol is actuated, said one of the further G.U.I. applications is running with a fourth data file or record loaded and the third and fourth data files or records are associated with each other.
6. A method as claimed in any preceding claim, which further includes, when one of die further G.U.I. applications is running with a particular data file or record loaded, displaying one or more further application symbols representing the other further applications, and, on actaation of one of die further application symbols by a user, causing the further G.U.I. application represented by said one of me further application symbols to be run with a data file or record automatically loaded which is associated widi said particular data file or record.
7. A mediod as claimed in any preceding claim, wherein the user is able to specify, at any stage during the method, the default directories to be used by the
G.U.I. applications (including the first G.U.I. application) when the G.U.I. applications are caused to be run by actaation of a relevant symbol.
8. A method as claimed in Claim 7, wherein two data files or records can only be associated with each other, for example by virtue of their names, when each of the data files or records is located in a respective default directory.
9. A method as claimed in Claim 8, which further includes displaying a number generating symbol and, on actaation of the number generating symbol, and input of start and finish values, by the user, generating a sequence of numbers, or alphanumeric strings, between the start and finish values.
10. A method as claimed in Claim 9, which also includes generating a bar code corresponding to each number or string, anάVor printing a label corresponding to each number or string, and/or creating a data file or record having a name corresponding to each string.
11. A device for carrying out the method claimed in any one of Claims 1 to 10, the device comprising computing means for running the G.U.I. applications, display means for displaying said symbols and information relating to the G.U.I. applications, first input means for allowing me user to operate the G.U.I. applications, and second input means for allowing me user to actuate said symbols.
12. A memod of allocating virtual memory in a GUI environment, said memod comprising the steps of: providing an allocation request for virtual memory; increasing said allocation request to define an extra virtual memory space for storing
GUI objects; and allocating an increased virtual memory space in response to said increased allocation request when said increased allocation request is less tiian or equal to the amount of free virtual memory available.
13. The memod according to claim 12 further comprising the step of writing overflow data in said allocated increased virtual memory space.
14. The method according to claims 11 or 13 wherein said allocation request for virtual memory is provided for an application.
15. The method according to claim 14 further comprising the step of releasing said allocated virtual memory when said application is closed.
16. The method according to any one of claims 12-15 wherein said allocation request is increased by a percentage value of said virtual memory.
17. The method according to any one of claims 12-16 wherein said GUI objects comprise a window name and a window class.
18. The method according to claim 17 wherein said GUI objects further comprise a desk class, or a child class, or a child class and a desk class.
19 The method according to any one of claims 12-18 wherein said GUI environment is Microsoft Windows .
20. A method of allocating windows resources in the Microsoft Windows® environment, said method comprising the steps of: providing an allocation request for windows resources; increasing said allocation request to define a buffer for storing GUI objects; and allocating an increased portion of said windows resources in response to said increased allocation request when said increased allocation request is less man or equal to the amount of free windows resources available.
21. The method according to claim 20 further comprising the step of storing overflow data in said allocated increased portion of windows resources.
22. The method according to claims 20 or 21 wherein said allocation request for windows resources is provided for an application.
23. The method according to any one of claims 20-22 wherein said allocation request is increased by a percentage value of said windows resources.
24. The memod according to any one of claims 20-23 wherein said GUI objects comprise a window name and a window class.
25. The method according to claim 24 wherein said GUI objects further comprise a desk class, or a child class, or a desk class and a child class.
®
26. A method of managing windows resources in me Microsoft Windows environment, said method comprising the steps of: allocating an increased percentage of windows resources for an application displayed in a main window, said increased percentage of windows resources comprising a nominal portion of windows resources for said application and a buffer which are contiguously arranged in relation to one another; and storing windows resources of one or more child windows of said main window in said buffer.
27. The method according to claim 26 wherein said step of allocating an increased percentage of windows resources comprises the steps of: obtaining a request for said nominal portion of said windows resources generated by opening said application in said main window; increasing said request by a factor for allocating said buffer contiguously with said nominal portion of said windows resources; reserving said increased percentage of windows resources in response to said increased request for windows resources when said increased request is less man or equal to the amount of free windows resources available.
28. The method according to claim 27 wherein said step of storing windows resources of one or more child windows of said main window in said buffer comprises the steps of: obtaining a second request for windows resources generated by a child window; and providing a portion of said buffer for said child window in response to said second request when said second request is less d an or equal to the amount of free windows resources available in said buffer.
PCT/AU1995/000068 1994-02-14 1995-02-14 Use of multiple applications and allocation of memory or other resources in a gui environment WO1995022104A1 (en)

Priority Applications (4)

Application Number Priority Date Filing Date Title
AUPM387594 1994-02-14
AUPM3875 1994-02-14
AUPM8698 1994-10-10
AUPM869894 1994-10-10

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
GB9617167A GB2301210B (en) 1994-02-14 1995-02-14 Use of multiple applications and allocation of memory or other resources in a GUI environment

Publications (1)

Publication Number Publication Date
WO1995022104A1 true true WO1995022104A1 (en) 1995-08-17

Family

ID=25644622

Family Applications (1)

Application Number Title Priority Date Filing Date
PCT/AU1995/000068 WO1995022104A1 (en) 1994-02-14 1995-02-14 Use of multiple applications and allocation of memory or other resources in a gui environment

Country Status (1)

Country Link
WO (1) WO1995022104A1 (en)

Cited By (8)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US7111307B1 (en) * 1999-11-23 2006-09-19 Microsoft Corporation Method and system for monitoring and verifying software drivers using system resources including memory allocation and access
US7814498B2 (en) 2006-05-01 2010-10-12 Microsoft Corporation Loading application resources
US20130321453A1 (en) * 2012-05-31 2013-12-05 Reiner Fink Virtual Surface Allocation
US9177533B2 (en) 2012-05-31 2015-11-03 Microsoft Technology Licensing, Llc Virtual surface compaction
US9230517B2 (en) 2012-05-31 2016-01-05 Microsoft Technology Licensing, Llc Virtual surface gutters
US9235925B2 (en) 2012-05-31 2016-01-12 Microsoft Technology Licensing, Llc Virtual surface rendering
US9307007B2 (en) 2013-06-14 2016-04-05 Microsoft Technology Licensing, Llc Content pre-render and pre-fetch techniques
US9384711B2 (en) 2012-02-15 2016-07-05 Microsoft Technology Licensing, Llc Speculative render ahead and caching in multiple passes

Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
EP0325885A2 (en) * 1988-01-26 1989-08-02 International Business Machines Corporation Direct cursor-controlled access to multiple application programs
EP0456275A2 (en) * 1990-05-11 1991-11-13 Fujitsu Limited A static memory allocation system

Patent Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
EP0325885A2 (en) * 1988-01-26 1989-08-02 International Business Machines Corporation Direct cursor-controlled access to multiple application programs
EP0456275A2 (en) * 1990-05-11 1991-11-13 Fujitsu Limited A static memory allocation system

Non-Patent Citations (3)

* Cited by examiner, † Cited by third party
Title
"Microsoft Windows User's Guide for the Windows Graphical Environment", Published 1985, by MICROSOFT CORPORATION, pages 135-137. *
ANDREW S. TANENBAUM, "Operating Systems: Design and Implementation", Published 1987, by PRENTICE-HALL INTERNATIONAL, ENGLEWOOD CLIFFS (NEW JERSEY), Paragraph Bridging pages 199-200. *
BRIAN LIVINGSTON, "Windows 3 Secrets", Published 1991, by IDG BOOKS WORLDWIDE, SAN MATEO (CALIFORNIA), pages 100-105. *

Cited By (13)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US7111307B1 (en) * 1999-11-23 2006-09-19 Microsoft Corporation Method and system for monitoring and verifying software drivers using system resources including memory allocation and access
US7814498B2 (en) 2006-05-01 2010-10-12 Microsoft Corporation Loading application resources
US9384711B2 (en) 2012-02-15 2016-07-05 Microsoft Technology Licensing, Llc Speculative render ahead and caching in multiple passes
US9235925B2 (en) 2012-05-31 2016-01-12 Microsoft Technology Licensing, Llc Virtual surface rendering
US9177533B2 (en) 2012-05-31 2015-11-03 Microsoft Technology Licensing, Llc Virtual surface compaction
US9230517B2 (en) 2012-05-31 2016-01-05 Microsoft Technology Licensing, Llc Virtual surface gutters
CN104321752A (en) * 2012-05-31 2015-01-28 微软公司 Virtual surface allocation
US9286122B2 (en) * 2012-05-31 2016-03-15 Microsoft Technology Licensing, Llc Display techniques using virtual surface allocation
US9940907B2 (en) 2012-05-31 2018-04-10 Microsoft Technology Licensing, Llc Virtual surface gutters
US20130321453A1 (en) * 2012-05-31 2013-12-05 Reiner Fink Virtual Surface Allocation
US9959668B2 (en) 2012-05-31 2018-05-01 Microsoft Technology Licensing, Llc Virtual surface compaction
US9832253B2 (en) 2013-06-14 2017-11-28 Microsoft Technology Licensing, Llc Content pre-render and pre-fetch techniques
US9307007B2 (en) 2013-06-14 2016-04-05 Microsoft Technology Licensing, Llc Content pre-render and pre-fetch techniques

Similar Documents

Publication Publication Date Title
US5900871A (en) System and method for managing multiple cultural profiles in an information handling system
US7346855B2 (en) Method and system for switching between multiple computer applications
US6396515B1 (en) Method, system and computer program product for dynamic language switching in user interface menus, help text, and dialogs
US5732266A (en) Storage medium storing application programs and application initialization files and automatic launching of computer applications stored on the storage medium
US7310781B2 (en) System and method for content and information transfer between program entities
US6323853B1 (en) Method, system and computer readable medium for addressing handling from a computer program
US5355497A (en) File directory structure generator and retrevial tool with document locator module mapping the directory structure of files to a real world hierarchical file structure
US5847707A (en) Icon menu display devices and methods
US6031537A (en) Method and apparatus for displaying a thought network from a thought&#39;s perspective
US5206951A (en) Integration of data between typed objects by mutual, direct invocation between object managers corresponding to object types
US7200617B2 (en) Program for managing external storage, recording medium, management device, and computing system
Abowd et al. Giving undo attention
US6026416A (en) System and method for storing, viewing, editing, and processing ordered sections having different file formats
US6212541B1 (en) System and method for switching between software applications in multi-window operating system
US5625809A (en) Method for constructing a data structure which allows data to be shared between programs
US5999942A (en) Method and apparatus for enforcement of behavior of application processing systems without modifying application processing systems
US5867678A (en) Method and system for searching and retrieving specific types of objects contained within a compound document
US7660817B2 (en) System and method for representing content in a file system
US5384911A (en) Method of transferring programs from action oriented GUI paradigm to object oriented GUI paradigm
US5425140A (en) Method and apparatus for providing conditional cascading in a computer system graphical user interface
US7703036B2 (en) User interface for displaying selectable software functionality controls that are relevant to a selected object
US6592626B1 (en) Method and system in an electronic spreadsheet for processing different cell protection modes
US6918096B2 (en) Method and apparatus for displaying a network of thoughts from a thought&#39;s perspective
US6757867B2 (en) Method and system in an electronic spreadsheet for adding or removing elements from a cell named range according to different modes
US6449617B1 (en) Edit command delegation program for editing electronic files

Legal Events

Date Code Title Description
AK Designated states

Kind code of ref document: A1

Designated state(s): AM AT AU BB BG BR BY CA CH CN CZ DE DK EE ES FI GB GE HU JP KE KG KP KR KZ LK LR LT LU LV MD MG MN MW MX NL NO NZ PL PT RO RU SD SE SI SK TJ TT UA US UZ VN

AL Designated countries for regional patents

Kind code of ref document: A1

Designated state(s): KE MW SD SZ UG AT BE CH DE DK ES FR GB GR IE IT LU MC NL PT SE BF BJ CF CG CI CM GA GN ML MR NE SN TD TG

DFPE Request for preliminary examination filed prior to expiration of 19th month from priority date (pct application filed before 20040101)
121 Ep: the epo has been informed by wipo that ep was designated in this application
ENP Entry into the national phase in:

Ref country code: US

Ref document number: 1996 693261

Date of ref document: 19960927

Kind code of ref document: A

Format of ref document f/p: F

NENP Non-entry into the national phase in:

Ref country code: CA

REG Reference to national code

Ref country code: DE

Ref legal event code: 8642

122 Ep: pct application non-entry in european phase