WO1999035588A1 - System and method for managing administration of medicine - Google Patents

System and method for managing administration of medicine Download PDF

Info

Publication number
WO1999035588A1
WO1999035588A1 PCT/US1998/022830 US9822830W WO9935588A1 WO 1999035588 A1 WO1999035588 A1 WO 1999035588A1 US 9822830 W US9822830 W US 9822830W WO 9935588 A1 WO9935588 A1 WO 9935588A1
Authority
WO
WIPO (PCT)
Prior art keywords
data
patient
method
delivered
sub
Prior art date
Application number
PCT/US1998/022830
Other languages
French (fr)
Other versions
WO1999035588A9 (en
Inventor
Philippe Pouletty
Richard G. Hamilton
Stephen J. Rossi
Debra L. Mcenroe
Original Assignee
Sangstat Medical Corporation
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
Priority to US7110798P priority Critical
Priority to US60/071,107 priority
Priority to US14348398A priority
Priority to US09/143,483 priority
Application filed by Sangstat Medical Corporation filed Critical Sangstat Medical Corporation
Publication of WO1999035588A1 publication Critical patent/WO1999035588A1/en
Publication of WO1999035588A9 publication Critical patent/WO1999035588A9/en

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F19/00Digital computing or data processing equipment or methods, specially adapted for specific applications
    • G06F19/30Medical informatics, i.e. computer-based analysis or dissemination of patient or disease data
    • G06F19/34Computer-assisted medical diagnosis or treatment, e.g. computerised prescription or delivery of medication or diets, computerised local control of medical devices, medical expert systems or telemedicine
    • G06F19/3456Computer-assisted prescription or delivery of medication, e.g. prescription filling or compliance checking
    • GPHYSICS
    • G06COMPUTING; CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F19/00Digital computing or data processing equipment or methods, specially adapted for specific applications
    • G06F19/30Medical informatics, i.e. computer-based analysis or dissemination of patient or disease data
    • G06F19/32Medical data management, e.g. systems or protocols for archival or communication of medical images, computerised patient records or computerised general medical references
    • G06F19/324Management of patient independent data, e.g. medical references in digital format
    • G06F19/326Medication information, e.g. drug reference databases
    • GPHYSICS
    • G06COMPUTING; CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F19/00Digital computing or data processing equipment or methods, specially adapted for specific applications
    • G06F19/30Medical informatics, i.e. computer-based analysis or dissemination of patient or disease data
    • G06F19/34Computer-assisted medical diagnosis or treatment, e.g. computerised prescription or delivery of medication or diets, computerised local control of medical devices, medical expert systems or telemedicine
    • G06F19/3418Telemedicine, e.g. remote diagnosis, remote control of instruments or remote monitoring of patient carried devices
    • GPHYSICS
    • G16INFORMATION AND COMMUNICATION TECHNOLOGY [ICT] SPECIALLY ADAPTED FOR SPECIFIC APPLICATION FIELDS
    • G16HHEALTHCARE INFORMATICS, i.e. INFORMATION AND COMMUNICATION TECHNOLOGY [ICT] SPECIALLY ADAPTED FOR THE HANDLING OR PROCESSING OF MEDICAL OR HEALTHCARE DATA
    • G16H10/00ICT specially adapted for the handling or processing of patient-related medical or healthcare data
    • G16H10/60ICT specially adapted for the handling or processing of patient-related medical or healthcare data for patient-specific data, e.g. for electronic patient records
    • GPHYSICS
    • G16INFORMATION AND COMMUNICATION TECHNOLOGY [ICT] SPECIALLY ADAPTED FOR SPECIFIC APPLICATION FIELDS
    • G16HHEALTHCARE INFORMATICS, i.e. INFORMATION AND COMMUNICATION TECHNOLOGY [ICT] SPECIALLY ADAPTED FOR THE HANDLING OR PROCESSING OF MEDICAL OR HEALTHCARE DATA
    • G16H15/00ICT specially adapted for medical reports, e.g. generation or transmission thereof

Abstract

A method for managing doses of medication delivered to a patient is described. A computer system (101) receives dosage data and administration data that represent, respectively, times and quantities for taking a drug that are prescribed for a patient, and the times and quantities the drug is delivered to the patient. Based on the dosage and administration data, compliance information is generated and displayed, representing the degree to which a drug has been delivered in accordance with the dosage data. In one aspect, a calendar (126) in the form of a grid comprised of grid elements is displayed. Each grid element represents a period, such as a day in a month, and contains one or more icons. An icon's appearance indicates whether a particular dose was delivered properly, when a grid element is selected by a user, more detail is displayed about the administration of the drug for the respective day.

Description

SYSTEM AND METHOD FOR MANAGING ADMINISTRATION OF MEDICINE

RELATED APPLICATIONS

SYSTEM AND METHOD FOR MANAGING ADMINISTRATION OF MEDICINE

RELATED APPLICATIONS

This application claims priority from prior U.S. provisional application serial number

60/071,107 filed on January 12, 1998, entitled "Method and System for Monitoring Doses," which is incorporated by reference in its entirety as if fully set forth herein.

COPYRIGHT NOTICE

A portion of the disclosure of this patent document contains material that is subject to copyright protection. The copyright owner has no objection to the facsimile reproduction in paper copies by anyone of the patent document or the patent disclosure, as it appears in the Patent & Trademark Office patent file or records, but otherwise reserves all other copyright rights whatsoever.

FIELD OF THE INVENTION

The present invention relates generally to computer systems. The invention relates more specifically to managing administration of medicine, monitoring dosages of drugs given to patients, and the like.

BACKGROUND OF THE INVENTION

Monitoring dosages of drugs or medicines for patients requires communication among several levels. First, a physician must diagnose and prescribe a dosage for a patient. The medication must then be distributed accurately and, finally, the patient or a care provider must ensure that the dosages are properly administered to or taken by the patient.

For many reasons, ensuring that accurate dosages are delivered to a patient in a consistently timely manner can be difficult despite the importance of accurate administration in many instances.

Therefore, it is desirable to provide a method of automating the delivery of medicine and monitoring the delivery of medicine.

Moreover, special challenges are presented in managing patients who are taking more than one medication. Elderly patients on multiple medications may have difficulty keeping track of whether they have taken all their medications, when, and in what quantity. In the clinical setting, proper administration of multiple medications to acutely ill patients is challenging for care providers.

Thus there is a need to track multiple medications and multiple dispensing mechanisms, and to present data for all such dispensers in a report.

To facilitate the proper administration of medication and the tracking of when it is administered, medication dispensing devices are used. Conventional medication dispensing devices typically include a medicine container and an alarm mechanism which notifies a patient at the time intervals the dose(s) are due. Each time the patient opens the container, the device records the event and the time it occurred. One example of a conventional medication dispensing device is a jar with lid which incorporates an alarm mechanism and a recording mechanism. When the lid is removed, the recording mechanism records this event and the time it occurred. One drawback to conventional dispensing devices is that they do not control access to medicine or the quantities dispensed. Thus, there is little assurance that when a dispensing device is opened, the proper amount is dispensed. Another drawback is that once opened, the dispensing devices may be re-opened immediately. Thus a confused elderly patient, having forgotten the dose they just took, may take another far too soon.

Thus, there is further need for a system that controls dispensing times and amounts and which tracks those times and amounts.

SUMMARY OF THE INVENTION

The foregoing needs, and other needs and objects that will become apparent from the following discussion, are fulfilled by the present invention, which comprises, in one aspect, a method for managing doses of medication delivered to a patient. Generally, a computer system receives dosage data and administration data. The dosage data represents a drug prescription, and includes, but is not limited to, one or more times for taking the drug, the quantities in which the drug is to be taken by the patient, or a combination thereof. The administration data represents when and in what quantities each dose in a set of doses of the drug is actually delivered to the patient. Based on the dosage and administration data, compliance information is generated and displayed. Compliance information indicates the degree to which a drug has been delivered in accordance with the dosage data. The compliance information can be displayed in variety of forms. According to another aspect, a calendar in the form of a grid comprised of grid elements is displayed. Each grid element represents a period, such as a day in a month, and contains one or more icons. An icon's appearance indicates whether a particular dose was delivered properly. For example, a green square icon indicates that a dose was delivered on time, and a triangular red icon indicates that a dose was not delivered. When a user selects a grid element, more detail is displayed about the delivery of the drug for the respective day. In particular, a graphical object is displayed that contains one or more icons for each dose delivered in the day. An icon's position along an axis of the graphical object reflects when a dose was delivered.

According to another aspect, data is generated that specifies what portion of a set of doses was delivered properly. The data includes values that indicate what portions of the doses were delivered, and what proportion of doses were delivered on time.

According to another aspect, dosage data is transmitted to a dosage-dispensing device. The dosage data includes times and quantities to deliver a drug to a patient. In addition, data representing a lockout period may be transmitted. The dosage-dispensing device dispenses the drug to the patient in accordance with the data transmitted to it. BRIEF DESCRIPTION OF THE DRAWINGS

The present invention is illustrated by way of example, and not by way of limitation, in the figures of the accompanying drawings and in which like reference numerals refer to similar elements and in which: FIG. 1 is a block diagram illustrating a system for monitoring patient dosages. FIG. 2 is a flow chart illustrating steps for a computer-implemented method for monitoring patient dosages.

FIG. 3 is a flow chart showing steps for retrieving data that is used in a system for monitoring the administration of doses to a patient. FIG. 4 is flow chart showing steps for transmitting dosage information to a dosage- dispensing device.

FIG. 5 A is block diagram depicting a calendar in the form of a grid. FIG. 5B is a block diagram depicting a grid element and icons used to indicate patient compliance. FIG. 5C is a block diagram depicting a graphical object used to graphically represent when doses were delivered.

Fig. 6 is a block diagram depicting a histogram showing dosage scores over period of time.

DETAILED DESCRIPTION OVERVIEW

One embodiment is a system and method for substantially automating the administration of patient dosages, the monitoring of the delivery of doses, whether or not timely and whether or not accurate in amount, and the accumulation of data for individual patients representing administration data over an extended period of time. Another embodiment encompasses accumulation of data for each patient from a plurality of dosage dispensing devices, and the assimilation of such data into reports which may be either specific for the particular patient, or an accumulation of data for an entire range of patients. In this way, more accurate dispensing of doses is achieved, as well as more accurate monitoring to facilitate detection of whether prescribed doses are being properly administered to the patients.

A preferred embodiment provides a computer-implemented method for monitoring patient dosages by retrieving administration data, including times and amounts of medication prescribed for a patient, retrieving patient data, including times and amounts of medication delivered for the patient, determining evaluation data by analyzing the retrieved dosing and patient data to determine compliance of the delivered medication to the prescribed medication, and displaying the evaluation data.

The method may include one or more of the following features. Patient data, including administration data, may be received from an associated device over a communications line, from local memory, or from user input. The data may be accumulated to provide a basis for patient evaluation. The patient data may be transmitted to a dosage-dispensing device, which dispenses doses to the patient in accordance with the received patient data.

The evaluation data may be displayed in a variety of ways, including display in a patient administration report that may indicate compliance of the delivered doses to the prescribed dosages. In one implementation, the data retrieved may be viewed in a scrollable tabular grid, with displayed values for all medication events, and dates, times and dose sizes dispensed from the dosage dispensing device. In addition, non-medication events may be displayed, including "bottle replaced" or other ancillary but relevant data.

Additionally, evaluation data may be displayed in the form of a patient summary report which may, for example, include all information for a particular patient including name, ID, monitoring dates, drug, brand, and so on. In addition, a histogram may be prepared summarizing the patient's compliance, including calculation of a "compliance index" or similar quantification of the patient's overall compliance with the prescribed dosing plan. The evaluation data may be displayed for varying periods, such as a week, a month, or a shorter or longer period, and may be displayed in graphical form including options for displaying doses delivered, missed, or delivered but not within compliance parameters. The data may also be displayed in calendar form.

In many instances, patients undergoing treatment may have multiple dosage dispensers. In a manner similar to the single dispenser arrangement discussed above, data for each such dispenser can be tracked and presented in a merged patient summary report. Likewise, a summary of all patients may be provided which may provide, in either graphical or tabular form, any of the selected data including name, ID, compliance index, dosage, time of day, or any other field. Histograms may also be developed across the patient class.

Evaluation data may be provided in any suitable format, such as a data file or hard copy. For example, the data may be printed or transmitted to a remote facsimile machine. According to one embodiment, the delivery of doses of multiple patients is monitored.

In this embodiment, a preferred method comprises retrieving dosage data, including times and amounts of medication prescribed for a plurality of patients, retrieving patient data, including times and amounts of medication delivered for the plurality of patients, determining evaluation data by analyzing the retrieved dosing and patient data for the plurality of patients to determine overall compliance of the delivered medication to the prescribed medications, and displaying the evaluation data.

Another embodiment includes a memory device storing computer readable instructions for aiding a computer to implement a method for monitoring patient dosages such as that described above. Yet another embodiment provides a system for monitoring patient dosages including a computer implementing a method such as that described above.

MEDICINE ADMINISTRATION MANAGEMENT SYSTEM Embodiments of the invention may be implemented on special purpose electronic or data processing hardware, software applications running on general purpose hardware, or a combination of both. For example, an embodiment may be implemented in a dose administration system that includes a computer system running one or more application programs that provide functions for manipulating dosing and patient data, having access through appropriate communications links to remote devices.

FIG. 1 shows an illustrative system incorporating the present invention, including personal computer 101 running application software. Computer 101 has access to both dosage data and patient data. For example, as shown in FIG. 1, the computer 101 includes a communications link 105 that couples computer 101 to dosage dispensing device 110. The dosage dispensing device 110 may be, for example, the portable medication administration device described in U.S. Patent Application Serial No. 08/ 867,010 entitled Liquid Medication Dispenser Apparatus, filed on June 2, 1997 and naming as inventors Debra L. McEnroe, Robert A. Britts, Phillippe Pouletty and Ralph Levy, the entire contents of which are hereby incorporated by reference as if fully set forth herein. Dosage dispensing device 110 may be used to dispense, for example, an analgesic drug, opiate agonist or antagonist drug, or a immunosuppressive drug, such azathioprine, Tacrolimus, Sirolimus, mycophenolate, mofetil, and their chemical derivatives,.

A portable medication administration device is a device which may be transported with the patient outside a medical facility such as a hospital or doctor's office, and which delivers multiple doses to the patient without immediate supervision by a registered medical clinician. Such dispensers are typically used by, for example, physicians and pharmacists, to input dosage data.

Communications link 105 enables the dosage data to be recorded at locations remote from the monitoring system, such as at medical facilities where medications are prescribed.

In the illustrated monitoring system, the computer 101 retrieves information relating to the patient data from data stored on diskette 120 or in a mass storage device, such as the computer's hard disk drive 122. This data typically includes a record of doses delivered to the patient and is typically created by the patient or a caretaker. As with the dosage information, this information may be input at remote locations, such as at a patient's home or a location where the medication is administered.

Of course, dosage and patient data may also be provided by alternative methods. For example, the data may be input directly by a user through the computer keyboard 102. The computer 101 can save input and retrieve information by downloading to the diskette 120 or hard drive 122, or if appropriate, may initiate to medication dispenser and monitor 109 a communications link 107. Communications link 107 may use electrical, electromagnetic, optical signals, or other signals that may carry digital data. These signals are exemplary forms of carrier waves transporting information.

Application software running on the computer 101 processes the dosage and patient data to determine monitoring information for patients. The monitoring information is provided to a user in the format of, for example, patient summary reports and graphs 124, event calendars 126, and summaries of groups of patients 128. The monitoring information can also be provided in hard copy via printer 130 or fax 132 through appropriate communication links. Computer 110 may transmit data to dosage dispensing device 110 via communications link 105. The data may include times and quantities to administer a drug to a patient, and a value representing a lockout period. Dosage dispensing device 110 delivers a drug in accordance with the received data. In one embodiment, computer 101 is a personal computer having an Intel or AMD- type processor and running the Microsoft® Windows 95 or Windows NT operating system, and equipped with volatile memory such as RAM and non- volatile memory such as a hard disk. A display device such as a CRT also forms part of computer 101. MONITORING ADMINISTRATION OF MEDICINE TO A PATIENT

FIG. 2 is a diagram of a method of monitoring the administration of medicine to a patient. In one embodiment, the method of FIG. 2 is implemented in one or more application programs that are executed by computer 101.

At block 202, a computer such as personal computer 101 of the system of FIG. 1, begins execution of the application software. As shown in block 210, computer 101 retrieves dosage and patient data for a patient from stored data. As indicated by block 212, the steps of block 210 may involve retrieving previously stored data files from a mass storage device such as disk drive 122.

Alternatively, computer 101 may establish an appropriate communications link, such as a modem or ISDN line, to retrieve data from a remote device, such as the portable medication administration device illustrated in FIG. 1 and described in the above-referenced U.S. Patent Application Serial No. 867,010, filed June 2, 1997 and entitled Liquid Medication Dispenser Apparatus, previously incorporated by reference. In this alternative case, as indicated in block 214, the dispensing device 110 is connected to the computer 101 and prepared for communication with the computer.

At block 220, dosage and medicine administration information for a patient is reviewed. Specifically, updated patient data is processed by the application software and displayed as requested by a user. The application software may be adapted to manipulate the dosage and patient information as needed. For example, the software may monitor the dosages delivered to patients by recording times and amounts of doses taken by a specified patient, as indicated by the retrieved patent data. With access also to the dosage information for that patient, the software may determine, for example, compliance of a patient's delivered doses with the prescribed doses, either for specified dose times or over a period of time.

Block 220 may involve generating one or more reports, as shown by block 224. For example, the method may be used to generate calendars showing the dosing events indicating, for example, the times of prescribed doses for specific patients and whether the patient complied with those doses. The method may also generate summary reports and graphs reflecting the progress of treatment for specific patients, incorporating, for example, test results. Additionally, the method may generate summary reports for groups of patients, such as groups of patients taking the same medication or groups of patients of a specific physician. The analyzed results may be stored and may be provided to a user. For example, the method may display the results on a computer monitor. Alternatively, as indicated in block 222, the computer 101 may provide hard copies of reports by printing to a printer or transmitting the results to a remote facsimile machine. Optionally, as shown by block 230, the data is saved after it is reviewed. As indicated by block 232, the data is saved to the mass storage device from which it was retrieved. Alternatively, as indicated in block 234, computer 101 may clear the memory of an external device from which the data was received and save a new copy of the data, or modify appropriate parameters of the external device. A pre-defined format is used. For example, data read from the device 110 may be saved as one or more comma-delimited ASCII files on disk 122. Use of such a format enables the data to be human-readable, and allows the data to be imported into commercial, off-the-shelf application programs such as spreadsheets or word processors. In one embodiment, the data is saved with a validation code that is computed at the time the file is saved. Whenever a saved data file is reopened, the code will be used to test and guarantee the validity of the data against corruption of the data or intentional modification by any means outside of the program. In a preferred embodiment, a relational database system such as the Microsoft Access Jet Engine is used for storing and retrieving all data. At block 240, the operational sequence is complete.

RETREIVING PATIENT DATA - INCLUDING DOSES AND TIME DELIVERED FIG. 3 illustrates an embodiment of a method of retrieving data. FIG. 3 illlustrates substeps involved in block 210 of FIG. 2 in greater detail.

At block 304, the computer system receives a request to read device data. For example, block 304 may involve receiving a request to read "current patient data" that is stored in the dispensing device 110. The request may be generated in response to, for example, a user selecting a program menu option in a graphical user interface ("GUI").

As shown by block 320, the system determines whether dosage or patient data for the requested patient already exists and has not been saved since a prior retrieval operation. If patient data for the requested patient already exists in memory and has not been saved during a prior retrieval, then in block 324, the system displays a prompt message to the user. The prompt message enables the user to select (1) canceling the request to retrieve patient data from the device, or (2) saving the prior data before continuing with the process of retrieving current patient data from the dosage-dispensing device. If the user chooses to cancel the request to retrieve the current patient data, then execution ends. If the user chooses to save the already existing data, then control flows to block 328, where the data is saved in a user specified file. Block 328 may involve displaying a dialog box or prompt to the user that requests the user to enter a file name or pathname. Control then flows to block 330.

At block 330, the current patient data is retrieved from the dosage-dispensing device and stored in a temporary buffer. The temporary buffer may be, for example, a temporary disk file or a buffer area in memory. At block 334, the data is checked to determine whether any transmission or data errors occurred during transmission from the dosage-dispensing device. For example, an 8-bit checksum algorithm can be applied to data received from a dispensing device 110 to detect errors. Such checksums are conventionally included by the dispensing device 110 in data that it transmits to computer 101. If any errors are detected, then at block 338, a message to the user is displayed, informing the user that errors exist in the data, and execution ends. If no transmission errors are detected, then control flows to block 340.

As indicated by block 340, the disk or other storage device is checked to determine whether any prior patient data for the patient has been retrieved and stored. If previous data has been retrieved from the device, then control flows to block 344. In this case, as shown by block 344, data for the patient is updated by merging the current patient data with the prior data. The merged data is stored in memory. A message is displayed informing the user that the merge has occurred.

As shown by block 348, the current data is stored. Alternatively, the merged data is stored, if merged data was created at block 344. The user interface is updated to reflect the addition of current patient data.

At block 360, a device retrieval dialogue is displayed, which is data about the just retrieved patient data. Such data can include patient name, the drug(s), prescribed doses per day, and the administration times. TRANSMITTING DOSAGE DATA TO DOSAGE DISPENSING DEVICE

In one embodiment, computer 101 transmits dosage data to dosage dispensing device 110. The dosage data is used by dosage dispensing device 110 to control the dispensing of medicine. The dosage data may represent medicine to deliver, administration times, quantities, and a lockout period. A lockout period is a period of time that must elapse after dispensing a dose before another dose may be administered or delivered to the patient. The dosage data may specify medicines that include, for example, an analgesic drug, opiate agonist or antagonist drug, or a immunosuppressive drug. An example of a dosage dispensing device that receives data specifying administration times and quantities and a lock out period, and then which operates in accordance to such data, is the portable medication administration device, described in U.S. Patent Application Serial No. 867,010, filed June 2, 1997 and entitled Liquid Medication Dispenser Apparatus, previously incorporated by reference.

The ability to transmit data to a dosage device that dispenses medicine accordingly provides significant advantages. The amounts of medicine that are actually dispensed to the patient may be controlled, and premature administration of doses may be prevented. FIG. 4 is a diagram of a method of collecting dosage data from a user, such as a physician or other clinician, and transmitting the dosage data to a dosage dispensing device.

As shown by block 410, a request is received from a user to enter dosage data. The request may be generated in response to a user selecting a program menu option in a GUI. As indicated by block 420, current dosage data for the patient is retrieved from stored data. At block 430, a data entry screen or dialog box is displayed, showing the current dosage data as the default data.

As indicated by block 440, dosage data is received from the user. The dosage data includes prescribed administration times and quantities and a lockout period. For example, the user enters the following information: Number of Doses Quantity and Unit

Times for Each Dose

Lock-out Period

As shown by block 450, the dosage data is transmitted to a dosage dispensing device, such as device 110 shown in FIG. 1. At block 460, the dosage data is stored in a mass storage device of a computer system, for example, hard disk 122 of computer 101.

In an embodiment of the present invention, the application software may be adapted to analyze additional data. This may include device monitoring data, such as the time a drug bottle was changed, temperature monitoring data, battery status, times data was downloaded from a dosage dispensing device, data identifying the bottle of the drug, such as data read from a bar code. Patient data may include test results measured at specified times to measure the effect of the administered dosages, or information on multiple drugs dispensed by a dosage dispensing device. Dosage data may include proper dosages of specified medications, as well as an indication of possible side effects and information regarding whether the dosage should be altered should those side effects be detected. In such a case, the application software may be adapted to provide an analysis of the effectiveness of the administered dosage.

EXEMPLARY GENERATION OF COMPLIANCE INFORMATION

To help determine whether a patient is administering a drug properly, compliance information is generated and displayed to a user. The system may display such compliance information in many forms. For example, the system may display a calendar that indicates whether particular doses were delivered properly. As another example, the system may display one or more compliance indexes, such as the percent of daily doses delivered or the percent of doses delivered on time. The compliance information may be generated by, for example, a computer system executing a computer program according to the source code set forth in the Appendix.

CALENDAR SHOWING PATIENT COMPLIANCE

FIG. 5A is a block diagram depicting a calendar 500. In the preferred embodiment, one or more calendars 500 are displayed to graphically convey user compliance information on a computer display, or other output device such as a printer. Calendar 500 of FIG. 5 A comprises a grid 502, which includes one or more grid elements 520. Each grid element 520 represents a particular day of the month, and may contain one or more icons 521 for each dose due on the particular day. The calendar 500 may also include a legend 523 that identifies each icon 521 with a descriptive label. Thus, each calendar 500 provides a snapshot display to the user of the dosages due for a particular patient throughout a particular month.

FIG. 5B shows grid element 520 in greater detail. Grid element 520 of FIG. 5B pertains to the second day of a particular month, as indicated by the numeric day value 540. Grid element 520 includes one or more icons 521 selected from among a new dosage icon 522, wrong time icon 524, on-time icon 526, and missed dose icon 528. The particular icons 521 that appear in a particular grid element 520 depend upon the content of the data previously entered for the patient by the user.

New dosage icon 522 is displayed so that it reflects the day the dosage was changed, as specified by, for example, dosing data retrieved from a dosage dispensing device 110. The new dose size may be displayed within new dosage icon 522. For example, new dosage icon

522 may include text showing that the dosage is "250 mg".

Preferably, wrong time icon 524, and missed dose icon 528 each are displayed with different patterns that indicate whether a dose was delivered properly. For example, wrong time icon 524 is a square shaped icon that is displayed in a first color, such as brown or tan, and is displayed for a dose that was delivered at the wrong time. A dose is delivered at the wrong time if it was delivered to the patient at a time outside the scheduled administration time.

Similarly, on-time icon 526 may be a green colored icon, and is displayed for a dose that was delivered on time. A dose is delivered on time if it was delivered to the patient within the scheduled administration time.

Missed dose icon 528 is a circular icon displayed, for example, in red, and has a thick border. The missed dose icon 528 indicates that a patient failed to take a scheduled dose.

The colors and shapes of the icons 521 disclosed herein are not required and are not important. What is important is that a wrong time dose, on time dose, and missed dose each are represented by a unique icon or symbol. In addition, another row of icons can be displayed in each grid element to indicate the number of doses due, each icon representing a scheduled dose for a day.

In one embodiment, each of the grid elements in grid 520 are graphical user controls. A user may cause the computer to display more information about a particular day reflected in grid 502 by manipulating the day's respective grid element. For example, a user, using mouse 103 as an input device, moves a mouse cursor of calendar 500 onto the day's respective grid element and then clicks the mouse. In response, computer 101 displays a graphical time line with icons positioned to reflect when the drug was delivered.

FIG. 5C depicts an exemplary graphical time line. Time line 550 is a graphical image having a horizontal length that reflects one 24-hour day. One or more icons 562 each represent a dose delivered for a particular day. Each of the icons 562 are displayed along the horizontal axis 564 of time line 550 so that their respective positions along the horizontal axis of time line 550 reflects when they were delivered. One or more hour labels 566 indicate the time at which a dose was delivered. For example, icon 562 represents a dose that was delivered at approximately 8:00 a.m., as indicated by hour label 568.

In one embodiment, icons 562 may include icons for missed doses. Such icons may be displayed using a different pattern than those used to represent doses delivered on time. In addition, icons representing doses delivered at the wrong time can be displayed using a third pattern. COMPLIANCE INDEXES

Compliance information can also be provided in the form of compliance indexes. A compliance index is a set of one or more values that reflects the degree to which the actual delivery of a drug complies with the prescribed administration. A variety of compliance indexes may used.

For example, the compliance indexes may include a dosage-on-time index. The dosage-on-time index reflects the percent of doses that were delivered to the patient on time in a given period. For example, assume that a drug is prescribed to be administered three times a day, at 7:00 a.m., 3:00 p.m., and 11 :00 p.m., plus or minus an hour. If for a given day the drug is in fact delivered twice at 8:00 a.m. and 6:00 p.m., then the dosage-on-time index for the day is thirty-three percent (33%).

A dose-per-day index reflects the percentage of prescribed doses that were at least delivered in a given period. In the previous example, the dose-per-index would be sixty-six percent (66%) because two out of three doses were delivered in the day. A unit-per-day-index reflects what portion of the amount of a drug prescribed for a day was delivered to the patient. For example, 2000 mg may be prescribed, but 2200 mg may be delivered to the patient. Thus, the unit-per-day-index would be 110%.

The user may specify the period covered by a compliance index in a variety of ways. For example, a graphical user control list box may provide selectable list box items which each represent a period for which to generate a compliance index. One list box item specifies the last week, another the last two weeks, and another the previous month. In addition, the graphical user control text boxes can be configured to accept the beginning and end dates of a period.

Also, various techniques may be used to display compliance indexes to the user. Each index can be displayed as a numeral, or a graphic, such as a horizontal bar. The length of the bar would represent 100 percent, and a position of an indicator along the length would indicate a percent.

One or more compliance indexes may be presented in the form of a weekly dosing graph, as shown in FIG. 5C, or in other graph forms, such as a line, area, and histogram graph. In addition, a GUI may present a graphical user control through which a user may select the form of the graph for displaying compliance indexes. For example, a GUI may display a graphical user control list box containing list box items for each graph form. By selecting one of the list box items, a user specifies a graph form for displaying a compliance index.

Fig. 6 shows a score histogram graph according to an embodiment of the present invention. Score histogram graph 600 displays patient dosing scores in the form of a graph of "Time Span" versus "Score." The time span is selectable for a time range specified by the user. The score value represents a compliance index over, for example, the last 7, 14, 21, or 28 days, or a time span specified by the user.

Score histogram graph 600 contains one or more graphical bars, such as graphical bar 610. Each graphical bar is used to reflect a dosage score for a time period within the time span, such as a day. To measure the graphical bars, score histogram graph 600 includes graphical score scale 604. The height of the graphical bars together with graphical score scale 604 indicate a dosage score for a particular time period. Graphical bar 610 reflects a score of 66%. OTHER REPORTS Other reports can be generated based on the foregoing information.

In particular, a Patient Dosing Report is generated based on data retrieved from the dispenser device 110. The data is displayed in a scrollable tabular grid. Displayed values include all medication events, dates, times, and dose sizes that are retrieved from the dispenser. Other non-medication events that are reported from the dispenser device to the computer 101 can be displayed at the option of the user. For example, when a user replaces a bottle in the dispenser, the dispenser device 110 reports a "bottle replaced" event to the computer 101. Such events can appear in the Patient Dosing Report.

As another example, a Patient Summary Report is generated. The report includes a header containing complete patient information such as Name, ID, Monitoring Dates, Drug, Brand, etc.

A Patient Summary Report, based on the merged data created in block 344 of FIG. 3, can be generated. The report summarizes data downloaded from multiple devices for the same patient.

A Summary of All Patients report presents a summary of all patients in grid form. The grid includes Name, ID, and Score for each patient. The grid may be sorted by any column. The Score value may be selected based on Doses Per Day or Time Of Day.

Preferably, the system provides a Print Preview function whereby the user can view any pages on the screen before they are printed. PROGRAM STRUCTURE Embodiments of the methods described further below may be implemented, for example, in one or more computer programs developed using Microsoft Visual Basic®. Preferably, the programs provide a multi-document interface whereby a user may view multiple documents simultaneously within the program. For example, the calendar dialog and medication event data dialogs described herein may be viewed at the same time. In one embodiment, the program functions and method steps described above are organized in an application program using one or more pull-down menus, each of which has one or more menu options. Table 1 presents a hierarchy of menu options in one embodiment of such a program.

TABLE 1 - MENU OPTIONS FILE

New Open Save ... Save As ... Print Setup ... Print Preview ... Print ... Exit ... DEVICE Retrieve Dispenser Data

Program Dispenser VIEW

Dosing Data Dosing Calendar Reports & Graphs ...

HELP

About The application program may also provide confirmation dialogs that prompt the user to verify various functions, such as dosing, as they are performed and where appropriate. In the foregoing specification, the invention has been described with reference to specific embodiments thereof. It will, however, be evident that various modifications and changes may be made thereto without departing from the broader spirit and scope of the invention. The specification and drawings are, accordingly, to be regarded in an illustrative rather than a restrictive sense.

APPENDIX

CycloTech Medication Monitoring Program

SangStat Medical Corporation Produced by Glen Hamilton, Cyber Innovations Corporation

Code Listing From 3/19/98

/<£ Table Of Contents

General. bas 1

Comm.bas 26

Printing. bas 46

Fax. bas 57

Calendar.bas 61 frmMain.frrή ' __^ 76 frmSpiash.frm __^ 85 frn.l_ogin.frm 86 frmOptions.frm 88 frmAboutfrm 92 frmBrowser.frm 95 frmTip.frm ^^ 98 frmAIIPatients.frm 100 frmRecentDosingGraph.frm ^^ 106 frmDosingCalendar.frm 111 frmPatientDosingRptfrm 117 frmReadDeviceData.frm 122 frmPrintfrm 124 frmDeviceDiagnostics.frm 128 frmFaxStatus.frm 133 frmFaxSend.frm 134 frmFaxLog.frm 141 frmFaxEditGroups.frm 142 frmFaxEditLocations.frm 144 frmDevicelnitiaiize.frm 146 frmGetDateTime.frm 151

n Attπbute VB_Name = "modGeneral"

Figure imgf000020_0001
Option Explicit

'Declare DLL calls

Declare Function OSWinHelp% Lib "user32" Alias "WnHelpA" (ByVal hWhdS, ByVal HelpFileS, ByVal wCommand%, d Data As Any)

Declare Function GetPπvateProfilelnt Lib "kernel32" Alias "GetPπvatePro-lelntA" (ByVal IpApplicationName As Stπng, ByVal IpKeyName As V Stπng, ByVal nDefault As Long, ByVal IpFileName As Stπng) As Long

Declare Function GetPπvateProfileStπng Lib "kemel32" Alias "GetPnvateProfileStnngA" (ByVal IpApplicationName As Stπng, ByVal IpKeyName As Any, ByVal IpDefault As Stπng, ByVal IpRetumedStπng As Stπng, ByVal nSize As Long, ByVal IpFileName As Stπng) As •* Long

Declare Function WπtePπvateProfileStπng Lib "kernel32" Alias "WntePπvatePro-leStπngA (ByVal IpApplicationName As Stπng, ByVal .* IpKeyName As Any, ByVal IpStπng As Any By al IpFileName As Stππg) As Long

'Set up some tempcrsr/ buffers for getting strrgs 'row DL- calls

Public Const gιBufSιze102 = 102 se' size of input bufsr 'or smngs

Public gsTempBuf As Stπng Input biter ,'orstr.ngs icelned at program start)

Public giLatestOptionsTabSelected As Integer <eep racx of the tab that was last selected sy use' tgoes oacκ to it next time :t is

.* ooened! Public gsLastStartDateChosen As Stπng a staring p:ot date last selected by user

Public gsLastEndDateChosen As Stπng an enαng slot cate last selected bv user

Public gsLastDateSet As Stπng a 'awp stnng used to pass dates back and tcrthe io the calendar

Public gsDateDisplayFor at As Stππg noids the user's cnαce for the displayed data format for αaiogs ana reports

Public gsTimeDisplayForm at As Stπng holds the users cnoice for the displayea time format for dialogs and reports

Public gsCustomLblPatientLastName As Stππg replacement labels tor the dialogs if exist in config file

Public gsCustomLblPatientFirstName As Stππg replacement laαals for the dialogs if exist in config file

Public gsCustomLblPatientID As Stπng Public gsCustomLblTxCenter As Stπng Public gsCustomLblDrug As Stπng Public gsCustomLblOrgan As Stπng Public gsLabelGridColumnCustoml As Stπng Public gsLabelGπdColumπCustom2 As Stnng Public gsLabelGπdCoiumnCustom3 As Stπng

'This value is stored in αevice & indicates the version of data structure within tr.e device 'This does not relate directly to the version of the host software because the host software 'version can change xwth meaning that the structure of the data in the device has changed 'This value should be increased when any kind of change occurs to the custom areas of the device 'such as changing the length of sinngs to accommodate nexv features The purpose of this value 'is to let us read it back from a device and determine if newer host software is being used on 'a device programmed with another version

Public Const gsREV_DATA_STRUCTURE = "01 "

Tήere are 4 Hetds in the device containing 16 characters each In the oπginal device design, this was intended to contain 4 sepeate pieces of information

'The length of each data type is as follows

Public Const gιlEN_REV DATA STRUCTURE = 2

Public Const gιLEN_PATIENT NAME = 26

Public Const giLEN ID = 11

Public Const giLEN~DRUG = 2

Public Const gιLEN~TX CENTER = 18

Public Const giLEN DFtGAN = 2

Public Const giMaxDose Times = 4 the ma-< nurr.ser of prescπbed dcsing time (entry ooxes) Public Const giDosesPerDayDefault - 2 Public gbPatientDataNotSaved As Boolean true once the data in memory has been saved (from devicel

Public gdTempDateTime As Double rg1' put this var in the term that uses it can also be cone Public giTempCya As Integer Public gfTempCreatinine As Single Public gsTempCustomlnfo As Stπng

Public gsActiveForm Name As Stπng

/ ? Public giCurrentTip As Integer 'most recent up number that xvas shown

Public gsWebStartlngAddress As Stππg 'urt address and any associated password for web site

Public Function ComputelniSectionChecksum(ByVal sFileSpec As String, ByVal sSection As Strinα)

'Read each line in the section name of an INI file mat was passed here 'Compute a unique value and pass pack to caller On Error GoTo 0 rgn temp

Dim ICheckSumTally As Long, r As Integer, I As Long, i As Integer, iKey As Integer Dim sLme As Stπng

'Ger the names of all ct the keys in this section

'A null Key field in above nr.e loacs ail keys in that section

Dim iStrSize As Integer, sTempBuf As Stπng, iBufSize As Integer

Dim sKeyLιst(200O) As Stπng make room 'o- this many ey names in this secαon sTempβuf = SpaceS(16384) iBufSize = 16384

I = GetPπvateProfileStπng(sSectιon, ByVal OS, "', sTempBuf, iBufSize, sFileSpec) r = ParseDelιmStπng(LeftS(sTempBuf, I), ChrS(O), sKeyLιst()) put the key names in a list

For iKey = 1 To r sϋne = GetlNISettιπg(sFileSpec, sSection, sKeyϋst(ι'Key), ~)

For i = 1 To Len(sϋne)

ICheckSumTally = ICheckSumTally + (Asc(Mid$(sLιne, i, 1)) * iKey)

Next I Next iKey ICheckSumTally = ICheckSumTally Mod 536870912 'a 29 bit number

CαmputelniSectlonChecksum = ICheckSumTally -pass result back to caller

End Function

Public Sub EventDelete(DataStruct As DeviceDataStruct, ByVal ilndex As Integer)

'Remove an event from the data structure. The index to the position is 'passed here.

Dim i As integer

'It is not a valid index

If ilndex < 1 Or ilndex > DataStruct.iEventData(O) Then Exit Sub all events up one + 1)

Figure imgf000021_0001

DataStrucUEventData(O) = DataStruct.iEveπtData(O) - 1 'decrement event count gbPatlentDataNotSaved = True set flag to indicate that the tile has changed but not yet been saved

End Sub

/? General bas - Eventlnsert

Public Sub Eventlnsert(DataStruct As DeviceDataStruct, ByVal ilndex As Integer, ByVal dDate As Double)

Insert a new event into the data structure at the index location passed here If the indef =0 then it prooaϋlv indicates that a previous function could not find where to insert the date m the structure In this case the event r-^s Le nse ed at the ϋeg-ining or the end of 'he structure depending or the date

Dim i As Integer

to ma <s room for new o-e

Figure imgf000022_0001

'Wow insert the new event

DataStruct.ιEventData(O) = DataStruct lEveπtData(O) + 1 increment event count

DataStruct byteEventType(ιlndex) = gιEVENT_USER_DEFINED

DataStruct.dEventDate(ιlndex) = dDate

DataStruct.sUserDatal (ilndex) = giTempCya put change in structure

DataStruet.sUserData2(ilndex) = gfTempCreatinine 'put change in structure

DataStruct.sUserData3(ilndex) - gsTempCustomlnfo put change in structure previous events unαl this one 0 DataStruct ιEveπtData(llndex - 1)

Figure imgf000022_0002
gbPatientDataNotSaved = True ser flag to indicate that the file has changed but not yet been saved

End Sub

Public Function FindPrescibedDoseSιzeForSpecificDay(DataStruct As DeviceDataStruct, ByVal IDate As Long)

'Find the prescπbed dose tor the day that is passed here

This is accomplished by looking for the most recent dose change event that occurred on or pnor to this date

Figure imgf000022_0003

Z ° General.bas - FindPrescibedDoseSizeForSpeα )ay

i DataStr.ict.icventDatali)

Figure imgf000023_0001

End Function

Public Function CalcDayDoseScore_OnTime(DataStruct As DeviceDataStruct, ByVal IStartingDate As Long) Aε

'Computer the dosing score for the day passed here

'This score tests to see it the dcsen taken was within the orescπsed time range

'Pass the score back to the caller as nearest χ.vr.cιe percent

'nndex is the index in the array where computation is to star..

'It snould already be sat to the first event that occurred on that day

Dim I As Long, i As Integer, iTotalDoses As Integer Dim ilndex As Integer, r As Integer

Figure imgf000023_0002

End Function

Public Function CalcDayDoseScore_AIIDoses(DataStruct As DeviceDataStruct, ByVal IStartingDate As Long) A

'Computer the dosing score for the day passed here.

'Calculate for all doses taken on that day regardless of if they were taken on time or not

'Pass the score back to the caller as nearest whole percent.

'ilndex is the index in the array where computation is to start.

'It should already be set to the first event that occurred on that day

Dim ITotalDoses As Integer, ilndex As Integer

iTotalDoses + 1

Figure imgf000023_0003

/ Geπeral.bas - CalcDayDoseScore_A-Dos<

End Function

Public Function CalcDosesSumTakenOnSpecificDay(DataStruct As DeviceDataStruct, ByVal IStartingDate As I

'Computer the dcsing total number of doses taken on a sceαtic date 'Nets this calculation does not take into consideration whether or net the dose 'was taken within the pres πbed time Tins is all doses for a particular dav 'P3ss the count back to the caller

Dim iTodayDoseCount As Integer, ilndex As Integer

iTodayDoseCount = iTodayDoseCount + 1

Figure imgf000024_0001

End Function

Public Sub EraseDatalnMemory(DataStruct As DeviceDataStruct)

Dim i As Integer

'clear out any data that may be in memory and initialize the arrays

DataStruct.sPatientLastName = ~

DataStruct.sPatientFirstName = ~

DataStruct.sPatientID = ~

DataStruct.sDrug = ~

DataStruct. sOrgan = ~

OataStruct.sTxCenter = ~

DataStruct.sSeπalNumber = ~

DataStruct.sFirm areVer = ~

DataStruct.sDoseSize = ~

DataStrυct.sPatientDataFileName = ~

For i = 0 To giMaxDoseTimes

DataStruct.dPrescπbedDoseTime(i) = -1 Next !

DataStπjct.iDosesPerDay = 0 DataStruct.sDoseResolution = ~ DataStruct.sMedRemaining = "

Erase Data Struct. sScore Data Erase DataStruct.iEventData Erase DataStruct.dEventDate Erase DataStruct.byteEventType 'erases all elements of a fixed array

Erase DataStruct. sUserDatal

Erase DataStruct.sUserData2 _^

^ ^ General bas - EraseDalaln emory

Erase DataStruct sUserData3

DataStruct IDevicelnitDate » 0 DataStruct sBatteryChangeTimer = ~ DataStruct sDoseLockoutHours = ~

DataStruct b Error Fata I = False DataStruct bErrorNoπFatal = False DataStruct bErrorOoseSize = False DataStruct bErrorMedRemaining = False DataStruct bErrorMemoryFull = False DataStruct bErrorsExist = False DataStruct bErrorBro nOut = False DataStruct dLastDownloadDate - 0 gbPatieπtOataNotSaved = False

End Sub

Public Sub Create TxtSummaryFileO

'This routine creates a temp text file in the 'tax" subdirectory This will allow the information to be taxed as a text document

Dim I As Integer, r As Integer, sFileSpec As Stπng, lErrorCode As Long

Dim sLDlName As Stπng, sLbilD As Stπng, sLblTxCenter As Stπng sLblDrug As Stππg sLblOrgan As Stπng

Ger πd of the previous temporary file sFileSpec - App Path * ΥaxesVemp txf sFileSpec » App Path + "\faxes\" + PAT_DATA sPatientLastName + " " + PAT.DATA sPatientFirstName + " " + PAT.DATA sPatientID + " t t" r = FileExιsts(sFileSpec, lErrorCode) If r Then Kill sFileSpec sLblName - gsCustomLblPatientLastName sLbilD = gsCustomLblPatientID sLblTxCenter = gsCustomLblTxCenter sLblDrug = gsC stomLblOrug sLblOrgan = gsCustomLblOrgan

Open sFileSpec For Output Shared As #1

Pπnt #1 , sLblName + " " + PAT DATA sPatientLastName + " " + PAT_DATA sPatientFirstName

Print#1, sLbllD + " " + PAT DA"TA sPatientID

Pπnt #1 , sLblTxCenter + " - + PAT_DATA sTxCenter

Print #1 , sLblDrug + " " + PAT_DATA sDrug

Pπnt #1 , sLblOrgan + " " ♦ PAT DATA sOrgan

Print #1,

Pπnt #1 , "Device Senal Number " + PAT_DATA sSeπalNumber

Print #1 , "Firmware Version " + PAT DATA sFirmwareVer

Pnnt #1 , "Last Download Date " + Fo7mat$(PAT DATA dLastDownloadDate, gsDateDisplayFormat)

Close #1 rgh ensure that the complete tile is pnnted

End Sub

^3

Figure imgf000026_0001

Function FileExists(ByVal sPath As Stπng, lErrorCode As Long) As Integer

' Check tor existence of a file by attempting an OPEN ' Petu true (-1) it exists eise return False id or error condition ' Note that since this function tnes to open a file an error could return to caller it file is there but in use by another apolication

Dim X As Integer

X = FreeFile

On Error Resume Next

Open sPath For Input As X

Close X

If Err = 0 Then

FileExists = True lErrorCode = 0 Clear error coce Else

FileExists = False set flag tor error lErrorCode = En- pass error back to caller End If

End Function

Public Function GetlNISettiπg(sFileSpec As String, sSection As String, sKeyField As String, sDefault As String

Dim lStrSlze As Integer, sTempBuf As Stπng, iBufSize As Integer sTempBuf - Space$(1024) iBufSize = 1024

IStrSize = GetPπvateProfileStπngfsSection, sKeyField, sDefault, sTempBuf, IBufSize, sFileSpec) « Tπm$(Lert$(sTempBuf, IStrSize)) = sDefault

Figure imgf000026_0002

End Function

Public Function GetPatientDataFromDisk(ByVal sFileSpec As String, DataStruct As DeviceDataStruct, lErrorRe

Get all of the patient data from the tile on dsk and place into memory 'The filename that is passed here must be a valid patient file and venfied 'by the calling procedure

Dim sSection As Stπng, I As Integer, sTemp As Stπng, r As Integer Dim IFileCheeksum As Long, ICheckSumTally As Long

On Error GoTo GetPa6entDataFromDιsk_Error

Read the file and calculate the checksum

IFileCheeksum = ComputelnιSectιonChecksum(sFιleSpec, "Device Data") ICheckSumTally = GetlNISettιng(sFileSpec, "General", "Device Data Validation", 0) _ If IFileCheeksum <> ICheckSumTally Then lErrorRetum = ERR_DATA_CHECKSUM Exit Function _ End If

IFileCheeksum = ComputelniSectionChecksumfsFileSpec, "Event Data") ICheckSumTally = GetlNISettingfsFileSpec, "General", "Event Data Validation", 0) _ If IFileCheeksum <> ICheckSumTally Then lErrorRetum = ERR_DATA_CHECKSUM Exit Function _ End If

<*¥ General bas - GelPatienlDataFromDisk

IFileCheeksum » ComputelnιSectιonChecksum(sFιleSpec, "Device Error Flags") ICheckSumTally = GetlNISettιπg(sFιleSpec "General", "Device Error Flags Validation", 0) If IFileCheeksum < ICheckSumTally Then lErrorRetum = ERR_DATA_CHECKSUM

Exit Function End If sSection = "Device Error Flags"

DataStruct bErrorFatal = CBool(GetlN!Settιng(sFιleSpec. sSection "Fatal", False))

DataStruct bErrorNonFatal = CBool(GetlNISettιng(sFιleSpec, sSection, "Non Fatal", False))

DataStruct bErrorDoseSize = CBool(GetlNISettιng(sFιleSpec, sSection, "Dose Size", False))

DataStruct bErrorMedRemaining = CBool(GetlNISettιng(sFιleSpec sSection, "Med Remaining", False))

OataStruct bErrorMemoryFull = CBool(GetlNISettιng(sFιleSpec, sSection, "Memory Full", False))

DataStruct.bErrorBrownOut = C8ool(GetlNISettιng(sFιleSpec, sSection, "Brownout", False)) sSection - "Device Data" EraseDataJnMemory DataStruct sTemp = GetlNISettιng(sFιleSpec, sSection, "Device Init Date", 0) If IsDate(sTemp) Then

A DataStruct IDevicelnitDate = DateValue(sTemp) End If sTemp = GetlNISettιng(sFιleSpec, sSection, "Events Ref Date Time", 0) If IsDate(sTemp) Then Z DataStruct dDevtceRefDateTime = DateVaiue(sTe p) End If sTemp = GetlNISettιng(sFιleSpec, sSection, "Last Download Date", "0") If lsDate(sTemp) Then

Z DataStruct.dLastDownloadDate = DateValue(sTe p) End If

DataStruct sPatientLastName = GetlNISettιng(sFileSpec, sSection, "Last Name", —j DataStruct.sPatientFirstName = GetlNISettιng(sFιleSpec, sSection, "First Name", "~) DataStruct.sPatientlD = GetlNISettιng(sFιleSpec, sSection, "Patient ID", "") DataStπjct.sTxCenter = GetlNISetting(sFιleSpec, sSection, Tx Center, "") I = Clnt(GetlNISettιng(sFιleSpec, sSection, "Organ Reference Number, "0")) If i And i <= UBound(gsOrganNames) Then DataStruct-sOrgan = gsOrganNames(f) I = Clnt(GetlNISettιng(sFιleSpec, sSection, "Drug Reference Number, "0")) If l And i <= UBound(gsDrυgNames) Then DataStruct.sDrug = gsDrugNames(ι) DataStruct.sSeπalNumber = GetlNISettιng(sFιleSpec, sSection, "Seπal Number, "") DataStructsFirmwareVer = GetlNISettιng(sFιleSpee, sSecbon, "Fiπnware Version", "") DataStnιct.sDoseSize = GetlNISettιng(sFιleSpec, sSection, "Dose Size", "") DataStruet.iDosesPerDay = Clnt(GetlNISettιng(sFιleSpec, sSection, "Doses Per Day", "0")) DataStruct.sDoseResolution = GetlNISetting(sFιleSpec, sSection, "Dose Resolution", "") DataStruct.sMedRemaining = GetlNISettιng(sFιleSpec, sSection, "Medication Remaining", ~) DataStπ ct.sBatteryChangeTimer = GetlNISettιng(sFιleSpec, sSection, "Battery Change Timer, ~) DataStruct.sDoseLockoutHours = GetlNISettιng(sFιleSpec, sSection, "Lockout Hours Between Doses", "")

For ι = 1 To 1

LZ DataStruct.sScoreData(l) = GetlNISettιng(sFιleSpec, sSection, "Patient Score Data " + CStr(i), "") Next i

For i = 1 To giMaxDoseTimes sTemp = GetlNISettιng(sFιleSpec, sSection, "Prescπbed Dose Time " + CStr(ι), "-1")

DataStruct dPrescnbedDose Time(ι) = -1 aβfautr value

If IsDate(sTemp) Then DataStruct dPrescrιbedDoseTime(ι) = CDate(sTemp)

Next i

DataStruct lEventData(O) = Clnt(GetlNISettιng(sFιleSpec, "Event Data", "Event Count", "0"))

Dim sTempϋst(10) As Stπng

For i = 1 To DataStruct lEventData(O) General.bas - GelPatientDataFromDisl sTemp = GetlNISettιng(sFιleSpec, "Event Data" CStr(i) ~) r ' ParseDellmStπngfsTemp, ",", sTempUst(J) DataStπιct.dEventDate(i) = CDate(sTempLιst(1))

- Select Case TπmS(LCaseS(sTempϋst(2)))

— Case "dose taken" DataStruct.byteEventType(ι) = giEVENT DOSE TAKEN DataStruct.ιEventData(ι) - sTempUst(3)~

— Case "dose change" DataStruct.byteEventType(ι) = giEVENT DOSE CHANGED DataStruct.ιEventData(ι) = sTempLιst(3)~

Case "custom event" DataStruct.byteEveπtType(ι) = giEVENT USER DEFINED DataStruct lEventData(ι) = sTempϋst(3)~

- End Select DataStruct.sUserDatal(ι) = sTempLιst( ) DataStruct.sUserData2(ι) = sTempLιst(5) DataStruct.sUserData3(ι) = sTempϋst(6)

Next I

bErrorFatal As Boolean true it this flag was set in the returned Hags stnng bErrorNonFatal As Boolean true if this flag was set in the returned flags stnng b rrorDoseSize As Boolean 'true it tms flag was set m the returned flags stπng bErrorMedRemaining As Boolean 'true if this flag was set in the returned flags stnng bξrrorMemoryFull As Boolean 'true if this flag was set in the returned flags stππg bErrorBrownOutA 3oolean 'true if this flag was set in the returned flags stnng

- ,„ °^m^-xιst s Soo/ean (■) byte) Bits are set if vaπous errors have occurred and have not

GetPatieπtDataFromDisk = True 'return success flag to caller

GetPatlentDataFromDιsk_Exιt: Exit Function

GetPatlentDataFromDisk Error lErrorRetum = Err Resume GetPatlentDataFromDisk Exit

End Function

Public Sub GetProgramPreferencesO load toe program and user preferences into the global vaπaoles

Dim IStrSize As Integer, I As Integer, sFileSpec As Stπng, r As Integer

Dim sSection As Stπng sSection = "Preferences" gsDateDisplayFormat = GetlNISettιng( sApplnιFileSpec, sSection, "Date Display Format", "Short Date") gsTimeDisplayFormat = GetlNISettιng(gsApplnιFileSpec, sSection, Time Display Format", "Short Time") gsngCompliaπceTimeRange = CSng(GetlNISettιng(gsApplnιFιleSpee, sSection, "Compliance Time Range", "2")) sSection = "Custom Settings"

'G't 'ny cust m field labels that may be in the INI file If none exist the set some defaults here gscustomLblPatientLastName = GetlNISettιng(gsApplnιFιleSpec, sSection, "Last Name Label", ~) if gsCustomLblPatientLastName = "Then gsCustomLblPatient stName = "Last Name"

?f S^t0["L .' ,l,,eπtFlratNamβ * Ge«NISettιng( sApplnιFileSpec, sSection, "First Name Label", ~) ir sCustomLblPatientFirstName = "" Then gsCustomLblPatientFirstName = "First Name" gsCustomLblPatientlD = GetlNISetting(gsApplnιFιleSpec, sSecbon, "Patient ID Label" -) it gsCustomLblPatientlD = - Then gsCustomLblPatientlD = "Patient ID" gsCustomLblTxCenter = GetlNISettιng(gsApplnιFιleSpec, sSection, "TX Center Label" ~) ir gsCustomLblTxCenter = "" Then gsCustomLblTxCenter = "TX Center gsCustomLblDrug = GetlNISettιng(gsApplnιFιleSpec, sSection "Drug Label" ~) If gsCustomLblDrug - - Then gsCustomLblDrug = "Drug"

<Z ζ General. bas - GetProgramPreferences

gsCustomLblOrgan = GetlNISettιng(gsApplnιFιleSpec, sSection, "Organ Label", "") If gsCustomLblOrgan = "" Then gsCustomLblOrgan = "Organ" gsLabelGndColumnCustomI = GetlNISettιπg(gsApplnιFιleSpec, sSection, "Grid Column 1" "") If gsLabelGndColumnCustomI = "" Then gsLabelGndColumnCustomI = "CYA Level (ng/ml)" gsLabelGπdColumnCustom2 = GetlNISettιng(gsApplnιFιleSpec, sSection, "Gπd Column 2", "") If gsLabelGπdColumnCustom2 = ~ Then gsLabelGπdColumnCustom2 = "Creatinine (mg/dl)" gsLabelGndColumnCustom3 = GetlNISettιng(gsApplnιFιleSpec, sSection, "Gπd Column 3", ~) If gsLabelGπdColumπCustom3 = ~ Then gsLabelGπdColumnCustom3 = "Custom"

of the file

)

Figure imgf000029_0001

'Get the Drug types from file and place in global list sSecton - Transplant Centers'

TxCenterstO) = GetlNISettng(gsApplnιFιleSpec. sSecbon. 'Counr O )

For! = 1 To TxCenters(G)

TxCenterst = GetlNISetOngfgsApplntFileSpec sSecbon CStr(ι>. O") Next i

from file and place in global list GetlNISettιng(gsApplnιFileSpec, sSection, "Count", "0") Names(O) = GetlNISettιng(gsApplnιFileSpec, sSection, CStr(i), "0")

Figure imgf000029_0002

sSection, "Count", "0") c, sSection, CStr(ι), "0")

Figure imgf000029_0003
giCurrentTip = Clnt(GetlNISettιng(gsApplnιFιleSpec, "Options", "Current Tip", 1))

'Get serftπgs of calendar form

CAL.DEFAULTS chkDosesMissed = CByte(GetlNISettιπg(gsApplnιFιleSpec, "Calendar Settings", "chkDosesMissed", 1))

CAL_DEFAULTS.chkDosesNotComplιed = CByte(GetlNISettιng(gsApplnιFιleSpec, "Calendar Settings", "ChkDosesNotComplied", 1))

**7

Figure imgf000030_0001

Gef Settings of Patient summary form

PAT_SUM_DEFAULTS cmboDataToView = CByte(GetlNISettιng(gsApplπιFιleSpec, "Patient Summary Settings", "cmboDataTo iew" 1 ))

PAT_SUM_DEFAULTS c boChartType = C8yte(GetlNISettιπg(gsApplnιFιleSpec, "Patient Summary Settings", "cmboChartType", 1))

Get fήe web address tor the brcwsei gsWebStartingAddress = "http //" gsWebStartingAddress = gsWebStartingAddress + GetlNISettιπg(gsApplπιFιleSpec, "Web Data", "User Name" "") + " " gsWebStartingAddress = gsWebStartingAddress + GetlNISettιng(gsApplπιFιleSpec, "Web Data", "Access", "") + "@" gsWebStartingAddress = gsWebStartingAddress + GetlNISettιng(gsApplnιFιleSpec, "Web Data ', "URL", "")

End Sub

Sub ain()

Dim I As Long, r As Integer, i As Integer, sMSG As Stπng, sTemp As Stππg, dTime As Double Dim bBrowserFound As Boolean, ILastAccessOate As Long, INextReminderDate As Long

'Initialize some application settings ni"

Figure imgf000030_0002
than true or false to properly initialize the dialog frmSplash.Show frmSplash.Refresh dTime a Now 'gef the ome value of now

Wait 0.75 frmLogin.Show vbModal

If Not frmLogin.OK Then End login Failed so exit app

Unload frmLogin

Do Events

'rgn note that the debug flag is turned on and the tax icon is hidden ' I = ShelKApp Path * "Ψaxman32 exe D H" 1) 'start the fax server I = ShellfFaxman32.exe /H", 1 ) 'start the tax server Load frmMaln Set gcFax = frmMain.FaxManl ϊf browser feature is turned on in the tm file then activate item on the menu

'See it we should allow access to visit Saπgstat on the Internet r = CBool(GetlNISetting(gsApplnιFileSpec, "Web Data", "Active", "False"))

If r = False Then frmMain.mnuAccessWebSite Visible = False 'no key found in mi fise

CommJnitializeCommPort 'initialize the co port from INI file settings GetProgramPreferences EraseDatalnMemory PAT.DATA EraseDatalnMemory TEM"P_DATA

'Set some menu items frmMain.mnuFileSave. Enabled = False frmSplash.ZOrder

Do

If CDbl(Now) > dTime + 0 00005 Then Exit Do Λait for a minimum amount of time before unloading splash screen

Do Events

Loop

Y

Figure imgf000031_0001

Unload frmSplash frmMain Show SetPπnterlcon False ""

See if we should shown ήps at startup r = C8ool(GetlNISettιng(gsApplnιFιleSpec "Options" "Show Tips at Startup" True))

If r Then frmTip Show

web

dy have web access available

"Medium Date")

Figure imgf000031_0002

End Sub

<* ! General.bas - LogonToWebSite

Public Sub LogonToWebSiteQ

'Visit Sangstat on the Internet 'Dim fr B As New trmBrowser •load trmBrowser frmBrowser.StartingAddress = gsWebStartingAddress DoEvents 'allow time to paint DoEvents 'allow time to paint frmBrowser.Refresh frmBrowser.Show End Sub

Public Function OpenPatientData(ByVal sFileSpec As String) As Integer

'Cpen patient data file and load to memory

'Return a true if load :vas successful false if not and voCancel it user cancelled

Dim r As Integer, sTemp As Stπng, lErrorCode As Long On Error GoTo OpeπPatιeπtData_Error r = ValidatePatientDataSaved 'make sure any cevice data has first oeen saved If r * vbCancel Then Exit Function

'Get a filename from the common dialog

'Setup the common dialog control pπor to howing it

With frmMaiπ.dlgCommonDialog

.Flags = cdlOFNOverwπtePrompt Or cdiOFNPathMustExist Or cdlOFNExplorer Or cdlOFNExtensionDlfferent Or cdlOFNNoReadOnlyRetum Or cdlOFNHideReadOnly Or cdlOFNFileMustExist

.CancelError = True CANCEL button is pressed

.InitDir = App.Path +

Figure imgf000032_0001

.Filter = "CycloTech Data File *.cpd|'.cpd"

.DlalogTitle = "Open Patient Data File"

.DefaultExt = "CPD" 'append 'Structure' extenbon when saving

If sFileSpec <> "" Then .filename = sFileSpec

.ShowOpen "Open dialog

End With

Wow gef fήe σafa from file frmMain.MousePointer = vbHourglass DoEvents

- " ♦ Error(r)

Figure imgf000032_0002

PAT_DATA.sPatιeπtDataFιleName = frmMain.dlgCommonDialog.filename

OpenPatientData = True r = GetFileNameFromSpec(PAT_DATA.sPatιentDataFιleName, sTemp) 'hold the name of the fiie

VpDateRecentFileUenu sFileSpec

UpDateRecentFileMenu sTemp frmMain. mnuFileSave. Enabled = True

OpenPatιentData_Exιt: On Error GoTo 0 RefreshAIIOpenFomis frmMain.MousePointer = vbDefault Exit Function

3 * General bas - OpenPatientData

was pressed in dialog

ta and can not be read ", vbExciamation, "Invalid Data File - " + Error

Figure imgf000033_0001

OpenPatientData = False

Resume OpenPatιentData_Exιt exit anyway for now

End Function

Public Sub PopulateDeviceDiagDialog(DataStruct As DeviceDataStruct, SourceForm As Form)

'There are two possible αaiogs that nave the same controls an tnsm 'This common procedure will populate both Dim i As Integer

With SourceForm 'Snow custom labels from conng file if there were any .Label1(3) = gsCustomLblPatientLastName .Labell (1) = gsCustomLblPatientFirstName .Labell (5) = gsCustomLblPatientlD .Labell (6) = gsCustomLblTxCenter .Labell (7) = gsCustomLblDrug .Labell (0) - gsCustomLblOrgan

If TypeOf .txtDrug Is SSPanel Then .txtDrug = DataStruct.sDrug

Elself TypeOf .txtDrug Is ComboBox Then 'It is a list box .bttDπjg. Clear For i = 1 To gsDrugNames(O) 'fill the drugs list box with available choices

L .txtDrug.Addltem gsDrugNames(i) Next I

For I = 0 To .txtDrug.ListCount - 1

If .txtDrug. Ust(l) = DataStruct.sDrug Then .txtDrug.Listlndex = i Exit For End If Next i End If

If TypeOf .txtOrgan Is SSPanel Then .txtOrgan = DataStructsOrgan

Elself TypeOf .txtOrgan Is ComboBox Then '// is a list box .txtOrgan. Clear For i = 1 To gsOrganNames(O) 'fill the drugs list box with available choices

LZ .brtOrgan.Addltem gsOrganNames(ι) Next i 1 .sOrgan Then

Figure imgf000033_0002

End If

.txtPatientLastName = DataStruct. sPatientLastName

3 / General. as - PopulateDeviceDiagDialog

.txtPatleπtFirstName » DataStruct sPatientFirstName .txtPatientID = DataStruct.sPatientlD .txtTxCenter = DataStruct.sTxCenter .bctSeπalNumber = DataStruct. sSeπalNumber .txtDoseSize = DataStruct. sDoseSIze

.txtPatientLastName.SetFocus

If DataStruct.ιEventData(O) Then

.txtEventCouπt = " " + CStr(DataStruct.ιEventData(0)) Else

.txtEventCount = ~ End If

For i = 1 To giMaxDose imes

If DataStruct.dPrescrιbedDoseTιme(ι) >= 0 Then .txtDoseTιme(ι) = Format$(DataStruct.dPrescπbedDoseTime(ι), gsTimeDispiayFormat) Next i txtDosesPerDay = CStr(DataStruct.iDosesPerDay) .txtDoseβesolution = DataStr ct.sDoseResclueon .txtDoseLockoutHours = DataStruct.sDoseLockoutHours If DataStrucUDevtcelmtDate Then

.txtDeviceStarted = " " + FormatJ(CDate(DataStruct.lDevιcelnιtDate), "Medium Date") End If

.txtMedlcationRemaining = " " + DataStruct.sMedRemaining .brtBatteryChangeTimer = " " + DataStructsBatteryChangeTimer .txtFirmwareVer = " " + DataStruct.sFirmwareVer

'sβf Indicators tor error flags If DataStruct.bError Fatal Then

.imgFatal.Picture = .imgError.Picture Else

.imgFatal.Picture = .imgNoError.Picture End If

If DataStrucLbE irNonFatal Then

.ImgNonFatal.Picture = .imgError.Picture Else

.imgNonFatal. Picture = .imgNoError.Picture End If

If DataStruct.bErrorDoseSιze Then mgDoseSize.Picture - .imgError.Picture Else

JmgDoseSize.Picture = .imgNoError.Picture End If

If DataStruct.bErrorMedRemaining Then JmgMedRemaining.Picture = .imgError.Picture

Else .imgMedRemaiπing.Picture - .imgNoError.Picture

End If

If DataStrucLbErrorMemoryFull Then

JmgMemoryFuil = .imgError.Picture Else

.imgMemoryFuli.Picture = .imgNoError.Picture End If

If DataStruct.bErrorBrownOut Then

.imgBrowπOut = .imgError.Picture Else

.ιmgBrownOut.Pιcture = .imgNoError.Picture End If

End With

3^ General. bas - PopulateDeviceDiagDialog

End Sub

Public Sub RefreshAIIOpenFormsO

Dim r As Integer

'If any of these forms are open at the time a new file is loaded then refresh them

Date = CVDate(PAT_DATA.

Figure imgf000035_0001

End Sub

Public Sub SetPriπterlcon(bEnable As Boolean, sTip As String)

On Error Resume Next frmMaiπ.mnuFilePπnt.Enabled = bEnable

Figure imgf000035_0002

'If the active tor is not the pnnt form, then keep the name of the 'form in the key property of the icon This is so that the pπnt 'form will know what kind of information to display and pnnt

If frmMain.ActiveForm.Name <> "frmPπnt" Then gsActiveFormName * frmMain.ActiveForm.Name On Error GoTo 0 End Sub

Figure imgf000036_0001

Public Sub UpDateReceπtFile enu(ByVal sFileSpec As Stπng)

Add the newest FileName to the menulist and move the other ones down On Eπ-or GoTo 0

Dim bDuplicateFound As Boolean i As Integer r As Integer sFileName As Stππg r = GetFιleNameFromSpec(sFιleSpec, sFileName) hold the name of the file

With frmMain = LCaseS(sFιleName) Then remove a-j c„jιιc3tes tha' might appear

Figure imgf000036_0002

'or αsplay purposes

Figure imgf000036_0003
mnuFιleMRU(l) Tag = sFileSpec mnuFileMRUO ) Caption = sFileName mnuFileMRUO ) Visible = True mnuFileBarβ Visible = True

End Sub

Public Function GetFileNameFromSpec(ByVal sFileSpec As String, sFileName As String) As Integer

'Stnp the filename and extenαon from the filespec (dπve\path\filenamel

Dim r As Integer

ReDi sϋst(50) As Stπng

On Emir GoTo GetFιleNameFromSpec_Error delimit all subpaths name is last item in list pec = True return success fo caller

Figure imgf000036_0004

GetFιleNameFromSpec_Exιt Exit Function

GetFιleNameFromSpec_Error "Resume 0 Resume GetFιleNameFromSpec_Exιt

End Function

44 General. as - ParseDelimSlring

Public Function ParseDeiimString(ByVal sParse As String, ByVal sDelim As String, sFieldStrings() As String)

'Parse "sParse" passed here Put resulting parsed names in a list called sFieldStnngs

'Use sΩβitm as the delimiter to parse stnng.

'Tnm any leading and trailing spaces tram each field srieldStnng list must pre-exist before calling here and should oe big enough to

'hold all delimited stπngs

'The list contains fields in the order they apcearec from lert to ngnt

'Function returns number of fields found

Dim i As Integer Voop counter

Dim iDeli l As Integer, ιDelim2 As Integer marks begπnmg and enc of a fielα Exit Function 'exit if no chars :n stnng 'sef first deiim marker to begnmng of tine elim)) <■> sDelim Then see if a delim is aireadv at the end of the stnng elim 'put a delim at end of line

Figure imgf000037_0001

'Note, an Erase method can not oe used as it redims the array to only a few elements 0 To UBound(sFieldStπngs) 'clear out aid data from the array ldStπngs(i) = ~

Figure imgf000037_0002

1 = 0 _ Do While iDeliml < Len(sParse) 'keep looking til all delims are found iDenm2 = lnStr(IDelιm1 + 1 , sParse, sDelim) VooA- for delim in stnng 'get field from stnng tnm off spaces and put field into list sFieldStπngs(l + 1 ) = TπmS(Mιd$(sParse, iDeliml + 1 , iDelim2 - iDeliml - 1 )) iDelim 1 = iDelim2 Vesef first delim marker to lastest one found i = i + 1 'increment field counter

— Loop 'repeat search

ParseDelimStπng = i 'put parsed items count in element 0 of list

End Function

Public Function SaveDataToNew File() As Integer

'Gef a filename from the common άalog

'Setup the common dialog control pπor to showing it

On Eπ-or GoTo SaveOataToNewFile_Error With frmMain.dlgCommonDiaiog

.Flags = cdlOFNOverwπtePrompt Or cdlOFNCreatePrompt Or cdiOFNPathMustExist Or cdlOFNExplorer Or CdlOFNExtensionDlfferent , Or cdlOFNNoReadOnlyRetum Or cdlOFNHideReadOnly

.CancelError = True generate error it CANCEL button is pressed

.InitDIr = App.Path + "\Patient Data"

.Filter = "CycloTech Data File -.cpd|\cpd"

.DialogTitlβ = "Save Patient Data As..."

.DefaultExt = "CPD" 'append 'Structure' extenύon when saving If PAT DATA.sPatιentDataFileName = - Then

.filename - PAT_DATA.sPatιentLastName ♦ " " + PAT_DATA.sPatιentFιrstName + " " + PAT_DATA.sPatιentlD + ".cpd" 'set a

, default tile name Else

.filename = PAT DATA.sPatientDataFileName End If

.ShowSave save as dialog End With

PAT_DATA.sPatιentDataFileName = frmMain.dlgCommonDiaiog. filename SavePatientData PAT_DATA sPatientDataFileName SaveDataToNewFile = True

SaveDataToNewFiie_Exιt: Exit Function

SaveDataToNewFile_Error:

s- General bas - SaveDataToNewFile

_ If Err = cdlCancel Then cancel button was -ressed in dialog

SaveDataToNewFile = vbCancel Resume SaveDataToNewFile Exit _ End If

SaveDataToNewFile = False

End Function

Public Function SavePatιentData(ByVal sFileSpec As String) As Integer

Save all of the patient data currently in merrorj to a disk file

Retun a true tf save was successful false if net and vbCancel f user cancelled

Dim sTemp As Stnng r As Integer i As Integer sSection As Stnng Dim ICheckSumTally As Long

On Error GoTo SavePatιentData_Error

' = GβtFιieNameFror-Spec{fmMaιr dlgCcmmo-Dialog llsnar-e sTemp) save the αr was selected ύJ user

We need to conffm wifi user that it is desired Ό save these file modifications under tte same name as the one tha' was just loaded

If LenftrmMain dIgCommonDialog filename) And frrrMa i dIgCommorDialog filename = UCaseliFroi sStructFileName) Then ■ MSGS - 'You are about to save changes to the same file they were loaded from1' MSGS - MSGS + " Are you sure you want to do this7' Beep r = Msgβox(MSGS MB_YES_NO 'Confirm Over Wπte")

It r = ID NO Then Exit Function oops user almost made mistake exit sub

End If

Now save the data to the file r - GetFileNameFromSoecfsTemp sFileSpec) hold the name of the file sFil Spec = App Path & "\Patlent Data" frmMain MousePointer = vbHourglass DoEvents sSection = "Device Data"

SavelNISetting sFileSpec, sSection, "Date Saved To File", Now

SavelNISetting sFileSpec sSection, "Host Software Version" CStr(App Major a " " a App Minor a " " App Revision) SavelNISetting sFileSpec, sSection, "Firmware Version" PAT_DATA sFirmwareVer

SavelNISetting sFileSpec sSection, "Last Download Date", CDate(PAT_DATA dLastDownloadDate) snort dare must be used to prevert

, error when loading back

SavelNISetting sFileSpec sSection, "Device Init Date" CDate(PAT_DATA IDevicelnitDate)

SavelNISetting sFileSpec, sSection, "Events Ref Date Time", CDate(PAT_DATA dDeviceRefDateTime)

SavelNISetting sFileSpec, sSection, "Last Name", PAT.DATA sPatientLastName

SavelNISetting sFileSpec sSection "First Name", PAT~DATA sPatientFirstName

SavelNISetting sFileSpec, sSection, "Seπal Number P.AT_DATA sSeπalNumber

SavelNISetting sFileSpec, sSection, "Patient ID", PAT_DA? A sPatientID

SavelNISetting sFileSpec, sSection, "Organ", PAT_DATA sOrgan

SavelNISetting sFileSpec, sSection, "Organ Reference Number CStr(Ge(OrganRefNumber())

SavelNISetting sFileSpec, sSection, Tx Center PAT_DATA sTxCenter

SavelNISetting sFileSpec sSection "Drug" PAT.DATA sDrug

SavelNISetting sFileSpec, sSection "Drug Reference Number CStr(GetDrugRefNumber())

SavelNISetting sFileSpec sSection "Dose Size" PAT_DATA sDoseSize

SavelNISetting sFileSpec sSection "Doses Per Day" "cStr(PAT_DATA iDosesPerDay)

SavelNISetting sFileSpec sSection "Oose Resolution" PAT_DATA sDoseResolution

SavelNISetting sFileSpec sSection "Medication Remaining" PAT_DATA sMedRemaining

SavelNISetting sFileSpec sSection "Battery Change Timer PAT_DATA sBatteryChangeTimer

SavelNISetting sFileSpec sSection, "Lockout Hours Between Doses" PAT_DATA sDoseLockoutHours

For i = 1 To 1<t

SavelNISetting sFileSpec sSection "Patient Score Data " + CStr(ι) PAT DATA sScoreData(ι) Next I

For i = 1 To giMaxDose Times If PAT_DATA dPrescπbedDoseTime(ι) >= 0 Then

Figure imgf000038_0001
General bas - SavePatientData

sSection, "Prescπbed Dose Time " + CStr(ι), FormatS(PAT_DATA dPrescπbedDoseTime(i), sSection "Prescπbed Dose Time ' ♦ CStr(ι), " None"

Figure imgf000039_0001

'This section is Imsned Go compute the checksum and save it ICheckSumTally = ComρutelnιSectιonChecksum(sFιleSpec sSection) SavelNISetting sFileSpec, "General", "Device Data Validation ' CStr(ICheckSumTally)

Figure imgf000039_0002

This section is finished Go compute the checksum and save it ICheckSumTally = ComputelnιSectιonChecksum(sFileSpec, sSection) SavelNISetting sFileSpec, "General", "Event Data Validation", CStr(ICheckSumTally) sSection = "Device Error Flags"

SavelNISetting sFileSpec, sSection, "Fatal", CStr(PAT_DATA.bErrorFatal)

SavelNISetting sFileSpec, sSection, "Non Fatal", CStr(PAT_DATA.bErrorNonFatal)

SavelNISetting sFileSpec, sSection, "Dose Size", CStr(PA"f.DATA.bErrorDoseSιze)

SavelNISetting sFileSpec, sSection, "Med Remaining", CStr(PAT_DATA.bErrorMedRemaιnιπg)

SavelNISetting sFileSpec, sSection, "Memory Full", CStr(PAT_DATA.bErrorMemoryFull)

SavelNISetting sFileSpec, sSection, "Brownout", CStr(PAT_DATA.bErrorBrownOut)

'77ι;s secftoπ is finished Go compute the checksum and save it

ICheckSumTally = ComputelπιSectιonChecksum(sFιleSpec, sSection)

SavelNISetting sFileSpec, "General", "Device Error Flags Validation", CStr(ICheckSumTally) gbPatientOataNotSaved = False r * GetFιleNameFromSpec(sFιleSpec, PAT_DATA sPatientDataFileNa e) 'hold the name of the file

UpDateRecentFileMenu sFileSpec ~ frmMain. nuFileSave. Enabled = True

SavePatientData = True

S

Figure imgf000039_0003
frmMain MousePointer = vbDefault Exit Function

SavePatιentData_Error SavePatientData = False

^ General.bas - SavePatieniData r 2l

Resume SavePatιentData_Exιt exit anyway for now End Function

Public Sub PopulateDeviceCommDialog(DataStruct As DeviceDataStruct, SourceForm As Form)

Tήere are nvo possible dalαgs that have the same controls on them This common procedure will populate both

On Error Resume Next 'not all text ooxes will appear on every form Dim i As Integer

With SourceForm 'SΛow custom laoeis from config file it there were any .Labell (3) = gsCustomLblPatientLastName .Labell (1) = gsCustomLblPatientFirstName .Labell (5) = gsCustomLblPatientlD .Labell (6) = gsCustomLblTxCenter .Labell (7) = gsCustomLblDrug .Labell (0) = gsCustomLblOrgan

list box list box with available choices

Figure imgf000040_0001

'it is a list box 'fill the drugs list box with available choices

Then

Figure imgf000040_0002

.txtPatieπtLastName = DataStruct.sPatientLastName .txtPatientFirstName = DataStruct.sPatientFirstName .txtPatientID = DataStruct.sPatientlD .txtTxCenter = DataStruct.sTxCeπter . ctSerialNumber = DataStruct.sSerialNumber .IxtDoseSize = " " + DataStruct.sDoseSize

3 ? General.bas - PopulateDeviceCommDTa'

Data(O) Then " " + CStr(DataStruct.iEventData(0)) ♦ " " ~

Figure imgf000041_0001
loadDate Then " " + Format$(CDate(DataStruct.dLastDownloadDate), "Short Date") + " " + FormatS(CDate(Data Struct. "Medium Time") + " " ~
Figure imgf000041_0002

.txtPatientLastName 'take focus away from list box after it 'wa set

For i = 1 To giMaxDoseTimes

If DataStruct.dPrescribedDoseTime(i) >= 0 Then

LZ .txtDoseTime(i) = " " + FormatS(DataStruct.dPrescribedDoseTime(i), gsTimeDisplayFormat) ♦ " " End If Next i

" Date), "Medium Date")

Figure imgf000041_0003
♦ " "

'sef Indicators for error flags With DataStruct ize Or .bErrorMedRemaining Or .bErrorMemoryFull Or .bErrorBrownOut Then errors were found 'no errors exist

Figure imgf000041_0004

End With

On Error GoTo 0

End Sub

Public Sub SaveProgramPreferencesO

Dim I As Integer, sSection As String, sFileSpec As String sSection = "Preferences"

SavelNISetting gsAppiniFiieSpec, sSection, "Date Display Format", gsDateDisplayFormat

SavelNISetting gsAppiniFiieSpec, sSection, Time Display Format", gsTimeDisplayFormat

SavelNISetting gsAppiniFiieSpec, sSection, "Compliance Time Range", CStr(gsngComplianceTimeRange) the names of the most recently used files from the menu 1 To frmMaiπ.mnuFileMRU.UBound elNISetting gsAppiniFiieSpec, "Recent Files", CStr(i), frmMain.mnuFileMRU(i).Caption

Figure imgf000041_0005

SavelNISetting gsAppiniFiieSpec, "Options", "Current Tip", CStr(giCurrentTip)

'Save Settings of Calendar Form

SavelNISetting gsAppiniFiieSpec, "Calendar Settings", "chkDosesMissed", CStr(CAL_DEFAULTS. chkDosesMissed) SavelNISetting gsAppiniFiieSpec, "Calendar Settings", "chkDosesNotComplied", CStr(CAL_DEFAULTS.chkDosesNotComplied) SavelNISetting gsAppiniFiieSpec, "Calendar Settings", "chkDosesTaken", CStr(CAL_DEFAULTS.chkDosesTaken) SavelNISetting gsAppiniFiieSpec, "Calendar Settings", "chkDoseChanged", CStr(CAL_DEFAULTS.chkDoseChanged)

7 O 99/35588

General.bas - SaveProgramPrefetenc

'Save Settings of Patient Summary Form

SavelNISetting gsAppiniFiieSpec, "Patient Summary Settings", "cmboDataToView", CStr(PAT_SUM_DEFAULTS.cmboDataToVιew)

SavelNISetting gsAppiniFiieSpec, "Patient Summary Settings", "cmboChartType", CStr(PAT_SUM_DEFAULTS.cmboChartType)

End Sub

Public Function FiπdFirstlV1atchiπgDateinArray(DataStruct As DeviceDataStruct, ByVal IBeginDate As Long)

'Find the earliest event date in the global structure that starts on the same day as the date passed here Return 0 if net found or return the meet to the date if one is found

'Note that this date is not neceεsanly a dcαng e-jent date It could oe any kind of event

'Conduct a successive accroximation lockup cf the date in the array

Dim i As Integer, iLowlndex As Integer, iHighlndex As Integer, iTestlndex As Integer iLowlndex = 1 'start at being of array iHighlndex = DataStruct.iEventData(0) 'stop at end of array iTestlndex = (iHighlndex + iLowlndex) / 2 _ For i - 1 To 7 'this number of iπes is all that is necessan tc find the date If IBeginDate < lnt(DataStruct.dEventDate(iTestlndex)) Then iHighlndex = iTestlndex Elself IBeginDate > lnt(DataStruct.dEventDate(iTestlndex)) Then iLowlndex = iTestlndex Elself IBeginDate = lnt(DataStructdEventDate(iTestlndex)) Then

IHighlndex = iTestlndex FindFirstMatehiπgDatelnArray = iTestlndex End If iTestlndex = (iHighlndex + iLowlndex + 0.5) / 2

Public Function FindClosestDatelnArray(DataStruct As DeviceDataStruct, ByVal IFromDate As Long) As Long

'Find the latest event date in the global structure that starts on the same day

'as the date passed here Return 0 if not found or return the index to the date

'if one is found.

'If a 0 value is passed here then find the most recent date in the array

'Note that this date is not necessaπly a dosing event date. Tnere is a separate

'procedure to find that date

'rgh it necessary tor faster speed, this procedure can be recoded to do a successive approximation

Dim i As Integer

If IFromDate = 0 Then IFromDate = 99999

Figure imgf000042_0001

End Function

γύ General bas - SavelNISetting

P SavelNISettιng(ByVal sFileName As Stπng, ByVal sSection As String, ByVal sKeyField As String,

I = WπtePπvateProfileStπngfsSectioπ, sKeyField, sValue, sFileName) End Sub

Public Function ValidateDoseNumbers(frm Target As Form)

Ensure that there are at leas: as manv cose times as there are 'for the number of doses oer day

Dim i As Integer, iDailyDoseCounts As Integer, iDosesPerDay As Integer _ If Len(PAT_DATA sPatieπtDataFileName) = 0 And Len(PAT_DATA sSeπalNumber) = 0 Then

ValidateDoseNumbers = True

Exit Function _ End If

With frm Target iDosesPerDay = Val( DctDosesPerDay) For i β 1 To 4

If lsDate(.txtDoseTime(l)) Then Z IDailyDoseCounts = iDailyDoseCounts + 1 End If Next i

ses Per Day, yet " + CStrODailyDoseCounts) + " Dose Times were Dosing Values"

Figure imgf000043_0001

End With End Function

Public Function ValidatePatιentDataSaved()

'Ensure that the patient data in memory is saved before proceeding to load new data from device 'Return true it successful else return vbCancel if usr cancelled

Dim r As Integer

ValidatePatientOataSaved ■ True this is the default condition unless set otherwise below + vbQuestion,

Figure imgf000043_0002

A General.bas - ValidatePatlentDataSaved

End Function

Public Sub WaitfByVal dSeconds As Double)

'waif for the specified time passed here men return to caller Dim dDelay As Double cDelay - DateAddt's' dSeconds CDbl(Now)) dDelay = CDbl(Now) + (dSeconds / 86 00) '364CG seconcs ■n a dav

- Do

DoEvents

DoEvents _ Loop While (dDelay >= CDbl(Now))

End Sub

____

? ^ Comm bas - File Declarations

Attπbute VB_Name = "modComm" Option Explicit

'Global definitions tor device communication bv Glen Hamilton 10/5/ 7

' for RS232 communication

Public gbCommTimerExpired As Integer this fiag is set when the comm timer expires

Public giCommPort As Integer 'Communication Port #

Public gsCommDeviceSettings As Stπng speed settings (te 2400 N 8 2)

Public gbCommReplyPeπding As Boolean a command was just sent and reply is pending

Public gbCommBusy As Boolean 'a command is in progress Get's cleared wneπ replv is received or times out

Public gbCommOK As Integer needs to ue an integer mo boolean) keecs current status of communications føι«-

► ccmm true = comm ok any other value for simulation

Public giDeviceResponseWait As Integer 'miliisecs to watt tor next char before assuming end of received smn-

Pnvate Const ERR_COMM_BADRESPONSE = 31001

Private Const ERR_COMM_TIMEOUT = 30998

'=nvate Const ERR_COMM_STRlNGLΞNGTrt = 3CSS

'Pnvate Const ERR_COMM_B'JSY = 309SS

Private Const ERR_COMMjCHECKSUM = 30995

Public Const ERR_DATA_CHECKSUM = 99997

Public Const ERR_NEWER_HOST_SOFTWARE = 99998 set when device returns custom data that was saved -with a newer revision level

'Device communications

Public gbKeepPollingDevice As Boolean 'when true continuous polling cf device is done

'Define some application specific vanables & constants Public gsAppiniFiieSpec As Stπng

Type DeviceDataStruct sPatientLastName As Stπng '(16 bytes) uses 1st 75 flyfe block of the patlent/phamnacy ID & Names sPatientFirstName As Stnng '( S bytes) uses 1st 16 byte block of the patient/pharmacy ID & Names sPatientID As Stπng sDπjg As String '(16 bytes! uses 2nd 16 byte block of the patlent/phamnacy ID & Names sOrgan As String 'f 76 bytes) uses 3nd 76 byte block of the patent/pharmacy ID & Names sTxCenter As Stπng 'C75 bytes) uses 3nd 16 byte block of the patient/pharmacy ID & Names sSerialNu ber As Stπng γ 70 byres) device seπal number sFirmwareVer As Stπng 'Rev version and date of firmware sDoseSlze As String '(1 byte) stored here in mg The device uses "ml' (100mg = 7 mi)

'Device Dose size is in optical ticks (0 to 200) max dose = 5 ml sPatientDataFileName As Stπng 'file path and filename of the data in memory

'Note' the daily prescnbed dosing bmes below are stored in fractional days This is done

'to speed display operations and reduce the amount of memory needed The device actually stores

'these values as intervals relative to 1 00 in the morning Thus, the times are converted to

'intervals when communicating xxπth the device dPrescnbedDoseTime( ) As Double doses due duπng the day (prescπbed) usually a max of tour

IDosesPerDay As Integer '(1 byte) # of doses per day (1 to 4) sDoseResolution As Stπng '(1 byte) Called 'Dose Conversion' in firmware

'Optical ticks to mg multiplier (IB 2 ticks = 10 mg)

'Optical ticks are fixed at 0 05 ml per tick sMedRemaining As Stnng '(2 bytes) Medication 'Supply volume' remaining (in optical ticks) sScoreData(1 ) As Stπng 'Today's score(14 bytes for all scores) of last 14 days doses taker Circular puffer

'valid data is value from 0-4 representing number of doses taken each day

'Note Tnβ "Score pointer" points to the current day

'Note that the foiioxning arrays can not be larger than 1500 events or else tne space limit

Of S4K wιll be exceeded If necessary in the future to have more events than this for

'a single file then make a separate array for the dtagr.osπc data or temp data iEventData(1 -100) As Integer 'the data occumng tor the event data Might be a dose size error flags etc dEventDate(1400) As Double 7ιsf of dose days in order of first taken to most recent byte EventType(1400) As Byte 'value =0 if it is a dose taken

'value = 7 if data event is a dose command change

'value = 2 if user entered entered sUserData 1 (1400) As Stπng 'user entered data in the first column of the gπd sUserOata2(1400) As Stπng 'user entered data in the first column of the gπd ^

¥3 Comm.bas - File Declarations

sUserData3(1400) As Stπng 'user entered data m the first column of me gπd sClock As Stπng '(2 bytes) 10 minute resolution OOOO" = 1 am on first dose day

IDevicelnitDate As Long 'date the device started dDevlceRefDateTime As Double 'dare and time that all events are referenced to sBatteryChangeTimer As Stππg '(2 bytes)3attery change timer, in 10 minute increments sDoseLockoutHours As Stπng '(1 bytel Hours to lockout dosing after a dose is taken bErrorFatal As Boolean 'true if this flag was set in the returned flags stπng bErrorNonFatal As Boolean 'true it this flag was set in the returned flags stnng bErrorDoseSize As Boolean 'true if this flag was set in the returned flags stπng bE orMedRemaining As Boolean 'frue :/ this flag was set in the returned flags stπng bErrorMemoryFull As Boolean 'true if this flag was set in tr.e returned flags stπng bErrorBrownOut As Boolean 'true it this flag was set in the returned flags stπng bErrorsExist As Boolean '(1 byte) Bits are set if vaπous errors nave occurred and have not

'been corrected A value of "0" is normal (no errors) Errors

'are corrected by either correcting the specific situation or

'resetting & reloaάng the cosing parameters

'30=1 it fatal system failure

'B1=1 it non-fatal system failure has occurred

'32-1 it error has occurred in Dose Size Volume . -23=7 // error has occurred in Supply Volume value

'34- 1 it compliance memory is near full

'B5-1 if brownout (low voltage) occurred dLastDownloadDate As Double 'date of last data retπeval from device

End Type

Public PAT_DATA As DeviceDataStruct

Public TEMl=_DATA As DeviceDataStruct

Public gsDrugNames(25) As Stπng 'names of drugs used to populate the list boxes on dialogs

Public gsOrgaπNames(25) As Stπng 'names of gsOrganNa es used fo populate the list ooxes on dialogs

Public Const giEVENT DOSE TAKEN = 0 Public Const glEVENT~OOSE~CHANGED ■ 1 Public Const giEVENT_USER_DEFINED = 2

These values indicate the stπng position (returned from the device) where each element

'begins. This is the stπng that is returned when a request tor "all memory" is sent.

'See above structures tor more detail information about format.

Public Const DATA BEGIN DOSE SIZE = 1 '7 fjyfe

Public Const DATA BEGIN DOSE INTERVAL1 = 1 * 2 + 1 '1 byte

Public Const DATA BEGIN DOSE INTERVAL2 = 2 * 2 + 1 'J oyfe

Public Const DATA BEGIN-DOSE~INTERVAL3 = 3 * 2 + 1 '1 byte

Public Const DATA BEGIN DOSE INTERVAL4 = 4 * 2 + 1 '1 bvte

Public Const DATA BEGIN DOSES PER OAY = 5 * 2 + 1 'J b'yfe

Public Const DATA_BEGIN DOSE CONVERSION = 6 * 2 + 1 '1 byte

Public Const DATA~BEGIN~DOSE~LOCKOUT HOURS = 7 * 2 + 1 '7 byte

Public Const DATA_BEGIN_DOSE~SCORE DAY POINTER = 8 * 2 + 1 '7 byte

Public Const DATA_BEGIN_MED_REMAINING = 9 * 2 + 1 '2 bytes

Public Const DATA_BEGIN CLOCK = 11 * 2 + 1 '2 bytes clock starts at 1am on first dosing day (10 mm increments)

Public Const DATA~BEGIN~BATTERY CHANGE TIMER = 13 * 2 + 1 '2 bytes

Public Const DATA_BEGIN_ERROR_FIAGS = 15~* 2 ♦ 1 '7 byfe

Public Const DATA_BEGIN~PREV_DOSE_PARAMS = 16 * 2 + 1 '16 bytes of copy of prev dosing para s

'(used tor error checking internal fo dispenser) Public Const DATA BEGIN KEY BITS = 32 * 2 + 1 'activation of keys on device

Public Const DATA~BEGIN~LIFE_COUNT = 33 * 2 + 1 'LSB in 33 MSB in 34

Public Const DATA~BEGINJ FE~COMPLETION = 35 * 2 + 1 '=0 when life cycle is programmed - 1 when life test completes successfully

Public Const DATA_BEGIN_COMPENSATION FACTOR = 36 * 2 + 1 'values from 64-192 (128= 1 0 factor)

Public Const DATA_BEGIN~SERIAL_NUMBER~= 38 * 2 + 1 '70 oyfes

Public Const DATA~BEGIN_CUSTOM1 = 48 * 2 + 1 '16 bytes of patient/pharamcy ID & names

Public Const DATA 3EGIN~CUSTOM2 = 64 * 2 + 1 '76 bytes of patientpharamcy ID & names

Public Const DATA_BEGIN~CUSTOM3 = 80 * 2 + 1 '7fi byres of patient/pharamcy ID a names

Public Const DATA_BEGIN~CUSTOM4 = 96 * 2 + 1 '76 byres of patient/pharamcy ID & names

Public Const DATA_BEGIN_SCORE = 112 * 2 + 1 '14 bytes

Public Const DATA_BEGIN_COMPLIANCE_CHECKSUM = 128 * 2 + 1 '2 byfes Includes compliance pointer ana data

'(up to data word 1 before data pointed to by comp pointer

-7"

M Comm.bas - File Declarations

28

PuMc Const DATA_BEGIN_COMPLIANCE_POINTER = 130 * 2 + 1 '2 byres points to necf location after end of current compliance"

'base value = 732 10x0084)

Public Const DATA_BEGIN_COMPLIANCE_DATA = 132 * 2 + 1 '-7900 bytes mat Array of 2 bvte values for dose Mm„-, history ««« tumpi/anc

OocK tone values (in 10 minutes resolution from start) when each dose was taken Represented by values 0-65279 (0-Oxtetf) Each dose time 'is changed via rήe "Sef Mode" a value between CxtfCO and OxffcS is wπtten with the LSD byte representing the dose size When compliance memory is cleared the current dose size is always wntten as the first location in 'the compliance memorv

Public Sub ChaπgeBatter iesRequest() Dim r As Integer, lErrorCode As Long, sMSG As Stnng sMSG = "You should continue only if you are replacing the batteπes in the device " sMSG = sMSG " This ensures that the battery time counter will be accurate " + vbCrLf + VbCrLf sMSG - sMSG + " Did you just replace the batteπes or are you about to change them now?" r = MsgBox(sMSG, vbQuestion + vbYesNo + vbDefaultButton2, "Change Batteπes")

alse 'sfop polling for now

Figure imgf000047_0001

On Error GoTo ChangeBatteπesRequest_Error tClockAndBattery(IErrorCode) error number he device batteπes now and retπeve data from the device again when complete ' vbExciamation, "Change Batteries")

Figure imgf000047_0002

ChaπgeβatteπesRequest_Exit: gbKeepPollingDevice - True 'continue polling device

Exit Sub

ChangeBatteπesRequest_Erroι. DisplayErrorMessage lErrorCode Resume ChangeBattenesRequest_Exιt

End Sub

Public Function Comm_CheckComm(IErrorCode As Long) As Integer

'Check the device communication by sending a command and waiting tor a reply 'If no reply Is received, then return β "false" flag to caller

'Important Note- Due to the way the firmware was designed for the device it seems not 'to return anything if the command is in error This is not good because 'wβ would not know whether or not a failed reply is due to a back cable, incorrect comm port 'or settings, etc Hopefully in a future version, the comm check can return some sort of ' haracter to indicate that a common byte was received, but could not be interpreted correctly

Dim sOut As Stπng, sChecksum As Stnng, sin As Stππg sOut = "Pp" 'this is the code for checking communication wth device

CreateChecksum sOut, sChecksum 'calculate a checksum sOut = sOut + sChecksum "I" 'append checksum and ending stπng identifier

If Not frmMain.CommDevice PortOpen Then frmMain.CommDevice.PortOpen = True gbCommBusy = True 'prevent other procedures from communicating with device frmMain.CommDevιce.lnputLen = o 'clear input buffer

4s- O 99/35588

Comm.bas - Comm CheckComm

frmMain.CommOevice Output = sOut 'send stππg to device gbCommReplyPending = True 'prevent other procedures from communicating with device

SetComm Timer giDeviceResponseWait 'set timer to wait for response lErrorCode = 0 'reset error code

Figure imgf000048_0001
or timeout occurs sin = frmMain. CommDevice Input 'Peac response from senal oort

If sin = "S" Then Comm_CheckComm = True return success to caller

Comm_CheckComm_Exιt'

If frmMain.CommDevice.PortOpen Then frmMain. CommDevice PortOpen = False ' Oose the senal port gbCommReplyPending = False 'reset fiag gbCommBusy = False 'resef fiag

End Function

Public Function Comm_GetDeviceReply(sReply As String, lErrorCode As Long) As Integer

'A command snould have been just sent to the device from another procedure and a repiy is pendng

'Get the reply into 'sReply' and return to caller

'Return false if no reply and set lErrorCode to reason.

'Return ERR_COMM_TIMEOUT if no reply from the device error code - 0 if comm is aireaα)/ busy

'If reply, then return number of characters received

'Close comm port once a reply is received or if an error occurs.

Dim iLastBufferCount As Integer, r As Integer

On Error GoTo Comm_GetDeviceReply_Error gbCommReplyPending = True 'sef busy fiag frmMain.MousePointer = vbHourglass

'Open comm port in case it is closed

'prevent device unavailable error

If frmMain.CommDevice.PortOpen = False Then frmMain.CommDevice.PortOpen = True 'open port sReply = " 7n/f reply '20 milliseconds is normally sufficient > 0 OMM_TIMEOUT 'return message to caller. No response

Figure imgf000048_0002

'First char has oeen received 'Wait tor all data to arrive iLastBufferCount = -1 'init buffer count

Do While frmMaiπ.CommDeviee. InBufferCount > iLastBufferCount 'characters are still arriving iLastBufferCount = frmMain.CommDevice. InBufferCount 'remembe intermediate count SetCommTimer giDeviceResponseWait 'this value works as low as 25 milliseconds

. Do Until gbCommTimerExpired = True 'wait for timer to expire

DoEvents DoEvents - Loop Loop Vooo if characters are still coming in

'All data has a ved or time has been too long

y Comm.bas - Comm_GetDevιceReply

r = frmMain.CommDevice.lnBufferCount 'get character length sReply = frmMain.CommDevice.lπput read stπng from buffer

Comm_GetDevιceReply = Len(sReply) return bufferleπgth to caller (- checksum)

Comm_GetDevιceReply_Exιt: prevent device unavailable error

If frmMain.CommOevice PortOpen = True Then frmMain CommDevice PortOpen = False 'Cose poir if open frmMain MousePointer = vbDefault On Error GoTo 0 clear error status gbCommReplyPending = False 'reser pending flag gbCommBusy = False reset busy fiag

Exit Function

Comm_GetDevιceRepiy_Error lErrorCode = Err 'return error coαe to caller

"Resume 0 'tor testing only

Resume Comm_GetDevιceReply_Exιt End Function

Public Function Comm_ReadFirmwareVersion(DataStruct As DeviceDataStruct, IReturnError As Long) As Integ

Dim sOut As Stπng, sChecksum As Stπng, sin As Stnng, lErrorCode As Loπy, r As Stππg sOut = "Vv" 'fήis is me code for version number

CreateChecksum sOut, sChecksum 'calculate a checksum sOut » sOut + sChecksum + "I" 'append checksum and ending stπng identifier

If Not frmMain.CommDevice.PortOpen Then frmMain.CommDevice.PortOpen = True frmMain.CommOevice. InputLeπ = 0 'clear input buffer frmMain.CommDevice. Output = sOut 'send stπng to device r - Comm_GetUevιceReply(sln, lErrorCode)

array

Figure imgf000049_0001
End Function

Public Sub DisplayCommError(SourceForm As Form) gbCommOK = False

SoureeForm.lmgCommStatus.Picture = SourceForm. imgRedUght

SoureβForm.lblCommStatus = "No Device Found"

'Play disconnect sound and snow status visually 'Set properties needed by MCl to open With SoureeForm.MMControU

.Notify = False

.Wait = False

.Shareable = False filename = App.Path +

Figure imgf000049_0002

'Open the MCl Wave Audio device .Command = "Open" .Command = "sound" .Command = "close" End With

^ Comm. as - DisplayCommError . r

31

End Sub

Public Sub DisplayCommOk(SourceForm As Form)

'■-lay connect sound and show status visually 'Set properties needed by MCl to open gbCommOK = True With SourceForm.MMControM

.Notify = False

.Wart = False

Shareable » False filename = App.Path + "\morsecode.wav"

'Ccen the MCl Wave Audio device .Command = "Open" .Command = "sound" .Command = "sound" .Command = "close" End With .

SourceForm.lmgCommStatus Picture = SourceForm.imgGreeπLight SourceForm.lblCommStatus = "Device Ready"

End Sub

Public Sub DisplayErrorMessage(IErrorCode As Long)

Dim sMSG As Stnng

_ Select Case lErrorCode Case ERR_COMM_TIMEOUT sMSG = "No response was received from the device to the command just issued. Remove the device from the communicator and re-insert it to ensure that it is seated properly."

— Case ERR_COMM_CHECKSUM sMSG = "Data retπeved from the device is corrupted. This probably occurred duπng transmission. Please read the device again."

— Case ERR_COMM_BADRESPONSE sMSG = The device did not interpret the command properly."

— Case ERR_NEWER_HOST_SOFTWARE sMSG = The device was previously programmed with a newer version of this software. The data can not be retπeved." + vbCrLf + x VbCrLf + "Please obtain an updated version this software." Case Else sMSG = "An error was detected while communicating with the device. Please try again." + bCrLf VbCrLf + ErrorS(IErrorCode)

_ End Select

MsgBox sMSG, , App.ProductName + " Comm Error - " + CStr(IErrorCode)

End Sub

4? Comm. bas - GetDrugRefNumber

Public Function GetDrugRefNumber() As Integer

'Find the index to the organ name being using in the global structure

Dim i As Integer To UBound(gsOrugNames) se(PAT_DATA.sDrug) = LCase(gsOrugNames(i)) Then Exit For

Figure imgf000051_0001

GetDrugRefNumber = i return ret number to caller

End Function

Public Function GetOrganRefNumber() As Integer

'Find the index to the organ name oeing using in the looal structure

Dim i As Integer es) LCase(gsOrganNames(i)) Then Exit For

Figure imgf000051_0002

GetOrganRefNumber = i 'return ret numoer to caller

End Function

Private Function lnterpretDosingData(DataStruct As DeviceDataStruct, ByVal sData As String, ByVal dCheckSumTally As Double, ByVal ICheckSum As Long, lErrorCode As Long) As Integer

'Parse apart the dosing data that is passed here and put into global structure

'Each dosing event is 2 bytes in length.

'The checksum is passed here for compaπson to the stπng.

'The checksum includes the pointer bytes which is why it is passed in.

Dim sTemp As Stnng, iLowByte As Integer, IHiByte As Integer, ICurrentDoseAmount As Long Dim r As Integer, iposition As Integer, iCount As Integer, ITemp As Long On Error GoTo lnterpretDosingData_Error

Figure imgf000051_0003
dCheckSumTally = dCheckSumTally Mod 65536 If dCheckSumTally = ICheckSum Then

^ f Comm.bas - InterpretDosingData

InterpretDosingData = True 'return success to caller - Else lErrorCode = ERR COMM_CHECKSUM _ End If lnterpretOosιngData_Exιt: On Error GoTo 0 Exit Function lnterpretDosιngData_Error: lErrorCode = Err Resume lnterpretDosιngData_Exιt-

End Function

Public Function ValidateChecksum(ByVal sData As String) As Integer

'Look at the data stnng passed nere and get tns cnecxsu from the

'end of the stnng

'sDATA should be a stπng that was returned from the device

'The last charm the stnng is a termination char preceeced oy 4 bytes of checksum

Dim sTemp As Stππg, iByte As Integer, r As Integer, iposition As Integer Dim ICheckSum As Long, ICheckSumTally As Long On Error GoTo ValιdateChecksum_Error r = Len(sData) _ For Iposition = 1 To r - 5 iByte = Asc(Mldϊ(sData, iposition, 1 ))

Vflyfe = Clnt("&H' * MidSlsData. iposition. 2))

ICheckSumTally = ICheckSumTally + iByte 'add to checksum

_ Next iposition

ICheckSumTally = ICheckSumTally Mod 65536 sTemp = "4H" + "0" + MidSfsData, r - 2, 2) + Mld$(sData, r - 4, 2)

ICheckSum = CLng(sTemp)

If ICheckSumTally = ICheckSum Then ValidateChecksum = True 'pass success tlag back to caller

ValldateChecksum_Exit: On Error GoTo 0 Exit Function

ValιdateChecksum_Erroι.

Resume ValιdateChecksum_Exit

End Function

Private Sub lnterpretErrorFlags(DataStruct As DeviceDataStruct, ByVal iFlagsByte As Integer)

'Break out the bits of the flags bytes passed here 'Put the results into the global arrays

'if any flags exist, then set this to true

If IFlagsByte Then DataStruct.bErrorsExist = True

'Parse out flags separately DataStruct.bErrorFatal = (iFlagsByte And 2) DataStruct.bErrorNonFatal = (iFlagsByte And 4) DataStruct.bErrorDoseSize = (iFlagsByte And 8) DataStruct.bErrorMedRemaining = (iFlagsByte And 16) DataStruct.bErrorMemoryFull = (iFlagsByte And 32) DataStruct.bErrorBrownOut = (iFlagsByte And 64) 'remaining upper 3 bits not used at present

End Sub

t ό Comm. bas - Comm ReadEntireMemoryCon

Public Function Comm_ReadEntireMemoryConteπts(DataStruct As DeviceDataStruct, IReturnError As Long) ;

Dim sOut As Stπng, sChecksum As Stπng, sin As Stπng, lErrorCode As Long, r As Stπng

On Error GoTo Comm_ReadEntιreMemoryContents_Error

EraseDatalnMemory DataStruct sOut = "Rr" 'this is the code for reading entire memory

CreateChecksum sOut, sChecksum 'calculate a checksum sOut = sOut + sChecksum + "!" append checksum and ending stnng icenαfter

If Not frmMain.CommDevice.PortOpen Then frmMain.CommDevice.PortOpen = True

Figure imgf000053_0001
r = Comm_ReadFirmwareVersιon(DataStruct, lErrorCode) If lErrorCode Then

Z IReturnError - lErrorCode End If

Comm_ReadEntireMemoryCoπteπts_Exit: On Error GoTo 0 Exit Function

Comm_ReadEntireMemoryConteπts_ Error IReturnError ■ Err Resume Comm_ReadEntireMemoryContents_Exit

End Function

7

Figure imgf000054_0001

Public Function Comm_SendResetClockAπdBattery(IReturnError As Long)

'Resets the device clock to an offset that represents 1 OOam 'and rese's the battery timer to zero

Dim sData As Stπng, sOut As Stππg, sReply As Stπng, sChecksum As Stπng Dim r As Integer, lErrorCode As Long, iTemp As Integer iTemp * Clnt(Format(Now, "hh"))

If iTemp = 0 Then iTemp = 24 micnigrt iTemp = (iTemp - 1) 6 calc number of iQ-m ute oenod ' houis iTemp = iTemp + Clnt((FormatS(Now, "nn") - 5) / 10) calc number of IC- in penods in this hour sData = CStr(Hex(ιTemp))

If Len(sData) < 2 Then sData = "0" + sData ensure stnng is always 2 oytes long

dentifier

Figure imgf000054_0002

End Function

Public Function Comm_SeπdCustomData(DataStruct As DeviceDataStruct, ByVal sLocation As String, IReturn

TΛerβ are 4 locations in the device, each containing a 16 byte stπng There first location is usually reserved for Patient ID 'Any stnng can be contained in any location. 'Data is taken from the global structure

Dim sData As String, sOut As Stπng, sReply As Stπng, sChecksum As Stπng Dim r As Integer, lErrorCode As Long, sCustomData As Stπng Dim I As Integer, sTemp As Stnng

'Determine the appropπate command forthe location of the data to be stored "There are 4 fields in the device containing 76 characters each In the oπgπal 'device design, this was Intended to contain 4 sβpeate pieces of information The dient has now decided that some fields are too short and others are too long 'Thus, the fields are combined to be one stπng of 64 characters

'Data Structure Rev level = giLEN_REV_DATA_STRUCTURE

'Patient name - gILEN PATIENT NAME

'ID = giLENJD ~

'Drug = giLEN DRUG

TX Center - gLEN TX CENTER

Organ - gtLEN_ORGAN

'Create a 64 byte stπng from the vaπous data elements to be saved 'This stππg identifies the format of custom information If the format 'changes in a future version then this ID can be used to determine which 'version of the software saved the info to the device sCustomData = gsREV_DATA_STRUCTURE

'Save the 2 digit number that represents this drug

'To save space a numencal index of the Organ name is stored in the device i = GetDrugRefNumberO sTemp = CStr(i)

If Len(sTemp) < 2 Then sTemp = "0" + sTemp 'force code to be 2 digts sCustomData = sCustomData + sTemp 'concatenate result to outbound stnng

'Save the 2 digit number that represents this organ

'To save space a numencal index of the Organ name is stored in the device

AT^ Comm bas - Comm SendCustomData i = GetOrganRefNumberO sTemp = CStrfl)

If Leπ(sTemp) < 2 Then sTemp = "0" * sTemp force code to be 2 digits sCustomData = sCustomData + sTemp sTemp = DataStruct.sPatientID If Len(sTemp) > gιLEN_ID Then sTemp = Left$(sTemp, gιLEN_ID) name is too long mm letters of first name

Elself Len(sTemρ) < giLENJD then sTemp = sTemp + Space$(gιLEN ID - Len(sTemp)) 'name is too snort to fill the designated length

End If sCustomData = sCustomData + sTemp concatenate result to outbound stπng sTemp = DataStruct.sTxCenter

If Len(sTemp) > gιLEN_TX_CENTER Then sTemp = LeftS(sTemp, giLEN TX CENTER) 'name is too long tnm letters of first name

Elself Leπ(sTemp) < gιLEN_TX_"CENTER Then sTemp = sTemp + Space$(gιLEN TX CENTER - Leπ(sTemp)) 'name is too short is fill the designated length End If sCustomData = sCustomData + sTemp 'concatenate result to outbound stπng sTemp = DataStruct.sPatientLastNa e + "," + DataStruet.sPatientFirstName If Len(sTe p) > gιLEN_PATIENT_NAME Then sTemp = Left$(sTemp, gιLEN_PATIENT NAME) 'name is too long, tnm letters of first name

Elself Len(sTemp) < gιLEN_PATIENT_NAME Then sTemp = sTemp + Space$(gιLEN PATIENT NAME - Leπ(sTemp)) name is too snort to fill the designated length

End If sCustomOata = sCustomData + sTemp 'concatenate result to outbound stπng

'Assemble the stππg to be sent _ Select Case sLocation Case DATA BEGIN CUST0M1 sOut = "VΛv" sData = Mid$(sCustomData, 1, 16) Case DATA_BEGIN_CUST0M2 sOut * "Xx" sData = Mld$(sCustomData, 17, 16) Case DATA_BEGIN_CUST0M3 sOut = Υy" sData = Mid$(sCustomData, 33, 16) Case DATA_BEGIN_CUST0M4 sOut = "Zz" sData = Mid$(sCustomData, 49, 16)

_ End Select

ntifier

Figure imgf000055_0001

End Function

Figure imgf000055_0002
Comm bas - Comm SendCustomData

Public Function Comm_SeπdDosingParams(DataStruct As DeviceDataStruct, IReturnError As Long)

Sends the dosing parameters from the global structure to the device

Structure 'Ddttuuwwwxxyyzzmmss "

'Response "$"

' "ft"" is Dose Size in pump ticks Note that pump ticks per illiliter is fited at 40 Hex value from 0 to Oxff (Maximum dose s.ze is currently . 5 mis or 200 decimal)

"uu' "vv" "ww" "xx" are tour Dose Interval values in hours pe'ween doses hex values between 1 and 0x18

' "yv" is Numoer of Doses per day nex value from 1 to 4 "zz" is Pump Ticks per 10 mg Conversion value Hex value Typical value χ.vιth present meαcaticn is 4 tic s per 10 milligrams

' "mm" is Lockout Hours value Number of hours 'o prevent dosing after a dose is taken

' 'ss' are the two cnec sum digts (hex) equai the one s compliment value of the two s compliment sum of the commend characters and . the data Tne ASCII values are si oly addec together in an 8 bit sum then one is subtracted (modulo 255)

Dim iData As Integer, sData As Stπng, sOut As Stπng, sReply As Stπng Dim r As Integer, lErrorCode As Long, sChecksum As Stππg, i As Integer Dim iLastlntervaiSet As Integer

On Error GoTo 0 sOut = "Dd" puf command m stnng

'Get Dose Size in pump ticks iData = Val(DataStruct.sDoseSιze) * 40 / 100 'get dose size from global struct & convert to pump ticks (convert from mg to ml) sData - CStr(Hex(IData)) convert value to a hex stnng

If Len(sData) < 2 Then sData = "0" + sData 'ensure stnng is always 2 bytes long sOut = sOut + sData

ILastlntervaiSet = 1 '7 00 am is the ret time tor the first dose

'Get Dose intervals in hours

to the last one that is set

Figure imgf000056_0001

'Gef number of doses per day sData = CStr(Hex(DataStruct.lDosesPerDay)) convert value to a hex stnng If Len(sData) < 2 Then sData = "0" + sData ensure stππg is always 2 bytes long sOut = sOut + sData

'Get conversion value

IData 0 in case of error reset temp value iData = Clπt(DataStruct.sDoseResolutιon) gef cose resolution from global struct sOata = CStr(Hex(ιData)) convert value to a hex stπng

If Len(sData) < 2 Then sData = "0" + sData ensure stπng is always 2 bytes long sOut = sOut + sData

'Get Dose lockout hours iData = 0 'in case of error reset temp value iData = Clnt(DataStruct.sDoseLockoutHours) 'get lockout hour from global struct sData = CStr(Hex(ιData)) 'convert value to a πev st ng

If Len(sData) < 2 Then sData = "0" + sData ensure stnng is always 2 bytes long sOut - sOut + sData

CreateChecksum sOut, sChecksum 'calculate a checksum sOut = sOut ♦ sChecksum + "I" append checksum and ending stπng identifier

*Ϋ Comm bas - Comm_SendDosιngPafams

dexnce

Figure imgf000057_0001

End Function

Public Function Comm_SendSerialNumber(DataStruct As DeviceDataStruct, IReturnError As Long) As Integer

'Sends the senal numoer from the glooal structure to the device

Dim sData As Stnng, sOut As Stπng, sReply As Stπng, sChecksum As Stππg Dim r As Integer, lErrorCode As Long first 16 chars

r

Figure imgf000057_0002

End Function

Private Sub ConvertHexStringToAscii(ByVal sData, sConverted As String)

'Stπng Data from the device is usually returned as Hex characters 'Convert the stπng (passed in here) to an ASCII stπng and return to caller 'Such stnngs are items like patient name, senal number, etc

Dim sTemp As Stπng, i As Integer, iTemp As Integer On Error Resume Next sConverted = "* 'dear out any old stπng

For i = 1 To Len(sData) Step 2 sTemp = "SH" ♦ Mid$(sData, I, 2) 'get a 2 char hex Byte from stπng sTemp = ChrS(sTemp) 'convert value to ASCII sConverted = sConverted + sTemp concatenate to existing stπng being built Next i

End Sub

3/199B

≤s~

Figure imgf000058_0001

Private Sub CreateChecksum(sOut As String, sChecksum As String) πe stππg 'sOuf will be sent to the device by another procedure Before it is sent 'this procedure calculates a checksum and retiims it to the caller Return the ASCII representation of the checksum value

Dim i As Integer, ICheckSumTally As Long, iChecksumByteLow As Integer

For i = 1 To Len(sθut) 'calculate Checksum

ICheckSumTally = ICheckSumTally + Asc(MιdS(sOut, I, 1)) Next i iChecksumByteLow = ICheckSumTally Mod 256 tChecksumByteHigh = ICheckSumTally '. 256 not being using by the device sChecksum » HexfiChecksumByteLow - 1 ) 'checksum is the 'one s complement vaiue of a ftvo s complement checksum' value must always be 2 chars

If Len(sChecksum) < 2 Then sChecksum = "0" + sChecksum piace a leading O" in front of Checksum

End Sub

Public Sub EstablishDeviceCommO

'This procedure continues to try and establish communication with the Device 'unύl it succeeds When successful control is returned to the calling procedure "The purpose of this procedure is to allow the user to try caole changes device 'movement etc without having to continue pressing keys on the keyboard

Dim r As Integer, lErrorCode As Long

be processed, so we don't lock up the computer before trying

Figure imgf000058_0002

End Sub

Function Comm_lπitiaiizeCommPort() As Integer

'Gef the imtal values from INI file and 'Initialize device comm port settings

Dim IReply As Long

Const sSection = "Communications"

'Gef the amount of time needed for a reply to be received from the device giDeviceResponseWait = Clnt(GetlNISettιng(gsApplnιFileSpec, sSection, "Device Response Wait", "50")) If giDeviceResponseWait < 25 Then giDeviceResponseWait = 25 'sef a minimum delay time

If giDeviceResponseWait > 500 Then giDeviceResponseWait = 500 'damp upper limit frmMain.CommTimer.lnterval = giDeviceResponseWait sef up the timer

'Get the comm port speed settings giCommPort = Clnt(GetlNISettιng(gsApplπiFileSpec, sSection, "Port", "1"))

If giCommPort = 0 Then giCommPort = 2 'ser a default of comm 2 if nothing is in the f.ie gsCommDeviceSettmgs = GetlNISettιng(gsApplnιFιleSpec, sSection, "Settings", "2400,n,8,2") prevent device unavailable error

If frmMain.CommDevice.PortOpen = True Then frmMain. CommDevice PortOpen = False 'close port it open frmMain.CommDevice.Settings = gsCommDevice Settings frmMain.CommDevice.CommPort = CStr(gιCommPort)

S~ > Comm.bas - Comm InilializeCommPort

frmMain.CommOevice InBufferSize = 1024 frmMain.CommOevice InputLen = 0 Comm InitialrzeCommPort = True return success to caller

Comm_lnιtιalιzeCommPort_Exιt. Exit Function

Comm_lπιtιalιzeCommPort_Error Comm nitiaiizeCommPort = Err 'return error to caller On Error GoTo 0 Resume Comm IπitializeCommPort Exit

End Function

Sub Device_OnComm()

Tms procedure is called by the OnComm evenet of the comm control located on 'frmMain This is so that the cede can be shared between applications

Dim r As Integer, sTemp As Stπng r = frmMain.CommDevice.CommEvent

It r * MSCOMM_ER_RXOVER Then

'An overrun error occured Ususally happens when getting events

Itrs MSCOMM_EV_ EOF Then end of file flag received

Exit Sub who cares Happens duπng receipt of events

End If

Iff* MSCOMM_ER_BREAK Then 'break signal received

5 Then 'its xαn otf. CD error

Figure imgf000059_0001

MsgBox 'Unexpected error occured with the device Please try again ' , 'Comm Event ' * StrS(r)

'7 Comm bas - Devιce_OnComm

41

End Sub

Private Sub lnterρretScoreData(DataStruct As DeviceDataStruct, ByVal sData As String, ByVal iCurrentDayPoi

Gef score data and place into gobal structure Seems that the pointer is 0 based 'The value is from 0 to 4 doses ta en per day A vaiue of "ZHF=" means that 'he value is cleared and not set yet

Dim i As integer, sTemp As Stπng, iTempPointer As Integer iTempPointer = iCurrentDayPointer + 1 start -vit'i the current dav days of data σef score tor this dav (2 bvte hex) 'save score * 2 end of circular puffer Start at oottpm

Figure imgf000060_0001

End Sub

Private Function ParseMemoryContents(DataStruct As DeviceDataStruct, sAIIData As String, lErrorCode As Lo

On Error Resume Next

Dim i As integer, sDoseData As Stnng, ICheckSum As Long

Dim sTemp As Stnng, sConverted As Stπng, ITemp As Long, r As Integer, sCustomData As Stπng

Dim sLastlntervalTime As Stπng, IStartingLocation As Integer

ReDim sTempLιst(25) As Stnng

On Error GoTo ParseMemoryContents_Error

'Gef Cfocλ-

'The device dock reports the number of 10 minute intervals that have passed since 1 am on

'the morning of the first dose Thus, calculate when the first dose occurred tor later use sTemp = "SH" + "0" + Mid$(sAIIData, DATA_BEGIN_CLOCK + 2, 2) + Mιd$(sAIIData, DATA_BEGIN_CLOCK, 2)

'calculate back to the date and time the clock should have started

DataStnict.dDevieeRefDateTime = CObi(DateAdd("n", -(CLng(sTemp)) * 10, Now))

DataStrucUOevicelmtDate = CLng(DataStruct.dDevιceRefDateTιme)

'Gef Battery Change Timer sTβmp = "SH" + "0" + Mιd$(sAIIData, DATA BEGIN BATTERY CHANGE_TIMER + 2, 2) + Mιd$(sAIIData, DATA_BEGIN_BATTERY_CHANGE_TIMER, 2)

ITemp = CLng(sTemp) / 6 'convert to hours (there are 6 'ten-minute" intervals in one hour) OataStruct.sBatteryChangeTimer = Format$(CStr(ITemp / 24), "##00 days") 'convert to days and store it

'Get Dosing Event Data sTemp = "4H" + "0" + Mid$(sAIIData, DATA BEGIN COMPLIANCE POINTER + 2, 2) + Mιd$(sAIIData, DATA_BEGIN_COMPLIANCE_POINTER, 2) 'gef pointer ITemp = CLng(sTemp) 'convert hex value to a long value

If ITemp Then sDoseData = Mιd$(sAIIData, DATA_BEGIN_COMPLIANCE_DATA, (ITemp - 132) * 2) get stnng

'Get Compliance Checksum sTemp = "4H" + "0" + Mιd$(sAIIData, DATA BEGIN_COMPLIANCE CHECKSUM + 2, 2) + Mιdϊ(sAIIData, DATA_BEGIN_COMPLIANCE_CHECKSU . 2) ICheckSum = CLng(sTemp) r = lnterpretDosιngData(DataStruct, sDoseData, ITemp, ICheckSum, lErrorCode) parse out the events and place in global structure

If r = False Then 'bad checksum data

GoTo ParseMemoryContents Exit End If

'Get Patient Score Data sTemp = Mid$(sAIIData, DATA_BEG!N_SCORE, 28) parse the 14 days et dosing and store in global structure If Len(sTemp) > 0 Then ITemp = CLngfSHO" + Mιd$(sAIIData, DATA_BEGIN_DOSE_SCORE_DAY_POINTER, 2))

4 O 99/35588

Comm.bas - ParseMemoryConteπts

if ITemp Then InterpretScoreData DataStruct, sTemp, Clπt(ITemp) parse out the scores and ulace m global structure

End If

Get Error Flags sTemp = MidϊfsAIIData, DATA_BEGIN_ERROR_FLAGS, 2)

If Len(sTemp) > 0 Then InterpretErrorFlags DataStruct, Val(sTemp) 'parse out the flags and save in glcoat structure

'Get Medication remaining in device sTemp = "4H0" + Mιd$(sAIIData, DATA_BEGIN_MED_REMAINING + 2, 2) + Mιdϊ(sAIIData, DATA_BEGIN_MED_REMAINING, 2)

DataStruct.sMedRemaiπing = CStr(CSπg(sTemp / 40) * 100) + " mg" pump ticks are fixed at 40 per millilter (100 mg per ml)

'Get Dose Lockout Hours sTemp = "5H0" + Mιdϊ(sAIIData, DATA_BEGIN_DOSE_LOCKOUT_HOURS, 2)

DataStruct.sDoseLockoutHours = CStr(CSng(sTemp))

'Get Doses per day sTemp = "&H0" ♦ MidS(sAIIData, DATA_BEGIN_DOSES_PER_DAY, 2)

DataStruct.iDosesPerDay = Clnt(sTemp~)

'Get Dose Resolution sTemp = "-SH0" ♦ Mιd$(sAIIData, DATA_BEGIN_DOSE_CONVERSION, 2)

DataStruct.sDoseResolution = CStr(CSng(sTemp)) ~

'Gef Oose Intervals sLastlntervalTime = "1:00"

'Gef Dose Interval 7 (alarm time) sTemp = "4H0" + MιdJ(sAIIData, DATA_BEGIN_DOSE_INTERVAL1, 2) lf Val(sTemp) Then sTemp ■ DateAddfH", CDbl(sTemp), sLastlntervalTime) 'the first dose is relative to 1 00 am sLastlntervalTime = sTemp

DataStruct.dPrescπbedDoseTime(l) = TimeValue(sTemp) Else

DataStruct.dPrescπbedDoseTime(1 ) = -1 'this value indicates that no time was received

End If

'Gef Dose Intervel 2 (alarm time) sTemp = "4H0" + Mid$(sAIIData, DATA_BEGIN_DOSE_INTERVAL2, 2)

If Val(sTemp) Then sTemp = DateAddfH", CDbl(sTemp), sLastlntervalTime) 'the first dose is relative to 1.00 am sLastlntervalTime - sTemp

DataStruct.dPrescπbedDoseTime(2) = TιmeValue(sTemp) Else

DataStruct.dPrescπbedDoseTime(2) = -1 'this value indicates that no time was received

End If

'Get Dose Interval 3 (alarm time) sTemp = "4H0" + MidJ(sAIIData, DATA BEGIN DOSEJNTERVAL3, 2) lf al(sTemp) Then sTemp ■ DateAddfH", CDbl(sTemp), sLastlntervarrime) 'the first dose is relative to 1 00 am sLastlntervalTime * sTemp

DataStruct.dPrescπbedDoseTime(3) = TimeValue(sTemp) Else

DataStruct.dPrescπbedDoseTime(3) = -1 'this value indicates that no time was received

End If

'Gef Dose Interval 4 (alarm time) sTemp = "4H0" + MιdJ(sAIIData, DATA BEGIN DOSE INTERVAL4, 2) lf al(sTemp) Then sTemp « DateAddfH", CDbl(sTemp), sLastlntervalTime) 'the first dose is relative to 1 00 am sLastlntervalTime - sTemp

DataStruct.dPrescπbedDoseTιme(4) = TimeValue(sTemp) Else

DataStruct dPrescπbedDoseTime(4) = -1 'tins value indicates that no time was received

End If

5~7 Comm.bas - Parse emoryCoπtents

sTemp = "4H0" + MιdJ(sAIIData, DATA_BEGIN_DOSE_SIZE, 2) If IsNumeπe(sTemp) Then

DataStruet.sOoseSize = CStr(CSπg(sTemp) / 40 100) convert from mg to ml Else

DataStruet.sOoseSize = ~ End If

Tήere are 4 fields in the device containing IS characters each In the or.gnal 'device αesign. this was intended to contain - seαeate pieces of information 'The dient has now decided that some fields are ΌO short and others are too long 'Thus the fielcs are combined to be one stnng et 64 characters

'Patient name = gLEN PATIENT NAME

'ID = gLENJD ~

'Drug = giLΞN DRUG

TX Center = gLEN_ TX_CEN7ER

Organ = gLEN_ORGAN

'Send a message to the user if the revision ιeve: is nignerthan the one

'this software is using to send custom data to the device

'~he user must upgrade to the current version is order to get accurate custem data

'This code should also handle any previous versions mat savec csta to the αevics

'Get Custom stnng 1 sTemp = Mid$(sAIIData, DATA_BEGIN_CUSTOM1, 32) ConvertHexStnngToAscii sTemp, sConverted sCustomData = sConverted

'Gef Custom stπng 2 sTemp = Mιd$(sAIIData, 0ATA_BEGIN_CUSTOM2, 32) ConvertHexStnngToAscii sTemp, sConverted sCustomData = sCustomData + sConverted

'Gef Custom stπng 3 sTemp ■ MldJ(sAIIData, DATA_BEGIN_CUSTOM3, 32) ConvertHexStnngToAscii sTemp, sConverted sCustomData = sCustomData + sConverted

'Get Custom stπng 4 sTemp = Mid$(sAIIData, DATA_BEGIN_CUSTOM4, 32) ConvertHexStnngToAscii sTemp, sConverted sCustomData = sCustomData + sConverted

'Pull apart the 64 char stπng into its sub-components

'Get the custom data structure revision level that was previeuslv saved to the device

'Note this is not the same as the major and minor versions of the host software iStartingLocation = 1 sTemp » Mid$(sAIIData, iStartingLocation, glLEN_REV_DATA_STRUCTURE)

ConvertHexStnngToAscii sTemp, sConverted

"The device custom data was apparently saved with a newer version of software than this one lf Val(sConverted) > gsREV DATA STRUCTURE Then lErrorCode = ERR_NEWER_HOST_SOFTWARE

GoTo ParseMemoryContents Exit End If

'Determine the real name of the Drug by the re'erence number received from the device iStartingLocabon = iStartingLocation ♦ gιLEN_REV_DATA_STRUCTURE sTemp = Tπm(Mid$(sCustomOata, IStartingLocation, gιLEN_DRUG)) r = Val(sTemp)

If r > 0 And r < UBound(gsDrugNames) Then DataStruct.sDrug = gsDrugNames(r)

'Determine the real name of the Organ by the reference number received from the dewce iStartingLocation = iStartingLocation + gιLEN_DRUG sTemp = Tπm(M!d$(sCustomData, iStartingLocation, gιLEN_ORGAN)) r = Val(sTemp)

If r > 0 And r < UBound(gsOrganNames) Then DataStruct sOrgan = gsOrganNames(r)

IStartingLocation = iStartingLocation + gιLEN_ORGAN

£ o Comm.bas - Parse emoryContents

DataStruct.sPatientlD = Tπm(Mld$(sCustomData, iStartingLocation, giLENJD)) iStartingLocation = IStartingLocation ♦ giLEN ID

DataStruct.sTxCenter = Tπm(Midϊ(sCustomD~ata, iStartingLocation, giLEN_TX_CENTER)) iStartingLocation = IStartingLocation + giLEN_TX_CENTER r = ParseDelimStπng(Tπm(MidS(sCustomData, isTartingLocation, giLEN PATIENT NAME)), ",", sTempListfi)

DataStruct.sPatieπtLastName = Tnm$(sTempList(1 ))

DataStπjd.sPatientFirstName = Tπm$(sTempList(2))

'Gef Senal Numoer sTemp = Mid$(sAIIData, DATA_BEGIN_SERlAL NUMBER, 20) ConvertHexStnngToAscii sTemp, sConverted DataStruct.sSeπalNumber = Trim(sConverted) ParseMemoryContents = True 'senα success to caller

ParseMemoryContents_Exit: On Error GoTo 0 Exit Function

ParseMemoryContents_Error:

'tores a Checksum error here because any type of error is likely due to a checksum problem lErrorCode = ERR_COMM_CHECKSUM Resume ParseMemoryContents Exit

End Function

Public Sub Po!IDeviceContinually(SourceForm As Form)

'This procedure continues to try and establish communication with the Device 'until It succeeds. When successful, control is returned to the calling procedure. 'The purpose of this procedure is fo allow the user to try cable changes, device 'movement, etc without having to continue pressing keys on the keyboard

Dim r As Integer, bProcedurelnProgress As Boolean, lErrorCode As Long

If bProcedurelnProgress Then Exit Sub

If gbCommBusy Or gbCommReplyPending Then Exit Sub bProcedurelnProgress = True 'prevent recursive calls to this procedure

'allow other Windows events to be processed, so we don't lock uo the computer K = True Then 'no need to poll as often if device was working the last time we checked 'wait an additional amount of time before trying 'poll faster until a good comm is made

Figure imgf000063_0001
'poll only if port not busy

Figure imgf000063_0002

Wef 005 'allow polling icon to be viewed If gbKeepPollingDevice = False Then Exit Sub

A Comm.bas - PollDeviceContinually

SourceFor jmgPollmg Visible = Felse

If r = ERR_COMM_TIMEOUT Then 'send an additional error message that no reply was received

MsgBox "No response was received to a wake up command that was sent to the DosPro device ", , "Communication Error" End If

'flag has not been reset yet

If gbKeepPollingDevice Then GoTo QueryDevice try comm again bProcedurelnProgress = False 'allow future calls to this prcedure now tha' we are finished

End Sub

Public Sub Comm_SeπdDataToDevice(ByVal sOut As String)

Dim dGoAheadTime As Double

'A data stπng snoutd have been assembled oy another procedure and is now

'ready to sent to the device

'If another command is in progress then wait till it :s done 'If the flags have not been reset after this delav then exit loop anyway 'This prevents lockups inside this loop in case there is a proolem elsewhere dGoAheadTime = DateAddf s", 5, CDbl(Now)) gbCommReplyPending

dTime Then Exit Do

Figure imgf000064_0001
gbCommBusy = True 'sef busy flag (gets reset if timeout or reply not received)

'if comm port is not open then open it

If Not frmMain.CommDevice.PortOpen Then frmMain.CommDevice.PortOpen = True frmMain.CommOevice.lπputLen = 0 'clear input buffer frmMaln.CommDevice. Output = sOut 'send stπng to dexnce

End Sub

Private Sub SetCommTimer(iTϊme As Integer)

Tne comm timer determines whether or not a reply has come back from the device Tne timer fires an event if the ITime has passed without the timer being reset 'Reset the timer to the interval passed in then start it 'Set the comm busy flag, then return to caller frmMain. CommTimer. Enabled = False 'ώsable timer while resetting It frmMain.CommTimer.lnterval = iTime 'set interval gbCommTimerExpired = False reset timer expiration flag frmMain. CommTϊmer.Enabled = True 'start timer

End Sub

£^ O 99/35588

Comm.bas - SetCommTimer

Attπbute VB_Name » "modPπntlng" Option Explicit

Public gbPπntFormLoading As Integer

Public gbPπnterErrorDetected As Integer

Public giTotalPπntPages As Integer 'track the numoer of pages being pπevewed

Public gbPreventPreviewUpdates As Integer

Public giPπntedPageNumber As Integer

Public gbPageNumberSuspend As Integer 'if true don't pnnt page numoer for the active page (probably cover picture)

Public giFontOptSel As Integer

Public gsSelectPπntPages As String

Public gbPnnterErrorReceived As Integer 'teils other crocs that error occurred Fre must reset flag

Public gbPπntSpoolinglnProgress As Integer 'prevent crashes dunnc spooling

Private Sub btπPrinter_Preview_CIick_Proc()

If gTotalPnntFages > 1 Then 'there is more than one page to pπnt frmSelectPages.Show MODAL

Select Case gsSelectPπr.tPages Case, "All" frmPriπt.MousePointer = vbHourglass gbPπntSpooliπglπProgress = True frmPπnt.vsPπnterl .Action = paPπntAII 'pnnt all pages gbPrfntSpooiiπglnProgress = False

Case 'Page' frmPπnt.MousePointer = vbHourglass gbPπntSpoolinglnProgress = True frmPπnt. vsPrlnten Action - paPππtPage 'pπnt current page only gbPπntSpoolinglπProgress - False

Case " 'nothing to do gύPπntSpoolinglnProgress = False End Select

Else 'pπnting a single page that is not a picture frmPnnt.MoυsePomter ~ vbHourglass gbPπntSpoolinglπProgress = True frmPπnt.vsPrinteπ. Action = paPnntAll 'pπnt all pages gbPnntSpoαlinglnProgress = False

End If

1,3 99/35588

Printing bas - btnPriπter_P.evιew_CϊfCl oc

frmPππt.btnClose Enabled = True 'alloxv button to sliow ffmPriπt.btnPπntNow Enabled = True frmPrint.MousePointer = vbDefault DoEvents

End Sub

Private Sub DrawHorizontalLine(cPrinter As Control, IPenColor As Long)

' trmPnπt vsPnntert FontSize = dgBadyrettSize ' frmPπnt vsPnntert = " SKIP a une from aαcve

'Draw a hoπzoπtal divider on the page

'Usually divides the header or topic tram the res: of the cage cPπnter.FontSize = 12 cPππter = ™ 'skip a line from aoove cPπnter PenStyle = 0 O=solιd 2=dot cPπnter Pen Width = 10 'sef pen width cPπnter PeπColor = IPenColor sef pen color cPπnter.BrushColor = IPenColor

'Pnnt line only across a portion of page cPπnter_X1 = (cPπnter.PageWidth / 2) - (cPπnter PageWidth * 0.25) cPrinte tt = (cPπnter.PageWidth / 2) + (cPπnter PageWidth * 0.25) cPπnter.YI = cPπnter.CurreπtY cPrfnter.Y2 = cPππter.CurrentY + 50 cPπnter.Draw ■ 2 '7=/ιπe 2=rectangle

End Sub

Private Sub PrintAJIPatientsSummary

Dim i As Integer, lErrorCode As Long, sTableFormat As Stππg, sTable As Stππg, sϋst As Stπng Dim fFoπtSize As Single, ICount As Integer

On Error Resume Next

'Prepare progress guage With frmPπnt

.pnlProgress.FloodPercent = 0

.pnlProgressContainer. Visible = True

.pnlProgressContainer.Refresh End With

InitPageProperties fFontSize = 10

'Pnnt the logo on the first page WHh frmPnπt.vsPπnteι

.XI » 700

.X2 = frmPπnt.vsPππter1.X1 + frmPππt.picLogo. Width

.Y1 - 500

.Y2 = frmPπnt vsPnnterl Y1 ♦ frmPππt picLogo Height

.Picture = frmPπnt.pιcLogo. Picture End With

'Pnnt Information Header gbPageNumberSuspend = False With frmPπnt. sPnntert

Figure imgf000067_0001
frmPπnt.vsPπnterl = "" 'skip a line frmPπnt.vsPπnterl = - .ϋnβSpacing = 90 'skip a line -TextAlign = taCenterTop ' % of current font End With 'center text

'Print the report Data sTableFormat = "<2400|<1800|>1700|>1700|>1000;" 'Get the column titles from gπd WHh ftmAIIPatιents.gπd .Row » 0 .Col = 0 sUst = .Text .Col ■ 1 sList = sList + "|" + .Text .Col * 2 sList = sUst + "I" + .Text .Col « 3 sUst = sList + "I" + .Text .Col ■ 4

SList = sUst + "|" + .Text End WHh sTable * sTableFormat + sList

With frmPππt.vsPrinter1

.TableBorder = tbBottom

.FontSize » 10

.FontBold = TΠJB

.Table = sTable 'send out header frmPriπt.vsPπnterl = "" End With

Figure imgf000067_0002

S" O 99/35588

Pπnting.bas - PπntAIIPatιentsSumm>

List ♦ "I" + .Text + "," pnlProgress FloodPercent = (i / iCount) * 100 pnIProgressContainer Refresh

Figure imgf000068_0001
sTable = sTableFormat + sϋst With frmPπnt. vsPπnterl

FontSize = fFontSize ' 09 'set font size

.UneSpacing = 80 ' % of current font

.TextAlign = taCenterTop

.TableBorder = tbNone

.Table = sTable send out table

End With

On Error GoTo 0 frmPππt.pnIProgressContainer. Visible = False ''urn off progress indicator frmPπnt.pnIProgressContainer.Refresh

End Sub

Private Sub PrintPatieπtDosingReportfJ

Dim I As Integer, lErrorCode As Long, sTableFormat As Stππg, sTable As Stπng, sϋst As Stππg Dim fFontSize As Single, iCount As Integer, bltemChecked As Boolean

On Error Resume Next

'Pπnt Cover Art to the Pnnt preview control if needed and available If frmPrint.lbPictures Ustlndex > 0 Then a covens chosen

If FiieExlstsCboversV * sgCurrentCoverName. lErrorCode) Then 'look for a bitmap on dsk 'Pnnt preview the Picture gbPageNumberSuspend - True LoadPicture ToPnnterControi True 'get cover InltPageProperties frmPπnt.vsPnnten. Action = 4 'start a new page gbPageNumberSuspend = False

End If End If

'Prepare progress guage With frmPππt

.pnlProgress.FloodPerceπt = 0

.pnlProgressContainer. Visible = True

.pnlProgressContainer.Refresh End With

InitPageProperties (FontSize = 10

'Pnnt the logo on the first page With frmPππt.vsPπntert

.XI * 700

,X2 » frmPπnt.vsPπnterl .XI + frmPπnt picLogo Width

.Y1 = 500

.Y2 = frmPππt.vsPπnterl Y1 + frmPπnt.picLogo. Height

.Picture = frmPnntpicLogo Picture End With

'Pπnt InfomnaOon Header gbPageNumberSuspend = False With frmPπnt. vsPπnterl .FontName = "Anal"

CL Printing bas - PπntPπtieπlDosingRa

.FontSize = (FontSize * 1 6 sef font size .FontBold = True .Fontltalic = True ' TextCdor *

TextAligπ = taCenterTop cenrer text used in paragraphs .CurreπtY = 1440 1 pπnr name on this line ffmPπnt. vsPπnterl = "Patient Dosing Report" pnnt name

FontSize = (FontSize * 1 2 sef font size

Fontltalic = False frmPπnt.vsPπnterl = PAT.DATA sPatientLastName + ", " + PAT.DATA sPatientFirstName DrawHoπzoπtalLine ffmPπnt. vsPπnterl , SH40000 'Dravj a coiαrlme End With sTableFormat = "<1400|«2800|<1400|<2800," sTable = sTableFormat + gsCustomLblPatientlD ♦ " |" + PAT.DATA sPatientID + "|" sTable = sTable + gsCustomLblTxCenter + " |" + PAT_DATA*sTxCenter + "," sTable = sTable + gsCustomLblDrug + " |" + PAT.DATA.sDrug + "|" sTable = sTable + gsCustomLblOrgan + " |" + PAT.DATA.sOrgan + ","

With ffmPπnt vsPnntert frmPπnt.vsPππtert - ~ 'skip a line

TextAlign = taCenterTop

FontBold = True

.TableBorder = tbNone

FontSize = (FontSize * 1 1 'set font size

.Table - sTable 'send out table frmPπnt.vsPπnterl = "" 'skip a line frmPπnt.vsPπnterl = ~ 'skip a line

.UneSpacing = 90 '% of current font

.TextAlign = taCenterTop 'centertext

ses Value Then

Figure imgf000069_0001

e

Figure imgf000069_0002

'Pnnt the report Data frmPπnt.vsPππterl = ~ 'skip a line frmPπnt.vsPnnterl .TextAlign = taCenterTop PπntDosmgEventsHeader sTableFormat Pnnr we information from the gnd control With frmPatientDosmgReport.gπd iCount = .Rows - 1 sList = - . For i = 1 To iCount number of patients in gπd

(.1 99/35588

Pπnfing.bas - PnntPaticnlDosiπgRt

51

rcent = (i / iCount) * 100 r.Refresh

Figure imgf000070_0001
sTable = sTableFormat + sList With frmPπrtt.vsPπnteπ

.FontSize = fFontSize * 09 'set font size

.ϋneSpacing = 80 ' % of current font

.TextAlign = taCenterTop

.Table - sTable 'send out table

End With

On Error GoTo 0 frmPπnt.pnlProgressContainer. Visible = False 'turn off progress indicator frmPnnt.pnIProgressContainer.Refresh

End Sub

Sub PrintDosiπgEventsHeader(sTableFormat As String)

Dim sTable As String

Dim (PrevFontAs Single, bPrevBold As Boolean, sϋst As Stππg fPrevFont = frmPrint.vsPπnterl. FontSize

'Pnnt the information from the gπd control

'Pass table format back to caller sTableFormat = "«2100|<1600|<1000|«1700|<1700|<1700;"

With frmPatientOosingReport.gnd sϋst = ""

.Row = 0

.Col » 0 sList * sList + .Text

.Col = 1 sϋst = sϋ'st + "J" + .Text

.Col * 2 sList = sϋst + "|" + .Text

.Col > 3 sList - sϋst + T + .Text

.Col * 4 sϋst = sList + "|" + .Text

.Col » 5 sList = sList + T + .Text + "" End With sTable = sTableFormat + sList frmPπnt.vsPππterl. TableBorder = tbBottom (rmPπnt.vsPπnten. FontSize = 10 (r Pπnt.vsPπnterl. FontBold = True (mPπnt.vsPπnterl.Table = sTable 'send out header frmPnnt.vsPrintert = **

t? Printing. as - PπntDosingEventsHeaσer

'Put setting back to previous ones frmPrtnt.vsPπnterl. TableBorder = tbNone frmPπnt.vsPπntei . FontSize = fPrevFont frmPπnt.vsPπnterl. FontBold = bPrevBold

End Sub

Public Sub LoadPictureToPrinterControl(ByVal bCover)

'Set the pπnter control to size a picture and coov 'picture from holding area to the pnnt preview control If the picture re ue αspiayed is a cover ' en the bCover fiag should oe sef ro true by caller 'otherwise it is assumed to be a border

Dim iPaperWldth %, iPaperHeιght%, iNonPππtWidth %, ιNonPπntHeιght% frmPπnt.vsPππteπ .PhysicalPage = True set physical page to paper αmeπsion iPaperWldth = frmPπnt.vsPπnterl .PageWidth 'determine size of paper iPaperHeight = frmPπnt.vsPπnterl.PageHeight frmPπnt.vsPπnterl .PhysicalPage = False refurπ pr.r.ter re pnntaαle area iNonPπntWidth = (iPaperWldth - frmPπnt.vsPπnterl .PageWidth) / 2 iNonPπntHeight = (iPaperHeight - frmPnnt.vsPπnte .PageHeight) / 2

If iNoπPππtWidth < 350 Then iNonPπntWidth = 350 'make a minimum margin

If iNonPπntHeight < 350 Then INonPππtHeight = 350 make a minimum margin frmPnnt.vsPnnter1.X1 = iNonPπntWidth frmPπnt.vsPπnterl .X2 = frmPπnt.vsPnnterl. PageWidth - iNoπPππtWidth frmPrint.vsPnnter1.Y1 = iNonPπntHeight frmPπnt.vsPπnterl.Y2 = frmPπnt.vsPnnterl. PageHeight - iNonPπntWidth

' fnvPnnt.vsPnnterl.Draw = 2 'picture holder only frmPππt.vsPπnterl. Picture = LoadPicturef graphicsV" & "deco.wmr)

End Sub

Private Sub lnitPageMargins()

Figure imgf000071_0001
frmPrint.vsPπnterl.MarginTop = 1350 rop margin frmPπnt.vsPπnterl .MarginBottom = 1500 'bottom margin frmPrint.vsPπnterl .MarginLeft = 1725 'left margin

(rmPπnt.vsPπnterl .MarginRight = 1700 'nght margn (from nght edge)

End Sub

£ / Printing. bas - inilPageProperties

Private Sub lnitPageProperties()

'Reset margins for text and initialize other items fπnPπnt.vsPπnterl ϋneSpacing = 100 '100% of current font

'Set the normal attnbutes here fπnPπnt.vsPπnterl .TextAlign = 0 ser centenr.g oacit to normal

End Sub

Private Sub PrintPageDateQ

'Pnnf Date

Dim ITextHeight As Long, ITextWidth As Long, sTextS

'pnnf date for the above tabs oniy

'Rather than using TextAlign property text is centered nera using this method

'to ensure page ceπteππg regardless o margins or paragrapn settings

InitPageProperties frmPπnt.vsPπnterl . FontName = "Anal" frmPπnt.vsPπnterl FontSize = 8 sText = "Pπnted. " + DateS + " with " + App Title + " software." frmPπnt.vsPπnterl .Measure = sText 'sef smπg fo measure

ITextHeight = frmPπnt.vsPπnterl .TextHei get text height

ITextWidth = fπnPπnt.vsPπnterl .TextWid gef rexf width frmPπni-vsPπnterl .CurrentX = (frmPπnt.vsPπnter1 PageWidth - ITextWidth) / 2 If frmPπnt. vsPπnterl .CurrentY < 13000 Then frmPnnt.vsPππtert .CurrentY = frmPπnt.vsPπnter1.PageHeight - (frmPπnt.vsPπnterl .MarginBottom + (2.5 * ITextHeight)) ser line to ver.

Η bottom Else frmPπnt.vsPπnterl . CurrentY = frmPπnt.vsPπnterl .PageHeight - (frmPnnt.vsPπnterl .MarginBottom + (0.1 * ITextHeight)) 'set line to ver, bottom End If frmPπnt.vsPπntert = sText sText = "Copynght 1998 by SangStat Medical Corporation" frmPrint.vsPrtnterl .Measure = sText 'sef stnng to measure

ITextWidth = frmPπnt.vsPπnterl .TextWid 'get text wdth frmPπnt.vsPπnterl .CurrentX = (frmPπnt. vsPπnterl .PageWidth - ITextWidth) / 2 frmPrint.vsPπnterl = sText

End Sub

Public Sub PrintPageNumberO

'Pπnt page numoer it check box is active on form giPrintedPageNumber = giPπntedPageNumber + 1 'increment page number for next time If gbPageNumberSuspend = False Then frmPπnt.vsPπnterl .HdrFontSize « 8 frmPπnt.vsPπnterl .Footer = "|Dosιng Report " + PAT.DATA sPatientLastName + ", " + PAT.DATA.sPatientFirstName + *: " + V PAT DATA.sPabeπtID + " Page " + CStr(gιPπntedPageNumber) Else frmPπnt.vsPππter1.Footer = "" Vπusr pπnr a plank footer otherwise old page It will show End If

End Sub

-?o

Figure imgf000073_0001

Public Sub RefreshPreviewO

Static bRefreshPreviewlπProgress As Integer prevent recursive calls to here If bRefreshPreviewlnProgress = True Then Exit Sub If gbPreventPreviewUpdates Then Exit Sub bRefreshPreviewlnProgress = True frmPrint.MousePointer = vbHourglass frmPnnt.HScrolH. Enabled = False frmPnnt.HScrolH Refresh frmPnnt.HScrolH Value = 1

DoEvents

On Error GoTo 0 'resef error processing frmPπnt.btnRefresh.Enabled = False frmPπnt.btnRefresh.Refresh frmPπnt.btnPππtNow. Enabled = False frmPnnt.btnPπntNow Refresh frmPππt.btnClose. Enabled = False 'disable buttons until preview build is complete frmPππt.btnClose.Refresh

' frmPnnt.btnFonrιat Enabled = False ' frmPπnt btnFormat Refresh DoEvents giTotalPπntPages = 0 yβsef the page counter giPnntedPageNumber = 1 frmPrinLvsPπn'.ert .Preview = True 'pnnf fo screen frmPrint.vsPrinterl .Footer = "" 'Clear the footer

' fimPπnt.vsPnnterl HdrFontName = "font name goes here' 'Controls footer also ' timPππt vsPnnt en .HdrFont Size = ?? 'Controls footer also

'Send information to the preview screen 'Initialize pnnt job InitPageMargins

If gbPπnterErrorDetected Then GoTo RefreshPrevιew_Exιt frmPπnt.vsPπnterl. PreviewPage = 1 'snow 1st page frmPπnt.vsPπnterl. PreviewMode = 0 O=screen compatible 1=pπnt compat 2 - force monochrome frmPπnt.vsPπnterl .PageBorder = 0 no page border frmPπnt.vsPπnterl .TextAlign = 0 Verϊ align text

" Call LoadPιctureToPnnterContmt(False) Select Case gsActiveFormName

_ Case "frmPatientSummary"

. Case "frmAIIPatients"

Call PπntAIIPatieπtsSummary

. Case "frmPatientDosiπgReport" Call PrintPatientDosiπgReport

End Select

PππtPageDate 'pπnr date fonast recipe frmPnnt.vsPππterl .Action = paEndDoc 'END DOC frmPπnt.vsPπnterl. Visible = True

Vo5 says ooject does not support this method frmPπnt vsPr.nterl Refresh Call UpdatePageButtons

7/ Printing. bas - RefreshPreview

frmPπnt.HScrolH Max = giTotalPπntPages

RefreshPrevιew_Exιt: frmPnπt.btnClose Enabled = True enable buttons DoEvents bRefreshPreviewlnProgress = False allow future calls to this procedure frmPπnt btnPπntNow Enabled = True frmPπnt MousePointer = vbDefault DoEvents

End Sub

Public Sub SetPreviewSizeQ

Dim bHeιghtLιmιt%, (Temp As Single frmPπnt MousePointer = vbHourglass

' tππpππt Refresh a refresh of the term causes controls inside a frame to disaccea' frmPnnt vsPnntert Visible = False frmPnnt vsViewPortI Visible - False DoEvents

If (frmPπnt. vsPπnterl PageHeight / frmPπnt vsPππte .PageWidth) > (frmPπnt vsViewPortI Height / frmPπnt vsViewPortI Width) Then V» bHeightϋmit = True Select Case frmPnnloptZoom(O) Value Case True 'full page view If bHeightϋmit = True Then 'fnere is a height restπction in the viewport control for this pnnt onentation frmPπnt.vsPπnterl. Height = frmPπnt.vsViewPort1. Height * 0.99 fTemp = frmPπnt.vsPπnterl .PageWidth / frmPπnt.vsPπnterl PageHeight fTβ p = frmPπnt.vsPπnterl .Height * fTemp frmPπnt.vsPπnterl .Width = fTemp Else frmPrlnt.vsPπnterl .Width = frmPπnt.vsViewPortl .Width * 0.99

(Temp = frmPπntvsPrinterl .PageHeight / frmPπnt.vsPπnterl .PageWidth

(Temp = frmPπnt.vsPπnteM .Width * fTemp ffmPrint.vsPπnteri. Height = (Temp End If

'Make viewport virtual screen large enough to show full page of pnnt control frmPπnt.vsViewPortl.VirtualWIdth = frmPπnt vsPπnterl .Width * 1 frmPπnt.vsViβwPortl VirtualHeight = frmPrint.vsPππterl. Height * 1 frmPnnt.vsViewPortl.BorderStyle = 1 'turn off border Case Else 'Magnify view frmPπntvsPrinterl Width = frmPπnt.vsPπnterl .PageWidth * 1 frmPπnt.vsPππtert. Height = frmPπnt.vsPπnterl .PageHeight * 1 ftmPπnt.vsVιewPort1.VlrtualWidth = frmPπnt.vsPπnterl .Width * 1 'ensure scroll bars will be shown frmPrint.vsViewPortl .VirtualHeight = frmPπnt.vsPπnterl. Height * 1 frmPπnt.vsViewPortl. BorderStyle = 0 'turn on border - End Select frmPπnt.vsPπnterl .Visible = True frmPπnt.vsViewPortl Visible = True frmPnnt vsViewPertl Refresh frmPrint.MousePoιnter = vbDefault DoEvents

End Sub

-4-

Figure imgf000074_0001
Printing. bas - UpdatePageButtons

+ CStr(frmPrint.HScrolH .Value) + " of " + CStr(giTotalPrintPages) scroll bar needed for a single page

Figure imgf000075_0001
DoEvents

End Sub

Figure imgf000076_0001

Public gsEditGrouplndexes As Stπng (iotas tempcrary ■πdexes to all locations associated with a group Public gsEditGroupName As Stnng

Type FaxDataStructure sFaxlD As Stπng sDialPrefix As Stπng iRetπes As Integer iRetrylnterval As Integer bFaxResolution As Byte sSenderName As Stπng sSenderCompany As Stπng sSenderFaxNumber As Stπng sSenderVoiceNumber As Stπng iLocTotal As Integer 'a count of the locations sLocPersonName(IOO) As Stπng 'rgh it may oe desirable in the future to make these arrays dynamic sLocFaxNumber(IOO) As Stπng sLocVoiceNumber(IOO) As Stπng

IGrou sTotal As Integer sGroupTitle(50) As Stπng sGroupNameslπTitle(50) As Stπng 'indexes tc names separated by pipe fie 3\6\ 15)

IGroupLastSelected As Integer End Type Public FAX_DATA As FaxDataStructure

Public Sub GetFaxLocationsO

Dim i As Integer, r As Integer, sSection As String

With FAX_DATA sSection = "Fax Locations"

.ILocTotal = Clnt(GetlNISetting(gsFaxFileSpec, sSection, Total Locations", "0")) — For I = 1 To .iLocTotal

.sLocPersonNamefl) = GetlNISettιng(gsFaxFileSpec, sSection, "Person " + CStr(i), "") .sLocFaxNumberfl) = GetlNISettmgtøsFaxFileSpec, sSection, "Fax " + CStr(i), "") .sLocVoιceNumber(i) = GetlNISettιng(gsFaxFileSpec, sSection, "Voice " + CStr(l), "") Next i sSection = "Fax Groups"

JGroupsTotal = GetlNISettιng(gsFaxFileSpec, sSection, "Total Groups", "0") . For I = 0 To .iGroupsTotal

.sGroupTitiefl) = GetlNISettιng(gsFaxFileSpec, sSection, "Group " + CStr(i), ~) .sGroupNameslnTitle(i) = GetlNISettιng(gsFaxFileSpec, sSection, "Group Locations " + CStr(i), "") . Next i sSection = "User Selections"

.iGroupLastSelected = Clnt(GetlNISettιng(gsFaxFileSpec, sSection, "Last Group Selected", "0"))

End With

End Sub

71 Fax bas - GetlndexToFaxGroupNJame

Public Function GetlndexToFaxGroupName(ByVal sGroup As String) As Integer

'Find sName in the list of tax names If found pass index back to caller otherwise return 0

Dim I As Integer sGroup = LCaseJ(sGroup)

With FAX.DATA For i = 1 To iGroupsTotal If LCaseS( sGroupTitle(ι)) = sGroup Then

GetlndexToFaxGroupName = i Exit Function End If Next I

End With

End Function

Public Function GetlndexToFaxLocName(ByVal sName As Stπng) As Integer

'F'hd sName in the list of tax names If found pass index oack to cailer otherwise return 0

ι)) = sName Then i

Figure imgf000077_0001

End Function

Public Sub RemoveGroupFromFaxList(ByVal sGroup As String)

'Remove the name from the list and move up all others in the list Dim I As Integer, j As Integer, ilndexFound As Integer

With FAX.DATA

— For I = 1 To .IGroupsTotal VooΛ through whole list for name

— If .sGroupTitle(ι) = sGroup Then 'found it here ilndexFound = i

Exit For End If Next i

— For I = ilndexFound To .iGroupsTotal - 1

.sGroupTιtle(ι) = sGroup Titlefj + 1 ) .sGraupNameslnTιtle(ι) = sGroupNameslnTitle(i ♦ 1) Next i

.iGroupsTotal = iGroupsTotal • 1 End With End Sub

Figure imgf000077_0002

^

Figure imgf000078_0001

Public Sub RemoveNameFromFaxList(ByVal sName As String)

'Remove the name from the list and move uo all others in the list

Dim I As Integer, ] As Integer, ilndexFound As Integer, r As Integer

Dim sTempϋst(IOO) As Stπng, sNewlndexes As Stnng, iTemp As Integer

With FAX.DATA For ι = 1 To iLocTotal 'look through whole list for name If sLocPersonName(ι) = sName Then 'cund it here ilndexFound = i

Exit For End If Next i For i = ilndexFound To .iLocTotal - 1 sLocPersonName(ι) = .sLocPersonName(ι + 1) sLocVoιceNumber(ι) = sLocVoιceNumber(ι + 1) sLocFaxNumber(ι) = sLocFaxNumber(ι + 1) Next i

.iLocTotal = iLocTotal - 1

'Now that the name nas been removed we must look at all of the indexes of 'each fax group to see it an index pointer was in there If so it must 'be removed Additionally, all index greater than the one removed must be 'decremented by one If IlndexFound Then For I = 1 To .iGroupsTotal Vook at eacn index record in a tax group

'Perse out all of the indexs into a list for easier processing r ■ ParseDellmStnng(.sGroupNameslnTϊtle(ι), "|", sTempϋstO) sNewlndexes = "" If r Then 'indexes where found for this record For | - 1 To r

'look at each item In the list to see If it equals or great than the one removed iTemp = Clnt(sTempUstQ)) If fTemp = ilndexFound Then 'same index must be removed from list

'nothing to do. Don't add it to new list of indexes Elself iTemp > ilndexFound Then 'higher indexes must be decremented by one iTemp = iTemp - 1 sNewlndexes = sNewlndexes + CStr(iTemp) + "l" Else Ongnal value is OK sNewlndexes = sNewlndexes + CStr(iTemp) + "|" End If NextJ End If

.sGroupNameslnTitle(r) = sNewlndexes 'store the new list of indexes back to array Next i End If

End With

End Sub

?A Fax. as - SetFaxDeviceLabel _ r

60

Public Sub SetFaxDeviceLabel()

'This label on the options tab displays the status of the fax device. 'If a tax device exists then the lapel displays the device, otherwise 'it shows an appropnate message

With frmOptions.lblFaxDevice If gcFax.DeviceCouπt > 0 Then 'at least ana fa < device was found

' For i - 0 To gcrax.DeviceCcunt ■ 1

.Caption = gcFax.Devιces(O) 'show name of '.he device found .BackColor = &HFF00& 'green background

.ForeColor = &H0& ' Next I

— Else 'no fax devices were found

.Caption = "A fax device was not found. Please ensure the fax or modem is connected propery '

.BackColor = &H80& 'red background

.ForeColor = &HFFFFFF 'white End If

End With

End Sub

_-_.

y Calendar.bas - File Declarations

Attπbute VB_Name « "modCaleπdar" Option Explicit

Private giCompliedDosesCreated As Integer number of Complied Doses to show on the calendar

Private giNonCompliedDosesCreated As Integer numoer of non-complied Doses to show on the calendar

Private giDoseSizeChangesCreated As Integer

Private giZoomDosesCreated As Integer numoer of Doses to show m zoom box

Private giDosesMissedCreated As Integer numoer of objects to show for missed days

Private gbCalendarUpdatelπProgress As Integer prevents recursive calls while updating calendar

Public gsngComplianceTimeRaπge As Single 3 of hrs on either side of a prescπpec cose ir which a dose must oe taken

Type CALENDAR_SELECTIONS chkDosesTaken As Byte chkDosesNotComplied As Byte chkDosesMissed As Byte

ChkDoseChanged As Byte End Type Public CAL_DEFAULTS As CALENDAR_SELECTIONS

Type SUMMARY_SELECTIONS cmboDataToView As Byte cmboChartType As Byte End Type Public PAT_SUM_DEFAULTS As SUMMARY_SELECTIONS

Public Function CalcDayslnMonth(ByVal iMonth As Integer, ByVal iYear As Integer)

'Calculate the number of days In the month/year that is passed here Dim I As Integer, ITemp As Long i = iMonth + 1 lf i * 13 Then ! = 1

ITemp = CVDate(CStr(i) + 70ir + CStr(iYear)) ITemp ■ rTemp - 1 CaicDayslπMonth = Day(ITemp) End Function

Public Sub DrawAIIDoseSizeChaπgesQ

Dim I As Integer, r As Integer, iDayslnMonth As Integer

Dim sCaleπdarStartDate As Stπng, dTime As Double

Dim IDateDifference As Long, ICalendarStartDate As Long

Dim bFirstDayAlreadyPlotted As Boolean, bLastDayAlreadyPlotted As Boolean

RemoveDoseSizeChanges 'remove all of the old doses first iDayslnMonth = CalcDayslnMonth(frmDosingCalendar.Calendar.Month, frmDosingCalendar Calendar.Year) sCaleπdarStartDate = CStr(frmDosιngCalendar.Calendar.Month) + 01 Λ + StrS(frmDosιngCalendar Calendar Year) ICalendarStartDate = DateValue(sCalendarStartDate)

etc)

Figure imgf000080_0001

Tftis section of code ensures that dosing info is always plotted on the first and last day of the month

If bFirstDayAlreadyPlotted = False Then

7f Calendar bas - Dra AIIDoseSizeChanges

r = FindPrescιbedDoseSιzeForSpecιrιcDay(PAT_DATA, ICalendarStartDate) DrawSingleDoseSizeChange 1 , dTime, r, False End If

If bLastDayAlreadyPlotted = False Then r = FindPrescιbedDoseSιzeForSpecιficDay(PAT_DATA, ICalendarStartDate ♦ iDayslnMonth - 1)

DrawSingleDoseSizeChange iDayslnMonth, dTime, r, False End If

For i = 1 To giDoseSizeChangesCreated 'show all the Doses

Z frmDosιngCalendar.shapeDoseSιzeChange(ι) Visible = True Next i

End Sub

Public Sub DrawAIICompiiedDosesTakenO

Dim I As Integer, r As Integer

Dim SCalendarStartDate As Stπng, dTime As Double

Dim IDateDifference As Long, ICalendarStartDate As Long

Dim I'DayDoseCount As Integer, iDayNumberBeingPlotted As integer, iLastDoseDayDrawn As Integer

Dim iDayslnMonth As Integer, ITemp As Long

RemoveCompliedDosesTaken remove all of the old doses first

If frmOosingCalendar.chkDosesTaken. Value = False Then Exit Sub sCalendarStartDate = CStr(frmDosιngCalendar.Caleπdar.Month) + 01T + Strϊ(frmDosιngCalendar.Caleπdar.Year) ICalendarStartDate = DateValue(sCalendarStartDate)

'Calc the number of days in the month being dsplayed

IDayslnMonth = CalcDayslnMonth(frmDosιngCalendar.Calendar.Moπth, ffmDosingCaleπdar.Calendar.Year)

Figure imgf000081_0001

For i = 1 To giCompliedDosesCreated 'sΛow all the Doses

Z -τnDosιngCalendar.shapeDose(i). Visible = True Next i

End Sub

7 ? Calendar.bas - Dra AIIDosesMisseσ

Public Sub DrawAIIDosesMissed()

Dim i As Integer, IDayslnMonth As Integer, I As Long Dim sCalendarStartDate As String Dim IDateDifference As Long, ICalendarStartDate As Long Dim iDayDoseCount As Integer, iDayBeiπgPlotted As Integer

RemoveDosesMissed remove all of the old doses first

If frmDosingCalendar.chkOosesMissed.Value = False Then Exit Sub iDayslnMonth = CalcDayslnMonth(frmDosingCalendar.Calendar.Month, frmDosingCalendar.Caleπdar.Year) sCalendarStartDate = CStr(frmDosingCalendar.Caleπdar.Moπth) + 01T + CStr(frmDosingCalendar.Calendar.Year) ICalendarStartDate = DateValue(sCalendarStartDate)

Figure imgf000082_0001
sMissedCreated show all the Doses ar.shaρeDoseMissed(i). isible = True
Figure imgf000082_0002

End Sub

Public Sub DrawAIINonCompliedDosesTakenO

Dim I As Integer, J As Integer, bDoseOutOfCompliance As Boolean

Dim dTimeϋmit As Double, dLowUmit As Double, dHlghUmit As Double

Dim sCalendarStartDate As String, dTime As Double

Dim IDateDifference As Long, ICalendarStartDate As Long

Dim iDayDoseCount As Integer, iDayNumberBeingPlotted As Integer, iLastDoseDayDrawn As Integer

Dim iDayslnMonth As Integer

RemoveNonCompliedDosesTaken remove all of the old ddses first

If frmDosingCalendar.chkDosesNotComplied. Value = False Then Exit Sub iDayslnMonth = CalcDayslnMonth(frmDosingCalendar.Calendar.Month, frmDosingCalendar.Calendar.Year) sCalendarStartDate = CStr(frmDosingCalendar.Calendar.Month) + 701 " + Str$(frmDosingCalendar.Calendar.Year) ICalendarStartDate = DateValue(sCalendarStartDate) d TimeUmit » gsngComplianceTimeRange / 24 _ For I = 1 To PAT_DATA.IEventData(0) 'total number of events If PAT_DATA.byteEventType(I) * giEVENT DOSE TAKEN Then 'snow only med events (not errors, etc)

IDateDifference = lnt(PAT_DATA.dEventDate(l))~ ICalendarStartDate If IDateDifference >= 0 And IDateDifference <= iDayslnMonth Then dose occurred duπng this month dTime - PAT_DATA.dEventDate(i) - lπt(PAT_DATA.dEventDate(i)) 'get time of dose 'Determine if the dose occurred within the compliance parameters 'rgh see If we can use our procedure already created If gsngComplianceTimeRange Then 'do test If there is a value set In the compliance time range bDoseOutOfCompliance = True 'sef default to be out of range unless otherwise set below — Forj = 1 To PAT_DATA.iDosesPerDay

'compare dose time against all of the alarm times dLowUmit = PAT_DATA.dPrescribedDoseTime(j) - dTimeUmit - 0.0001 'add a factor to prevent rounding error dHighϋmit = PAT^ DATA.dPrescribedDoseTimefj) + dTimeϋmit ♦ 0.0001 If dTime >= dLowϋmit And dTime <= dHighϋmit Then '(his cose is within compliance bDoseOutOfCompliance = False sef flag to not plot this dose

Exit For 'no need for further testing of this dose. It is in compliance End If Next !

fo Calendar.bas - DrawAIINonCompliedDosesT]

dat

Figure imgf000083_0001
To giNonCompliedDosesCreated 'show all the Doses singCalendar shapeDoseNonCompfy(i) Visible = True
Figure imgf000083_0002

Public Sub DrawSingleDoseSizeChange(iDay As Integer, dTime As Double, iEventNumber As Integer, bHighlig

'Draw dosing Doses for the day of the month and time of day passed in here

'Time of time is expressed in decimal places as a portion of a day (VB time format)

'NOTE No checks are currently made to determine whether the event Is a med event or

'a non-med event If both events are kept in the same array then a test of the med bit

'must be done before plotting

'A Dose is not visible when first created The caller should dsplay the Doses once they

'a all created so as to speed the redraw df the screen.

'Create another done of the the Dose shape located in the array DosefO)

'When this feature is on. a dose size is automatically entered on the first and last day of the month

' On Error Resume Next

Dim I As Integer, iWeekDay As Integer

Dim IDoseLelt As Single, IDoseTop As Single

Dim ITemp As Long, IDayWidth As Long, IDayHeight As Long

umber)) + " mg

Today "

Figure imgf000083_0003

'These lines are a work-around for a bug in the control that causes it to

'return the wrong values for day left day top. etc When fixed, we can simply use those properties

'and remove these calculations

IDayWidth = (frmDosingCalendar Calendar. idth - 50) . 7 actual scalewidth of a single day

ITemp « (frmDosingCalendar.Calendar.DayLeftfJDay) * 26) / IDayWidth 'approximate location of the day iWeekOay = Clnt(ITemp)

IDoseLelt = (IWeekDay * IDayWidth) gef /er? edge of day to plot

'IDoseLeft - IDoseLeft * ((IDayWidth / 5) * iPlotPosition ■ 1) - (IDayWidth / 10)

IDoseLelt = IDoseLelt + (IDayWidth * 0 8) - (rmDosιngCalendar.shapeDoseSιzeChange(gιDoseSιzeChangesCreated) Width

If lnt(IOayWidth / 150) < 7 Then frmDosιngCalendar.shapeDoseSιzeChange(gιDoseSιzeChangesCreated) FontBold = False Else

f t Calendar.bas - DrawSmgleDoseSizeChang

frmDosingCalendar shapeDoseSizeChange(gιDoseSιzeChangesCreated) FontBold = True End If

(rmOosιngCalendarshapeDoseSιzeChange(gιDoseSιzeChangesCreated).FontSize = lnt(IDayWidth / 150) (rmDαsιπgCalendar.shapeDoseSιzeChange(gιDoseSιzeChaπgesCreated).Lert = IDoseLeft ήese lines are a work-around for a bug in the control that causes it to

'return the wrong values for day left day top etc When fixed we can simμy use those properties

'and remove these calculations

'The control is even moe stupid than I first sucected It can not always return the proper vertical

'location of a day thus we have to jump through more heaps to figure out what week that a particular

'day is in

IDayHeight = (frmDosingCalendar Calendar.Height - 50) - 625 'an offset is used to compensate tor height of title

IDayHeιght = IDayHeιght/ 6 iWeekDay = (frmDosingCalendar Calendar.DayLeft(l) * 26) / IDayWidth 'the approximate locacαπ of the cay

ITemp = lnt((IDay + iWeekDay - 1) / 7)

IDoseTop = (ITemp * IDayHeight) + 625 'this numoer factors in the title bar IDoseTop = IDoseTop + 50 frmDosιngCalendar.shapeDoseSιzeChange(gιDoseSιzeChangesCreated).Toρ = IDoseTop frmDosingCalendar shapeDoseSizeChange(gιDoseSιzeChangesCreated).Tag = iEventNumber 'keep event number for updating the zoom pox

' On Error GoTo 0

End Sub

Private Sub DrawSingleNonCompiiedDoseTaken(iDay As Integer, dTime As Double, iEventNumber As Integer, iPlotPositioπ As Integer)

'Draw dosing Doses for the day of the month and time of day passed in here

Time of time is expressed m decimal places as a portion of a day (VB time format)

'NOTE: No checks are currently made to determine whether the event is a med event or

'a non-mβd event If both events ere kept In the same array, then a test of the med tut

'must be done before plotting.

'A Dose is not visible when first created The caller should display the Doses once they

'are all created, so as to speed the redraw of the screen.

'Create another clone of the the Dose shape located in the array Dose(O)

On Error Resume Next

Dim I As Inteπer, IWeekDay As Integer

Dim IDoseLeft As Single, IDoseTop As Single

Dim ITemp As Long, IDayWidth As Long, IDayHeight As Long giNonComplledDosesCreated = giNonCompliedDosesCreated + 1 'increment Dose counter

Load frmDosιngCaleπdar.shapeDoseNonComply(giNonComplιedDαsesCreated) 'create a new Dose

'These lines are a work-around for a bug in the control that causes it to

'return the wrong values for day left, day.top. etc When fixed, we can imply use those properties

'and remove these calculations

IDayWidth = (frmDosiπgCalendar.Caleπdar. Width - 50) / 7 'actual scalewidth of a single day iWeekDay = (frmOosιngCalendar.Calendar.DayLeft(iDay) * 26) / IDayWidth 'approximate location of the day

IDoseLeft = (iWeekDay * IDayWidth) 'gef left edge of day to plot IDoseLeft = IDoseLeft + ((IDayWidth / 5) * iPlotPosition - 1) - (IDayWidth . 10) (fmDosιngCalendar.shapeDoseNonComply(gιNonComplιedDosesCreated).Left = IDoseLeft

These lines are a work-around for a bug in the control that causes it to

'return the wrong values for day left day.top etc When fixed, we can simply use these properties

'and remove these calculations

The control is even moe stupid than I first supected It can not always return the proper vertical

'location of a day thus we have to jump through more hoops to figure out what week that a particular

'day is in = (frmDosingCalendar. Calendar.Height - 50) - 625 'an offset is used to compensate for height of title Calendar.bas - DrawSingleNonCompliedDose ,

IDayHeight = IDayHeight / 6 iWeekDay = (frmDosιngCalendar.Calendar.DayLert(1 ) * 26) / IDayWidth 'fne approximate location of the day

ITemp = lπt((IDay + iWeekDay - 1) 17)

IDoseTop ■ (ITemp ' IDayHeight) + 625 'this numoer factors in the title bai

IDoseTop = IDoseTop + IDayHeight - 50 - frmDosιngCalendar.shapeDose(O) Height - frmDosingCalendar shapeDoseNoπComply(O). V Height 'draw m middle of day frmDosιπgCaleπdar.shapeDoseNonComply(gιNonComplιedDosesCreated).Top = IDoseTop frmDosingCalendar shapeDoseNonComply(gιNonComplιedDosesCreated).Tag = iEventNumber 'keeo event numoer for updatinc the

W room box

On Eπ-or GoTo 0 End Sub

Public Function lsDoseWithinPrescribedTimeRaπge(DataStruct As DeviceDataStruct, ByVal ilndex As Integer)

'Test to see that the event at the incex passed r.ere is a meαcation event and that vr is mtnir. the orescnbed time range rcr a daily dese If yes. then pass TRUE pack to the caller

Dim i As Integer, dTime As Double

Dim d TimeLimit As Double, dLowUmit As Double, dHighϋmit As Double 'gef time of dose

'add a factor to prevent rounding error

Figure imgf000085_0001
End Function

Private Sub PrintCalendarQ

This routine is called when the user presses the pπnt button on the calendar form

Dim sPπntlπfo As Stnng Dim CRLF As String Dim bcolorCalendar As Long Dim bcolorpnIZ∞m As Long Dim bcαlorpnITimβ As Long Dim bcolorForm As Long Dim fcolorPrescnbed As Long Dim fcoiorMlssed As Long Dim fcolorWβek As Long

Dim curTop As Long Dim curWidth As integer Dim curHetght As Integer

Const XOffset = JS20 Coπsf YOflser = 1890

On Error GoTo Errαr_btr.Pnnt CRLF = ChrS(13) ♦ ChrZ(IO)

43 O 99/35588

Calendar.bas - PrintCalendar

curTop = Me Top curWidth - Me Width curHeight = Me Height

' Hide this guy off the screen while we pπnt Me.Top = -(curHeignt ' 2)

' Save current background colors bcαtorCalanoar - Calendar BackColor bcoioronlZoo = onlZoo BackColor bcoiorsnlTtme - pnlTime BackColor bcotorForm = We BackColor rcolorPrescπoed = chkDosesTaken Fn'ICetαr tcolorMissed = ChkDosesMissed FillCcicr fcdorWeek - ch WeekNumoers FtllColor

' hide the buttons btnClose Visible = False btnPπnt.Visibie = False

' Add date + time into to onnted data sPnntlnfo - "Pnnted en ' - FormatStNew "dcαdd hh nn'l

IblPnntlnto.Capαon = sPnntlnto

' Set titles at top of pnnted page IblTitlβ.Captiαn = "Dosing Calendar" IblPatient.Caption = "Patient' ' * tgDevicestat.sPaαent Ibldπig Caption - "Drug ' * tgDevicestat sDrug

' Set background colors Caiendar.BackColor= WHITE pnlZoom.3ackColor - WHITE pnlTime BackColor* WHITE Me.3ackCdor -~ WHITE chkDosesTakeπ.FillColor = WHITE chkDosesMissed.FillColor = WHITE chkWeekNu bers FillCdor= -WHITE

' Let user know we are pπnting

Load frm_Status frm_Status.iblStatus Caption - 'Prepaπng to pπnt calendar" frm_Status.Show

' Move resize the form and move objects to gve space forpnnting

Call DeleteAIIObjects ' remove extraneous elements from calendar

Call MoveFormObjectsfMe XOffset. YOffset. True)

Call UpdateCalendar

DoEvents

'Call UpdateZoomBox

' Smtch on visibility of titles IblPnntlnfo.Visible = True IblTitle.Visible = True IblPatient.Visblβ = True ibldrug.Visble = True

' Make Check ooxes two dimensional chkDosesTaken CheckSoxΣd - True ChkDosesMissed CheckBox2d = True chkWeekNumbers CheckBox2d = True

' Sπng the Zoom laoles to the front IblZoomTime.ZOrder 0 IblZoomTtme Visible - True

' Pπnt the fomx Caleπdar.bas - PriπtCalendar

.We Height - Me Height - YOtfset Me Width - Me Width - XCftset

DoEvents Me PnntFoπr. DoEvents frm_Status lblS:a:us Cacticn - 'Sending calendai to pπnte'"

' hide the π'les and show the buπons . oiPnntlnto Visible = False IblTitle Visible - False

fY Calendar.bas - PrintCalendar

IblPatient.Vtstble = Faise ibldmg.Visibie = raise

' Move ever/thing back Call DeteteAIIObiecis Call MoveFormObjects(Me XOftset -YOffset. True) Call UpdateCalendar

' Restore background colors Calendar BackColor = ocolorCalendar pnlZoom.3ackColor - bcciorpniZoom pnlTime. BackColor - ocolorpnlTi e Me. BackColor = ocαlorFoim ChkDasesTaken.FillColor = fcolorPrescnoed chkDcsesMissed.FHICαlor - fcolorMisseo cnkWee Numbers FAICdαr - tcclorWeek

' Restore buttons btnClcse Visible = True btnPnnt.Visibie = True

' Set check boxes pack to 3d ' Make Check boxes rxvo dimensional chkDosesTakeπ.CheckBox2d = False chkDosesMlssed.CheckBox2d = False chkWeekNumbers.CheckBox2d = False

Figure imgf000088_0001

Mβ.Height = curHeight

Me. Top - cur Top ' bπng form back into view

Unload fmt_Status

'Exit btnPnn Exit Sub

'Error_btnPιinf

Resume Exιt_btπPnnt

Figure imgf000088_0002
Caleπdar.bas - PrintCalendar

70

End Sub

Public Sub RemoveDoseSizeChanges()

Dim i As Integer

On Error Resume Next 1 To giDoseSizeChangesCreated remove all previous Doses ad frmDosingCalendar. shapeDαseSιzeChange(i)

Figure imgf000089_0001
giDoseSizeChangesCreated = 0

On Eπ-or GoTo 0 End Sub

Public Sub RemoveDosesMissedf) Dim i As Integer On Error Resume Next To giDosesMissedCreated 'remove ail previous oo/ecrs frmDosιngCalendar.shapeDoseMιssed(i)

Figure imgf000089_0002
giDosesMissedCreated = 0

On Error GoTo 0 End Sub

Public Sub RemoveCompliedDosesTakenO

Dim i As Integer

On Error Resume Next 'remove all previous Doses (l)

Figure imgf000089_0003
giCompliedDosesCreated = 0 On Error GoTo 0 End Sub

Public Sub RemoveNonCompliedDosesTakenO

Dim i As Integer

On Error Resume Next

For i = 1 To giNoπCompliedDosesCreated 'remove all previous Doses

Unload frmDosιngCalendar.shapeDoseNonComply(i) Nexti giNonCompliedDosesCreated = 0

On Error GoTo 0 End Sub

?7

Figure imgf000090_0001

Public Sub UpdateZoomBoxO

'A afferent day was dicked on the calendar so we need to plot the events lor

'the current day into the zoom box

This procedure draws doses taken for a gven day

NO i = No checks are currently made to catermine whether the event is a med event or

'a non-med event If both events are kept in the same array then a test cf the med bit

'must be done before plotting.

Dim i As Integer, dTime As Double, iDoseDay As Integer, iZoomPanelWidth As Integer

Static bProcedurelnProgress

If bProcedurelnProgress Then Exit Sub bProcedurelnProgress = True pre venf error if already unloaded ated 'remove ait previous Doses shapeZoomDose(i)

Figure imgf000090_0002
giZoomDosesCreated = 0 For i = 1 To 4

Unload frmDosιngCalendar.shapeZoomPrescπbed(i) 'clear the text box fcr zoom time

Unload frmDosιngCalendar.shapeZoomTιmeRange(i) 'dear the text box for zoom time

On Error GoTo 0 'resume normal error status

Figure imgf000090_0003

' Foπ = 1 To 4 frmDostngCalencartxtZαomTιme(i) Caption = " dear the text box fcr zoom time

' Nexti

Dim ICalendarOate As Long

ICalendarOate = DateValue(frmDosιngCalendar.Caleπdar.Date)

- For i = 1 To giCompliedDosesCreated

'rgh we may laterwant to use a global array instead of the tag property to prevent flashing and speed things UP iDoseDay = frmDosιngCalendar.shapeDose(i).Tag 'gef the dav that the cose was taken on If lnt(PAT_DATA.dEventDate(lDoseDay)) = ICalendarOate Then

'Create another clone of the the Dose shape located in the array Dose(O) giZoomDosesCreated = giZoomDosesCreated + 1 'increment Dose counter

8Z Calendar.bas - UpdateZoomBox

Load frmDosingCalendar shapeZoomDose(gιZoomDosesCreated) 'create a new Oose dTime = PAT_DATA dEventDate(ιDoseDay) - lnt(PAT_DATA.dEventDate(IDoseDay)) frmDosingCalendar.shapeZoomDose(giZoomDosesCreated).Left - (frmDosingCalendar pnlZoom Width * dTime) • ( frmDosingCalendar shapeZoomDose(gιZoomDosesCreated).W1dth / 2) frmDosιngCalendar.shapeZoomDose(gιZoomOosesCreated) ToolTipText = FormatϊfdTime, gsTimeDisplayFormat) frmDosingCalendar shapeZoomDose(gιZoomDosesCreated) Visible = True (rmDosιπgCalendar.shapeZoomDose(gιZoomDosesCreated).ZOrder End If Next i For i = 1 To giNonCompliedDosesCreated iDoseDay = frmDosingCalendar shapeDoseNonComply(ι).Tag gef rfie day mat the dose

Figure imgf000091_0001
taken on If lnt(PAT_DATA dEventDate(ιDoseDay)) = ICalendarOate Then

'Create another clone of the the Dose snape Ipcarecm 'he array Dose(Q) giZoomDosesCreated = giZoomDosesCreated + 1 'increment Dose counter

Load ffmDosιngCalendar.shapeZoomDose(gιZoomDosesCreated) 'create a new Dose dTime = PAT_DATA.dEventDate(ιDoseDay) - lnt(PAT_DATA.dEventDate(iDoseDay)) frmDosιπgCalendar.shapeZoomDose(gιZoomDosesCreated).Left = (frmDosingCalendar.pnlZoom.Width ' dTime) - ( » frmDosingCalendar shapeZoomDose(giZoαmDosesCreated) Width / 2) frmDosιngCaiendar.shapeZoomDose(gιZoomDosesCreated).ToompText = Format$(dTιme, gsTimeDisplayFormat) frmDosingCalendar shapeZoomDose(gιZoomOosesC-eated). isible = True frmOosιπgCalendar.shapeZoomDose(gιZoomDosesCreated).ZOrder End If Next i frmDosingCalendar pnlZαom Caption = FormatS(frmDdSingCalendar Calendar Date 'General Date") * " Detail View"

'update position of time scale For l = 2 To 22 Step 2 frmDosιngCalendar.lblDetaιiTime(ι).Lef) = (frmDosingCalendar.pnlZoom.Wldth * (I / 24)) - (frmDosingCalendar.lblDetailTime(i). Width V* 12) Next i frmDosingCalendar.shapeDayϋght(2).Width = fmiDosingCalendar.pnlZoom. idth * 0.53 ffmDosingCalendar.shapeDayUght(1 ).Width = frmDosiπgCalendar.pnlZoαm.Wldth * 0.03 ffmDosιngCalendar.shapeDayϋght(3).Width = frmDosingCalendar.shapeDayϋght(1 ).Width frmDosιngCalendar.shapeDayϋght(2).Left = (frmDosingCalendar.pnIZoom.Width - frmDosιngCalendar.shapeDayLιght(2).Wldth) / 1.8 frmDosιngCalendar.shapeOayUght(1).Left = 20 + frmDosιngCalendar.shapeDayUght(2).Left - frmDosingCalendar. shapeDayϋght(l). Width ffm0osιngCalendar.shapeDayϋght(3).Left = frmDosιngCalendar.shapeDayLight(2).Left + frmDosιngCalendar.shapeDayϋght(2).Width V - 15 bProcedurelnProgress = False

End Sub

Private Sub MoveFormObjects(frrn As Form, XOffset As Integer, YOffset As Integer, VisibleOnly As Integer)

This routine moves all objects on a form by the speαfed amount

Argument Description trm Form object

XOffset offset (in tvπps) to move in x plane Positive is to the nght

YOffset offset n twtps) to move in y plane Positive is down

VisibleOmy If true only move visible ob/ects Dim i As Integer On Error GoTo Error_MoveFormObjeets

Figure imgf000091_0002

y ? Calendar.bas - oveFormObjects

Figure imgf000092_0001

Error_MoveFormObjects'

Resume Exιt_MoveFormObjects

End Sub

Private Sub DrawSingleCompliedDoseTaken(iDay As Integer, dTime As Double, iEventNumber As Integer, iPIo

Draw dosing Doses for the day of the month ana time of dav passed in nere

'Time is expresseα in decimal places as a portion of a day f'/3 time Ormat)

'NO~E No checks are currently made to σeiermine whether the event is a med event or a non-τed event if bth events are kept in the same array then a test of the eα bit must be done before plotting

'A Dose is not visible when first created The caller snouid dsptay the Dcses once they

'are all created so as to speed the recraw of the screen

'Create another clone of the the Dose shape located m tne array Cose(C)

On Error Resume Next

Dim i As Integer, iWeekDay As Integer

Dim IDoseLelt As Single, IDoseTop As Single

Dim ITemp As Long, IDayWidth As Long, IDayHeight As Long giCompliedDosesCreated = giCompliedDosesCreated + 1 'increment Dose counter

Load frmOosιngCalendar.shapeDose(gιComplιedDosesCreated) create a new Dose

'These lines are a work-around for a bug in the control that causes it to

'return the wrong values for day left day top etc When fixed we can simplv use those properties

'and remove these calculations

IDayWidth = (frmDosingCalendar.Calendar.Width - 50) / 7 'actual scaiexwidth of a single day

IWeekDay = (frmDosingCalendar .Calendar.DayLeri(iDay) * 26) / IDayWidth approximate location of the day

IDoseLeft = (IWeekDay * IDayWidth) 'gef left edge of day to plot IDoseLeft = IDoseLeft + ((IDayWidth / 5) * IPIotPosition - 1) - (IDayWidth / 10) ftmDosιngCalendar.shapeDose(gιComplledDosesCreated).Left = IDoseLeft

TTiese lines are a .work-around for a bug in the control that causes it to

'return the wrong values for day left day top. etc When fixed, we can simply use those properties

'and remove these calculations

"The control Is even moe stupid than I first suoected It can not always return the proper vertical

'location of a day, thus, we have to jump through more hoops to figure out what week that a particular

'day is in

IDayHeight = (fr DosingCalendar.Calendar.Height - 50) - 625 'an offset is used to compensate for height of title

IDayHeight = IDayHeight / 6 iWeekDay = (frmDosιngCalendar.Calendar.DayLeft(l) * 26) / IDayWidth 'fήe approximate location of the day

FTemp = lnt((IDay + IWeekDay - 1) / 7)

IDoseTop = (ITemp * IDayHeight) + 625 'this number factors in the title bar

IDoseTop = IDoseTop + IDayHeight - 25 - (rmDosingCalendar.shapeDose(O).Height 'draw in bottom of day ffmDosιngCaleπdar.shapeDose(gιComplιedDosesCreated).Top = IDoseTop frmDosingCalendar .shapeOose(gιComplιedDosesCreated).Tag = iEventNumber 'keep event number for updating the zoom boy

On Error GoTo 0 End Sub

Figure imgf000092_0002
Figure imgf000093_0001

Private Sub DrawSingleDoseMissed(iDay As Integer, iPlotPosition As Integer) 'Draw doses tor the day of the month passed in here

NOTE No checks are currently made to determine whether 'he event is a med event or 'a non-med event A test of the med bit must be done before catling this procedure 'A Dose is not visible when first created The caller should dsulay the Doses once they are all created so as to speed the redraw of the screen

On Error Resume Next

Dim I As Integer, iWeekDay As Integer

Dim IDoseLeft As Single, IDoseTop As Single

Dim ITemp As Long, IDayWidth As Long, IDayHeight As Long giDosesMissedCreated = giDosesMissedCreated + 1 'increment Dose counter

'Create another clone of the the Dose snape located in 'he array Dose( )

Load frmDosingCalendar shapeDoseMιssed(gιDosesMιssedCreated) create a new Dcse

'Tnese tines are a work-around for a pug in the control mat causes it to

'return the wrong values fcr day. left, day top. etc When fixed we can simply use these properties

'and remove these calculations

IDayWidth = (frmDosingCalendar Calendar. Width - 50) / 7 'actual scalewidth ct a single day iWeekDay = (frmDosιngCalendar.Calendar.DayLeft(ιDay) * 26) / IDayWidth approximate location cf the cay

IDoseLeft = (iWeekDay * IDayWidth) 'gef left edge of day to plot IDoseL-ft = IDoseLeft + ((IDayWidth / 5) * iPlotPosition - 1) - (IDayWidth / 10) frmOosιngCalendar.shapeOoseMιssed(gιDosesMιssedCreated).Left = IDoseLeft

'These lines are a work-around for a bug in the control that causes it to

Figure imgf000093_0002

IDoseTop = (TTemp * IDayHeight) + 625 'this number factors in the title ber

IDoseTop = IDoseTop + IDayHeight - 75 - frmDosιπgCalendar.shapeDose(0).Heιght - ffmDosιπgCalendar.shapeDose(O) Height - frmDosingCalendar.shapeDose(O). Height 'draw in bottom of day

(IτnDosιngCalendar.shapeDoseMιssed(giDosesMιssedCreated).Top = IDoseTop

On Error GoTo 0 End Sub

Public Sub UpdateCalendarO

The month or year to the calendar has changed, so we need to plot the events tor 'the current month and year being shown

Static bProcedurelnProgress As Boolean If bProcedurelnProgress Then Exit Sub bProcedurelnProgress = True

Dim iObjeetDiameter As Integer

'Show custom laoeis from config file if there were any

If Len(gsCustomLblPatιentLastName) > 0 Then frmDosingCalendar.Labell = gsCustomLbiPatientLastName frmDosingCalendar IblPatientName = " " + PAT_DATA sPatientLastName + ", " + PAT_DATA.sPatιentFιrstName iObjectOameter = frmDosingCalendar.Calendar.Width / 45 'resize the objects drawn on the calendar

If iObjeetDiameter > frmOosingCalendar.Calendar Height / 50 Then iObjeetDiameter = frmDosingCaleπdar.Calendar.Height / 50

V

Figure imgf000094_0001

DrawAIICompliedDosesTaken DrawAIINonCompliedDosesTaken DrawAIIDosesMissed DrawAIIDoseSize Changes

UpdateZoomBox bProcedurelnProgress = False End Sub

Public Sub RemoveAIIObjectsO

Remove all oo/ects from calendar RemoveCompliedDosesTaken Remove DosesMissed DoEvents End Sub

?* frmMain.frm - File Declarations

Attπbute VB_Name = "frmMain" Attπbute VB_GlobalNameSpace = False Attnbute VB_Creatable = False Attπbute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit

Private Sub CommTimer_Timer() gbCommTimerExpired = True CommTimer.Enabled = False End Sub

Private Sub Fax an1_ConfigurationDone()

Dim i As Integer frmOptions.MousePointer = vbDefault frmOptions.btnConfigureFax. Enabled = True

SetFaxDeviceLabel End Sub

Integer, Status As Integer) .Status(Devιce) = "Answeππg" Then

Figure imgf000095_0001
frmFaxStatus.lblRemotelD = gcFax.StatusRemotelD(Device)

_ If geFax.StatusConnectSpeed(Device) > 0 Then = gcFax.StatusConnectSpeed(Device) = "" vιce) Then CStr(gcFax.StatusPagesSent(Devιce)) + " of " + Str$(gcFax.StatusPages(Device)) CStr(gcFax.StatusPagesSent(Device))

Figure imgf000095_0002
ntage(Devιce) > 0 Then rcent = CStr(gcFax.StatusPerceπtage(Device)) + " % Complete" rcent = "*
Figure imgf000095_0003
ftmFaxStatus.lblStatus = gcFax.Status(Devιce) frmFaxStatus.lblDestination = gcFax.StatusDestιnatιon(Devιce) firmFaxStatus.lblFaxNumber = gcFax.StatusNumber(Devιce) End Sub

?3 frmMain.irm - MDIForm_Load

Private Sub MDIForm_Load()

On Error Resume Next

Me. Left = CLng(GetlNISettιng(gsApplnιFιleSpec, "Windows", "Mam Left", "1000")) Me.Top = CLng(GetlNISettιng(gsApplπιFιleSpec, "Windows", "Main Top", "1000")) Me.Width = CLng(GetlNISettιng(gsApplnιFileSpec, "Windows", "Main Width", "6500")) Me.Height = CLπg(GetlNISettιng(gsApplnιFιleSpec, 'Windows", "Mam Height", "6500")) Me WindowState = CLng(GetlNISettιng(gsApplnιFιleSpec "Windows' "Main WmαowState' "0")) On Error GoTo 0 End Sub

Private Sub DIForm_Unload(Cancel As Integer)

Dim r As Integer r = ValidatePatlentDataSaved 'make sura any αevice data has first been saved Save Window positions ndowState <> vbMinimized Then NISetting gsAppiniFiieSpec, "Windows", "Main Left", CStr(Me Left) NISetting gsAppiniFiieSpec, "Windows", "Main Top", CStr(Me.Top) NISetting gsAppiniFiieSpec, "Windows", "Main Width", CStr(Me Width) NISetting gsAppiniFiieSpec, "Windows", "Main Height", CStr(Me. Height) NISetting gsAppiniFiieSpec, "Windows", "Mam WindowState", CStr(Me.WindowState)

Figure imgf000096_0001

SaveProgramPreferences End Sub

Private Sub mnuAccessWebSite_Click()

'if the form is minimized then set it back to nomnal

Call LogonToWebSrte

If frmBrowser. WindowState = vbMinimized Then frmBrowser.WlndowState = vbNormal End If frmBrowser.ZOrder End Sub

Private Sub mnuFaxConfigure_Click() g atestOptionsTabSelected = 2 'άsplay the tax tab once the dialog is opened frmOptions.Show vbModal End Sub

Private Sub mnuFaxSeπd_Click() frmFaxSend.Show End Sub

Private Sub mnuFaxViewLogs_Click() frmFaxLog.Show End Sub frmMain frm - mnuFιlePropertιes_Clic

Private Sub mnuFilePropertιes_Clιck() frmOptions Show vbModal End Sub

Private Sub mnuFileSave_Click()

Dim r As Integer Name = "" Then ATA sPatientDataFileName)

Figure imgf000097_0001

_ If r = False Then

Beep

MsgBox "An error occurred while attempting to save the data file It was not saved vbCπtical "File Not Saved" _ End If End Sub

Private Sub mnuGenError_Click()

MsgBox This is a temporary test error handler When you click OK, a synthethic error (Divide by 0) will be generated The same dialog

V will bt: shown when any eπ-or is generated It generates a log Hie that provides valuable information for the developer This will be * removed from the next build ", vblnformation, Test Error Handler"

Error 11 End Sub

Private Sub nuHelpDeviceDiag_Click()

Dim sMSG, sReply As Stπng sMSG = "Performing a device diagnostics test could cause loss of vital device information and should be done only with the assistance of technical support." sMSG = sMSG + vbCrLf + vbCrLf + "Please contact our technical support department at 1 -600-777-777? for a password and assistance

V

' Display message, title and default value sReply = lnputBox(sMSG "Password Required") If LCaseS(sReply) = "h2o" Then frmDeviceDiagnosbcs Show End Sub

Private Sub mπuHelpTiρs_Click() frmTip Show

'if the form is minimized tnen set it back to normal

If frmTip WindowState = vbMinimized Then frmTip WindowState = vbNormal frmTip.ZOrder End Sub

5- frmMain frm - mnuReadDeviceData Ctifck

Private Sub mnuReadDeviceData_Click() frrnReadDeviceData Show 'if the form is minimized then set it back to normal

If frrnReadDeviceData WindowState = vbMinimized Then frrnReadDeviceData WindowState = vbNormai frmReadDevice Data.ZOrder End Sub

Private Sub mπuSeπdDeviceData_Click() frmDevicelnitialize Show

'if the form is minimized then sent oack to normal

If frmDevicelnitiaiize.WindowState = vbMinimized Then frmDevicelnitialize WindowState = vbNormai frmDevicelnitialize ZOrder End Sub

Private Sub mnuViewAIIPatients_Click() frmAIIPatients Show

,f the term is minimized then set it back to normal

1f frmAIIPatients WindowState = vbMinimized Then frmAIIPatients WindowState = vbNormai frmAHPatιents.ZOrder End Sub

Private Sub mnuHelpAbout_Click() frmAbout.Show vbModal, Me End Sub

Private Sub mnuViewCalendar_ClickO frmDosingCaiendar.Show 'if fήe form is minimized then set it back to normal

If frmDosingCalendar. WindowState = vbMinimized Then frmDosingCalendar. WindowState = vbNormai frmDosιngCaleπdar.ZOrder End Sub

Private Sub mnuViewExplorer_Click() mnuVlewExplorer. Checked = Not mnu ViewExplorer Checked 'toggle the state of the check box

SSUstBarl. Visible = mnuViewExplorer.Checked End Sub

Private Sub mnuViewOptioπs_Click() frmOptions Show vbModal, Me End Sub

? <- frmMain frm - mnuViewPatιentDosingRepκjr(

Private Sub mnuViewPatientDosingReport_Click() frmPatlentDosingReport.Show 'it the form is minimized then set it back to normal

If frmPatientDosingReport WindowState = vbMinimized Then frmPatientDosingReport. WindowState = vbNormai frmPatientDosingReport.ZOrder End Sub

Private Sub mnuViewPatientSummary_Click() frmPatieπtSummary.Show ':fihe ror is minimized then set it beck to norms'

If frmPatientSummary WindowState = vbMinimized Then frmPatientSummary WindowState = vbNormai frmPatientSummary ZOrder End Sub

usBar_Click() Then = False = True

Figure imgf000099_0001

Click()

Figure imgf000099_0002

Private Sub SSListBarl_ListltemClick(ByVal ItemClicked As Ustbar.SSListltem)

_ Select Case SSUstBaM .CurrentGroupKey Case "Patient Data" 'patient data Select Case ItemClicked.Key Case "Event Calendar" 'calendar mπuV!ewCalendar_Cliek

Case "Summary" 'summarv mnuViewPatιentSummary_Click

Case "Dosing Information" 'gπd mnuViewPatιentDosιngReport_Clιck

Case "All Patients" 'all patients mnuVιewAIIPatιeπts_Clιck

End Select

Case "Device" 'device data Select Case ItemClicked.Key

Figure imgf000099_0003
frmMain frm - SSLιstBar1_LιstltemC1i_k

Case "Retπeve Data" reac evics data

Figure imgf000100_0001
mnuReadDevιceData_Clιck Case "Program Device" send to DosPio De-Jice mnuSendDevιceData_Clιck End Select

- End Select End Sub

Pπvate Sub tbToolBar_ButtonClιck(ByVal Button As ComctlLib.Button)

— Select Case Button Key

Case "Open" mnuFιleOpen_Clιck

Case "Save" mπuFιleSave_Clιck

Case "Pπnt" mπuFιlePπnt_Clιck

Case "Cut" mnuEd,tCut_Clιck

Case "Copy" mnuEdιtCopy_ Click

Clipboard dear If TypeOf ActiveForm ActiveControl Is TextBox Then Select Case Index Case O ' Cut

Copy selected text to Clipboard

Clipooard SetText ActiveFoπn ActiveControl SelText

Delete selected text ActiveForm ActiveControl SelText = "' Case 1 ' Copv

Copy selected text to Clipboard

Clipboard SetText ActiveForm Ac'iveControl SetText Case 2 ' Paste

Put Clipboard text in text box

ActiveForm ActiveControl SelText - Clipboard GetTextO Case 3 ' Delete

Delete selected text

ActiveForm ActiveControl SelText - ~

?ϊ frmMain.frm - tbToolBar_ButtoπClifck

Figure imgf000101_0001

End Select End It

Case "Paste"

'mnuEdιtPasιe_Cltck

Case "Bold"

Case "Italic"

Case "Underime"

Case "Left"

Case "Center"

Case "Right"

_ End Select End Sub

Private Sub mnuHelpContents_Click() Dim nRet As Integer message to the user in the There is no Help associated with this project.", vblnformation, Me.Caption e, 3, 0)

Figure imgf000101_0002

Private Sub mnuHelpSearch_Click()

Dim nRet As Integer the user

Help associated with this project.", vblnformation, Me.Caption

Figure imgf000101_0003

? ? frmMain frm - mnuWindowArrangelC0rt9_

Private Sub mnuWiπdowArrangelcons_Click()

Me Arrange vbArrangelcons ~

End Sub

Private Sub mnuWiπdowCascade_Click()

Me Arrange vbCascade End Sub

Private Sub mnuWindowTileHori2ontal_Click()

Me Arrange vbTileHoπzontal End Sub

Private Sub mnu indowTileVertical_Click()

Me Arrange vbTϊle Vertical End Sub

Private Sub mnuFileOpeπ_Click()

Dim r As Integer r = OpβnPatientDataf")

'If any of these forms are open at the time a new file is loaded

'then refresh them

Figure imgf000102_0001

Private Sub mnuFileSaveAs_Click()

SaveDataToNewFile End Sub

/ ' frmMain.frm - mnuFilePageSeluft_ffi>

84

Private Sub mnuFilePageSetup_Click()

On Error GoTo mnuFιlePageSetup_Clιck_Error dIgCommonDialog. ShowPπnter m Clιck Exit:

Figure imgf000103_0001
mnuFιlePageSetup_Clιck_Error

Resume mnuFilePageSetup Click Exit ., - , ,

End Sub uP_U'CK_Ex.t any emr -essege would have already been sent by the common dialog

= vbNormai

Figure imgf000103_0002

Private Sub mnuFileSend_Click()

To Do

MsgBox "Ability to send a file will be active in a future release"

En idd SSuubb

Figure imgf000103_0003

Private Sub mnuFileExit_Click()

'unload the form Unload Me End Sub

/ <> /

Figure imgf000104_0001

Private Sub Form_Load()

IblVersion.Caption = "Version " 4 App Major 3, " " a App Minor 'IblProduclNa a Caption = App Title " App Revision

End Sub

Figure imgf000104_0002

/ * . O 99/35588

frmLogin frm - File Declaraitan?

Attπbute VB_Name = "frmLogin"

Figure imgf000105_0001
Attπbute VB_GlobalNameSpaee = False Attπbute VB_Creatable = False Attribute VB^Predeclaredld = True Attπbute VB~Exposed = False Option Explicit

Pπvate Oeclare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal Ipbuffer As Stπng, nSize As Loπα) As Lonn

Public OK As Boolean

Private Sub Form_Load()

Dim sBuffer As Stππg Dim ISize As Long

Me Move frmSplash Left + -KJ00, f iSplash Top + 3500 sBuffer = Spaceϊ(2S5) ISize = Len(sBuffer) Call GetUserName(sBuffer, ISize) 0 Then rName = Left$(s8uffer, ISize) rName = vbNullStπng

Figure imgf000105_0002

Private Sub cmdCancel Click{)

OK = False Me.Hide End Sub

, "Login"

Figure imgf000105_0003

Figure imgf000105_0004

Figure imgf000106_0001

Figure imgf000106_0002
O 99/35588

frmOptions.frm - File Declarβfians

Attπbute VB_Name = "frmOptions"

Figure imgf000107_0001
Attπbute VB_GlobalNameSpace = False Attπbute VB_Creatable = False Attπbute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit

Private Sub btπConfigureFax_Click() btnCon-gurefax. Enabled = False Me.MousePointer = vbHourglass gcFax.AutoDetect With IblFaxDevice

.Caption = "Searching for a Fax Device Please wait a few seconds."

.BackColor = SHCOFFFF 'highlight background

.ForeColor = &H0&

.Refresh End With End Sub

Private Sub cmdApply_Click()

Dim sSection As Stπng giLatestOptionsTabSelected = sstabl.Tab

'set the global value to the user's selection gsDateOispiayFormat = Choose(cmboDates.Listlndex + 1, "Short Date", "Medium Date", "Long Date") gsTimeDisplayFormat = Choose(cmboTimes.Listlndex + 1, "Short Time", "Medium Time", "Long Time")

Figure imgf000107_0002

RefreshAUOpenForms

'Save the Fax Information With FAX_DATA

.sSenderName = txtName

.sSenderCompany = txtCompany

.sSenderVoiceNumber = txtVoiceNumber

.sSeπderFaxNumber = txtFaxNumber

/'≤~ O 99/35588

Figure imgf000108_0001
.sDialPrefix = bctDlalPrefix ; = ΛigΛ
Figure imgf000108_0002

'Save values for the Fax control that was last set oy user sSection = "User Selections"

With FAX_DATA

SavelNΪSetting gsFaxFileSpec, sSection, "Sender Name", .sSenderName SavelNISetting gsFaxFileSpec, sSection, "Sender Company", .sSenderCompany SavelNISetting gsFaxFileSpec, sSection, "Sender Voice Number", .sSenderVoiceNumber SavelNISetting gsFaxFileSpec, sSection, "Sender Fax Number", .sSenderFaxNumber SavelNISetting gsFaxFileSpec, sSection, "Fax ID", .sFaxlD SavelNISetting gsFaxFileSpec, sSection, "Dial Prefix", .sDialPrefix SavelNISetting gsFaxFileSpec, sSection, "Retπes", CStr(.iRetπes) SavelNISetting gsFaxFileSpec, sSection, "Retry Interval", CStr(.iRetrylnterval) SavelNISetting gsFaxFileSpec, sSection, "Resolution", CStr(.bFaxResolutιon)

End With End Sub

Private Sub cmdCancel_Click()

Unload Me End Sub

Private Sub cmdOK_Click()

' "Code goes here to set options and dose dialog." cmdApρly_Click Unload Me End Sub

Private Sub Form_Activate()

SetPrinterlcon False, "" End Sub

Private Sub Form_Load()

'Define the mask for the telephone and fax nu oers text box toad the available choices into the list boxes cmboDatesjAddltem FormatJ(Now, "Short Date") cmboDates.Addltem FormatS(Now, "Medium Date") cmboDates-Addltem Format$(Now, "Long Date") cmboTϊmes.Addltem Format$(Now, "Short Time") + " (24 hour)" cmboTimes.Addltem Format$(Now, "Medium Time") + " (12 hour)" emboTimes.Addltem Format$(Now, "Long

Figure imgf000108_0003

_ Select Case gsngComplianceTimeRange Case 0.5 cmboComplianceTimeRange.Listlndex = 0 Case 1 cmboComplianceTimeRange.Listlπdex = 1 Case 1.5 cmboCompiianceTimeRange.Listlndex = 2 Case 2 cmboCompliance TimeRaπge.Listlπdex = 3 Case 2.5 cmboComplianceTϊmeRange.ϋstlndex = 4

Figure imgf000108_0004
O 99/35588

frmOptioπs frm - Form_Loaα

Figure imgf000109_0001

ser the list sex to the last selected user state/

Figure imgf000109_0002

'Ger Fax Info from global settings to the Fax Tab With FAX_DATA txtName « .sSeπderName txtCompany = .sSenderCompany txtVoiceNumber = .sSenderVoiceNumber txtFaxNumber = .sSenderFaxNumber txtFaxlO = .sFaxlD txtOialPrefix = .sDialPrefix txtRetries = CStr(.iRetπes) txtRetrylnterval = CStr( iRetiylπterval) chkResolution.Value = .bFaxResolution o=icw 1=hιgh End With sstabl.Tab = giLatestOptionsTabSelected SetFaxDeviceLabel 'update the devices label End Sub

/ o η

Figure imgf000110_0001

Private Sub txtFaxNumber_GotFocus() txtFaxNumber.SelStart = 1

End Sub

Private Sub txtRetries_GotFocus() bctRetπes.SelStart = 1 End Sub

Private Sub txtRetrylπterval GotFocusn txtRetrylnterva-SelStart = 1 -""'rocusf)

End Sub

P^ txtVoiece SNuumbb ^e Vo'ceN ceNumberr..SSeellSStatar-t =u = ,mber « Go°t«F-oOcusO txtVoi 1 - CUs{)

End Sub

Figure imgf000110_0002
frmAbout.frm - File Declarations

Attπbute VB_Name = "frmAbout" Attπbute VB GlobalNameSpace = False Attπbute VB~Creatable = False Attπbute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit

Reg Key Secuπty Options Const KEY_ALL_ACCESS = &H2003F

Reg Key ROOT Types Const HKEY_LOCAL_MACHINE = &H80000002 Const ERROR_SUCCESS = 0

Const REG_SZ = 1 ' Unicoee nul terminates stπng

Const REG~DWORD = 4 ' 32-bιr numoer

Const gREGKEYSYSINFOLOC = "SOFT ARE\MιerαsofttShared Tools Location" Const gREGVALSYSINFOLOC = "MSINFO"

Const gREGKEYSYSINFO = "SOFTWARE\Mιcrosoft\Shared Tools\MSINFO" Const gREGVALSYSINFO = "PATH"

Pπvate Declare Function RegOpeπKeyEx Lib "advapι32" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal IpSubKey As Stπng, ByVal

V ulOptions As Long, ByVal samDesired As Long, ByRef phkResult As Long) As Long

Pπvate Declare Function RegQueryValueEx Lib "advapι32" Alias "RegQueryVaiueExA" (ByVal hKey As Long, ByVal IpValueName As Stπng,

V ByVal IpReserved As Long, ByRef IpType As Long, ByVal IpOata As Stπng, ByRef IpcbOata As Long) As Long Pπvate Declare Function RegCloseKey Ub "advapl32" (ByVal hKey As Long) As Long

Private Sub Form_l_oad()

IblVersion.Caption = "Version " + App.Major + " " + App.Minor + "." + App.Revision ' IblTitlβ Caption * App Title End Sub

Private Sub cmdSyslnfo_Click()

Call StartSyslnfo End Sub

Private Sub cmdOK_Click()

Unload Me End Sub

Public Sub StartSyslnfc-0

On Enor GoTo SyslnfoErr

Dim re As Long

Dim SyslnfoPath As Stnng

' Try To Get System Info Program Path\Name F om Registry

- If GetKeyValue(HKEY_LOCAL_MACHINE, gREGKEYSYSINFO, gREGVALSYSINFO, SyslnfoPath) Then

' Try To Get System Info Program Path Onlv From Registry

- Elself GetKeyValue(HKEY_LOCAL_MACHINE, gREGKEYSYSINFOLOC, gREGVALSYSINFOLOC, SyslnfoPath) Then

' Validate Existanoe Of Known 32 Bit File Version

/ o f frmAbout.frm - StartSyslnfσ

Figure imgf000112_0001

Call Shell(SyslnfoPath, vbNormalFocus)

SyslnfoErr

MsgBox "System Information Is Unavailable At This Time", vbOKOnly End Sub

Public Function GetKeyValue(KeyRoot As Long, KeyName As String, SubKeyRef As String, ByRef KeyVal As S

Dim i As Long ' Lscs Counter

Dim re As Long ' Return Code

Dim hKey As Long ' Hanαle To An Open Regstry Key

Dim hDepth As Long

Dim KeyValType As Long 'Data Type Of A Regstry Key

Dim tmpVai As Stnng ' Tempory Storage For A Registry Key Value

Dim KeyValSize As Long Sirs Of Regstry Key Vaπable

' Open RegKey Under KeyRoot {HKEY_LOCAL_MACHINE...} re « RegOpenKeyEx(KeyRoot, KeyName, 0, KEY_ALL_ACCESS, hKey) ' Ooen Regstry Key If (re <> ERROR_SUCCESS) Then GoTo GetKeyError" ' Handle Error . tmpVai = Stnngϊ(102 , 0) Allocate Vaπable Space

KeyValSize = 102 ' Mark Vaπable Size

' Retneve Regstry Key Value . re = RegQueryValueEx(hKey, SubKeyRef, 0, KeyValType, tmpVai, KeyValSize) ' Get/Create Key Value If (re <> ERROR_SUCCESS) Then GoTo GetKeyError ' Handle Errors

If (Asc(Mid(tmpVal, KeyValSize, )) = 0) Then ' Wιn95 Adds Null Terminated Stπng .. tmpVai = Left(tmpVal, KeyValSize - 1 ) ' Null Found. Extract From Stnng

Else ' WinNT Does NOT Null Terminate Stnng... tmpVai = Left(tmpVal, KeyValSize) ' Null Not Found. Extract Stπng Only

End If

' Determine Key Value Type For Conversion..

Select Case KeyValType ' Search Data Types ..

Case REG_SZ ' Srnng Regstry Key Data Type

KeyVal = tmpVai ' Copy Sfππg Value

Case REG_DWORD ' Doufl/e Word Regstry Key Data Type fat i = Len(tmpVal) To 1 Step -1 ' Convert Each Bit

KeyVal = KeyVal + Hex(Asc(Mιd(tmpVal, i, 1))) ' 3uιid Vaiue Char 3v Char. Next

KeyVal = Format$("&h" + Key al) ' Convert Dcuole x/Vord To Stπng End Select

GetKeyValue = True ' Return Success re = RegCloseKey(rtKey) - Close Regstry Kev

Exit Function ' Exit

GetKeyError: ' Cleanup After An Error Has Occured

KeyVal = " Set Return Val To Empty Stπng

77 frmAbout.frm - GelKeyValue

GetKeyValue = False Raωrn Failure re = RegCloseKey(hKey) close Regstr, Kev

End Function

/ / / frmBro ser frm - File Declarations

Attπbute VB_Name = "frmBrowser" Attπbute VB_GlobalNameSpace = False Attπbute VB~Creatable - False Attπbute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit

Public StartingAddress As Stπng Dim mbDontNavigateNow As Boolean

Private Sub Form_Load() Dim r As Integer

'On Error Resume Next Me. Show tbToolBar.Refresh Form_Resιze

ress

Figure imgf000114_0001

Private Sub brwWebBrowser_DownloadComplete()

On Error Resume Next

Me.Caption = brwWebBrowser.LocationName

Me.MousePomter = vbDefault End Sub

Private Sub brwWebBrowser_NavigateComplete(ByVal URL As String) Dim i As Integer, r As Integer

Dim bFound As Boolean On Error Resume Next

Figure imgf000114_0002
mbDontNavigateNow = True

If bFound Then cboAddress Removeltem i cboAddress.Addltem brwWebBrowser.LocationURL, 0 cboAddress.Ustlndex = 0 mbDontNavigateNow = False On Error GoTo 0 Me.MousePomter = vbDefault

'Last time to visit the Internet

'Save new date in INI file that an attempt (or success, was made to visit

'the Internet web site on this date r = GetlNISettιng(gsApplnιFιleSpec, "Web Data", "Connection Reminder Days", 100)

SavelNISetting gsAppiniFiieSpec, "Web Data", "Next Web Visit Reminder Date", FormatS(Now + r, "Medium Date")

/^ frmBrowser frm - brw\Λ/ebBrowser_NavιgateCoι jtβ

SavelNISetting gsAppiniFiieSpec, "Web Data", "Last Web Visit Date", Formatϊ(Now, "Medium Date") End Sub '

Private Sub cboAddress_Click()

If mbDontNavigateNow Then Exit Sub timTimer.Enabled = True brwWebBrowser Navigate cboAddress Text Me.MousePomter = vbHourglass End Sub

Private Sub cboAddress_KeyPress(KeyAscii As Integer)

On Error Resume Next

If KeyAscn = vbKeyReturn Then cboAddress_Clιck End Sub

Private Sub Form_Resize()

Me. Refresh

If Me WindowState = vbMinimized Then Exit Sub brwWebBrowser.Move brwWebBrowser.Lefl, brwWebBrowser Top, Me SeaieWidth - 100, Me ScaleHeight - (pnlAddress Too • * pnlAddress.Heιght) - 100 ' brwWebBrowser Width = Me SeaieWidth - 100 brwxVebβrowser Height = Me ScaleHeight ■ (pnlAddress Top + pnlAddress Height) - 100 cboAddress.Move cboAddress.Left, cboAddress.Top, pnlAddress Width - cboAddress.Left - 100 End Sub

tionName

Figure imgf000115_0001

Private Sub tbToolBar_ButtonClick(ByVal Button As Button)

On Error Resume Next timTimer.Enabled = True _ Select Case Button.Key Case "Bad " brwWebBrowser.GoBack Case "Forward" brwWebBrowser.Go Forward Case "Refresh" brwWebBrowser.Refresh Case "Home"

' biwWeoSrowssr GoHomβ normally takes browser Ό the registered name page cboAddress = StartingAddress try to navigate to the starting adcress timTimer.Enabled = True brwWebBrowser Navigate StartingAddress

Me.MousePomter = vbHourglass

Case "Search" brwWebBrowser GoSearch Case "Stop"

//3 frmBrowser.frm - IbToolBar ButtonClick timTimer.Enabled = False brwWebBrowser.Stop

Me.Caption = brwWebBrowser.LocationName _ End Select End Sub

// < frmTip.frm - File Declarations

Attπbute VB_Name = "frmTip" Attπbute VB~GlobalNameSpace = False Attπbute VB~Creatable = False Attπbute VB_Predeclaredld = True Attπbute VB~Exposed = False Option Explicit

' The in-memcry database of tips Dim Tips As New Collection

' Name of tips file

Const TIP FILE = T1P0FDAY.TXT"

Private Sub DolMextTipQ

Indet in collection of tip currently being αisclayed 'cycle through tne Tips in order giCurrentTip = giCurreπtTip + 1

If Tips.Count < giCurrentTip Then giCurrentTip = 1

' Sήoivir frmTip.DisplayCurrentTip End Sub

Function LoadTips(sFile As String) As Boolean

Dim NextTip As Stnng ' Eacri tip read in from file Dim InFile As Integer ' Descnptor for file

' Obtain the next free file descnptor InFile * FreeFile

' Make sure a file is specified lf sFile = "" Then

LoadTips > False

Exit Function End If

' Make sure the file exists before trying to open it lf Dir(sFBe) = ""Then

LoadTips = False

Exit Function End If

' Read the collection from a text tile Open sFile For Input As InFile While Not EOF(lnFile)

Line Input #lnFile, NextTip

Tips-Add NextTip Wend Close InFile

' Display a tip at random. DoNextTip

LoadTips = True

End Function

//A frmAIIPatients frm - File Declarations

Attπbute VB_Name * "IrmAIIPatients" Attπbute VB_GlobalNameSpace = False Attπbute VB_Creatable = False Attπbutβ VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit

Dim xbAIIPatientsFormLoading As Boolean

Dim xsPatientFileSpecsQ As Stnng a cjnamc array holαing the names of patient files on ask

Private Function CalculateSinglePatieπtCompiiance(DataStruct As DeviceDataStruct) As Double

Calculate the compliance tor the oaner.t in memerj and pass result αacx to caller 'Use the settings of the aleg to cetermme calculations ana cars ranges

Dim IDateBegin As Long, IDateEnd As Long, I As Long, IScoreSum As Long Dim iPlotValue As Integer 'keeps a taily of the vaiue Ό be plotted tor eacn dav

IDateBegin = txtStartDate IrtfDataStwct cEventDatetl :)

IDateEnd = txtEndDate 'IntlDataStruct dEjentDateiDataStruct lEver.ιData(O)))

Figure imgf000118_0001
End Function

Private Sub btnClose_Click()

Unload Me End Sub

//

Figure imgf000119_0001

Pπvate Sub cmboDataToVιew_Clιck()

CalculateAIIPatientsComplianceOnDisk Slιder1_SlιdeChaπge End Sub

Private Sub cmboDateSelectιoπ_Clιck()

_ Select Case cmboDateSelection Ustlndex Case 0 recenf 7 days txtEπdDate = CDate(lπt(Now)) txtStartDate = CDate(lnt(Now) - 7) Case 1 'ecent 14 days txtEndDate = CDate(lnt(Now)) txtStartDate = COate(lnt(Now) - 1 ) Case 2 recent 30 days txtEndDate = CDateflnt(Now)) txtStartDate = CDate(lnt(Now) • 30) Case 3 recenf 6 months txtEndDate = CDate(lnt(Now)) txtStartDate = CDate(lnt(Now) - 180) Case 4 'all data If PAT_DATA lEventData(O) Then there are some events in arrav txtStartDate = CDate(lnt(PAT_DATA dEventOatet1l» txtEndDate = CDate(lnt(PAT~DATA dEveπtOatelPAT DATA iBventData )))) End If Case 5 custom dates If gsLastStartDateChosen = "" Then txtStartDate = CDate(lnt(PAT DATA dEventDate(l))) Else txtStartDate = gsLastStartDateChosen End If If gsLastEndDateChosen = ~ Then txtEndDate = CDate(lnt(PAT DATA dEventDate(PAT DATA lEventData(O)))) Else btEndDate = gsLastEndDateChosen End If

- End Select

CalculateAIIPatientsComplianceOnDisk Slιder1_SlιdeChange

End Sub

//7 frmAIIPatients. frm - Form Activate

Private Sub Form_Activate()

Me.Refresh gπd.Refresh Slider1_SlideChange

SetPπnTerlcon True, "SPπnt All Patienfs Summary-." End Sub

Public Sub CalculateAIIPatientsComplianceOnDiskO

This procedure is cailed when it is necessary to upαate the display 'cue to some element or feature oetng changed.

'Look at all ce' ice data files in the specified director/ Retπeve appropnate data from eacn file and put into a global 'structure holding all patients

If xbAIIPabentsFormLoading = True Then Exit Sub

Dim r As Integer, i As Integer, dCompliance As Double

Dim sPath As Stπng, sFileName As Stπng, sFileSpec As Stnng

Dim sTab As Stπng, sTemp As Stπng, lErrorCode As Long

On Error GoTo CalculateAIIPatientsComplιanceOnDisk_error

Me.MousePomter = vbHourglass

Me.Refresh

e code is still in the program |< Last Dose |> Doses " |< Last Dose |> Score "

Figure imgf000120_0001

Form_Rβsize grid.Col * 1 set to column 1 gπd.Redraw = False 'turn off redraw to speed up processing sPath = App.Path + Patient DataV sFileName « LCase$(DirS(sPath + "*.cpd")) 'gef all filenames

_ Do While sFileName <> ~ 'read all stπngs from directory sFileSpec = sPath ♦ sFileName l - l * 1 load the data for this patient into dobal array r GetPatientDataFromDisk(sFileSpec, TEMP_OATA, lErrorCode)

'rg xxxttt

'It a checksum error or other error occurred on in the above function.

'don't indude the file in the summary and warn user.

'Call routine to calculate compliance based on dialog settings dCompliance = CalculateSinglePatιentComplιance(TEMP_DATA)

'Put results into gπd sTemp = TEMP_DATA.sPatientLastName + ", " + TEMP_DATA.sPatientFirstName + sTab + TEMP_DATA.sPatientlD + sTab ffs.'

•, name and ID sTemp = sTemp ♦ FormatϊfTEMP DATA.dEventDate(l), "Short Date") + sTab 'get first dose date sTemp = sTemp ♦ FormatS(TEMP DATA.dEventDate(TEMP_DATA.iEventData(0)), "Short Date") 'get last dose date sTemp = sTemp ♦ sTab + Format$(CStr(dComplιance), "#0") 'get compliance

If cmboDataToView.Listlndex <> 2 Then sTemp = sTemp + " %" grid.Addltem sTemp

//? lAllPatients frm - CalculateAIIPalientsComplianc .Disk

gπd.RowOata(i) = i - 1

If i >= UBound(xsPatιentFιleSpecs) Then ReDim Preserve xsPatιentFιleSpecs(ι ♦ 10) xsPatientFileSpecs(ι - 1 ) = sFileSpec keep the name of the file nere for :vιιen user clicks on cell sFileName = LCaseS(Dιr) ger new He (one oy one) gπd.Redraw = True Loop process net: r.ieπame gπd.Redraw = True

CalculateAIIPatιentsComplιanceOnDιsk_Exιt: Me.MousePomter = vbDefault

Calculate AI!PatιentsComplιanceOnDιsk_error '" Resume 0 'testing oniy

Resume CalculateAIIPatιentsComplιaπceOnDιsk_Exit End Sub

Private Sub Form_Load() frmMain.MousePointer = vbHourglass DoEvents xbAIIPatientsFormLoading = True

ReDim xsPatιentFileSpecs(2)

If emboDateSeleetion.Listlndex < 0 Then cmboDateSeiectioπ.Listindex = 2 ser a default cmboDataToView.Listlndex = 0

XbAIIPatientsFormLoading = False

CalculateAIIPatientsComplianceOnDisk gπd.Col = 0 gπd.Sort = 1 'genenc ascending frmMain.MousePointer = vbDefault

RefreshAIIOpenForms

End Sub

Private Sub Form_Resize()

Dim iWidthRemaining As Integer

Static bProcedurelnProgress As Boolean

If bProcedurelnProgress Then Exit Sub

If Me. WindowState = vbMinimized Then Exit Sub bProcedurelnProgress = True

_ If Me.Wldth < 5000 Then

Me.Wϊdth = 5000 bProcedurelnProgress = False _ End If

_ If Me.Height < 5000 Then

Me.Height = 5000 bProcedurelnProgress = False _ End If

SSPaneM.Left = Me.Wldth - SSPaneH .Width - 100 gπd.Width = SSPaneM.Left - gπd.Left - 150 grid.Height = Me.Height - gπd.Top - 25 gπd.ColWidth(4) = 525 'Score gπd.ColWidth(O) = (gπd.Width - gπd.ColWidth(4)) / (grid. Cols - 1 ) 'Warns gπd.ColWldth(l) = gπd.ColWidth(O) 'ID iWidthRemaining = gπd.Width - gnd.ColWidth(O) - grid. Col idth(1) - gπd.ColWidth(4) - 120 gπd.ColWidth(2) = iWidthRemaining / 2 'Start Date gπd.ColWidth(3) = gπd.ColWidth(2) Las.' Dose Date

// ? frmAIIPatients. frm - Form Resize

bProcedurelnProgress = False End Sub

Private Sub grid_Click()

Dim iRow As Integer

'F ne out which column :vas clicked

'Sort the arrav only it the header :vas c'icksc

If gπd.Rows < 2 Then Exit Sub

αing

Figure imgf000122_0001

End Sub

Private Sub grid_DblClick()

Dim sFileName As Stπng, r As Integer, iRow As Integer If gπd.Rows < 2 Then Exit Sub iRow = gπd.MouseRow sFileName = xsPatιeπtFιleSpecs(gπd.RowData(iRow»

'open the document that was double-clicked r = OpenPatιentData(sFileName) End Sub

Private Sub Slideιi_SlideChange()

Dim i As Integer, j As Integer

Labell (O).Captιon = "Compliance Threshold =< " + CStr(Slιder1.Value) + "%" gπd.Redraw = False < Sliden Value Then

'S.HCOCOFF

Figure imgf000122_0002
gnd.Row = 0 gπd.Col = 0 gπd.Redraw = True End Sub

/<& 0 frmAIIPatients frm - Slιder1_SlιdeChangι

Private Sub txtEndDate_HideDropDown()

DoEvents gsLastEndDateChosen = txtEndDate emboDateSeleetion.Listlndex = 5 selec the custom setting

CalculateAIIPatientsCompliaπceOnDisk Slιder1_SlιdeChange End Sub

Private Sub txtStartDate_HideDropDown()

DoEvents gsLastStartDateChosen = txtStartDate cmboOateSelection Listlndex = 5 ss/ecr th custom sating

CalculateAIIPatientsComplianceOnOisk Slide r1_SlιdeChaπge End Sub

< I frmRecenlDosingGrap frm - File DeclaratU

Attribute VB_Name = "frmPatientSummary" Attπbute VB_GlobalNameSpace = False Attπbute VB_Creatable = False Attπbute VB~Predeclaredld = True Attπbute VB_Exposed = False Option Explicit

Public Sub UpDatefrmPatientSummaryHeaderO

Dim DataStruct As DeviceDataStruct DataStruct = PAT_DATA txtPatientLastName = " " + DataStruct.sPatieπtLastName txtPatientFirstName = " " + DataStruct.sPatientFirstName

truct.dLastDownloadDate, gsDateOispiayFormat)

Figure imgf000124_0001
txtSenalNumber = " " + DataStruct.sSeπalNumber

MSChartl .Visible = True

If cmboDateSeiectioπ.Listindex < 0 Then emboDateSeleetion.Listlndex = 1 'pick a default range

'txtStartDate = FormatS(CDate(DataStruct dEχventDate(1)l. gsDateDisplayFormat)

'txtEndDate - FormatS(CDaletDataStruct.dEver.<Date(DataStruct.iEventData(0))). gsDateOispiayFormat)

Me.Refresh

End Sub

Public Sub UpdatePatientDosingGraphO

'Update the graph due to a cneck box being changed.

Dim sTab As Stπng, I As Long

Dim IDateBegin As Long, IDateEnd As Long, IScoreSum As Long

Dim iPlotValue As Integer 'keeps a tally of the value to be plotted for each day

Dim dPIotDate As Double, iDayEventsFound As Integer, iDatelπdex As Integer

Me.MousePomter = vbHourglass DoEvents

te(l))

Figure imgf000124_0002
dDate) Then lnt(CDate(txtEndDate)) lnt(PAT_DATA.dEventDate(PAT_DATA.iEventData(0)))
Figure imgf000124_0003

MSChartl .RowCount = 0 dPIotDate = lπt(PAT_DATA.dEveπtDate(1 )) 'get the first event care

- If IDateBegin Then Were is at leas; a vaiue m there Select Case cmboDataToView.Listlndex

- Case 0 'Doses per day score (all doses on this cay regardless of time taken For I = IDateBegin To IDateEnd tne numoer of events is stored here iPlotValue = CalcDayDoseScore_AIIDoses(PAT_DATA, I)

MSChartl .RowCount = MSChartl .RowCount + T 'increment tne row count

MSChartl .Row = MSChartl .RowCount 'plot in last row

MSChartl .Data = iPlotValue

IScoreSum = IScoreSum + iPlotValue

7^^- _,„_ββ

WO 99/35588

TiRecentDosingGraph.frm - UpdatePatientDosm -aprt"

re m the text oo*

re >n rήe rex.' box

Figure imgf000125_0001

'MSChartl xaxisc'Je = "fes;" Me.MousePomter = vbDefault

End Sub

Λ33 frmRLcentDosingGraph frm - btnClose_C-

Private Sub btnClose_Click()

Unload Me End Sub

Private Sub cmboAverageDays_Click()

UpdatePatientDosingGraph End Sub

Private Sub cmboChartType_Click()

_ Select Case cmboChartType Text

MSChartl chartType = VtChChartType2dLιne

Case "Area" MSChartl chartType = VtChChartType2dArea

Case "Bar" MSChartl chartType = VtChChartType2dCombιnatιon

Case "Step" MSChartl .chartType = VtChChartType2dStep

_ End Select End Sub

Private Sub cmboDataToView_Click()

UpdatePatientDosingGraph End Sub

Public Sub cmboDateSelectioπ_Click() Then no data appears to be loaded

Figure imgf000126_0001

Select Case emboDateSeleetion.Listlndex . Case 0 'recent 7 days txtEndDate = CDate(lnt(PAT DATA dEveπtDate(PAT DATA.ιEventData(O)))) txtStartDate = CDate(lnt(PAT DATA dEventDate(PAT DATA lEventData(O))) - 7)

Case 1 'rseeπr 14 days txtEndDate = CDate(lnt(PAT DATA dEventDate(PAT_DATA lEventData(O)))) txtStartDate = CDate(lnt(PAT_DATA dEveπtDate(PAT_DATA lEventData(O))) - 14)

Case 2 recent 30 days txtEndDate = CDate(lnt(PAT_DATA dEventDate(PAT_DATA lEventData(O)))) txtStartDate = CDate(lnt(PAT_DATA dEventDate(PAT_DATA lEventData(O))) - 30)

Case 3 'scenr 6 montns txtEndDate = CDate(lnt(PAT_DATA dEventDate(PAT_DATA.ιEveπtData(0)))) txtStartDate = CDate(lπt(PAT_DATA dEventDate(PAT_DATA.ιEventData(0))) - 180)

yy frmRecenlDosingGraph.frm - Form_R'esr2

' 110

End If pnlCoπtrols.Left = Me.Width - pnlCoπtrols. Width - 200 pnlChart. Width = pnlControls.Left - 100 MSChartl Width = pnlChart. Width - 100 pnlChart.Height = Me.Height - pnlChart. Top - 500 MSChartl .Height = pnlChart.Height - 100 bProcedurelnProgress = False

End Sub

Private Sub Form_Unload(Cancel As Integer) Save last settings selected by user

PAT_SUM_DEFAULTS.cmboDataToVιew = cmboDataToView.Listlndex PAT~SUM~DEFAULTS. cmboChartType = cmboChartType.Listlndex

End Sub

Private Sub txtEndDate_Change() DoEvents

Then rting date is being set to the first dose.'

Figure imgf000127_0001
emboDateSeleetion.Listlndex = 5 'select the user setting UpdatePatientDosingGraph End Sub

Private Sub txtStartDate_Chaπge()

DoEvents last Date(1 )) Then dose taken by this patient. The starting date is being set to the first dose

Figure imgf000127_0002
emboDateSeleetion.Listlndex = 5 'select the user setting UpdatePatientDosingGraph End Sub

" frmDosingCalendar.frm • File Declaiations

111

Attπbute VB_Name = "frmDosingCalendar" Attπbute VB_GlobalNameSpace = False Attπbute VB~Creatable = False Attπbute VB~Predeclaredld = True Attπbute VB_Exposed = False Option Explicit

Pπvate bgResizedCalendar As Boolean

Private Sub btnChangeCompliance_Click() giLatestOptionsTabSelected = 1 cisplay V;s proper t30 onca the dialog is openec frmOptioπs.Show vbModal

End Sub

Private Sub btnClose_Click()

Unload Me End Sub

Private Sub Calendar_DayChange()

Static bProcedurelnProgress As Boolean

If bProcedurelnProgress Then Exit Sub prevent recursive calls bProcedurelnProgress = True frmDosingCalendar.MousePointer = vbHourglass 'hourglass

DoEvents

UpdateΣoomBox frmDosingCalendar.MousePointer = vbDefault 'default glass bProcedurelnProgress = False 'allow another call to this sub

End Sub

Private Sub Calendar_ onthChange()

Static bProcedurelnProgress

If bProcedurelnProgress Then Exit Sub 'prevent recursive calls bProcedurelnProgress = True frmDosingCalendar.MousePointer = vbHourglass 'hour glass

DoEvents

UpdateCalendar frmDosingCalendar.MousePointer = vbDefault 'default bProcedurelnProgress = False

End Sub

/^ frmDosingCalendar frm - Caleπda vlouse

Private Sub Calendar_MouselV1ove(Buttoπ As Integer, Shift As Integer, X As Single, Y As Single)

- If bgResizedCalendar Then

Update Calendar bgResizedCalendar = False _ End If

End Sub

Private Sub Calendar_YearChange()

Calendar_MonthChaπge

End Sub

Private Sub chkDoseChanged_Click()

DrawAIIDoseSizeChaπges UpdateZoomBox End Sub

Private Sub chkDosesMissed_Click()

DrawAIIDosesMissed UpdateZoomBox End Sub

Private Sub chkDosesNlotComplied_Click()

DrawAIINonCompliedDosesTaken UpdateZoomBox

End Sub

Private Sub chkDosesTaken_Click()

DrawAIICompliedDosesTaken UpdateZoomBox End Sub

Private Sub chkWeekNumbers_Click()

RemoveAIIObjects frmDosiπgCaleπdar.Caleπdar.WeekNumbers = chkWeekNumbers

DoEvents

UpdateCalendar

End Sub

Figure imgf000129_0001
frmDosingCalendar frm - Form_Actιvate

Private Sub Form_Actιvate()

SetPπnterlcon False, ~ End Sub

lEventData(O)) > 0 Then CVDate(PAT_DATA dEventDate(PAT_DATA lEventData(O))) Now

Figure imgf000130_0001

Load lblDetaιlTime(2)

Load lblDetaιlTime(4)

Load lblDetaιlTime(6)

Load IblDetaιlTime(S)

Loa lblDetaιlTιme(IO)

Load lblDetaιlTιme(12)

Load lblDetaιlTιme(14)

Load lblDetaιlTιme(16)

Load lblDetaιlTime(18)

Load lblDetaιmme(20)

Load IblDetail Time(22)

CreateCalendarTimeScale

DoEvents frmDosingCalendar Caleπdar.MouseExpand = 5 'expand the hot spot around date arrows

Me. Show

'Set the daiog controls to the settings last set by user ChkDosesMissed = CAL_DEFAULTS chkDosesMissed ChkDosesNotComplied = CAL DEFAULTS.chkDosesNotComplied ChkDosesTaken = CAL_DEFAULTS.chkDosesTaken ChkDoseChanged = CAL_DEFAULTS.chkDoseChanged

UpdateCalendar End Sub

Private Sub CreateCalendarTimeScale()

On Eπ-or Resume Next

'Create the time scale on detail area

Dim sAM As Stπng, sPM As Stπng, i As Integer

_ If frmDosingCalendar. Width < 5000 Then

Figure imgf000130_0002
lblDetaιlTime(2) Capbon = "2" ♦ sAM With lblDetaιlTime(2)

.Left = (Me pnlZoom Width (i / 24)) - (Me.lblDetaιlTime(ι) Width / 2) ForeColor = &HFFFFFF

Visible = True

.ZOrder End With lblDetaιiTime(4) Caption = "4" + sAM With lblDetaιlTime(4)

.Left = (Me pnlZoom Width (i / 24)) - (Me IblDetaιlTιme(ι) Width / 2)

ForeColor = &HFFFFFF

.Visible = True

7^ rmDosmgCalendar frm - CreateCalendarTimeS

1 114

ZOrder End With lblDetaιlTime(6) Caption ■ "6" + sAM With IblDetaιlTime(β)

Left = (Me pnlZoom Width (i / 24)) - (Me IblDetaιlTιme(ι) Width / 2)

FareColor = &HFF=FFF

Visible = True

ZOrder End With lblDetaιlTime(8) Caption = 8 + sAM With IblDetaιlTιme(B)

Left = (Me pnlZoom Width (I / 24)) - (Me IblDetaιlTιme(ι) Width / 2)

ForeCoicr - S.—F==-FF

Visible = True

ZOrder End With

IblDetaιlTιme(IO) Caption = "10 + sAM With lblDetaιlTime(IO)

Left = (Me pnlZoom Width (i / 24)) - (Me IblDetaιlTιme(ι) Width / 2)

-oreCdor - S.HF==FF=

Visible = True

ZOrder End With lblDetaιlTime(12) Caption = "12" + sPM With lbiDetaιlTιme(12)

Left = (Me pnlZoom Width (I / 24)) - (Me IblDetaιlTime(ι) Width / 2)

ForeCdor - i.HF=FFFF

Visible = True

ZOrder End With lblDetaιlTime(14) Caption = "2" + sPM Wιth lblDetallTιme( 4)

Left = (Me pnlZoom Width (I / 24)) - (Me IblDetaιlTιme(i) Width / 2)

ForeCdor = &HFFFFFF

Visible = True

ZOrder End With lblDetaιlTιme(16) Caption = "4 + sPM With lblDetaιlTime(16)

Left = (Me pnlZoom Width (i / 24)) - (Me IblDetaifTimefJ) Width / 2)

ForeColar = &HFFFFFF

Visible = True

ZOrder End With lblDetaιlTime(18) Caption = "6" + sPM With lblDetaιlTime(18)

Left = (Me pnlZoom Width * (i / 24)) - (Me IblDetaιlTιme(i) Width / 2)

ForeColar = &HF-FFF=

Visible = True

ZOrder End With lblDetaιlTime(20) Caption = "8" + sPM With lblDetaιlTime(20)

Left = (Me pnlZoom Width (i / 24)) - (Me IblDetaιlTιme(ι) Width / 2)

ForeColor = &HFFFFFF

Visible = True

ZOrder End With

yη frmDosingCalendar frm - CreateCaleπdarTifnf ale

Figure imgf000132_0001
lblDetaιlTιme(22) Caption = "10" + sPM With IblDetail Time(22)

.Left = (Me.pnIZoom Width (i / 24)) - (Me IblDetaιlTιme(ι) Width / 2)

ForeColor = &HFFFFFF

Visible » True

ZOrder End With

On Error GoTo 0 End Sub

Private Sub Form_MouseMove(Buttoπ As Integer, Shift As Integer, X As Single, Y As Single)

_ If bgResizedCalendar Then UpdateCalendar bgResizedCalendar = False _ End If End Sub

Private Sub Form_Resize() Me.Refresh Static bProcedurelnProgress As Boolean

If bProcedurelnProgress Then Exit Sub

If Me. WindowState = vbMinimized Then Exit Sub bProcedurelnProgress = True

_ If Me Width < 6000 Then

Me.Wldth = 6000 bProcedurelnProgress = False _ End If

_ If Me.Height * 5000 Then

Me.Height = 5000 bProcedurelnProgress = False _ End If

' DelβteAIIObjects

CreateCalendarTimeScale pnlControls.Left = Me Width - pnlControls. Width - 200

Caiendar.Wldth = pnlControls.Left - Calendar.Left - 50 pnlZoo .Top * Me Height - pnlZoom. Height - 450 ' pπlTime. Top = pnlZoom. Top

Calendar.Height = pnlZoom.Top - Calendar Top - 100 bgResizedCalendar = True 'med events on form can not be updated until resize is done pnlZoom. Width = Caiendar.Wldth bProcedurelnProgress = False End Sub

/3 0 frmDosingCalendar.frm - Form Unlσatt

Private Sub Form_Unload(Cancel As Integer)

CAL_DEFAULTS.chkOosesMissed = chkDosesMissed CAL_OEFAULTS.chkDosesNotComplied = ChkDosesNotComplied CAL.DEFAULTS.chkDosesTaken = ChkDosesTaken CAL_DEFAULTS.chkDoseChanged = chkDoseChaπqed End Sub

Private Sub frameView_Mouse ove(Button As Integer, Shift As Integer, X As Siπqle Y As Sinαloi _ If bgResizedCalendar Then y"=- ■ b aiπgie)

UpdateCalendar bgResizedCalendar = False - End If End Sub

As ,πte9er- Shift As lnte9er- * As Single, Y As Single)

Figure imgf000133_0001

/3/

Figure imgf000134_0001

Private Sub escaleGrid()

Dim (Remainder As integer puf any fixed width columns ϊrst gπd.ColWidth(β) = 0 'car. t shew 'his coiumn gπd.ColWidth(1) = 1300 gπd.ColWidth(2) = 900 gπd.ColWidth(3) = 1000 gπd.ColWidth(4) = 950 iRemamder = gπd Width - gπd ColWidth(4) - gπd ColWidth(3) - gπd ColWidth(2) - gπd ColWidth(1 ) gπd.ColWldth(O) = iRemamder 0.25 gπd.ColWidth(5) = iRemamder 0 75 - 370

End Sub

Public Sub UpdatefrmPatientDosingReportHeaderO

'Snow custom labels from config file if there were any Labell (3) = gsCustomLbiPatientLastName Labell (1 ) = gsCustomLblPatientFirstName Labell (2) = gsCustomLblOrgan Labell (0) = gsCustomLblPatientlD Labell (6) = gsCustomLblTxCenter Label 1(7) = gsCustomLblDrug brtPatientLastName - " " + PAT_DATA.sPatιeπtLastName txtPatieπtFirstName = " " + PAT DATA.sPatientFirstName txtPatientID = " " + PAT DATA.sPabentID txtDrug = " " + PAT_DATA.sDrug txtTxCenter = " " + PAT_DATA.sTxCenter brtOrgan = " " + PAT_DATA.sOrgan

End Sub

Public Sub UpdatePatientGridDisplayO Λis proc is called when it is necessary to update the display due to some element or feature being changed

Dim sTab As Stπng, i As Integer, sTime As Stπng, sDate As Stπng, sTemp As Stπng

Dim bShowDosesTaken As Boolean, bShowDoseChanges As Boolean, bShowUserEvents As Boolean sTab = Chr$(9) gπd.Clear 'ffte erase the gπd gπd.Rows = 1 gπd.FormatStππg = "<Date 4 Time | Event Type | Dose Size |" ♦ gsLabelGndColumnCustomI + " |" + gsLabelGπdColumnCustom2 + " I" + gsLabelGπdColumnCustom3

RescaleGπd

'gnd Row = 0 gπd.Col = 1 'set to column 1 gπd.Redraw = False bShowDosesTaken = chkDoses. Value 'speed up 'he csplay m loop bv assigning control value to a var bShowDoseChanges = chkDoseChanged Value bShowUserEvents = chkUserDefined. Value

/3- frmPatienlD&singP.pt frm - UpdalePatientGπdDi.

Figure imgf000135_0001
gnd.Redraw = True gnd.Row = 0 gπd.Col = 0 btnDeleteUserEvent.Eπabled = False

End Sub

Private Sub btnClose_Click()

Unload Me End Sub

^__

/ -3-S frmPatientDosingRpt frπ - bhιDeleteUser£ve

Private Sub btnDeleteUserEvent_Click()

Dim r As Integer, ilndex As Integer, sMSG As Stπng ently removed from the file " + vbCrLf + vbCrLf + "Do you want to delete the event7" "Verify Event Deletion") EVENT_USER_DEFlNED Then EventDelete PAT_DATA, ilndex delete (his

Figure imgf000136_0001

Private Sub btnfMewUserEvent_Click()

'Add an event to the gπd for a time ar.c date cefired ov the usei Dim ilndex As Integer, IDate As Long, i As Integer frmGetDatflTime.Show vbModal 'Get the date o' even; from user _ If gdTempDateTime Then don't add a date it user cancelled e~t of entry αaiog ind the date in the structure ilndex = FιndClosestDatelnArray(PAT_DATA, gdTempDateTime) Eventlnsert PAT_DATA, ilndex, gdTempDateTime insert a new custom event If ehkUserDefined.Value = 0 Then chkUserDefined. Value = vbChecked Else

Call UpdatePatientGπdDisplay End If gπd. SetFocus gπd.Col ■ 3 For i = 1 To gπd Rows - 1 If grid.RowData(l) = ilndex Then 'this is the index we just added gnd.Row = i 'highlight this row gπd.TopRow = i End If Next i

End If

End Sub

Private Sub chkDoseChaπged_Click()

Call UpdatePatientGπdDisplay End Sub

Private Sub chkDoses_Click()

Call UpdatePatientGπdDisplay End Sub

/3 frmPaticnlD .smgRpt frm - chkU:,erDefined_

Private Sub chkUserDefined_Click()

Call UpdatePatientGndDisplay End Sub

Private Sub Form_Activate()

Me.Refresh

Form_Resιze gπd Refresh

Call UpdatePatientGndDisplay

SetPππterlcon True, "SPnπt Dosing Report End Sub

Private Sub Form_Load()

UpdatefrmPatientDosingReportHeader End Sub

Private Sub Form_Resιze{) Static bProcedurelnProgress As Boolean If bProcedurelnProgress T en Exit Sub If Me. WindowState = vbMinimized Then Exit Sub bProcedurelnProgress = True

_ If Me.Wldth < 8100 Then

Me.Wldth = 8100 bProcedurelnProgress = False _ End If

_ If Me.Height < 5000 Then

Me.Height = 5000 bProcedurelnProgress = False - End If frameView.Left = Me.Wldth - frameView Width - 250 btnClose.Left = Me.Wldth - btnClose Width - 250 gπd Width = btnClose Left + btnClose Width - gπd.Left gπd.Height = Me.Height - gπd Top - 425 RescaleGnd bProcedurelnProgress = False End Sub

Private Sub grid_AfterEdit(ByVal Row As Long, ByVal Col As Long)

Dim ilndex As Integer _ Select Case Col Case 3 user column 1

PAT_DATA.sUserData1 (gπd RowData(Row)) = gπd. Text put the change into tne structure Case 4 user column 2

PAT_DATA.sUserData2(gπd RowData(Row)) = gπd Text put the change mto the structure Case 5 user column 3

PAT_DATA.sUserData3(gπd RowData(Row)) = grid Text 'put the change into the structure - End Select gbPatientDataNotSaved = True ser flag to indicate that tne file has cnanged out not yet been saved

If gπd.Col = 3 Then gπd.Col = 4 go to next cell

Elself gπd Col = 4 Then gπd.Col = 5 go ro next cell

Figure imgf000137_0001
frmPalieπlDosingRpt frm - gnd_Afte'rE t

prevent run time error hv looking tar last row

Figure imgf000138_0001

As Integer, Shift As Integer) ble re indicate ;ra> the f.:a nas changed but not Jet seen saved

Figure imgf000138_0002

Private Sub grid_RowColChange()

Dim ilndex As Integer Col > 4 Then allow ce'l to be edi'ed .f it is a custorr column . Editable = True . Editable = False

Figure imgf000138_0003
ιEVENT_USER_DEFINED Then

Figure imgf000138_0004

End Sub

/ t frmReadDeviceData.frrn - File Declarations

Attπbute VB_Name = "frmReadDeviceOata" Attπbute VB_GlobalNameSpace = False Attπbute VB~Creatable = False Attπbute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit

Private Sub btnClose_Click()

Unload Me End Sub

Private Sub btnReadEntireContents_Click()

Dim r As Integer, lErrorCode As Long, i As Integer, sMSG As Stπng r = ValidatePatlentDataSaved ensure tr.at previous patient data was saved percre proceeding If r = vbCancel Then Exit Sub btnReadEπtireContents.Eπabled = False 'prevent χ-ecursιχ;e calls to cevce gbKeepPollingDevice = False 'step oiling fcr now

Wait 0.25 txtPatientLastName = "" 'clear out the text boxes before reading data txtPatientFirstName = "" 'clear out the few ooxes before reactng data txtDrug = "" txtPatientID = "" txtTxCenter = ~ txtOrgan = "" txtSerialNumber = ~ txtDoseSize = ~ bttDoseTime(l) = "" txtDoseTιme(2) = ~ txtDoseTime(3) = ~ txtDoseTime(4) = ~ txtDosesPerόay = ~ txtDoseLockoutHours = ~ txtMedlcationRemaining = ~ bttEventCount = ~ txtLastRetπevalDate = "" txtDe vice Started = "" , lErrorCode)

Figure imgf000139_0001
btnReadEntireContents.Enabied = True 're-enable button

RefreshAIIOpenForms

'Compare battery time to value retneved from mi file to determine if a reminder should oe given fo We user to change the battenes i = Clnt(GetlNISettιπg(gsApplnιFileSpec, "Options", "Battery Change Days", 180)) _ If I And Val(PAT_DATA.sBatteryChangeTimer) >= i Then sMSG = The battery in this device needs to be changed." + vbCrLf ♦ vbCrLf

'Also look at the error flag returned from the device to see if the brownout

'bit was set If se append a afferent notice to the message than the normal one If PAT_DATA.bErrorBrownOut Then sMSG = sMSG + The device indicates that power was bπeify lost due to low voltage " _ Else sMSG = sMSG + They have been in place for over " + CStr(i / 30) + " months "

737 nReadDeviceData.frm - DtnReadEntireCσπtents. ιcκ

Needed")

Figure imgf000140_0001
End Sub

Private Sub Form_Activate()

PopulateDeviceCommDialog PAT_DATA, Me

Comm_lnιtιalιzeCommPort 'initialize tne comm port trorr. IN! Hie settings gbKeepPollingDevice = True 'continue polling device

PollDeviceContinually Me SetPπnterlcon False, "" End Sub

Private Sub Form_Load()

Me.Left = 0 Me.Top = 0

Unload frmDevicelnitialize 'don'f need this form gbCommOK = 99 'reser flag that will gve an indication as to the communication status End Sub

Private Sub Form_Unload(Cancel As Integer) gbKeepPollingDevice = False 'stop polling the device Wait 0.1 End Sub

/3 f frmPnnt frm - File Declarations

Attπbute VB_Name = "frmPπnt" Attπbute VB_GlobalNameSpace = False Attπbute VB_Creatable = False Attπbute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit

Private Sub btnClose_Click()

Unload Me End Sub

Private Sub btnPrintNow_Click() btnPπntNow Enabled = False btnPπntNow.Refresh vsPπnterl .Action = paPπntAII btnPnntNow Enabled = False End Sub

Private Sub btnPrintPage_Click() btnPπntPaoe. Enabled = False btnPrintPage.Refresh vsPπnterl .Action = paPπntPage btnPπntPage.Enabled = True End Sub

Private Sub btnRefresh_Click()

RefreshPreview End Sub

Private Sub Form_Load()

Dim i As Integer gbPππtFormLoading = True frmPπnt.vsVlewPortl .BorderStyle = 1 furπ off til needed gbPπnterErrorDetected = False

Me.Wldth = 7500

Me.Move (Screen.Width - Me Width) / 2, (Screen. Height - Me Height) / 2 'center form on screen ' datPπntingrediβnt DatabaseName - sgDataBaseName

IblActrvePπnter.Caption = " " + vsPπnterl. Device gbPreventPreviewUpdates = False 'allow controls to update when called

Me.Show DoEvents RefreshPreview SetPπnterlcon False, ~ End Sub

43 f frmPrint.frm - Form_QueryUnload

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)

Dim r As Integer If gbPπntSpoolinglnProgress Then 'user tned to exit while pπnt spooling

Beep r = MsgBoxfltems are still waiting to be pnnted. If you continue, the pπnt job may be lost " bCrLf + vbCrLf + "Do you still want to ->► close this form?", vbQuestion ♦ vbYesNo, "Waiting For Pπnter")

If r = vbNo Then Cancel = True 'prevent crasn error End If gbPrintSpoolinglnProgress = False End Sub

Then '::o' minimized l3D1.Width - 100 - 400) 100)

Figure imgf000142_0001

SetPreviewSize End Sub

Private Sub HScrolM_Change()

Static bProcedureActive _ If bProcedureActive Then HScrolM .Refresh Exit Sub _ End If bProcedureActive = True 'prevent recursive calls to this procedure HScrolM .Enabled = False frrnPrint.vsPrinterl.PreviewPage = HScrolH .Value UpdatePageButtons bProcedureActive = False 'prevent recursive calls to this procedure End Sub

Private Sub HScroll1_Scroll()

Static bProcedureActive

If bProcedureActive Then Exit Sub bProcedureActive = True 'prevent recursive calls to this procedure IblPageNumber = HScrolH. Value UpdatePageButtons bProcedureActive = False 'prevent recursive calls to this procedure End Sub

/ frmPππt. frm - IblActivePrinter Click

Private Sub lblActivePrinter_Click()

Static bProcedureActive

If bProcedureActive Then Exit Sub bProcedureActive = True 'pievent recursive calls to this oiocedure

On Error GoTo btnChangePπnter_Clιck_Error

CommonDialogl M = 1 'ser lowest page number to unnt

CommonOialogl .Max = giTotalPnπtPages sef highest page numoer to pr.r.t

CommonDialogl. FromPage = 1 'set lowest page numoer to pnnt

CommonOialogl ToPage = giTotalPπntPages 'set highest pace number to pnnt

Set flags 'PD_HIDEPRINTTOFILΞ &H10QC00& Tne ?:mt to -χ/e check is-, *s nor displayed 'PD_NOPAGEMUMS &HSZ Disables tne Pages option button and 're associated edit centre! 'PD_FR1NTSETU > &H403. Causes the sysrs.-rt ro s lay the Pπnt Setup dialog box rather than the pnnt dialog ex

CommonDialogl. Flags = &H40&

CommonDialogl. CaπcelError = True

CommonDialogl. Action = 5 'call pnnter common ciatog

'Update caption to esi current pnnter selection

IblActivePπnter Caption = " " + vsPπnterl .Device frmPππt.MousePoιnter = vbHourglass

DoEvents

SetPreviewSize 'this is mainly for layout ,t portrait/landscape is changed

RefreshPreview frmPπnt.MousePointer = vbDefault

DoEvents btnChangePππter_CIιck_Exιt- bProcedureActive = False 'prevent recursive calls to this procedure Exit Sub btnChangePπnter_Click_Erroι. Resume btnChangePππter_Click_Exit

End Sub

Private Sub optZoom_Click(lndex As integer)

SetPreviewSize End Sub

Private Sub vsPrinteιi_EndPage()

Call PπntPageNumber End Sub

Pπnt"

Figure imgf000143_0001

Figure imgf000143_0002
frmPπnt frm - vsPπnterl Error

, "Can t Pπnt"

Figure imgf000144_0001

Private Sub vsPπnter1_NewPage()

Dim fCurrentFontSize As Single, bCurrentFontltalie As Boolean sCurrentFontName As Stπng Dim iCurrentTextAlign As Integer, ICurrentY As Long

With frmPπnt vsPπnterl fCurrentFontSize = FontSize remember the existing se'tiπgs so they can oe changed back bCurrentFontltalie = Fontltalic iCurrentTextAlign = TextAlign ICurrentY = CurrentY sCurrentFontName = FontName

FontName = "Anal"

Fontltalic = False

TextAlign = taRightTop

CurrentY = 1440 * 05 'pnnt name on of program

FontSize = 9 sef font size

.Fontltalic = False frmPπnt vsPπnterl = App Title

.FontSize = fCurrentFontSize .Fontltalic = bCurrentFontltalie TextAlign = ICurrentTextAlign .CurrentY = ICurrentY .FontName = sCurrentFontName EndWKh

- Select Case gsActiveFormName Case "frmPatientDosingReport"

If gfTotalPπntPages Then PπntDosingEventsHeader "" . End Select giTotalPπntPages = gfTotalPππtPages + 1 End Sub

<7 frmDevr.eDiagnostics.frm - File Declaration;

Attπbute VB_Name » "frmDeviceDiagnosties" Attπbute VB_GlobalNameSpace = False Attnbute VB_Creatable = False Attπbute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit

Private Sub btnChangeBatteries_Click()

Call ChangeβatteπesRequest End Sub

Private Sub btnClose_Click()

Unload Me End Sub

Private Sub btnReadEntireContents_Ciick()

Dim r As Integer, lErrorCode As Long, i As Integer r = ValidatePatlentDataSaved 'ensure that previous patient data was saved before proceeding If r = vbCancel Then Exit Sub btnReadEntireContents.Enabled = False 'prevent recursive calls to device btnSendData.Enabled = False prevent recursive calls to device gbKeepPollingDevice = False 'stop polling for now Wait 0.25 txtPatientLastName = ~ 'dear ouf fΛe text boxes before readπg data txtPatientFirstName = "" 'clear out the text boxes before reading data txtDrug. Clear txtPatientID - ~ txtTxCenter = "" txtOrgaπ.Clβar txtSerialNumber = "" txtDoseSize = ~ txtDoseTime(1) = ~ txtDoseTime(2) = " txtDoseTime(3) = ~ txtDoseTιme(4) = ~ txtDosesPerDay = "" txtDoseLockoutHours = ~ txt Device Started = "" txtMedicationRema ing = ~ txtBatteryChangeTimer = "" txtEventCount = ~ bttFirmwareVer = ~ DATA, lErrorCode)

Figure imgf000145_0001
gbKeepPollingDevice = True start pol ng again btnReadEntireContents.Enabled = True ιe-er.able button btnSendData.Enabled = True RefreshAIIOpenForms End Sub

3 frmDeviceDiagnosties frm - btnSendData_Clk

Private Sub btnSeπdData_Click()

Dim i As Integer, r As Integer, lErrorCode As Long r = Validate DoseNumbers(Me) If r = False Then Exit Sub nd Dosing Information currently in the CycloTech device will be changed if you continue Medication » + vbCrLf + "Do you want to continue?", vbYesNo + vbQuestion, "Device Data being changed")

Figure imgf000146_0001
preven' recursive calls to device 'srop polling for now
Figure imgf000146_0002

On Error GoTo btnSendData_Clιck_Error r = Comm_SendCustomData(PAT_DATA, DATA_BEGIN_CUSTOM1 , lErrorCode) If lErrorCode Then Error lErrorCode error number r = Comm_SendCustomData(PAT_DATA, DATA_BEGIN_CUSTOM2, lErrorCode) send Ό device

If lErrorCode Then Error lErrorCode error numbeT r * Comm_SendCustomData(PAT_DATA, DATA_BEGIN_CUSTOM3, lErrorCode) 'send fo device

If lErrorCode Then Error lErrorCode error number r = Comm_SendCustomData(PAT_DATA, DATA_BEGIN_CUSTOM4, lErrorCode) send to device

If iErrorCode Then Error lErrorCode error number ensure that the values in the text boxes are convened into the global structure TimeValue(txtDoseTime(l)) save Dose Interval -1 'indicate that no time was set

Figure imgf000146_0003
r = Comm_SendDosιngParams(PAT_DATA, lErrorCode) If lErrorCode Then Error lErrorCode 'error number btnSeπdData_Clιek_Exιt: btnSendData.Enabled = True 're-enable button btnReadEntireContents.Enabled = True gbKeepPollingDevice = True 'continue polling device Exit Sub btnSendData_Click_Error

DisptayErrorMessage lErrorCode '" Resume 0 'temp test

Resume btnSendData_Clιck_Exιt End Sub

Figure imgf000146_0004
frmDeviceDiagnostics.frm - Form_Activa'{4;

Private Sub Form_Activate()

PopulateDeviceDiagDialog PAT_DATA, Me

Cαmm_lnitlalizeCommPort 'initialize the com port from INI file settings

IblCommPort.Caption = " " + CStr(giCommPort) IblSettings.Caption = " " ♦ gsCommDeviceSettmgs IblDeviceWaitTime = " " + CStr(giDeviceResponseWait)

gfiCommSusy = False 'reser flag gbCommReplyPending = False 'reset flag gbKeepPollingDevice - True 'continue coiling device

PollDeviceContinualiy Me

SetPrinterlcon False, "" End Sub

Private Sub Form_lnitialize()

Me. Left = 0 Me.Top = 0 ' End Sub

Private Sub Form_Load()

Unload frmDevicelnitialize Unload frrnReadDeviceData gbCommOK = 99 'nssef flag that will gve an indication as to the communication status. End Sub

Private Sub Form_Unload(Caπcel As Integer) Dim r As Integer r » VaildateDoseNumbers(Me) If r = False Then Cancel » True gbKeepPollingDevice => False 'sfop polling the device Wait 0.1 End Sub

Private Sub txtDoseTime_Change(lndex As Integer) (lndex) = TimeValue(txtDoseTime(lndex)) 'save Dose Interval (lndex) = -1 'indcate that no time was set

Figure imgf000147_0001

Figure imgf000147_0002
DeviceDiagnostics.frm - bciDoseLockoutHou s_k nge

131

Private Sub txtDoseLockoutHours_Change()

PAT_DATA.sDoseLockoutHours = txtDoseLockoutHours 'save Dose Lockout Hours

End Sub

Private Sub txtDoseSize_Change()

PAT_DATA.sDoseSize = txtDoseSize save Dcse Size

End Sub

Private Sub txtDosesPerDay_Change()

PAT_DATA.iDosesPerDay = Vai(txtDosesPerDay) save Dcses per day

End Sub

Private Sub txtDrug_Click()

PAT_DATA.sDrug = txtDrug save field

End Sub

Private Sub txtOrgan_Click()

PAT_DATA.sOrgan = txtOrgan 'save field

End Sub

Private Sub txtPatientFirstName_Change()

PAT_DATA.sPatientFirstName = txtPatientFirstNa e 'save field End Sub

Private Sub txtPatientlD_Change()

PAT_DATA.sPatientlD = brtPaBentID 'save Patient ID End Sub

Private Sub txtPatientl_astName_Change()

PAT_DATA.sPatientLastName = txtPatieπtLastName 'save field End Sub

Private Sub txtSerialNumber_Chaπge()

PAT_DATA.sSerialNumber = bctSeπalNumber 'save senal number End Sub

y frmDeviceDiagnosties frm - txtTxCenter CΠA

Private Sub txtTxCenter_Change()

PAT_DATA sTxCenter = txtTxCenter save field

End Sub

Private Sub UpDownDoseTime_DownClick(lndex As Integer)

Dim fDalylncrement As Single, ilndex As Integer 24

Figure imgf000149_0001
fDalylncrement = (ilndex / 24) txtDoseTιme(lndex) = " " + Format$(TιmeValue(CDate(fDalylncrement)), gsTimeDisplayFormat) End Sub

Private Sub UpDownDoseTime_UpClick(lndex As Integer)

Dim fDalylncrement As Single, ilndex As Integer 24

Figure imgf000149_0002
fDalylncrement = (ilndex / 24) txtDoseTime(lndex) = " " ♦ Format$(TimeValue(CDate(fDaiylncrement)), gsTimeDisplayFormat)

End Sub

Figure imgf000149_0003
frmFaxStatus. frm - File Declarations

Attπbute VB_Name = "frmFaxStatus" Attribute VB_GlobalNameSpace = False Attπbute VB_Creatable = False Attribute VB_Predeclaredld = True Attnbute VB_Exposed = False Option Explicit

Private Sub cmdCancel_Click()

On Error Resume Next gcFax CancelFax gcrax.FaxLogiD

Unload Me

End Sub

Private Sub Form_Activate()

SetPπnterlcon False, ~ End Sub

Private Sub Foπτt_Load()

IblDestination = "" IblPage = ~ IblSpeed = "" End Sub

≠? frmFaxSend frm - File Declarations

Figure imgf000151_0001

Attπbute VB_Name - "frmFaxSend" Attπbute VB_GlobalNameSpace = False Attnbute VB_Creatable = False Attπbute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit

Sub ReloadGrouρsϋst()

Dim i As Integer

With cmboGroups Clear

Figure imgf000151_0002

End Sub

Sub ReloadLocationsListQ

Dim i As Integer

With istLocations .Clear For i = 1 To FAX_OATA.iLocTotal

.Addltem FAX_DATA~.sLocPereonName(i) .ltemOata(. ewlndex) = i 'keep index Next i

End With

End Sub

Private Sub btnAddGroup_Click()

Dim I As Integer, r As Integer, sSection As Stnng gsEditGroupName = "" gsEditGrouplndexes = ""

Load ffmFaxEditGroups frmFaxEditGroups.Show vbModal

If gsEditGroupName = "" Then Exit Sub 'no name was enetered the list

meslnTitle(ι)

Figure imgf000151_0003

Figure imgf000151_0004
Figure imgf000152_0001

End Sub

Private Sub btnClose_Clιck()

Unload Me End Sub

Private Sub btnDeleteGroup_Click()

Dim i As Integer, r As Integer, sMSG As Stπng vbCrLf + vbCrLf + "Do t

Figure imgf000152_0002

RemoveGroupFromFaxList gsEditGroupName

ReloadGroupsϋst cmboGroups Listlndex = 0 'default to manual selections

End Sub

Private Sub btnDeleteName_Click()

Dim I As Integer, r As Integer, sMSG As Stπng gsEditName = IstLocabons Lιst(lstLocatιons Listlndex) sMSG = The following name and related information will be permanently deleted " + VbCrLf + gsEditName + VbCrLf + VbCrLf + "Do you » want to delete It?" r = Msgβox(sMSG, VbYesNo + vbDefaultButton2 + vbQuestion, "Confirm Name Deletion") If r = vbNo Then Exit Sub

RemoveNameFromFaxϋst gsEditName

ReloadLocationsList

If IstLocations UstCouπt < 1 Then btnOeleteName Enabled = False End If cmboGroups_Cllck cause appropriate boxes to be reselected End Sub

S-* frmFaxSend frm - btnEdιtGroup_Clιr

1 136

Pπvate Sub btnEditGroup_CIick()

Dim i As Integer, r As Integer, sSection As Stnng

With cmboGroups gsEditGroupName = Lιst( Listlndex) i = GetlndexToFaxGroupName(gsEdιtGroupName) get πcev 'rciv structure gsEditGrouplndexes = FAX_DATA sGroupNameslnTϊtle(ι) frmFaxEditGroups Show vbModal

Lιst( Listlndex) = gsEditGroupName End With

With FAX_DATA sGroupTιtle(ι) = gsEditGroupName sGroupNamesinTitle(ι) = gsEditGrouplndexes r = WπtePπvateProfileStπng(sSectιon, ByVal 04, ByVal 04 gsFaxFileSpec) SavelNISetting gsFaxFileSpec, sSection, Total Groups", CStr( iGroupsTotal) For i = 0 To iGroupsTotal

SavelNISetting gsFaxFileSpec, sSection, "Group ' + CStr(ι), sGroupTitle(ι)

SavelNISetting gsFaxFileSpec, sSection, "Group Locations ' + CStr(ι), sGroupNameslnTitle(ι) Next i

End With

UpDateListBoxSelecbαπs gsEditGrouplndexes

End Sub

Private Sub btnEditName_Click()

Dim i As Integer gsEditName * lstLαcations.Lιst(lstLocatιons.ϋstlndex) i = GetlndexToFaxLocName(gsEdιtName) 'get index from structure gsEditVoicβ = FAX_DATA.sLocVoιceNumber(i) gsEditFax = FAX_OATA.sLocFaxNumber(l) frmFaxEd-Locatioπs.Show vbModal IstLoeatιons.List(lstLocatιons.Ustlndex) = gsEditName FAX_DATA.sLocPersonName(i) = gsEditName FAX_DATA.sLooVoιceNumber(ι) = gsEditVoice FAX_DATA.sLocFaxNumber(ι) = gsEditFax

End Sub

Private Sub btnNew_Click()

End Sub

/*"/ O 99/35588

frmFaxSend frm - btnNewName G

Private Sub btπNewName_Clιck() Dim I As Integer gsEditName = "" gsEditVoice = ~ gsEditFax = ~

Load frmFaxEditLocatioπs fr FaxEditLocatioπs Caption = Enter New Name frmFaxEditLocations Show vbModal

If gsEditName = "" Then Exit Sub no na—e vas e-e'β'ed

Figure imgf000154_0001

End Sub

Private Sub btnSeπdFax_Click()

Dim I As Integer, r As Integer, sFileSpec As Stπng, lErrorCode As Long Dim sSourceFileSpec As Stπng, sOestFileSpec As Stπng

On Error GoTo btnSendFax_Error

_ to fax Please open a patient file " vbExciamation "No File Selected" _

Figure imgf000154_0002

Create TxtSummaryFile

Copy the report information to a text tile for conversion to a fax document atientLastName ♦ " " + PAT_DATA sPatientFirstName + " " + PAT.DATA entID + " " + PAT_DATA sPatientID + " fmr car de'errme that the fie is already open

Figure imgf000154_0003

ceverti'" ~errp 'xi"

Figure imgf000154_0004

Figure imgf000154_0005
99/35588

frmFaxSend frm -

Figure imgf000155_0001

ber

Figure imgf000155_0002

ocations ItemData(i) + 1)

Figure imgf000155_0003
btnSendFax_Exιt.

Unload Me 'must oe unloaded becau e the status form is a ncnmodal cniid form and can not oe displayed while a modal form is being displayed btnSendFax_£rror MsgBox "An uncorrectable eπ-or occurred while trying to fax the document. Please try again.", vbExciamation, "Fax Eπ-or - " + Errors Resume btnSendFax_Exιt

End Sub

Private Sub cmboGroups_Click()

Dim i As Integer, r As Integer, j As Integer, sName As Stnng

With cmboGroups i = GetlndexToFaxGroupName(.List(.Listlndex)) UpDateLιstBoxSelectιons FAX_DATA.sGroupNameslnTitle(i) selection was mace

Figure imgf000155_0004

End With End Sub

/S^3 99/35588

Figure imgf000156_0001

Private Sub UpDateListBoxSelectιons(ByVal sGroup As Stππg)

Dim i As Integer, ) As Integer, r As Integer, sTempLιst(100) As Stπng

With IstLocations Clear For I = 0 To FAX_DATA iLocTotal - 1

Addltem FAX_DATA sLocPersonName(ι + 1) ltemData( Newlndex) = I Aeeo index Next i

'Parse the attached locations and check the appropnate cores r = ParseDelιmStπng(sGroup, "|", sTempϋstf)) some locations are attached UstCount - 1 step through the names and check appropπate ones sTempListfj) Then True

Figure imgf000156_0002

End Sub

Private Sub Form_Actιvate()

SetPπnterlcon False, ~ End Sub

Private Sub Form_Load() txtFileToSend • PAT JATA.sPatiemOataFileName

GetFaxLocaqons

ReloadLocatlonsList

ReloadGroupsList

'make sure it is in range If cmboGroups.UstCount >= FAX_DATA.iGroupLastSeleeted Then cmboGroups Listlndex = FAX_DATA.IGroupLastSelected End Sub

Private Sub Form_Unload(Cancel As Integer)

Dim i As Integer, r As integer, sSection As String

With FAX_DATA sSection = "User Selections"

.iGroupLastSelected * cmboGroups.Listlndex

SavelNISetting gsFaxFileSpec, sSection, "Last Group Selected", CStr( IGroupLastSelected) End With

gsFaxFileSpec) CStr( iLocTotal) tr(ι), sLocPersonName(ι) , sLocFaxNumber(ι) (ι), .sLocVoιceNumber(l)

Figure imgf000156_0003
sSection = "Fax Groups"

yy^ O 99/35588

frmFaxSend. frm - Form Uπloai. __-. 1 — -F

upNameslnTitle(i)

Figure imgf000157_0001

End With End Sub

Private Sub lstLocatioπs_Click()

Dim i As Integer, sTemp As Stπng btπEditName. Enabled = True btπDeleteName.Enabled = True

selections

Figure imgf000157_0002

Private Sub lstLocations_DblClick() btnEd«Name_Click End Sub

Figure imgf000157_0003
99/35588

frmFaxLog.frπ. - File Declaration

Attπbute VB_Name = "frmFaxLog" Attπbute VB_GlobalNameSpace = False Attπbute VB_Creatable = False Attπbute VB_Predeclaredld = True Attπbute VB_Exposed » False Option Explicit

Private Sub btnClose_Click()

Me.Hide 'stay leaded because it contains the fax contra: End Sub

Private Sub Form_Activate()

SetPnnterlcon False, ™ End Sub

Private Sub Form_Load() optViewFaxes_Click 1 'cause the "Sent" button to be dlcked End Sub

Private Sub Foπn_Resize() btnClose.Left = Me.Wldth • btnClose.Width - 250 FaxManI .Width = Me.Wldth - FaxManI. ett - 250 FaxManI .Height = Me.Height - FaxManI .Top - 500 End Sub

Private Sub optViewFaxes_Click(lπdex As integer) _ Select Case Index Case 0

FaxManI .Log = Pending Case 1

FaxManI. Log = Completed Case 2

FaxManI. Log = Failed _ End Select End Sub

/A 99/35588

frmFaxEditGroups _ frm - File

Figure imgf000159_0001
_

Attπbute VB_Name = "frmFaxEditGroups' Attπbute VB_GlobalNameSpace = False Attπbute VB_Creatable = False Attπbute VB~Predeclaredld = True Attribute V8_Exposed = False Option Explicit

Pπvate Sub btnClose_Click()

Unload Me

End Sub

Private Sub Form_Activate()

SetPπnterlcon False, "" End Sub

Private Sub Form_Load()

Dim I As Integer, j As Integer, r As Integer, sTempLιst(IOO) As Stπng txtName * gsEditGroupName With IstLoeations e(l ♦ 1) x

Figure imgf000159_0002

check appropπate ones

Figure imgf000159_0003

Private Sub Form_Unload(Cancel As Integer)

Dim I As Integer, r As integer, sSection As Stπng gsEditGrouplndexes = "" With IstLoeations Grouplndexes = gsEditGrouplndexes + CStr( ItemData(ι)) -

Figure imgf000159_0004
gsEditGroupName = txtName End Sub

/S"?

Figure imgf000160_0001

Private Sub txtName KeVPress Kp„Δc- Λ ,

- lfKeyAsc„ = 13Then 7r, ,e"eS AS lπte9er>

IstLocatioπs.SetFocus ' " p,'esse2

KeyAscii = 0 'change it to a tap kev - End If End Sub

Figure imgf000160_0002
O 99/35588

frmFaxEdilLocations.frm - File Declan-.,jns

Attπbute VB_Name * "frmFaxEditLαcations" Attπbute V8_GlobalNameSpace = False Attribute VB~Creatable = False Attribute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit Dim bxSaveOata As Boolean

Private Sub btnCancel_Clic ()

Unload Me End Sub

Private Sub btπClose_Click() bxSaveOata = True Unload Me End Sub

Private Sub Form_Activate() txtName. SetFocus SetPrinterlcon False, "" End Sub

Private Sub Fonm_Load() txtName ■ gsEditName txtVoiceNumber * gsEditVoice txtfaxNumber = gsEditFax End Sub

Private Sub Form_Uπload(Cancel As Integer) Then = TrimS(txtName) = Trim$(txtVoiceNumber) TrimS(b(tFaxNumber)

Figure imgf000161_0001

Integer)

Figure imgf000161_0002

Figure imgf000161_0003
99/35588

frmFaxEdilLocations frm - tx(FaxNumber_ .yPress

Private Sub txtFaxf\iumber_KeyPress(KeyAscii As Integer)

_ If KeyAscii = 13 Then 'rfle "Enter" kev was pressed txtVoiceNumber.SetFocus

KeyAscii = 0 change it to a tao kev

- End If End Sub

Private Sub txtName_KeyPress(KeyAscii As Integer) Then the Enter" key was pressed r.SetFocus change it to a tao kev

Figure imgf000162_0001

(KeyAscii As Integer) presseα

Figure imgf000162_0002

Private Sub txtVoiceNumber_KeyPress(KeyAscii As Integer)

If KeyAscii * 13 Then 'the "Enter" key was pressed btnClose.SetFocus

KeyAscii = 0 'change it to a tab key End If End Sub

AA 99/35588

frmDevicelnitialize frm - File Declara-, <s

Attπbute V8_Name = "frmDevicelnitialize" -π: Attπbute VB_GlobalNameSpace = False Attπbute VB_Crβataβle - False Attπbute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit

Private Sub btπChangeBatteries_Click() btnChangeBatteπes.Enabled = False prevent recursive ca'ls to device

Call Change θatteπesRequest btnChangeSatteπes Enabled = True enable burcn again

End Sub

Private Sub btnClose_Click()

Unload Me

End Sub

Private Sub btn eadEπtireConteπts_Click()

Dim r As Integer, lErrorCode As Long, i As Integer r = ValidatePatientOataSaved 'ensure that previous patient data was saved before proceeding If r = vbCancel Then Exit Sub btnReadEntireContents.Enabled = False 'prevent recursive calls to device btnSendData.Enabled > False prevent recursive calls to device 'srop polling for now

Figure imgf000163_0001
txtPatientLastName - "" 'clear out the text boxes before reading data txtPatlentFirstName * "" 'dear out the text boxes before reading data txtPatlentID - " txtTxCenter ■ "" txtDrug.Clear txtOrgan.Clear txtSerialNumber = ~ txtDoseSee « ~ txtDoseTime(l) = "" txtDoseTime(2) = "" txtDoseTιme(3) = ~ txtDoseTime( ) « "" txtDosesPerDay ■ "" txtDoseLockoutHours = "" txtDeviceStarted = "" txtMedicatioπRemaining = "" bttBatteryChangeTimβr = "" txtEventCount ■ "" txtPatientLastName SetFocus 'f3*e focus away from llstbox

Me.Refresh , lErrorCode)

Figure imgf000163_0002
gbKeepPollingDevice = True start coiling again btnReadEntireContents.Enabled ■ True re-enable button

/^ / 99/35588

frmDevicelnitialize. frm - binReadEniireCoi. <s_Click btnSendData Enabled = True RerreshAIIOpenForms

End Sub

Private Sub btnSendData_Click()

Dim i As Integer, r As Integer, lErrorCode As Long r = ValιdateOoseNumbers(Me) If r = False Then Exit Sub nd Dosing Information currently in the CycloTech device will be changed if you continue. Medication x, + vbCrLf + "Do you want to continue?", vbYesNo + bQuestion, "Device Data being changed")

Figure imgf000164_0001
'prevent recursive calls to device 'step pcilmg tor now
Figure imgf000164_0002

On Error GoTo btnSendData_Clιck_Error r = Comm_SendCustomOata(PAT_DATA, DATA_BEGIN_CUSTOM1, lErrorCode) If lErrorCode Then Error lErrorCode error number r = Comm_SendCustomData(PAT_DATA, DATA_BEGIN_CUSTOM2, lErrorCode) send to device If lErrorCode Then Error lErrorCode 'error number r = Comm_SendCustomData(PAT_DATA, DATA_BEGIN_CUSTOM3, lErrorCode) 'send to device

If lErrorCode Then Emir lErrorCode 'error number t * Comm_SendCustomData(PAT_OATA, DATA_BEGIN_CUSTOM , lErrorCode) 'send to device

If lErrorCode Then Error lErrorCode 'error number

'ensure that the values In the text boxes a converted Interval

Figure imgf000164_0003
r » Comm_SeπdDosιngParams(PAT_DATA, lErrorCode) If lErrorCode Then Error lErrorCode 'error number

Figure imgf000164_0004
btnSeπdData_Cllck_Error

DisplayErrorMessage lErrorCode '" Resume 0 'temp test

Resume btnSeπdData_Click_Exιt End Sub

έΛ. O 99/35588

Figure imgf000165_0001

Private Sub Form_Activate()

PopulateDeviceCommOlalog PAT_DATA, Me

CommJnitializeCommPort 'initialize the comm port trcm INI file settings gbKeepPollingDevice = True 'continue polling device

PollDeviceContinually Me SetPπnterlcoπ False, "" End Sub

Private Sub Form_Load()

Me.Left = 0 Me.Top = 0

Unload frrnReadDeviceData 'don't need this form gbCommOK = 99 'reset Hag mat will gve an indication as tc the communication stalu End Sub

Private Sub Form_QueryUπload(Cancel As Integer, UnloadMode As Integer) Dim r As Integer r = ValidateDoseNumbers(Me) If r = False Then Cancel = True End Sub

Private Sub Form_Unload(Cancel As Integer) gbKeepPollingDevice ■ False 'stop polling the device Wait 0.1 End Sub

Private Sub txtDoseLockoutHours_Chaπge()

PAT_DATA.sDoseLockoutHours = txtDoseLockoutHours 'save Dose Lockout Hours

End Sub

Private Sub txtDoseSize_Change()

PAT_DATA.sDoseSize - txtDoseSize save Dose Size

End Sub

Private Sub txtDosesPerDay_Chaπge()

PAT_DATA.iDosesPerDay = Val(txtDosesPerDay) save Doses per day

End Sub

Figure imgf000165_0002
99/35588

frmDevicelnitialize frm - txtDrug_.C-—> p— — — ~ ' -\ u

Private Sub txtDrug_Click()

PAT_DATA.sDrug = txtDrug End Sub

Private Sub txtOrgan_Click()

PAT_OATA.sOrgan = txtOrgan End Sub

Private Sub txtPatientFirstName_Change()

PAT_DATA.sPatιentFιrstName = txtPatientFirstName save Patient name

End Sub

Private Sub txtPatientlD_Change()

PAT_DATA.sPatιentlD = txtPatientID End Sub

Private Sub txtPatientLastName_Change()

PAT_DATA.sPatientLastName = txtPatientLastName save Patient name

End Sub

Private Sub txtSerialNumber_Change()

PAT_DATA.sSeπalNumber = txtSeπalNu ber 'save senal number End Sub

Private Sub txtTxCeπter_Change()

PAT_DATA.sTxCenter ■ txtTxCenter

End Sub

Private Sub UpDownDoseTime_DownClick(lndex As Integer)

Dim fDalylncrement As Single, ilndex As integer

Figure imgf000166_0001
fDalylncrement = (ilndex / 2 ) txtOoseTime(lndex) = " " + FormatS(TimeValue(CDate(fDalylπcrement)), gsTimeDisplayFormat)

End Sub

4W

Figure imgf000167_0001
fDalylncrement = (ilndex / 2 ) £nrx .Do eTime(iπdex) . ■ ■ + Forma,S(T,meVa,ue(CDa,e(fDa,y,ncrement), gsTimeDisplayFormat)

/t> sr O 99/35588

Figure imgf000168_0001

Private Sub btnDateCancel_Click() gdTempOateTime = 0 .nctcate to cailer that a cancel cccurred giTempCya = 0 gfTempCreatiπine = 0 gsTempCustomlπfo = "" Unload frmGetDateTime End Sub

) vbExciamation, "Value Required"

Figure imgf000168_0002
0 Then Creatiniπe level", vbExciamation, "Value Required"
Figure imgf000168_0003

'On Error Resume Next gdTempDateTime = CVDate(txtDate Entry. Value) 'get date from control gdTempDateTime = gdTempDateTime + CVDate(txtTϊmeEntry.Time) giTempCya = txtCya.Text gfTempCreatiniπe * txtCreatinine.Text gsTempCustomlnfo = txtCustomlnfo

Unload frmGetDateTime 'On Error GoTo 0 End Sub

Private Sub Form_Activate()

SetPπnterlcon False, "" End Sub

Private Sub Form_Load()

Me.Wldth = pnlGetDate. Width ♦ 90 Me.Height = pnlGetDate. Height + 90 txtTimeEntry.Time = CStrfTi e) End Sub

/<- (- Function Index

B brwWebBrowser_DownloadComplete (frmBrowser.frm) , 95 brwWebBrowser_NavigateComplete (frmBrowser.frm) , 95 btπAddGrouρ_Click (frmFaxSeπd.frm) , 134 btπCancel_Click (frmFaxEditLocations.frm) , 144 btπChangeBatteries_Click (frmDeviceDiagnostics.frm) , 128 btπChangeBatteries_Click (frmDevicelnitialize.frm) , 146 btnChangeCompliance_Click (frmDosingCalendar.frm) , 111 btnClose_Click (frmAIIPatients.frm) , 100 btπClose_Click (frmDeviceDiagnostics.frm) , 128 btnClose_Click (fr Devicelnitialize.fim) , 146 btπClose_Click (frmDosingCalendar.frm) , 111 btnClose_Click (frmFaxEditGroups.frm) , 142 btnClose_Click (fπnFaxEditLocatioπs.fιτπ) , 144 btnClose_Click (frmFaxLog.frm) , 141 btnClose_Click (frmFaxSend.frm) , 135 btnClose_Click (frmPatientDosingRptfrm) , 118 btnClose_Click (fπnPrint.frm) , 124 btnClose_Click (fr ReadDeviceData.frm) , 122 btnClose_Click (fπnRecentDosingGrap .fπτι) , 108 btnConfigureFax_Click (fimOptions.frm) , 88 btnDateCancel_Click (frmGetDateTime.frm) , 151 btnDeleteGroup_Click (frmFaxSeπd.frm) , 135 btnDeleteName_Click (frmFaxSend.frm) , 135 btnDeleteUserEvent_Click (frmPatientDosingRptfrm) , 119 btnEditGroup_Click (frmFaxSeπd.frm) , 136 btnEditName_Click (frmFaxSend.frm) , 136 btnNew_Click (frmFaxSend.frm) , 136 btnNewName_Click (frmFaxSend.frm) , 137 btnNewUserEvent_Click (frmPatientDosingRptfrm) , 119 btnPrinter_Preview_Click_Proc (Printing, bas) , 46 btnPrintNow_Click (frmPrint.frm) , 124 btnPriπtPage_Click (frmPrint.frm) , 124 btπReadEntireCoπtents_Click (frmDeviceDiagnostics.frm) , 128

/Li Function Index btnReadEntιreConteπts_Click (frmDevicelnitialize.frm) , 146 btnReadEntireContents_Click (frmReadDeviceData.frm) , 122 btnRefresh_Click (frmPπntfrm) , 124 btπSendData_Click (frmDeviceDiagnostics.frm) , 129 btnSendData_Click (frmDevicelnitialize.frm) , 147 btnSendFax_Click (frmFaxSend.frm) , 137

C

CalcDayDoseScore_AIIDoses (General.bas) , 4 CalcDayDoseScore_OnTime (General.bas) , 4 CalcDayslnMonth (Calendar.bas) , 61 CalcDosesSumTakenOnSpecificDay (General.bas) , 5 CaiculateAIIPatientsComplianceOnDisk (frmAIIPatients.frm) , 102 CalculateSinglePatientCompliance (frmAIIPatients.frm) , 100 Calendar_DayChange (frmDosingCalendar.frm) , 111 Calendar_MonthChaπge (fππDosiπgCalendar.fπn) , 111 Calendar_MouseMove (frmDosingCalendar.frm) , 112 Calendar_YearChange (frmDosingCalendar.frm) , 112 cboAddress_Click (frmBrowser.frm) , 96 cboAddress_KeyPress (frmBrowser.frm) , 96 ChangeBatteriesRequest (Comm.bas) , 28 chkDoseChanged_Click (frmDosingCalendar.frm) , 112 chkDoseChanged_Click (frmPatientDosingRptfrm) , 119 chkDoses_Click (frmPatientDosingRptfrm) , 119 chkDosesMissed_Click (frmDosingCalendar.frm) , 112 chkDosesNotComplied_Click (frmDosingCalendar.frm) , 112 chkDosesTaken_Click (frmDosingCalendar.frm) , 112 chkLoadTipsAtStartup_Click (frmTip.frm) , 99 chkUserDefιned_Click (frmPatientDosingRpt.frm) , 120 chkWeekNumbers_Click (frmDosingCalendar.frm) , 112 cmboAverageDays_Click (frmRecentDosingGraph.frm) , 108 cmboChartTyρe_Click (frmRecentDosingGraph.frm) , 108 cmboDataToView_Click (frmAIIPatients.frm) , 101 cmboDataToView_Click (frmRecentDosingGraph.frm) , 108 cmboDateSelection_Click (frmAIIPatients.frm) , 101

/6Y Function Index cmboDateSelection.Click (frmRecentDosingGraph.frm) 108 cmboGroups_Click (frmFaxSend.frm) , 138 cmdApply_ciick (frmOptions.frm) , 88 cmdCancel_Click (frmFaxStatus.frm) , 133 cmdCancel_Click (frmLogin.fr ) , 86 cmdCancel_Click (frmOptions.frm) , 89 cmdDateOK_Click (frmGetDateTime.frm) , 151 cmdNextTip_Click (frmTip.frm) , 99 cmdOK_Click (fnmAboutfrm) , 92 cmdOK_Click (frmLogin.frm) , 86 cmdOK_Click (frmOptions.frm) , 89 cmdOK_Click (frmTip.frm) , 99 cmdSyslnfo_Click (frmAboutfr ) , 92 Comm_CheckComm (Comm.bas) , 28 Comm_GetDeviceReply (Comm.bas) , 29 Comm_lnitializeCommPort (Comm.bas) , 39 Comm_ReadEntire emoryContents (Comm.bas) , 34 Comm_ReadFirmwareVersion (Comm.bas) , 30 Comm_SendCustomData (Comm.bas) , 35 Comm_SendDataToDevice (Comm.bas) , 45 Comm_SendDosingParams (Comm.bas) , 37 Comm.SendResetClockAndBattery (Comm.bas) , 35 Comm_SendSerialNumber (Comm.bas) , 38 CommTimer_Timer (frmMain.frm) , 76 ComputelniSectionChecksum (General.bas) , 2 ConvertHexStnngToAscii (Comm.bas) , 38 ' CreateCalendarTimeScale (frmDosingCalendar.frm) , 113 CreateChecksum (Comm.bas) , 39 CreateTxtSummaryFile (General.bas) , 6

D

Device-OnComm (Comm.bas) , 40 DisplayCommError (Comm.bas) , 30 DisplayCommOk (Comm.bas) , 31 DisplayCurrentTip (frmTip.frm) , 99

/( ? Function Index

DisplayErrorMessage (Comm.bas) , 31 DoNextTip (frmTip.frm) , 98 DrawAIICompliedDosesTaken (Calendar.bas) , 62 DrawAIIDoseSizeChanges (Caleπdar.bas) , 61 DrawAIIDosesMissed (Caleπdar.bas) , 63 DrawAIINonCompliedDoses Taken (Calendar.bas) , 63 DrawHorizontalLine (Printing, bas) , 47 DrawSingleCompliedDoseTaken (Caleπdar.bas) , 73 DrawSingleDoseMissed (Calendar.bas) , 74 DrawSingleDoseSizeChange (Calendar.bas) , 64 DrawSingleNonCompliedDoseTaken (Calendar.bas) , 65

E

EraseDatalnMemory (General.bas) , 5 EstablishDeviceComm (Comm.bas) , 39 EventDelete (General.bas) , 2 Eventlnsert (General.bas) , 3

F

FaxMan1_ConfigurationDone (frmMain.frm) , 76 FaxMan1_FaxStatus (frmMain.frm) , 76 FileExists (General.bas) , 7 FindClosestDatelnArray (General.bas) , 23 FindFirstMatchingDatelnArray (General.bas) , 23 FindPrescibedDoseSizeForSpecificDay (General.bas) , 3 Form_Activate (frmAIIPatients.frm) , 102 Fσrm_Activate (frmDeviceDiagnostics.frm) , 130 Fσrm_Activate (frmDevicelnitialize.frin) , 148 Form_Activate (frmDosingCalendar.frm) , 113 Form_Activate (frmFaxEditGroups.frm) , 142 Form_Activate (frmFaxEditLocations.frm) , 144 Form_Activate (frmFaxLog.frm) , 141 Form_Activate (frmFaxSend.frm) , 139 Form_A ivate (frmFaxStatus.frm) , 133 Form_Activate (frmGetDateTime.frm) , 151 Form_Activate (frmOptions.frm) , 89

/ ? ό Function Index

Form_Activate (frmPatientDosingRptfrm) , 120 Form_Activate (frmReadDeviceData.frm) , 123 Form_Activate (fπnRecentDosingGraph.frm) , 109 Form_Activate (frmTip.frm) , 99 Formjπitialize (frmDeviceDiagnostics.frm) , 130 Form_Load (frmAbout.frm) , 92 Form_Load (frmAIIPatients.frm) , 103 Form_Load (frmBrowser.frm) , 95 Form_Load (frmDeviceDiagnostics.frm) , 130 Form_Load (frmDevicelnitialize.frm) , 148 Form_Load (frmDosingCalendar.frm) , 113 Form_Load (frmFaxEditGroups.frm) , 142 Form_Load (frmFaxEditLocations.frm) , 144 Form_Load (fmnFaxLog.fπm) , 141 Form_Load (frmFaxSeπd.frm) , 139 Form_Load (frmFaxStatus.fr ) , 133 Form_Load (frmGetDateTϊme.frm) , 151 Foπm_Load (frmLogin.frm) , 86 Form_Load (frmOptions.frm) , 89 Form_Load (frmPatientDosingRptfrm) , 120 Form_Load (frmPrintfrm) , 124 Form_Load (frmReadDeviceData.frm) , 123 Form_Load (frmRecentDosingGraph.frm) , 109 Foπm_Load (frmSplash.frm) , 85 Form_Load (frmTip.frm) , 99

Form_MouseMove (frmDosingCalendar.frm) , 115 Form_QueryUnload (frmDevicelnitialize.frm) , 148 Form_QueryUnload (frmPrintfrm) , 125 Form_Resize (frmAIIPatients.frm) , 103 Form_Resize (frmBrowser.frm) , 96 Form_Resize (frmDosingCalendar.frm) , 115 Form_Resize (frmFaxLog.frm) , 141 Form_Resize (frmPatientDosingRpt.frm) , 120 Form_Resize (frmPrintfrm) , 125 Form_Resize (frmRecentDosingGraph.frm) , 109

'?/ Function Index

Form_Unload (frmDeviceDiagnostics.frm) , 130 Form_Unload (frmDevicelnitialize.frm) , 148 Form_Unioad (frmDosingCalendar.frm) , 116 Form_Unload (frmFaxEditGroups.frm) , 142 Form_Uπload (frmFaxEditLocations.frm) , 144 Form_Uπload (frmFaxSend.frm) , 139 Form_Uπload (frmReadDeviceData.frm) , 123 Form_Unload (frmRecentDosingGraph.frm) , 110 frameView_MouseMove (frmDosingCalendar.frm) , 116

G

GetDrugRefNumber (Comm.bas) , 32 GetFaxLocations (Fax.bas) , 57 GetFileNameFromSpec (General.bas) , 17 GetlndexToFaxGroupName (Fax.bas) , 58 GetindexToFaxLocName (Fax.bas) , 58 GetlNISetting (General.bas) , 7 GetKeyValue (frmAboutfrm) , 93 GetOrganRefNumber (Comm.bas) , 32 GetPatientDataFromDisk (General.bas) , 7 GetProgramPreferences (General.bas) , 9 grid_AfterEdit (frmPatientDosingRptfrm) , 120 grid_Click (frmAIIPatients.frm) , 104 grid_DblClick (frmAIIPatients.frm) , 104 grid_KeyDown (frmPatientDosingRptfrm) , 121 grid_RowColChange (frmPatientDosiπgRptfπri) , 121

H

HScroll1_Change (frmPrintfrm) , 125 HScroll1_Scroll (frmPrintfrm) , 125

I

InitPageMargins (Printing.bas) , 52 InitPageProperties (Printing.bas) , 53 InterpretDosingData (Comm.bas) , 32 InterpretErrorFlags (Comm.bas) , 33

/^ Function Index

IπterpretScoreData (Comm.bas) , 41 IsDoseWithinPrescribedTϊmeRange (Caleπdar.bas) , 66

L lblActivePrinter_Click (frmPrintfrm) , 126 LoadPictureToPnnterControl (Printing.bas) , 52 LoadTips (frmTip.frm) , 98 lstLocations_Click (frmFaxSend.frm) , 140 lstLocations_DblClick (frmFaxSend.frm) , 140 lstLocations_KeyPress (frmFaxEditGroups.frm) , 143

M

Main (General.bas) , 11 MDIForm_Load (frmMain.frm) , 77 MDIForm_Uπload (frmMain.frm) , 77 mnuAccessWebSite_Click (frmMain.frm) , 77 mnuFaxConfigure_Click (frmMain.frm) , 77 mπuFaxSend_Click (frmMain.frm) , 77 mπuFaxViewLogs_Click (frmMain.frm) , 77 mπuFileExit_Click (frmMain.frm) , 84 mπuFileMRU_Click (frmMain.frm) , 84 mnuFileOpen_Click (frmMain.frm) , 83 mnuFilePageSetup_Click (frmMain.frm) , 84 mnuFilePrint_Click (frmMain.frm) , 84 mnuFileProperties_Click (frmMain.frm) , 78 mnuFileSave_Click (frmMain.frm) , 78 mnuFileSaveAs_Click (frmMain.frm) , 83 mnuFileSend_Click (frmMain.frm) , 84 mnuGenE or_Click (frmMain.frm) , 78 mnuHelpAbout_Click (frmMain.frm) , 79 mnuHelpContents_Click (frmMain.frm) , 82 mnuHelpDeviceDiag_Click (frmMain.frm) , 78 mnuHelpSearch_Click (frmMain.frm) , 82 mnuHelpTιρs_Click (frmMain.frm) , 78 mnuReadDeviceData_Click (frmMain.frm) , 79 mnuSendDeviceData_Click (frmMain.frm) , 79

/ Function Index mnuViewAIIPatients_Click (frmMain.frm) , 79 mnuViewCalendar_Click (frmMain.frm) , 79 mnuViewExplorer_Click (frmMain.frm) , 79 mnuViewOptions_Click (frmMain.frm) , 79 mnuViewPatientDosingReport_Click (frmMain.frm) , 80 mnuViewPatieπtSummary_Click (frmMain.frm) , 80 mnuViewStatusBar_Click (frmMain.frm) , 80 mnuViewToolbar_Click (frmMain.frm) , 80 mπuWiπdowArrangelcoπs_Click (frmMain.frm) , 83 mnuWindowCascade_Click (frmMain.frm) , 83 mnuWindowTileHorizontal_Click (frmMain.frm) , 83 mnuWindowTileVertical_Click (frmMain.frm) , 83 MoveFormObjects (Calendar.bas) , 72

O

OpenPatientData (General.bas) , 13 optViewFaxes_Click (fπnFaxLog.frm) , 141 optZoom_Click (frmPrintfrm) , 126

P

ParseDelimString (General.bas) , 18 ParseMemoryContents (Comm.bas) , 41 pnlControls_MouseMove (frmDosingCalendar.frm) , 116 PollDeviceContinually (Comm.bas) , 44 PopulateDeviceCommDialog (General.bas) , 21 PopulateDeviceDiagDialog (General.bas) , 14 PrintAIIPatientsSummary (Printing.bas) , 47 PrintCalendar (Calendar.bas) , 66 PrintDosing Events Header (Printing.bas) , 51 PrintPageDate (Printing.bas) , 53 PrintPageNumber (Printing.bas) , 53 PrintPatientDosingReport (Printing.bas) , 49

R

RefreshAIIOpeπForms (General.bas) , 16 RefreshPreview (Printing.bas) , 54

Figure imgf000176_0001
Function Index

ReloadGroupsList (frmFaxSend.frm) , 134 ReloadLocationsList (frmFaxSend.frm) , 134 RemoveAIIObjects (Calendar.bas) , 75 RemoveCσmpliedDosesTaken (Calendar.bas) , 70 RemoveDoseSizeChanges (Calendar.bas) , 70 RemoveDosesMissed (Calendar.bas) , 70 RemoveGroupFromFaxList (Fax.bas) , 58 RemoveNameFromFaxList (Fax.bas) , 59 RemoveNonCompliedDosesTaken (Calendar.bas) , 70 RescaleGrid (frmPatientDosingRpt.frm) , 117

S

SaveDataToNewFile (General.bas) , 18 SavelNISetting (General.bas) , 24 SavePatientData (General.bas) , 19 SaveProgramPreferences (General.bas) , 22 SetCommTimer (Comm.bas) , 45 SetFaxDeviceLabel (Fax.bas) , 60 SetPreviewSize (Printing.bas) , 55 SetPrinterlcon (General.bas) , 16 Slider1_SlideChange (frmAIIPatients.frm) , 104 SSListBar1_ListltemClick (frmMain.frm) , 80 sstab1_Click (frmOptions.frm) , 91 StartSyslnfo (frmAboutfrm) , 92

T tbToolBar_ButtonClick (frmBrowser.frm) , 96 tbToolBar_ButtonClick (frmMain.frm) , 81 timTϊmer_Timer (frmBrowser.frm) , 96 txtDoseLockoutHours_Change (frmDeviceDiagnostics.frm) , 131 txtDoseLockoutHours_Change (frmDevicelnitialize.frm) , 148 txtDoseSize_Change (frmDeviceDiagnostics.frm) , 131 txtDoseSize_Change (frmDevicelnitialize.frm) , 148 txtDosesPerDay_Change (frmDeviceDiagπostics.fπn) , 131 txtDosesPerDay_Change (frmDevicelnitialize.frm) , 148 txtDoseTime_Chaπge (frmDeviceDiagnostics.frm) , 130

Y7S Function Index txtDrug_Click (frmDeviceDiagnostics.frm) , 131 txtDrug_Click (frmDevicelnitialize.frm) , 149 txtEπdDate_Chaπge (frmRecentDosingGraph.frm) , 110 txtEπdDateJ-lideDropDown (frmAIIPatients.frm) , 105 txtFax_KeyPress (frmFaxEditLocations.frm) , 144 bctFaxNumber_GotFocus (frmOptions.frm) , 91 txtFaxNumber_KeyPress (frmFaxEditLocations.frm) , 145 txtName_Key Press (frmFaxEditGroups.frm) , 143 txtName_KeyPress (frmFaxEditLocations.frm) , 145 txtOrgan_Click (frmDeviceDiagnostics.frm) , 131 txtOrgan_Click (frmDevicelnitialize.frm) , 149 txtPatientFirstName_Change (frmDeviceDiagnostics.frm) , 131 txtPatientFirstName_Change (frmDevicelnitialize.frm) , 149 txtPatientlD_Change (frmDeviceDiagnostics.frm) , 131 txtPatientJD_Change (frmDevicelnitialize.frm) , 149 txtPatientLastName_Change (frmDeviceDiagnostics.frm) , 131 bctPatientLastName_Change (frmDevicelnitialize.frm) , 149 txtRetries_GotFocus (frmOptions.frm) , 91 txtRetrylnterval_GotFocus (frmOptions.frm) , 91 txtSerialNumber_Change (frmDeviceDiagnostics.frm) , 131 txtSerialNumber_Change (frmDevicelnitialize.frm) , 149 txtStartDate_Change (frmRecentDosingGraph.frm) , 110 txtStartDateJ-lideDropDown (frmAIIPatients.frm) , 105 txtTelephone_KeyPress (frmFaxEditLocations.frm) , 145 txtTxCenter_Change (frmDeviceDiagnostics.frm) , 132 b<tTxCenter_Change (frmDevicelnitialize.frm) , 149 txtVoiceNumber_GotFocus (frmOptions.frm) , 91 txtVoiceNumber_KeyPress (frmFaxEditLocations.frm) , 145

U

UpdateCalendar (Calendar.bas) , 74

UpdatefrmPatientDosingReportHeader (frmPatientDosingRptfrm) , 117 UpDatefrmPatientSummaryHeader (frmRecentDosingGraph.frm) , 106 UpDateListBoxSelections (frmFaxSeπd.frm) , 139 UpdatePageButtons (Printing.bas) , 56

/ ^ Function Index

UpdatePatientDosingGraph (frmRecentDosingGraph.frm) , 106 UpdatePatientGndDisplay (frmPatientDosingRptfrm) , 117 UpDateRecentFileMenu (General.bas) , 17 UpdateZoomBox (Calendar.bas) , 71

UpDownDoseTime_DownClick (frmDeviceDiagnostics.frm) , 132 UpDownDoseTime_DownClick (frmDevicelnitialize.frm) , 149 UpDownDoseTimeJJpClick (frmDeviceDiagnostics.frm) , 132 UρDownDoseTime_UpClick (frmDevicelnitialize.frm) , 150

V

ValidateChecksum (Comm.bas) , 33 ValidateDoseNumbers (General.bas) , 24 ValidatePatientOataSaved (General.bas) , 24 vsPrinter1_EndPage (frmPrintfrm) , 126 vsPrinter1_Error (frmPrintfrm) , 126 vsPrinter1_NewPage (frmPrintfrm) , 127

W

Wait (General.bas) , 25

B b LogonToWebSite (GeπeraLbas) , 8046736

F

File Declarations (Calendar.bas) , 61

File Declarations (Comrαbas) , 26

File Declarations (Fax.bas) , 57

File Declarations (frmAboutfrm) , 92

File Declarations (frmAIIPatients.frm) , 100

File Declarations (frmBrowser.frm) , 95

File Declarations (frmDeviceDiagnostics.frm) , 128

File Declarations (frmDevicelnitialize.frm) , 146

File Declarations (frmDosingCalendar.frm) , 111

File Declarations (frmFaxEditGroups.frm) , 142

File Declarations (frmFaxEditLocations.frm) , 144

File Declarations (frmFaxLog.frm) , 141

/11 Function Index

File Declarations (frmFaxSend.frm) , 134

File Declarations (frmFaxStatus.frm) , 133

File Declarations (frmGetDateTime.frm) , 151

File Declarations (frmLogin.frm) , 86

File Declarations (frmMain.frm) , 76

File Declarations (frmOptions.frm) , 88

File Declarations (frmPatientDosingRptfrm) , 117

File Declarations (frmPrintfrm) , 124

File Declarations (frmReadDeviceData.frm) , 122

File Declarations (frmRecentDosingGraph.frm) , 106

File Declarations (frmSplash.frm) , 85

File Declarations (frmTip.frm) , 98

File Declarations- (General.bas) , 1

File Declarations (Printing.bas) , 46

/ 7 $

Claims

What is claimed is:
1. A computer-implemented method for monitoring medication dosing by a patient, comprising: storing patient data, including a medication name and amounts of the medication prescribed for a patient; retrieving patient data, including times and amounts of the medication delivered to the patient; evaluating data by analyzing drug dispensing data and patient data to determine compliance of the delivered medication to the prescribed medication; and displaying the evaluated data.
2. The method of claim 1, wherein storing patient data further comprises storing information from a remote device over a communications line.
3. The method of claim 1, wherein storing patient data further comprises storing data from local memory.
4. The method of claim 1 , wherein storing patient data further comprises storing user input.
5. The method of claim 1 , wherein retrieving patient data further comprises retrieving data from local memory.
6. The method of claim 1 , wherein retrieving patient data further comprises retrieving user input.
7. The method of claim 1 , wherein displaying the evaluated data displays the evaluated data in a patient summary report.
8. The method of claim 1 , further comprising printing the evaluated data.
9. The method of claim 1, wherein dosages of multiple patients are monitored, the method comprising: storing patient data for a plurality of patients, including the medication name and amounts of the medication prescribed for the plurality of patients; retrieving patient data for the plurality of patients, including times and amounts of medication delivered to the plurality of patients; evaluating data by analyzing the stored patient data for the plurality of patients to determine overall compliance of the delivered medication to the prescribed medication; and displaying the evaluated data.
10. The method of Claim 1 , wherein: storing patient data includes storing amounts of an immunosuppressive medication prescribed for a patient; and retrieving patient data includes retrieving times and amounts of the immunosuppressive medication delivered to the patient.
11. The method of Claim 1 , wherein: storing patient data includes storing amounts of an analgesic drug prescribed for a patient; and retrieving patient data includes retrieving times and amounts of the analgesic drug delivered to the patient.
12. The method of Claim 1 , wherein: storing patient data includes storing amounts of an opiate agonist prescribed for a patient; and retrieving patient data includes retrieving times and amounts of the opiate agonist delivered to the patient.
13. The method of Claim 1 , wherein: storing patient data includes storing amounts of an opiate antagonist prescribed for a patient; and retrieving patient data includes retrieving times and amounts of the opiate antagonist delivered to the patient.
14. The method of Claim 1 , wherein: storing patient data includes storing amounts of a liquid drug prescribed for a patient; and retrieving patient data includes retrieving times and amounts of the liquid drug delivered to the patient.
15. The method of Claim 1 , wherein the step of retrieving patient data includes retrieving data transmitted via a carrier wave.
16. A computer-implemented method for monitoring patient dosages, comprising: retrieving dosing data, including times and amounts of medication prescribed for a patient; retrieving patient data, including times and amounts of medication delivered to the patient; determining evaluation data by analyzing the retrieved dosing and patient data to determine compliance of the delivered medication to the prescribed medication; and displaying the evaluation data.
17. A memory device storing computer readable instructions for aiding a computer to monitor patient dosages of a medicine, comprising: instructions for storing patient data, including the medication name and amounts of the medication prescribed for a patient; instructions for retrieving patient data, including times and amounts of the medication delivered to the patient; instructions for evaluating data by analyzing drug dispensing data and the patient data to determine compliance of the delivered medication to the prescribed medication; and instructions for displaying the evaluated data.
18. A computer system for monitoring patient dosages, comprising: a processor for storing patient data, including a name of a medication and amounts of the medication prescribed for a patient and for retrieving patient data, including times and amounts of the medication delivered to the patient, and evaluating data by analyzing drug dispensing data and the patient data to determine compliance of the delivered medication to the prescribed medication; and a monitor for displaying the evaluated data.
19. The computer system of claim 18, further comprising a communications link linking the processor to a remote device, wherein the retrieved patient data may be received from the remote device over the communications link.
20. The computer system of claim 19, wherein the retrieved patient data is received from the remote device over the communications link via a carrier wave.
21. The computer system of claim 20, further comprising an input device coupled to the processor, wherein the retrieved patient data may be received through the input device.
22. A method of graphically displaying drug compliance information, the method comprising the computer-implemented steps of: receiving dosage data representing one or more quantities and one or more administration times for delivering a drug; receiving administration data representing one or more times when each of a plurality of doses of the drug was delivered; generating a graphical display of the drug compliance information on a display device, wherein the graphical display comprises one or more elements that each correspond to a time period; displaying, within a first element among the elements, one or more icons that represent each dose due within said first period; and rendering each of the icons in one of a plurality of formats based on said dosage data and said administration data.
23. The method of Claim 22, wherein the step of rendering includes the steps of: determining whether a particular dose due within the first period was correctly delivered based on said scheduling data and said administration data; rendering a particular icon in a first format when the particular dose was incorrectly delivered; and rendering the particular icon in a second format when the particular dose was correctly delivered.
24. The method of Claim 22, wherein the step of receiving administration data includes the step of receiving data indicating an administration time for said particular dose, and wherein the method further includes the steps of: receiving data indicating a time period in which said drug should be delivered; determining whether the particular dose was delivered within the time period; and rendering the icon in a third format when the particular dose was delivered within the time period.
5. The method of Claim 22, wherein the step of receiving administration data includes receiving data indicating an administration time for said particular dose, and wherein the method further includes the steps of: receiving data indicating a time period within the administration time in which said drug should be delivered; determining whether the particular dose was delivered within the time period; and rendering the icon as a particular format when the particular dose was delivered within the time period.
26. The method of Claim 22, further including the steps of: displaying a graphical object; displaying a second set of icons along an axis of the graphical object, in which the second set includes an icon for each dose of the drug delivered within a first period, and the position of each of the second set along the axis identifies when the respective dose was delivered.
27. The method of Claim 26, further including the step of said user selecting said first grid element associated with said first period.
28. The method of Claim 27, further including the steps of: selecting a first icon of the second set of icons, wherein the first icon is associated with a first dose, wherein the first dose is associated with a first administration time; and displaying additional information about the first dose, including the administration time.
29. The method of Claim 22, wherein the step of receiving dosage data includes the step of receiving dosage data from a dosage dispensing device.
30. The method of Claim 29, wherein the step of receiving dosage data from a dosage dispensing device includes the step of receiving dosage data from a portable medication administration device.
31. The method of Claim 22, wherein the step of receiving administration data includes the step of receiving administration data from a portable medication administration device.
32. A method of generating data representing patient medication administration compliance, the method including the steps of: receiving dosage data indicating parameter values for delivering a drug to a patient, wherein the parameter values specify one or more quantities and one or more administration times for delivering doses of the drug to the patient; receiving administration data that indicates when each of a plurality of doses of the drug was administrated to the patient; and generating data indicating a portion of the plurality of doses that was delivered according to the parameter values.
33. The method of Claim 32, wherein the step of generating data includes the steps of generating one or more values specifying a portion of said plurality of doses that was delivered within a specified time period of said administration times.
34. The method of Claim 32, further including the step of receiving data specifying a time period for which to generate said compliance data, the time period containing a plurality of days; and wherein the step of generating data includes the steps of generating, for each day within a period, one or more values specifying a portion of the plurality of doses scheduled for the day that were delivered.
35. A method of managing the administration of drugs to a patient, the method comprising the steps of: receiving dosage data that represents one or more administration quantities and one or more administration times for delivering doses of a drug to a patient; transmitting, to a dosage dispensing device, data that specifies said one or more administration quantities and one or more administration times; receiving administration data that indicates how each of a plurality of doses of the drug was administrated to the patient; and storing the administration data in a memory device.
36. The method of Claim 35, further including the steps of: receiving data specifying a lockout period that must elapse after delivering a dose before another dose is delivered to the patient; and transmitting, to the dosage dispensing device, data that specifies the lockout period.
37. The method of Claim 36, wherein: the step of receiving dosage data includes the steps of receiving data indicating a volume to deliver; and the step of transmitting includes the steps of transmitting, to a dosage dispensing device, data that specifies said volume.
38. The method of Claim 35 , wherein: the step of receiving dosage data includes the steps of receiving data specifying a dose of a liquid drag; and the step of transmitting includes the steps of transmitting, to a dosage dispensing device, data that specifies a dose of said liquid drug.
39. The method of Claim 38, further including the steps of: receiving data indicating that a drug container has been removed from the dosage dispensing device; storing the data indicating that said drag container has been removed; and reporting the data in a report of medication events.
40. The method of Claim 38, further including the steps of: receiving data indicating that a drug container has been inserted into the dosage dispensing device; storing the data indicating that said drug container has been inserted; and reporting the data in a report of medication events.
41. A method of managing administration of drugs to a patient, the method comprising the steps of: receiving data indicating administration times for a drag to be delivered to a patient and a lockout period that must elapse after delivering a dose before another dose is delivered to said patient; and transmitting, to a dosage dispensing device, data that specifies the lockout period.
42. The method of Claim 41 , wherein the step of transmitting includes the steps of transmitting to a dosage dispensing device that dispenses a liquid.
PCT/US1998/022830 1998-01-12 1998-10-29 System and method for managing administration of medicine WO1999035588A1 (en)

Priority Applications (4)

Application Number Priority Date Filing Date Title
US7110798P true 1998-01-12 1998-01-12
US60/071,107 1998-01-12
US14348398A true 1998-08-28 1998-08-28
US09/143,483 1998-08-28

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
AU11247/99A AU1124799A (en) 1998-01-12 1998-10-29 System and method for managing administration of medicine

Publications (2)

Publication Number Publication Date
WO1999035588A1 true WO1999035588A1 (en) 1999-07-15
WO1999035588A9 WO1999035588A9 (en) 1999-10-07

Family

ID=26751842

Family Applications (1)

Application Number Title Priority Date Filing Date
PCT/US1998/022830 WO1999035588A1 (en) 1998-01-12 1998-10-29 System and method for managing administration of medicine

Country Status (2)

Country Link
AU (1) AU1124799A (en)
WO (1) WO1999035588A1 (en)

Cited By (18)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6202642B1 (en) 1999-04-23 2001-03-20 Medtrac Technologies, Inc. Electronic monitoring medication apparatus and method
EP1223532A2 (en) * 2001-01-15 2002-07-17 Siemens Aktiengesellschaft Method and medical system for providing a medicament to a patient
WO2002078594A3 (en) * 2001-04-02 2003-09-25 Glaxo Group Ltd Medicament dispenser
WO2004066182A1 (en) 2003-01-23 2004-08-05 David Wald Identification of risk of myocardial infarction
WO2004077363A1 (en) * 2003-02-25 2004-09-10 Rosti A/S Method and apparatus for controlling a dispensing apparatus for dispensing medication
US7072738B2 (en) 2001-04-02 2006-07-04 Glaxo Group Limited Medicament dispenser
EP1223855B1 (en) * 1999-10-01 2006-08-30 Glaxo Group Limited Medicament delivery system
WO2013156510A1 (en) * 2012-04-17 2013-10-24 Novo Nordisk A/S Medical delivery device with regimen identification feature
WO2014210465A1 (en) * 2013-06-27 2014-12-31 Smiths Medical Asd, Inc. Infusion planning system
US9069887B2 (en) 2000-05-18 2015-06-30 Carefusion 303, Inc. Patient-specific medication management system
US9307907B2 (en) 2004-08-25 2016-04-12 CareFusion 303,Inc. System and method for dynamically adjusting patient therapy
US9526920B2 (en) 2010-10-12 2016-12-27 Smith & Nephew, Inc. Medical device
US9741001B2 (en) 2000-05-18 2017-08-22 Carefusion 303, Inc. Predictive medication safety
US9981085B2 (en) 2005-02-11 2018-05-29 Carefusion, 303, Inc. Management of pending medication orders
US10029047B2 (en) 2013-03-13 2018-07-24 Carefusion 303, Inc. Patient-specific medication management system
US10062457B2 (en) 2012-07-26 2018-08-28 Carefusion 303, Inc. Predictive notifications for adverse patient events
WO2018181637A1 (en) * 2017-03-31 2018-10-04 大日本印刷株式会社 Display device, display system, computer program, recording medium and display method
US10275571B2 (en) 2011-07-18 2019-04-30 Carefusion 303, Inc. Distributed remote asset and medication management drug delivery system

Families Citing this family (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
AU6172301A (en) 2000-05-18 2001-11-26 Alaris Meidical Systems Inc Distributed remote asset and medication management drug delivery system

Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US4839806A (en) * 1986-09-30 1989-06-13 Goldfischer Jerome D Computerized dispensing of medication
US5016172A (en) * 1989-06-14 1991-05-14 Ramp Comsystems, Inc. Patient compliance and status monitoring system
US5347453A (en) * 1992-03-30 1994-09-13 Maestre Federico A Portable programmable medication alarm device and method and apparatus for programming and using the same

Patent Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US4839806A (en) * 1986-09-30 1989-06-13 Goldfischer Jerome D Computerized dispensing of medication
US5016172A (en) * 1989-06-14 1991-05-14 Ramp Comsystems, Inc. Patient compliance and status monitoring system
US5347453A (en) * 1992-03-30 1994-09-13 Maestre Federico A Portable programmable medication alarm device and method and apparatus for programming and using the same

Cited By (25)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6202642B1 (en) 1999-04-23 2001-03-20 Medtrac Technologies, Inc. Electronic monitoring medication apparatus and method
EP1223855B1 (en) * 1999-10-01 2006-08-30 Glaxo Group Limited Medicament delivery system
US9741001B2 (en) 2000-05-18 2017-08-22 Carefusion 303, Inc. Predictive medication safety
US9069887B2 (en) 2000-05-18 2015-06-30 Carefusion 303, Inc. Patient-specific medication management system
EP1223532A3 (en) * 2001-01-15 2002-10-16 Siemens Aktiengesellschaft Method and medical system for providing a medicament to a patient
EP1223532A2 (en) * 2001-01-15 2002-07-17 Siemens Aktiengesellschaft Method and medical system for providing a medicament to a patient
WO2002078594A3 (en) * 2001-04-02 2003-09-25 Glaxo Group Ltd Medicament dispenser
US7072738B2 (en) 2001-04-02 2006-07-04 Glaxo Group Limited Medicament dispenser
US7454267B2 (en) 2001-04-02 2008-11-18 Glaxo Group Limited Medicament dispenser
WO2004066182A1 (en) 2003-01-23 2004-08-05 David Wald Identification of risk of myocardial infarction
WO2004077363A1 (en) * 2003-02-25 2004-09-10 Rosti A/S Method and apparatus for controlling a dispensing apparatus for dispensing medication
US10064579B2 (en) 2004-08-25 2018-09-04 Carefusion 303, Inc. System and method for dynamically adjusting patient therapy
US9307907B2 (en) 2004-08-25 2016-04-12 CareFusion 303,Inc. System and method for dynamically adjusting patient therapy
US9981085B2 (en) 2005-02-11 2018-05-29 Carefusion, 303, Inc. Management of pending medication orders
US10086216B2 (en) 2010-10-12 2018-10-02 Smith & Nephew, Inc. Medical device
US9526920B2 (en) 2010-10-12 2016-12-27 Smith & Nephew, Inc. Medical device
US10275571B2 (en) 2011-07-18 2019-04-30 Carefusion 303, Inc. Distributed remote asset and medication management drug delivery system
US9734302B2 (en) 2012-04-17 2017-08-15 Novo Nordisk A/S Medical delivery device with regimen identification feature
JP2015514483A (en) * 2012-04-17 2015-05-21 ノボ・ノルデイスク・エー/エス Medical delivery device with a regimen specific features
CN104246782A (en) * 2012-04-17 2014-12-24 诺和诺德A/S Medical delivery device with regimen identification feature
WO2013156510A1 (en) * 2012-04-17 2013-10-24 Novo Nordisk A/S Medical delivery device with regimen identification feature
US10062457B2 (en) 2012-07-26 2018-08-28 Carefusion 303, Inc. Predictive notifications for adverse patient events
US10029047B2 (en) 2013-03-13 2018-07-24 Carefusion 303, Inc. Patient-specific medication management system
WO2014210465A1 (en) * 2013-06-27 2014-12-31 Smiths Medical Asd, Inc. Infusion planning system
WO2018181637A1 (en) * 2017-03-31 2018-10-04 大日本印刷株式会社 Display device, display system, computer program, recording medium and display method

Also Published As

Publication number Publication date
AU1124799A (en) 1999-07-26
WO1999035588A9 (en) 1999-10-07

Similar Documents

Publication Publication Date Title
Bell et al. A conceptual framework for evaluating outpatient electronic prescribing systems based on their functional capabilities
US7860724B2 (en) System and method for management of pharmacy workflow
CA2343796C (en) Communication station and software for interfacing with an infusion pump, analyte monitor, analyte meter, or the like
US5666492A (en) Flexible computer based pharmaceutical care cognitive services management system and method
US7630908B1 (en) Wireless electronic prescription scanning and management system
JP5725710B2 (en) Systems and methods for collecting patient information may determine the diabetes therapy
US9501272B2 (en) Systems and methods for updating a medical device
US8707392B2 (en) Systems and methods for disease management
US9740829B2 (en) Interface for medical infusion pump
US7072725B2 (en) Implantable therapeutic substance infusion device configuration system
JP4382488B2 (en) Clinical testing method and apparatus
US6047259A (en) Interactive method and system for managing physical exams, diagnosis and treatment protocols in a health care practice
CN104969228B (en) The computer-implemented method of electronic patient care systems and devices
US20130012880A1 (en) Interface for medical infusion pump
US7324949B2 (en) Implantable medical device management system
CA2307033C (en) Multiple patient monitoring system for proactive health management
US8965707B2 (en) Interface for medical infusion pump
JP5694948B2 (en) Structured inspection method and apparatus for the chronically ill diagnostic support or therapy support
US20130080186A1 (en) Method, System, And Apparatus For Clinical Trial Management Over A Communications Network
US7647237B2 (en) Communication station and software for interfacing with an infusion pump, analyte monitor, analyte meter, or the like
US20080071580A1 (en) System and method for medical evaluation and monitoring
US20070033074A1 (en) Therapy management system
AU2004209134B2 (en) Method and system for medical device connectivity
EP1197907A2 (en) Apparatus for monitoring, diagnosing and treating medical conditions of remotely located patients
US20020029223A1 (en) Prescription network supporting doctors, care givers and online drug store interaction

Legal Events

Date Code Title Description
AL Designated countries for regional patents

Kind code of ref document: A1

Designated state(s): GH GM KE LS MW SD SZ UG ZW AM AZ BY KG KZ MD RU TJ TM AT BE CH CY DE DK ES FI FR GB GR IE IT LU MC NL PT SE BF BJ CF CG CI CM GA GN GW ML MR NE SN TD TG

AK Designated states

Kind code of ref document: A1

Designated state(s): AL AM AT AU AZ BA BB BG BR BY CA CH CN CZ DE DK EE ES FI GB GD GE GH GM HR HU ID IL IS JP KE KG KR KZ LC LK LR LS LT LU LV MD MG MK MN MW MX NO NZ PL PT RO RU SD SE SG SI SK SL TJ TM TR TT UA UG US UZ VN YU ZW

121 Ep: the epo has been informed by wipo that ep was designated in this application
COP Corrected version of pamphlet

Free format text: PAGES 1-178, DESCRIPTION, REPLACED BY NEW PAGES 1-182; PAGES 179-185, CLAIMS, REPLACED BY NEW PAGES183-191; PAGES 1/8-8/8, DRAWINGS, REPLACED BY NEW PAGES 1/8-8/8; DUE TO LATE TRANSMITTAL BY THE RECEIVING OFFICE

AK Designated states

Kind code of ref document: C2

Designated state(s): AL AM AT AU AZ BA BB BG BR BY CA CH CN CZ DE DK EE ES FI GB GD GE GH GM HR HU ID IL IS JP KE KG KR KZ LC LK LR LS LT LU LV MD MG MK MN MW MX NO NZ PL PT RO RU SD SE SG SI SK SL TJ TM TR TT UA UG US UZ VN YU ZW

AL Designated countries for regional patents

Kind code of ref document: C2

Designated state(s): GH GM KE LS MW SD SZ UG ZW AM AZ BY KG KZ MD RU TJ TM AT BE CH CY DE DK ES FI FR GB GR IE IT LU MC NL PT SE BF BJ CF CG CI CM GA GN GW 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)
NENP Non-entry into the national phase in:

Ref country code: KR

REG Reference to national code

Ref country code: DE

Ref legal event code: 8642

NENP Non-entry into the national phase in:

Ref country code: CA

122 Ep: pct application non-entry in european phase