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
    Monitoπng 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 ajar 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-dispensmg 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 appropπate 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 Seπal No 08/ 867,010 entitled Liquid Medication Dispenser Apparatus, filed on June 2, 1997 and naming as inventors Debra L McEnroe, Robert A Bπtts, Philhppe 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 azathioprme, Tacrolimus, Sirohmus, 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 retπeves 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 1 10 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 descπbed m the above- referenced U S Patent Application Serial No 867,010, filed June 2, 1997 and entitled Liquid Medication Dispenser Apparatus, previously incoφorated 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 peπod 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 pπnter 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 retπeved 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
    RETREΓVΓNG PATIENT DATA - INCLUDING DOSES AND TIME DELIVERED
    FIG 3 illustrates an embodiment of a method of retrieving data FIG 3 llllustrates 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 retπeval operation If patient data for the requested patient already exists m memory and has not been saved duπng a prior retπeval, then m 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 pπor data before continuing with the process of retrieving current patient data from the dosage-dispensmg 
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 incoφorated 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 monitoπng 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 5 A 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 pπnter Calendar 500 of FIG 5A comprises a grid 502, which includes one or more gπd elements 520 Each gπd 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 descπptive 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 1 10. 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 ... Pπnt Setup ...
    Print Preview .. Pπnt ... 
 
    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 vaπous functions, such as dosing, as they are performed and where appropriate.
    In the foregoing specification, the invention has been descπbed with reference to specific embodiments thereof. It will, however, be evident that vaπous 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
    Caiendar.bas 61 frmMain.frm ' 76 frmSpiash.frm 85 frmLogin.frm 86 frmOptions.frm 88 frmAbou frm 92 frmBrowser.frm 95 frmTip.frm 98 frmAIIPatients.frm 100 frmRecentDosingGraph.frm 106 frmDosingCalendar.frm 111 frmPatientDosingRptfrm 117 frmReadDeviceData.frm 122 frmPrintfrm 124 frmDeviceDiagnost.ics.frm 128 frmFaxStatus.frm ~ 133 frmFaxSend.frm ; 134 frmFaxLog.frm 141 frmFaxEditGroups.frm 142 frmFaxEditLocations.frm 144 frmDevicelnitialize.frm 146 frmGetDateTime.frm • 151 
 General bas - File Declarations
    Attribute VB_Name = "modGeneral" Option Explicit
    'Declare DLL calls
    Declare Function OSWinHelp% Ub "user32" Alias "WiπHelpA" (ByVal hWhd&, ByVal HelpFileS, ByVal wCommand%, dwOata As Any) Declare Function GetPnvateProfilelnt Lib "kemel32*Αlιas "GetPπvateProfilelntA- fByVaf IpApplicationName As Stnng, ByVal IpKeyName As Stnng. ByVal nDefault As Long, ByVal IpFileName As Stnng) As Long
    Declare Function GetPπvateProfileStπng Lib " emeJ32" Alias "GerPπvateProfileStπngA" (ByVal IpApplicationName As Stnng, ByVal IpKeyName As Any, ByVal IpOefault As Stnng, ByVal IpRetumedStπng As Stnng, ByVal nSize As Long, ByVal IpFileName As Stnng) As
    V Long
    Declare Function WπtePπvateProfileStπng Lib Tcemel32" Alias "WπtePπvateProfileStπngA" (ByVal IpApplicationName As Stnng, ByVal IpKeyName As Any, ByVal Ip≤tπng As Any, ByVal IpFileName As Stnng) As Long
    'Set up some temporary buffers forgetting str.πgs from D . calls
    Public Const gιBufSize1024 = 1024 se' size of input buffer *or stores
    Public gsTempBuf As Stnng Input ourfer for strr.gs (ce^ned ar program stat*)
    Public giLatestOptionsTabSeiected As Integer keep rrgcx of the tab that was las: selected oy uset (goes bacπ to ic next tme it is ooeπed) Public gs a stStartDate Chosen As Stnng 3 starting plot date fast selected by user Public gsLastEndDateChσseπ As Stnng an enαng clot date last selected bv υser Public gsLastDateSet As Stnng a 'amp stnng used to pass dates back and torthe to the calendar Public gsDateOisplayFormat As Stnng 'noids the user's cacice for the displayed dare format for άaiogs ana reports Public gsTimeDisplayFormat As Stnng holds the user's cnoice for the displayed time format for dialogs and repots Public gsCustomLblPatientLastName As Stnng reolacerrent laoels far the dialogs if exist in config file Public gsCustomLblPatientFirstName As Stnng 'replacement labats for the άalogs if exist in config file Public gsCustomLbl atientlD As Stnng Public gsCustomLblTxC enter As Stnng Public gsCustomLblDrug As Stnng Public gsCustomLblOrgan As Stnng Public gsLabelGπdColumnCustoml As Stnng Public gsLabelGπdColumnCustαm2 As Stnng Public gsLabelGπdColumnCustom3 As Stnng
    'This value is stored in cevice & indicates the version of data structure within the device 'This does not relate dtrectfy to the version of the host software because the host software version can change wth 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 devict 'such as changing the length ofstπngs to accommodate new features The purpose of this value 'is to tet us read it back from a device and determine if newer host software :s being used on a device programmed with another version
    Public Const gsREV_DATA_STRUCTURE = "01"
    'There are 4 fields 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 giLEN REV DATA STRUCTURE = 2
    Public Const gιLEN~PATl*ENT NAME = 26
    Public Const gιLEN~ID = 11
    Public Const gιLEN~DRUG = 2
    Public Const gιLEN~TX_C ENTER = 13
    Public Const gιLEN~ORGAN = 2
    Public Const giMaxDoseTϊmes = 4 'the mar nur-cer of pres nbeϋ dcsir.g time (entry ooxes) Public Const giOosesPerOayDefauft = 2 Public gbPatientDataNotSaved As Boolean true once the data ir rremory has been saved (from device)
    Public gdTempDateTϊme As Double rgt: put this vann the rcrm that uses it can also oe cone Public gϊTempCya As Integer Public gfTempCreatinine As Single Public gsTempCustomlnfo As Stnng
    Public gsActtve Form Name As Stnng 
 Geπeral.bas - File Declarations ■ . F=q
    Public giCurrentTip As Integer most recent up number that was shown
    Public gsWebSlartiπgAddress As Stnng rl address and any associated passwoixt for weO site
    Public Function ComputeiniSectionChecksum(ByVal sFileSpec As String, ByVai sSection As String)
    'Read each line tn the section name of an IN! file that was passed here 'Compute a unique value and pass back to caller On Error Go To 0 'rgn tem
    Dim ICheckSumTally As Long, r As Integer, I As Long, i As Integer, (Key As Integer Dim sLine As Stnng
    'Get (he names of all of the keys in this section
    'A null Key field in above nr.e loses ail keys in that section
    Dim iStrSize As Integer, sTempBu As Stnng, iBufSize As Integer
    Dim sKeyLιst(2000) As Stnng 'maι<e room ' r- this many key names :n this secαon
    m a list
    
    CαmputelniSectlonChecksum = ICheckSumTally 'pass result back to caller
    End Function
    Public Sub EventDelete(DataStruct As DeviceDataStruct, ByVai 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.ιEventData(O) Then Exit Sub all events up one + 1) 
 
    DataStruct.ιEventOata(O) = Data Struct.! Event Data(O) - 1 'decrement event count gbPatientDataNotSaved - True 'sef flag to indicate thai the file has changed but not yet been saved
    End Sub 
    
    Public Sub Eventlnsert(DataStruct As DeviceDataStruct, ByVal ilndex As Integer, ByVal dDate As Double)
    'Insert a new eveπr into the data structure at the index location passed here It the index =0 'then it probably indicates that a previous function could not find where to insert the date in the structure In this case the event must be inserted at the beginning or the end of the 'structure depending on the date
    Dim i As Integer
    If ilndex = 0 Then 'cats was not found _ If dDate <= DataStruct dEveπtDate(1 ) Then ilndex = 1 _ Else ilndex = DataStruct lEveπtOata(O) insert at last ρoι~. - End If End If down tc maKs room for new ore
    
    'Now insert the new event
    DataStruct.iEventData(0) = DataStrud.ιEventData(O) ♦ 1 'increment event count
    DataStruct.byte£ventType(ilndex) = gιEVENT_USER_DEFINED
    OataStruct.dEventOate(ilndex) = dDate
    DataStructsUserOatal (Ilndex) = gfTempCya 'put change In structure
    DataStruct.sUserData2(llndex) = gfTempCreatlnine 'put change in structure
    DataStruct.sUserData3(ilndex) = gsTempCustomlnfo 'put change in structure previous events until this one 0 DataStruct.ιEveπtData(ιlndex - 1) 
 'sef Hag to indicate that the tile has changed out not yet been saved
 
    Public Function FindPrescibedDoseSizeForSpecificDay(DataStruct As DeviceDataStruct, ByVal IDate As Long
    'rind the prescnbed dose for 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
    Dim i As Integer, ilndex As Integer ilndex = FιndClosestOatelnArray(DataStruct, IDate)
    — If ilndex = 0 Then 'all events are occumng after the date requested
    — For i = 1 To DataStπjct.ιEventData(O) look throuςn wnole array if necessary If DataStruct.byteEventType(ι) = gιEVENT_DOSE_CHANGED Then
    FiπdPrescibedOoseSizeForSpecificDay = i 'DataStruct.ιΞvenlOatatl) 
    Else an event date was found - For i = ilndex To 1 Step -1
    It DataStruct byteEventType(ι) = gιEVENT_DOSE_CHANGED Then 
 
    End Function
    Public Function CalcDayDoseScore_OπTime(DataStruct As DeviceDataStruct, ByVal IStartingDate As onq) Computer the dcstng score for the day passed rare '
    This score tests to see if the tfosen taken was within the crescπoed fιrre rar.ge Pass (he score back to tlie caller as nearest wrote percent ttndex is the mde < tn the a ay v/rere ccmcutatiαn is to stat It snould already be sef to the first event that occurred on that day
    Dim I As Long, i As Integer, tTotalDoses As Integer Dim ilndex As Integer, r As Integer
    
    End Function
    Public Function CalcDayDoseScore_AIIDoses(DataStruct As DeviceDataStruct, ByVal IStartingDate As Long} '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 wnole percent 'ilndex ts 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
     
 General bas - CalcDayDosebcore_AIIL_.es
 
    End Function
    Public Function CalcDosesSumTakeπOnSpecificDay(DataStruct As DeviceDataStruct, ByVal IStartingDate As
    Computer the dosing total number of doses taken on a scecthc date Ncte this calculation does not laκe into consideration whether or not the dose 'was taι<en within the prescnbed sme This i all doses for a particular dav P3ss the count back tc the caller
    Dim iTodayDoseCount As Integer, ilndex As Integer
    1
    
    End Function
    Public Sub EraseDataInMemory(DataStruct As DeviceDataStruct)
    Dim i As Integer
    'clear out any data that may be in memory and initialize the arrays
    DataStruct.sPatientLastName = ~
    DataStruct.sPatieπtFirstName = ~
    DataStruct.sPatientlD = ~
    DataStruct.sOrug = "
    DataStrυct.sOrgan - "
    DataStruct.sTxCenter = ""
    DataStruct.sSenalNumber = ~
    DataStruct.sFirm areVer = ~
    DataStruct. sDoseSize = ~
    DataStn ct.sPatιentDataFileName =* "* 
    For i = 0 To giMaxDoseTimes
    DataStruct dPrescnbedDoseTime(i) = -1 Next i
    OataStπjct IDosesPerOay = 0 DataStruct.sDoseResolution = " DataStruct.sMedRemaiπing = "
    Erase DataStruct sScoreData Erase DataStruct lEveπtData Erase DataStruct.dEventDate Erase DataStruct.byteEventType 'erases all elements of a fixed array
    Erase DataStruct sUserOatal Erase DataStruct sUser0ata2 
 general bas - EraseDatainMemor>
    Erase DataStruct.sUserOata3
    Data Struct.l Device! nitDate = 0 ~ DataStruct.sBatteryChangeTimer = *" OataStruct-sDoseLαckoutHours = "* 
    DataStruct.bEiTorFatal = False OataStruct.bErrorNonFataf = False DataStruct.bErrorDoseSize - False DataStruct bErrorMedRemaintng = False DataStruct.bError emoryFull - False DataStruct.bEnOrsExist = False DataStπjct.bErrorBrownOut = False DataStruct.dLastDownfoadDate = 0 gbPatientDataNotSaved = False
    End Sub
    Public Sub CreateTxtSummaryFileO
    'This roucne creates a temp text tile in the "fax" subdirectory 'This will allow the information to be faxed as a text document
    Dim i As Integer, r As Integer, sFileSpec As Stnng, lErrorCode As Long
    Dim sLblName As Stnng, sLbllD As Stnng, sLblTxCenter As Stnng, sLblDrug As Stnng, slblOrgaπ As Stnng
    'Get πd of the previous temporary file 'sFileSpec = App.Path * axes emp txf sFPeSpec = App.Path + "\faxes\" ♦ PAT DATA.sPatientLastNa e + ", " ♦ PAT_DATA sPatientFirstName + " " ♦ PAT DATA sPatleπtID ^ * txt- r = FileExιsts(sFileSpec, lErrorCode) If r Then Kill sFϋeSpec sLblName = gsCustomLblPatlentLastName sLbllD = gsCustomLblPatientlD sLblTxCenter = gsCustomLbtTxCenter sLblDrug = gsCustomLblDrug sLblOrgan ~ gsCusto LblOrgan
    Open sFileSpec For Output Shared As #1
    Pππt #1 , sLblName + ". " + PAT DATA.sPatιentLastName * " " ♦ PAT DATA.sPatientFirstName
    Pπnt #1 , sLbllD + ": " + PAT.DATA sPatientlD
    Pnnt #1 , sLblTxCenter + ": " + PAT_DATA.sTxCenter
    Pnnt #1 , sLblDrug + "• " + PAT_OATA.sDrug
    Pπnt #1 , sLblOrgan + ": " * P AT DATA.sOrgan
    Pπnt#1,
    Pπnt #1 , "Device Senal Number " + PAT_DATA.sSenalNumber
    Pπnt #1 , "Firmware Version: " * PAT_OATA.sFιrm areVer
    Pnnt #1 , "Last Download Date. " + Format$(PAT_DATA.dLastDownloadDate, gsDateOispiayFormat)
    Close #1
    'rgh ensure that the complete file is pnπted
    End Sub 
    General bas - FileExists
    Function FileExιsts(ByVal sPath As Stnng, lErrorCode As Long) As Integer
    ChecK for existence of a file by artempnng an OPE.V Fetum true t-1) if exists else return False ιOI or eror condition Note that since this tunc'ion tnes to open a Hie an error could 'etu to caller it file is there but in use by ancihe' apolication
    Dim X As Integer
    X = FreeFile
    On Error Resume Next
    Open sPath For Input As X
    Close X dear error coce set flag for error pass error back to ca er 
 
    End Function
    Public Function GetlNISettιng(sFileSρec As String, sSection As Stnng, sKeyField As String, sDefault As Stπr Dim iStrSize As Integer, sTempBuf As Stnng, iBufSize As Integer sTempBuf = SpaceS(1024) IBufSize = 1024
    IStrSize = GetPπvateProfiieStnng(sSectιon, sKeyField, sDefault, sTempBuf, IBufSize, sFileSpec) Buf, IStrSize)) 
 
    End Function
    Public Function GetPatientDataFromDisk(ByVal sFileSpec As String, DataStruct As DeviceDataStruct, lErrorF
    Get all of the patient data from the Hie on disk and place into memory 'The filename that is passed here must be a valid patient tile and veπtled by the catting procedure
    Dim sSection As Stnng, I As Integer, sTemp As Stnng, r As Integer Dim IFiieChecksum As Long, ICheckSumTally As Long
    On Error Go To GetPaύentDataFromOisk Error
    Read the file and ca.culate the checksum
    IFiieChecksum - ComputelπlSecαonChecksumfsFileSpec, "Device Data") ICheckSumTally = GetlNISettingfsFileSpec, "General", "Device Data Validation", 0) If IFiieChecksum <> ICheckSumTally Then lErrorRetum = ERR_DATA_CHECKSUM
    Exit Function End If
    IFiieChecksum = ComputelnlSectlonChecksum(sFιleSpec "Event Data") ICheckSumTally = GetlNISettingfsFileSpec, "General", "Event Data Validation", 0) If IFiieChecksum <> ICheckSumTally Then lErrorRetum = ERR_DATA_CHECKSUM
    Exit Function End If
    3M9/98 
 General bas - GetPatιenlDatat-romU„.v
    IFiieChecksum = ComputelniSectionChecksumfsFileSpec, "Device Error Flags") ICheckSumTally = GetlNISettingfsFileSpec, "General" "Device Error Flags Validation", 0) If IFiieChecksum <> ICheckSumTally Then lErrorRetum = ERR_DATA_CHECKSUM
    Exit Function End If sSection = "Device Error Flags"
    DataStruct bErrorFatal = CBoolfGetlNISettingfsFileSpec sSection, "Fatal", False))
    DataStruct bErrorNoπFatal = CBool(GetlNISettιπg(sFιleSpec, sSection "Noπ Fatal", False))
    DataStruct bErrorDoseSize = C8ool(GetlNISettιng(sFιleSpec sSection "Dose Size", False))
    OataStruct bErrorMedRemaining = C8ool(GetlNISettlng(sFιleSpec, sSection "Med Remaining", False))
    DataStruct bErrorMemoryFuli = CBoolfGetlNISettingfsFileSpec sSection "Memory Full", False))
    DataStruct bErrorBrowπOut = CBoαl(GetlNISettιng(sFιleSpec, sSection "Brownout", False)) sSection = "Device Data" EraseDataJπMemory DataStruct sTe p = GetlNISettιng(sFιleSpec sSection, "Device Imt Date-, 0) If IsDate(sTemp) Then
    L DataStruct IDevicεlnitDate - DateValue(sTemp)
    End If sTemp - GetlNISettιng(sFιleSpec sSection, "Events Ref Date Time", 0) If IsDate(sTemp) Then
    [I DataStruct dDeviceRefDateTime - Date alue(sTemp) End If sTemp = GetlNISettιng(sFιieSpec, sSection, "Last Download Date", "0") If IsDatefsTemp) Then
    L DataStruct dLastDowπloadOate - DateValue(sTemp) End If
    DataStruct sPatientLastName = GetlNISettingfsFileSpec, sSection, "Last Name", "")
    DataStruct sPatientFirstName = GetlNISettingfsFileSpec, sSection, "First Name", "")
    DataStruct sPatieπtID = GetlNISettingfsFileSpec, sSection, "Patient ID", "")
    DataStruct sTxCenter = GetlNISettingfsFileSpec, sSection, Tx Center, ~) i = ClπtfGetiNISettingfsFileSpec, sSection, "Organ Reference Number", "0"))
    If i And i <= UBound(gsOrganNames) Then DataStructsOrgaπ = gsOrganNames(i)
    I = ClntfGetlNISettingfsFileSpec, sSection, "Drug Reference Number", "0"))
    If i And i <= UBound(gsOrugNames) Then DataStruct sDrug = gsOrugNames(ι)
    DataStruct sSenalNumber = GetlNISettingfsFileSpec, sSection, "Seπal Number", "")
    DataStruct sFirmwareVer = GetlNISettingfsFileSpec, sSection, "Firmware Version", "")
    DataStruct sDoseSize = GetlNISettingfsFileSpec, sSection, "Dose Size", ~)
    DataStruct IDosesPerOay = ClntfGetlNISettingfsFileSpec, sSection, "Doses Per Day", "0"))
    DataStruct sDoseResolution = GetlNISettingfsFileSpec, sSection, "Dose Resolution", "")
    DataStπjct sMedRemaimng = GetlNISettingfsFileSpec, sSection, "Medication Remaining", "")
    OataStπjct sBatteryChangeTimer = GetlNISettingfsFileSpec, sSection, "Battery Change Timer", "")
    DataStrucLsOoseLockoutHours = GetlNISettingfsFileSpec, sSection, "Lockout Hours Between Doses", ~)
    Foπ = 1 To 14
    LZ DataStruct sScoreDatafl) = GetlNISettingfsFileSpec, sSection, "Patient Score Data " + CStrfi), "") Next i
    Time " + CStrfi). "-1") DatefsTemp) 
 
    DataStruct ιEventData(O) = ClntfGetlNISettingfsFileSpec "Event Data" "Event Count", "0 ■))
    Dim sTempLιst(IO) As Stnng
    For i = 1 To DataStruct lEventData(O) 
 General bas - sTemp = GetlNISettingfsFileSpec. "Event Data", CStrfi),
 "") r = ParseOelimStπngfsTemp, ",", sTe pϋstf)) DataStruct dEventOate(l) = CDatefsTempListf!)) . Select Case Tπm5(LCaseS(sTempLlst(2))) Case "dose taken" DataStruct byteEventTypefl) = gιEVENT_DOSE_TAKEN DataStruct lEventOata(ι) = sTempϋst(3)
_  
    _ Case "dose change"
    DataStruct byteEventType(ι) = gιEVENT_DOSE_CHANGED DataStnict lEveπtData(ι) = sTempϋst(3)_ 
    -→ Case "custom event"
    DataStnict byteEventTypefl) = gιEVENT_USER_DEFINED DataStruct lEventData(ι) = sTempUst(3)-
    _ End Select
    DataStruct sUserOatal(ι) = sTempϋst(4) DataStruct sUserData2(ι) = sTempLιst(S) DataStruct sUserOata3(i) = sTempϋstfβ) Next i
    LErrorF atal As Boolear true if this lag was set ,n the returned Hags stnng bErrorNonratai As Boolean fυe if this flag was set in the returned flags stn~g bc'rαrDoseSize As Boolean true if this flag was set in the returned flags stnrg bErrorMedRemaining As Boolean 'true if this flag was set m the returned flags stnng bErrorMemoryFuli As Boolean 'true if this ilag was set in the returned lϊags stnng bEπvrBrowπOut As Boolean true if this (lag was set in the returned flags stnng bErrorsExist As Boolean (1 byte) Bits are ser if vaπous errors have occurred and have not
    GetPatlentOataFromDisk = True return success flag to caller
    GetPatieπtOataFromDιsk_Exιt Exit Function
    GetPatιentDataFromDιsk_Error lErrorRetum = Err Resume GetPatιentDataFromDιsk_Exιt
    End Function
    Public Sub GetProgramPreferencesQ
    Load the program ard user preferences into the global vanaoles
    Dim iStrSize As Integer, i As Integer, sFileSpec As Stnng, r As Integer
    Dim sSection As Stnng sSection = "Preferences" gsDateOispiayFormat = GetlNISettmgfgsApplniFileSpec, sSection, "Date Display Format" ■Short Date") gsTimeOisplayFormat = GetlNISettmgfgsApplniFileSpec, sSection, "Time Oisplay Fomiat" "Short Time") gsngComplianceTimeRange = CSngfGetlNISettingfgsApplniFileSpec, sSection, "Compliance Time Range", "2")) sSection = "Custom Settings"
    'Ger any custom field labels that may be m the IfJl file If none exist the set some defaults here gsCustomlblPatientLastName = GetlNISettmgfgsApplniFileSpec, sSection, "Last Name Label", "") If gsCustomLblPatientLasiName = "Then gsCustomLblPatientLastName = "Last Name" gsCustomLblPatlentFirstName = GetlNISettmgfgsApplniFileSpec, sSection, "First Name Label", "") If gsCustomLblPatlentFirstName = "" Then gsCustomLblPatlentFirstName = "First Name" gsCustomLblPatientlD = GetlNISettmgfgsApplniFileSpec, sSection, "Patient ID Label", "") If gsCustomLblPatientlD = "" Then gsCustomLblPatientlD = "Patient ID" gsCustomLblTxCenter = GetlNISettmgfgsApplniFileSpec, sSection "TX Center Label", ~) If gsCustomLblTxCenter = "" Then gsCustomLblTxCenter = "TX Center" gsCustomLblDrug = GetlNISettmgfgsApplniFileSpec, sSection, "Drug Label", "") If gsCustomLblDrug = "" Then gsCustomLblDrug = "Drug" 
 Seπeral bas - GetProgramPreferen gsCustomLblOrgaπ = GetlNISettmgfgsApplniFileSpec, sSection, "Organ Label", ~) If gsCustomLblOrgaπ = - Then gsCustomLblOrgan = "Organ" ~~ gsLabelGπdColumnCustoml = GetlNISettmgfgsApplniFileSpec, sSection, "Gπd Column 1", "") If gsLabelGndColumπCustoml = "" Then gsLabelGπdColumnCustoml = "CYA Level (ng/ml)" gsl_abelGndColumnCustom2 = GetlNISettmgfgsApplniFileSpec, sSection, "Gπd Column 2", "") If gsLabelGπdColumnCustom2 = "" Then gsLabelGπdColumnCustom2 = "Creatiπiπe (mg/dl)" gsLabelGπdColumnCustom3 = GetlNISettmgfgsApplniFileSpec, sSection "Gπd Column 3" "") If gsLabelGπdColumnCustom3 = "" Then gsLabelGπdCαlumπCustom3 - "Custom"
    
    Get last values for the Fax control that was 'ast set by user sSection = "User Selections"
    With FAX_DATA sSeπden ame = GetlNISettιng(gsFaxFιleSpec, sSection, "Sender Name", "") sSenderCo pany = GetlNISettιng(gsFaxFtleSpec, sSection, "Sender Company", "") sSenderVoiceNumber = GetINISettιπg(gsFaxFιieSpec, sSection, "Sender Voice Number", "") sSenderFaxNumber = Get!NISettιng(gsFaxFιieSpec, sSection, "Sender Fax Number", "") sFaxlD = GetlNISettιng(gsFaxFιleSρec, sSection, "Fax ID" ~) .sOialPrefα = GetlNISettingfgsFaxFileSpec, sSection, "Dial Prefix", ~) iRetπes = Clπt(GetINISettιng(gsFaxFιleSpec, sSection, "Retπes", "0")) iRetrylnterval = Clπt(GetlNlSettmg(gsFaxFιleSpec, sSection, "Retry Interval", "1")) bFax Resolution - GetlNISettιng(gsFaxFileSpec, sSection, "Resolution", "0")
    End With
    Gef the Drug types from file and place in global list sSecϋon ~ Transplant Centers"
    TxCenters(O) - GedNISet ng(gsApplnιFιle$Dec sSecπcπ "Count" "0")
    For i = 1 To TxCenters(G)
    TxCenters ) = GettNISet ngfgsAppln.F teSpec sSecαon CStr(ι) O") Next i
    
    Section "Count", "0") sSection, CStrfi), "0") 
 giCurrentTip = ClntfGetlNISettingfgsApplniFileSpec, "Options" "Current Tip" 1))
 
    Get settings of calendar form
    CAL_OEFAULTS chkDosesMissed = CBytefGetlNISettingfgsApplniFileSpec, "Calendar Settings", "chkDosesMissed", 1))
    CAL_OEFAULTS chkDosesNotComplied = CBytefGetlNISett gfgsApplniHleSpec, "Calendar Settings", "chkDosesNotComplied", 1)) 
 General ba', - GelProgramPreferenc
    CAL_DEFAULTS chkDosesTakeπ = CBytefGetlNISettmgfgsApplniFileSpec. "Calendar Settings" "chkOosesTaken", 0)) CAL_DEFAULTS chkDoseChanged = CBytefGetlNISettmgfgsApplniFileSpec, "Calendar Settings". "ChkDoseChanged", 1)) -
    Get Settings of Patient summary form
    PAT SUM DEFAULTS cmboDataToView * C8yte(GetINISettιng(gsApplnιFιleSpec, "Patient Summary Settings", "cmboDataToView" 1 ))
    PAT_SUM_DEFAULTS cmboChartType = C8yte(GetlNISettιπg(gsApplπιFileSpec "Patient Summary Settings", "cmboChartType", 1))
    Get the web address for the brcwset gsWebStartingAddress = "http /T gsWebStartingAddress = gsWebStartingAddress + GetlNISettmg(gsApρlnιFιieSpec, "Web Data" "User Name", -*) + " - gsWebStartingAddress = gsWebStartingAddress + GetlNISettιng(gsApplπιFιleSpec, "Web Data", "Access", "") + "@" gsWebStartingAddress = gsWebStartingAddress + GetlNISettmgfgsApplniFileSpec, "Web Data", "URL", "**)
    Sub Maιn()
    Dtm I As Long r As Integer, j As Integer sMSG As Stnng, sTemp As Stnng αTime As Double Dim bBrowserFound As Boolean, ILastAccessDate As Long INextReminderDate As Long
    Initialize some apolication settings gsApplπiFlleSpec = App Path + V + "CycloTech ιnι" gsFaxFileSpec 
a App Path + "VFax mi" gsTempBuf = SpaceS(1024) gbCommOK - 99 sef to some va'ue other than true or false to proper
ty initialize the dialog frmSplash Show frmSplash Refresh dTime = Now get the time value of now 
 frmLogtπ Show vbModal
 
    If Not frmLogin OK Then End Loom Failed so exit app
    Unload frmLogin
    Do Events rgn note that the debug flag is turned on and the fax icon is hidden
    I ~ ShelKApp Path + "\Faxman32 exe D/H" 1) 'start the fax server
    I - SheH("Faxman32 exe H", 1) 'start the fax server
    Load frmMain
    Set gcFax = frmMain FaxManl
    If browser feature is turned on tn the mi file then activate item on the menu See if tve should allow access to visit Sangstat on the Internet r ~ CBool(GetlNISetting(gsApp!nιFileSpec, "Web Data", "Active", "False")) If r = False T en frmMain mnuAccessWebSrte Vsible = False 'no key found tn mi fi.e
    CommJπitiaiizeCommPort 'initialize the comm port from INI file serftπgs GetProg ram Preferences EraseDatalnMemory PAT_DATA Erase DatalnMemory TEM~P_OATA
    Set some menu items frmMain mnuFtleSave Enabled = False frmSplash ZOrder
    Do
    If CDbl(Now) > dTime + 0 00005 Then Exit Do watt for a minimum amount of time before urloadng sp'asn screen
    
    Unload frmSplash frmMam.Shσw SetPnπtertcon False,
    'See if we should shown tips at startup r = CBool(GetlNISettιng(gsApρlπiFιleSρec, "Options", "Show Tips at Startup", True))
    If r Then frm Tip. Show
    available
    
    End Sub 
 General. as - LogonToWebSile
    — LU
    Public Sub LogonToWebSite{)
    'Visit Sangstat on the Internet 'Dim fr B As New frmBrαwsβr Load frmβrowser frmBrowser.StartiπgAddress = gsWebStartingAddress DoEvents 'allow time to paint DoEvents 'allow time to paint frm Browser 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 was successful false >f net and voCancel ,f usar cancelled
    Dim r As Integer, sTemp As Stnng, lErrorCode As Long On Error GoTo OpeπPatιentData_Error r ~ ValidatePatientDataSaved 'make sure any cevice data has first oeen saved If r = vbCancel Then Exit Function
    'Get a filename from the common ύalog
    'Setup the common dialog control pπor to showing it
    With frmMain.dlgCo monDialog
    .Flags = cdlOFNOverwπtePrompt Or cdlOFNPathMustExist Or cdlOFN Explorer Or cdlOFNExtensionDifferent Or ► cdtOFNNoReadOnlyReturn Or cdlOFNHideReadOnly Or cdlOFNFileMustExist
    .CaπcelError = True 'generate error if CANCEL button is pressed
    .InrtDir = App Path + "\Patient Data"
    .Filter = "CycloTech Data File \cρd|\cpd"
    .DialogTrtle - "Open Patient Data File"
    .DefaultExt - "CPD" 'append "Structure" extention when saving
    If sFileSpec <> "" Then .filename ~ sFileSpec
    .ShowOpen 'Open dialog
    End With
    'Now get the data from die frmMaiπ.MousePointer = vbHαurglass DoEvents
    
    PAT_DATA.sPatιentOataFιleName - frmMain.dlgCommonDialog filename
    OpenPatientData - True r ~ GetRleNameFromSpec{PAT_DATA.sPatιentDataFileName, sTemp) 'hold the name of the f.-e
    VpDateReceniFileMenu snleSoec
    UpDateRecentFileMenu sTemp frmMaιn.mnuFιleSave Enabled = True
    OρenPatιentData_Exιf On Error GoTo~0 RefreshAIIOpeπForms frmMain MousePointer = vbDefault Exit Function 
 General bas - OpenPatieπtData
    was pressed in dialog
    ta and can not be read ". vbExclamation, "Invalid Data File - " 
■*• Error 
 
    OpenPatlentOata = False
    Resume OpenPatιentData_Exιt 'exit any- .vay for now
    End Function
    Public Sub PopulateDeviceDiagDialog(DataStruct As DeviceDataStruct, SourceForm As Form)
    'There are two possible σaicgs that nave the same controls on 'nsm Tms common procedure will populate bcth Dim i As Integer
    With SourceForm 'Show custom labels from conng file if there were any .Labet1(3) = gsCustomLblPatientLastName Label1 (1) = gsCustomLblPatlentFirstName Label1 (5) = gsCustomLblPatientlD .Label1 (6) = gsCustomLblTxCenter .Labell (7) = gsCustomLblDrug Labell (0) = gsCustomUllOrgan
    box box with available choices
    
    If TypeOf .txtOrgan Is SSPanel Then .txtOrgan = DataStructsOrgan
    Eiself TypeOf .txtOrgan Is ComboBox Then 'it is a list box txtOrgan. Clear For i = 1 To gsOrganNames(O) 'fill the drugs list box with available choices
    L .txtOrgan Addltem gsOrgaπNamesfj) Next i Then
    
    .txtPatientLastName = DataStruct sPatient astName 
 General. bas - PopulateDeviceDiαyuiα j txtPatientFirstName - DataStruct sPatientFirstName txtPatlentlO = DataStruct.sPatleπtlO .txtTxCenter = DataStruct.sTxCeπter — .txtSeπalNumber = DataStruct.sSeπalNumber .txtDoseSize = DataStruct.sOoseSlze txtPatientLastName SetFocus ta(O) Then + CStrfDataStruct lEventData(O)) 
■ 
 0 Then .txtDoseTime(ι) = FormatS(DataStruct dPrescπbedDoseTime(ι), 
 txtDosesPerOay = CStrfDataStructiDosesPerDay) txtDoεeResolυtlon = DataStruct.sDoseRescluticn .brtDoseLockoutHours = DataStnictsDoseLockoutHours If DataStruct IDevicelnitDate Then txtDeviceStarted = " " + Format$(CDate(DataStrucUDevιcelnιtDate), "Medium Date") End If
 
    .txtMedlcatioπRemaiπing = " " + DataStructsMedRemaining txtBatteryChangeTtmer = " " + DataStructsBatteryChangeTimer .txtFiππ areVer = " " + DataStruct.sFirmwareVer
    
    
    If DataStruct.bErrαrDoseSize Then .imgError.Picture .imgNoError.Picture 
 
     
 rMemoryFull Then = .imgError.Picture Picture = imgNoError Picture 
  
    
    
    Public Sub RefreshAlIOpenFormsO
    Dim r As Integer
    " any of these forms are open at the tme a new file is loaded then refresh them For r = 0 To Forms Count - 1 _ Select Case Fαrms(r).Name
    Case "frmPatientDosingReport" frmPatientOosingReport.UpdatefrmPatientDosingReportHeader frrnPatientDosingReport.UpdatePatientGπdDisplay
    Case "frmOosiπgCaleπdar"
    If PAT DATA, d Event Da te(PAT_DATA lEventData(O)) > 0 Then fr DosingCalendar Calendar Date = CVDate(PAT DATA dEventOate(PAT_DATA.ιEventData(0)))
    UpdateCalendar
    Case -frmPπnt" Refresh Preview
    Case "frmPatientSummarγ" frmPatientSummary UpDatefrmPatientSummaryHeader frmPatientSummary cmbαDateSelectιon_CIιck 'frmPatientSummary. UpdatePatientDαsingGraph
    Case "frmDevicelnitialize"
    PopulateDeviceCommDialog PAT_DATA, frmDevicelnitialize
    Case "frmReadDe vice Data"
    PopulateDeviceCommDialog PAT_DATA, frmReadDeviceData
    - End Select Nex r
    End Sub
    Public Sub SetPππterfconfbEπable As Boolean, sTϊp As String)
    On Error Resume Next frmMaiπ.mnuFilePππt.Eπabled ~ bEnable _ If sTip = ""Then frmMain mnuFiIePπnt.Caption = "Pπnt..." _ Else frmMain.mnuFilePπnt.Caption = sTip _ End If frmMain. tbToolBar.Buttons Item(5). Enabled - bEnable frmMaln.tbToolBar.βurtons.ltem(5).ToorπpText = sTip
    'If the active form is not the pnnt form, then keep the name of the 'form in the key property of the icon This is so that the pnnt 'form will know what kind of information to display and pπnt
    If frrnMain.ActiveForm.Name <> "frmPπnt" Then gsActtveFormNa e = frmMaιn.ActιveFαrm Name On Error GσTo 0 End Sub 
    General bas - UpDateReceπlFileMenu
    Public Sub UpDateRecentFιleMeπu(ByVal sFileSpec As Stnng)
    'Add the newest FtleName to the menulist and move the other ones down On Error GoTo 0
    Dim bDuplicateFound As Boolean i As Integer r As Integer, sFileName As Stnng r = GetFιleNameFromSpec(sFιleSpec, sFileName) hold the name of the tile
    'hat mi ht apcear
    
    'or αsplay purposes
     
 mnuFileMRUfi ) Tag = sFileSpec mnuFileMRU(l) Caption - sFileName mnuFileMRUfi ) Visible = True mnuFileBaπS Visible = True
 
    End With
    End Sub
    Public Function GetFileNameFromSpec(ByVal sFileSpec As String, sFileName As String) As Integer
    Stπp the Rename and extenϋon from the lilespec (dnve\pathvlenamel
    Dim rAs Integer
    ReOim sLιst(50) As Stnng
    On Error Goto GetFιleNameFromSpec_Error
    If Leπ(sHleSpec) > 0 Then r = ParseDelimStπngfsFileSpec, , sListQ) delimit all subpaths sFileName - LCase5(sϋst(r)) 'f'e name is last item in list something was returned
    If en(sFιIeName) > 0 Then GetFileNameFromSpec = True return success to caller 
    GetFιleNameFromSpec_Exrt Exit Function
    GetFιleNameFromSpec_Error 'Resume 0 Resume GetFιleNameFromSpec_Exιt
    End Function 
 General has - Parseueiimairtng
    Public Function ParseDeIimStrϊπg(ByVal sParse As String, ByVal sDeiim As String, sFieldStringsQ As Strinαϊ
    'Parse "sparse' passed here Put resulting parsed names tn a list called sFieldStnngs "'
    'Use sDelim as the delimiter to parse stnng Tn any leading and trailing soaces from each field sFtefdStnng list must pre-exist before calling here and should oe oig enough to 'hold all delimited stnngs
    The list contains fields in the order they apcesreα from iert to πςr.t Function returns number of lelds found
    Dim i As Integer Voαp counti
    Dim iDeliml As Integer, ιDelιm2 As Integer marks begnr.mg and enc of a field
    If Len(sParse) = O Then Exit Function 'exit if no chars in stnng iDeliml = 0 'set first deii marker fo beginning of line
    If RιghtS(sParse, Leπ(sOelιm)) <> sDelim Then 'see if a deli is airsadv at the end of the st : c sparse = sParse + sDelim 'put a delim at end of na
    End If
    Note an Erase method can net oe used as it redi s the array to only a few elements c For i = 0 To UBσuπd(sFieldStπngs) clear out cid data from the arrav sFιeldStπngs(i) ~ 
™ Next i found 1 )) found 
 of list
 
    Public Function SaveDataToNewFiIe() As Integer
    'Get a filename from the common άalog
    'Setup the common dialog control pπor to showing it
    Or cdlOFNExplorer Or cdlOFNExtensionDifferent
    " " + PAT_DATA.sPatientiD + " pd" 'se.* a
    
    PAT_DATA sPatientDataFileName = frmMain dlgCommonDialog filename SavePatientData PATJDATA sPatientDataFileName SaveDataToNewFtle = True
    SaveDataToNewFιle_Exιt Exit Function
    SaveOataToNewFile Error 
 General bas - SaveData loNewr-i
    If Err = cdlCancel Then cancel oυt'on was „r*szed m dialog
    SaveOataToNewFile = vbCancel
    Resume SaveDataToNewrile_Exιt End If SaveOataToNewFile ~ False
    Public Function SavePatιeπtData(ByVal sFileSpec As String) As Integer
    Save all of the patten* data currently in merrorj to a dιsκ 1le
    Return a true if save ,vas 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
    - = GetFιleNaneFromSpec(frr*Maιr d'gCcmmo-Ωlalαg 1lenar-e sTer-c) sa/e the srwas selected by user
    We need to confι*m wit*' user that it is desired to save these file modιficatιoΛs under the same na~~e as the ere 'ha* was just loaded
    If ι-en frmMain dlgCommonOialog filename} And frr-Ma i dlgCommαrDlalαg llenar-e = UCaseSiProj sStructF leName) The" = "You are about to save changes to the same file the/ were lOacsd from'* ' SGS - VfSCS + ' Are you sure you want to do this7' Beep r - MsgBox(MSGS MB_YES_NQ 'Confirm Over Wnte 7 ltr = ID_NO Then Exit Function oops user almost made mstake exit sub
    End If
    Now save the data to the Hie r - GetFileNameFromSoecfsTemp sFileSpec! hold the name of the f'e sFileSpec = App Path & TPatfenf Oafa" frmMain MousePointer = vbHourglass DoEvents sSection - "Device Data"
    SavelNISettmg sFileSpec sSection, "Date Saved To File", Now
    SavelNISetting sFileSpec sSection "Host Software Version" CStrfApp Ma|or 4 " " 4 App Minor 4 " " 4 App Revision) SavelNISettmg sFileSpec sSection "Firmware Version" PAT_OATA sFirmwareVer
    SavelNISetting sFileSpec sSection, "Last Download Date", CDate(PAT_DATA dLastDownloadDate) sftcrt date must be used preve-
    > error when loading back ~
    SavelNISetting sFileSpec sSection, "Device Init Oate" CDate(PAT_DATA IDevicelnitDate)
    SavelNISetting sFileSpec sSection "Events ef Date Time" CDatefPAT_OATA dDevιceRefDateTime)
    SavelNISetting sFileSpec, sSection, "Last Name", PAT_DATA sPatientLastName
    SavelNISetting sFileSpec sSection "First Name" PAT_DATA sPatieπtFirstName
    SavelNISetting sFileSpec sSection "Seπal Number" PAT.DATA sSeπalNumber
    SavelNISettmg sFileSpec sSection, "Patient ID", PAT_DATA sPatientlD
    SavelNISettmg sFileSpec, sSection, "Organ", PAT_DATA.sOrgan
    SavelNISetting sFileSpec, sSection "Organ Reference Number" CStr(GetOrganRefNumberO)
    SavelNISetting sFileSpec sSection Tx Center", PAT 3ATA sTxCenter
    SavelNISettmg sFileSpec sSection "Drug" PAT_DATA sDrug
    SavelNISetting sFileSpec, sSection "Drug Reference Number" CStr(GetDπιgRefNumberO)
    SavelNISetting sFileSpec sSection "Dose Size", PAT_DATA sDσseSize
    SavelNISetting sFileSpec sSection "Doses Per Day", CStr(PAT_DATA iDosesPerOay)
    SavelNISetting sFileSpec sSection "Dose Resolution" PAT_DATA sDoseResolution
    SavelNISetting sFileSpec sSection "Medication Remaining" PAT_DATA sMedRemaimng
    SavelNISett g sFileSpec sSection "Battery Change Timer", PAT_DATA sBatteryChangeTimer
    SavelNISetting sFileSpec sSection "Lockout Hours Between Doses" PAT_DATA sDoseLockoutHours
    For i = 1 To 14
    SavelNISettmg sFileSpec sSection "Patient Score Data " + CStrfi) PAT_DATA sScoreOata(ι) Next i
    For i = 1 To giMaxOoseTϊmes - If PAT_DATA dPrescnbedDoseTime(ι) >= 0 Then 
 General bas - SavePatientData
    SavelNISett g sFileSpec, sSection, "Presoibed Dose Time " * CStr(ι), Format$(PAT_DATA dPrescπbedDoseTime(ι), V gsTimeOisplayFormat) Else
    SavelNISettmg sFileSpec, sSection, "Prescπbed Dose Time " + CStrfi), "None" End If Next i
    'This sectior is Imsned Go compute the checksum and save it ICheckSumTally = ComputelπiSectioπChecksumfsFile≤pec, sSection) SavelNISettmg sFileSpec, "General", "Device Data Validation" CStr(ICheckSumTally)
    Before saving new event data clear cut the old srπngs sSection = "Event Data" r = WπtePπvateProfileStπngfsSection, ByVal 04, ByVal 04, sFileSpec) SavelNISetting sFileSpec, sSection, "Event Count", CStr(PAT_DATA lEventData(O)) For i = 1 To P AT_DATA lEventData(O) 'total nur-oer of events sTemp = Format5(PAT_DATA dEventOatefi), "General Date") ♦ ", " - Select Case PAT_DATA byteEventType(i) Case gιEVENT_DOSE_TAKEN sTemp = sTemp ■*■ "Dose Taken, "
    Case gιEVENT_DOSE_CHANGED sTemp = sTemp + "Dose Change, "
    Case gιEVENT_USER_DEFINED sTemp = sTemp + "Custom Event, " . End Select sTemp = sTemp + CStr(PAT_DATA lEveπtDatap)) sTemp = sTemp + " ," + PAT_DATA sUserOatal (ι) sTemp = sTemp * " ," * PAT_DATA.sUserOata2(ι) sTemp = sTemp + " ," + PAT_DATA.suserOata3(i) SavelNISett g sFileSpec, sSection, CStrfi), sTemp Next i
    771/s section is finished Go compute the checksum and save it ICheckSumTally = ComputelπiSectionChecksumfsFileSpec, sSection) SavelNISetting sFileSpec, "General", "Event Data Validation", CStr(ICrteckSumTally) sSection - "Device Error Flags" SavelNISetting sFileSpec, sSection, "Fatal", CStrfPAT DATA bErrorFatal) SavelNISett g sFileSpec, sSection, "Non Fatar, CStr(PAT_DATA bErrorNonFatal) SavelNISetting sFileSpec, sSection, "Dose Size", CStr(PAT_DATA.bErrαrDoseSιze) SavelNISettmg sFileSpec, sSection, "Med Remaining", CStrfPAT_OATA bEπorMedRemaiπing) SavelNISettmg sFileSpec, sSection, "Memory Full", CStr(PAT_DATA.bErrorMemoryFull) SavelNISetting sFileSpec, sSection, "Brownout", CStr(PAT_DATA bErrorBrownOut)
    '777/s section /s finished Go compute the checksum and save it
    ICheckSumTally = CαmputelπiSectioπChecksumfsFϊleSpec, sSection)
    SavelNISetting sRleSpec, "General", "Device Error Flags Validation", CStrOCheckSum Tally) gbPatientDataNotSaved = False r = GetFileNameFromSpecfsFileSpec, PAT_DATA sPatientDataFileName) hold the name of the Hie
    UpDateRecentFileMenu sFileSpec frmMain mπuFileSave.Enabled = True
    SavePatientData = True
    SavePatιentData_Exιt On Error Go To 0 frmMain MousePointer = vbDefault Exit Function
    SavePatιeπtData_Error SavePatientData = False 
 General.bas - SavePatieπtDat
    Resume SavePatιeπtData_Exιt exit anyway for now End Function
    Public Sub PopulateDeviceCommDialog(DataStruct As DeviceDataStruct, SourceForm As Form)
    'There are nvo possible dialogs that have the same controls on them This common procecure will populate both
    On Error Resume Next 'net alt text boxes will apoear on every form Dim i As Integer
    With SourceForm 'Show custom laoeis from config file if there were any Label1(3) = gsCustomUjlPatientLastName Label! (1 ) = gsCustomLblPatlentFirstName Label1(5) = gsCustomLblPatientlD Labe (6) = gsCustomLblTxCenter .Label1(7) = gsCustomLblDrug .Label! (0) = gsCustomLblOrgan
    list box list box with availaole choices
    
    If TypeOf txtOrgan Is SSPanel Then txtOrgan = DataStrucLsOrgan
    Eiself TypeOf .txtOrgan Is ComboBox Then 'it is a list box txtOrgan.CIear tz For I = 1 To gsOrganNamesfO) 'till the drugs fist box with available choices
    .txtOrgan-Addltem gsOrganNames(ι) Next !
    rgan Then
    
    .txtPatieπtLastName = DataStruct.sPatientLastName txtPatientFirstName - DataStruct.sPatientFirstName txtPatieπtlD = DataStrucLsPatientlD txtTxCeπter = DataStructsTxCeπter .txtSenalNumber = DataStruct.sSeπalNumber txtDoseSize = " " ♦ DataStπjctsDoseSize 
 enerai Das - PopulateUeviceoomn Λog
    22
    If DalaSlruct lEventData(O) Then bctEventCount = " " ♦ CStrfDataStruct lEventData(O)) + ' Else txtEveπtCount = ""
    End If DatefDataStruct dLastDownloadDate) "Short Date") 
■ FormatSfCDatefDataStruct ♦ " " 
 txtPatientLastName tane /oc-s away from list box a«e
r t rvas sa' n PrescπbedOαseTime(i) gsTimeOisplayFormat) 
 txtOosesPerOay = " " + CStr(DataStrucLιDosesPerOay) + " " bctDoseResolutloπ = " " + DataStruct sDoseResαlutlon ♦ " " txtOoseLockoutHours = " " + DataStnjctsOoseLockoutHours + " " txtMedicatioπRemaining = " " + DataStructsMedRemammg + " " If DataStiucLIDevicelnitDate Then txtOeviceStarted = " " ♦ FormatSfCDatefDataStruct IDevicelnitOate), "Medium Date") End If txtBatteryChangeTimer - " " + DataStructsβatteryChange Timer + " "
 
    ize Or bErrorMedRemaining Or bErrorMemoryFull Or bErrorSrownOut Then errors were found no errors exist 
 
    End With
    On Error GoTo 0
    End Sub
    Public Sub SaveProgramPrefereπcεsQ
    Dim I As Integer, sSection As Stnng, sFileSpec As Stnng sSection = "Preferences"
    SavelNISetting gsApplniFileSpec, sSection. "Date Display Format", gsOateDisplayFor at
    SavelNISettmg gsApplniFileSpec, sSection, "Time Display Fomiat", gsTimeOisplayFormat
    SavelNISetting gsApplniFileSpec, sSection, "Compliance Time Range", CStr(gsπgCompIιanceTimeRaπge)
    Sa/e the names of the most recently used fies from the me u For i = 1 To frmMain mnuFileMRU UBound
    SavelNISetting gsApplniFileSpec "Recent Files", CStrfi) frmMain mnuFιleMRU(l) Caption Next l
    SavelNISetting gsApplniFileSpec "Options", "Current Tip" CStr(gιCurrentTip)
    Save Setcirgs of Calendar Form
    SavelNISettmg gsApplniFileSpec, "Calendar Settings", "chkDosesMissed", CStr(CAL_DEFAULTS ChkDosesMissed) SavelNISett g gsApplniFileSpec "Calendar Settings", "chkDosesNotComplied" CSt (CAL_DEFAULTS ChkDosesNotComplied) SavelNISetting gsApplniFileSpec "Calendar Settings", "chkOosesTaken", C≤tr(CAL_DEFA"ULTS chkDosesTakeπ) SavelNISett g gsApplniFileSpec "Calendar Setting *Str(CAL_DEFAULTS ChkDoseChanged) 
 Save Settings of Patient Summary Form
    SavelNISettmg gsApplniFileSpec, "Patient Summary Settings", "cmboDataToView", CStr(PAT_SUM_DEFAULTS cmboDataToView)
    SavelNISettmg gsApplniFileSpec, "Patient Summary Settings", "cmboChartType", CStr(PAT_SUM_DEFAULTS cmboChartType)
    End Sub
    Public Function FindFirstMatchingDateInArray(DataStruct As DeviceDataStruct, ByVai IBeginDate As Loπα 'Find the eadtest even' date tn the global structure that starts on the same day "
    'as the date oassed here Return 0 if net found or return the index to the date if one is found Note that this date is not necsssaπly a dcαng event da'e It could oe any kind of even:
    'Conduct a successive accroxtmation lockup ct the date in the arras
    Dim i As Integer, iLowlndex As Integer, iHighlπdex As Integer, iTestlndex As Integer
    
    Public Function FindClosestDateinArray(DataStruct As DeviceDataStruct, ByVal IFromDate As Long) As Lon
    'rtnd the latest event date m 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 necessanly a dαsmg event date Tπera is a separate
    'procedure to find that date
    'rgh if necessary for faster speed, this procedure can be receded to do a successive approximation
    Dim J As Integer
    If IFromDate = 0 Then IFromDate * 99999 the array
    
    End Function 
    General bas - SavelNISetting
    24
    Public Sub SavelNISetting(ByVal sFileName As Stnng, ByVal sSection As String, ByVal sKeyField As String Dim I As Long
    I = WπtePπvateProlileStπngfsSection, sKeyField. sValue, sFileName)
    End Sub
    Public Function ValidateDoseNumbers(frm Target As Form) Ensure that there are at least as anv cose times as there are 'for the number of doses oer day
    Dim i As Integer, iDailyDoseCounts As Integer, iDosesPerOay As Integer _ If Len(PAT_DATA sPatientDataFileName) = 0 And Len(PAT_DATA sSeπalNumber) =
    ValidateOoseNumbers = True
    Exit Function _ End If
    With frm Target
    IDosesPerOay = Val( txtDosesPerDay) me(i)) Then s = iDailyDoseCounts + 1 
 
    PerDay) + " Doses Per Day. yet " •*
■ CStrøDailyDoseCounts) + " Dose Times were , "Mis-matched Dosing Values" 
 
    End With End Function
    Public Function ValidatePatientDataSaved()
    '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
    ValidatePatientDataSaved = True this is die default conation unless set otherwise below
     
 General. as - ValidalePatientDataSa d
 
    Public Sub ait(ByVal dSeconds As Double)
    'wait tor the specified time passed here then return to caller Dim dDelay As Double
    ' αDelay = OateAddfs' dSeconds CDbl(Now)) dDelay = CDbl(Now) + (dSeconds / 86400) '36400 seconcs in a dev
    _ Do
    DoEvents
    DoEvents _ Loop While (dDelay >= CDbl(Now)) 
    Comm bas - File Declarations
    Attribute VB_Name = "modComm" Option Explicit
    'Global definitions tor device communication bv Glen Hamilton 10/597
    ' forRS232 communication
    Public gbCommTimerExpired As Integer this flag is set when 'he conn er expires
    Public giCommPort As Integer 'Communication Port #
    Public gsCommDeviceSettings As Stnng 'speed settings -ιe 2 0G N 8 2'
    Public gbCommReplyPending As Boolean a command was just sent and rspl/ is penαmg
    Public gbCommBusy As Boolean 'a command is in progress Gets cleared wnen re lv is received or times out
    Public gbCommOK As Integer needs to be an integer m boolean) keeαs current status of communications false= rtc comm true ~ com ok any other value for simulation
    Public giDeviceResponseWait As Integer 'milusecs to wait for next char before assuming end of received stnng
    Private Const ERR COMM BADRESPONSE = 31001
    Private Const ERR~COMM~TlMEOUT = 30998
    '?πvate Const - 3C9S7
    Fnvate Const E rT_OOMM_BUSY = 30956
    Private Const ERR_COMM_CHECKSUM = 30995
    Public Const ERR_DATA_CHEC SUM = 99997
    Public Const £RR_NEWER_HOST_SOFTWARE = 99998 set .vnsn device re'u s custom data that was saved with a newer rewsic le vet
    'Device communications
    Public gbKeepPolliπgOevtce As Boolean \vhen true, continuous polling cf device is done
    'Define some application specific vanables & constants Public gsApplniFileSpec As Stnng
    Type DeviceDataStruct s Patient La stNa me As Stnng '(16 bytes) uses 1st 16 byte block of the patient/pnar acy ID & Names sPatfeπtFirstName As Stnng '(16 bytes) uses 1st 16 byte block of the patient/pharmacy ID 2. Names sPatientlD As Stnng sDrug As Stnng '(16 bytes) uses 2nd 16 byte block of the patientpnarmacy ID & Names sOrgan As Stnng '(16 bytes) uses 3nd 16 byte block of the patient/pharmacy ID & Names sTxCenter As Stnng '(16 bytes) uses 3nd 16 byte block of the patient/pharmacy ID & Names sSeπalNumber As Stnng '(10 bytes) device seπal number sFirmwareVer As Stnng 'Rev version and date of firmware sDoseSize As Stnng '(1 bytei stored here in mg The device uses "ml' (100mg = 1 ml)
    'Device Dose size ts in optical ticks (0 to 200) max dose = 5 ml sPatientDataFileName As Stnng 'f.i path and filename of the data in memory
    'Note the daily prescnosd dosing times below are stored in fractional days This ts dona
    '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, (he times are converted to
    'intervals when communicating with the device dPrescπbedDoseTϊme(4) As Double 'doses due dunng the day (pres nted) usually a max of four iDosesPerOay As Integer '(1 byte) tt of doses per day (1 to 4) sDose Re solution As Stnng '(1 bytei Called 'Dose Conversion' in firmware
    'Optical ticks to mg multiplier. {IE 2 ticks = 10 mg)
    'Optical ticks are ήxed at 0 05 ml per tick sMedRemaming As Stnng '(2 bytes) Medication 'Supply volume' remaining fin cctical ticks) sScoreData(14) As Stnng 'Today's scorefl 4 bytes for all scores) of last days doses taten Crcular suffer
    'valid data is value from 0-4 representing number of doses taken each day
    'Note Tπe 'Score pointer" points to the current day
    Note that the following arrays can not be larger than 1500 events or else ine space limit
    Of S4K wιll β exceeded If necessary in die future to have more events than this for
    'a single file then make a separate array for the diagnostic data or temp data ιEventData(1 00) As Integer 'the data occumng for the event data Might be a dose size error flags etc d£vent0ate(1400) As Double list of dose days in order of first taken to most recent byteEventType(1400) As Byte 'value =0ιfι ιs a dose taken
    'value ~ 1 if data event is a dose command change
    'value - 2 if user entered entered sUserData1(14QO) As Stnng 'user entered data in the first column cf hs gπd sUserData2(1400) As Stnng 'user entered data in the first column of the gnd 
 Comm.bas - File Declarations sUser0ata3(1400) As Stnng user entered data tn the first column of the gnd sCloc As Stnng '(2 bytes) 10 minute nesolubon '0000' ~ I am on first dose day
    IDevicelπitDate As Long dare the device started dDeviceRefDateTime As Double 'date and time that all events are referenced to SBatteryChangeTimer As Stnng '(2 bytes)3attery change timer in 10 minute increments sDoseLockoutHours As Stnng '(1 bytei Hours to lockout dosing after a dose is taken bErrorFatal As Boolean 'true if this flag was set in the returned flags stnng bErrorNoπFatal As Boolean 'true it this flag was set in the returned lags stnng bErrorDoseSize As Boolean 'hue if this fiag was set in the returned flags stnng bErrorMedRemaining As Boolean 'true ..' this flag was set in rhe re'umed flags stnng bErrorMemoryFull As Boolean 'true it this flag was set in ire returned flags stnng bErrorθrownOut As Boolean 'true it this flag was set in the returned lags stnng bErrorsExlst As Boolean '{1 byte) Bits are set if vanous errors nave occurred and have net been corrected A value of '0' is normal (no errors) Ξ'rcrs are corrected by either coσectlnc the specific situation of resett.ng 1 reloading the cosing parameters
    '30~1 if fatal system failure
    'B1-1 if non-fatal system failure has occurred
    B2-1 it error has occurred in Dose Size Vclurre
    B3→ 1 if error has occurred m Supply Votume value
    '£4=1 it compliance memory is near tull
    B5=1 it brownout (low voltage) occurred dLastDownloadDate As Double date of las: data retneval from device
    End Type
    Public PAT_DATA As DeviceDataStruct
    Public TEMP_DATA As DeviceDataStruct
    Public gsDrugNames(25) As Stnng 'names of drugs used to populate the list boxes on dialogs
    Public gsOrgaπNames(25) As Stnng names of gsOrganNames used to peculate the list boxes on dialogs
    Public Const giEVENT DOSE TAKEN = 0 Public Const glEVENTlDOSEj:HANGED = 1 Public Const gιEVENT_USER_OEFINED = 2
    'These values indicate the stnng position (returned from the device) where each element
    'begns Tnis is the stnng that is returned when a request for 'ell memory is sent
    See above structures for more detail inforτnabon aoαut format
    Public Const DATA BEGIN DOSE_SI2E = 1 '? byte
    Public Const DATA~BEGIN~DOSE INTERVALI = 1 * 2 + 1 '1 byte
    Public Const DATA BEGINJDOSEJNTERVAL2 = 2 • 2 + 1 "I byte
    Public Const DATA BEGIN_DOSE_INTERVAL3 = 3 • 2 + 1 '1 byte
    Public Const DATA~BEGIN_DOSE_INTERVAL4 = 4 • 2 + 1 "I bvte
    Public Const DATA~BEGIN~OOSES PER DAY = S • 2 ♦ 1 '1 byte
    Public Const OATA~BEGIN~DOSE CONVERSION = 6 * 2 + 1 '1 byte
    Public Const DATA = 7 * 2 ♦ 1 '1 byte
    Public Const DATA~BEGIN~DOSE_SCORE_DAY_POINTER = 8 * 2 + 1 '1 byte
    Public Const DATA~BEGIN ulED_RE AINING = 9 * 2 + 1 '2 bytes
    Public Const DATA BEGIN_CLOCK = 11 * 2 + 1 '2 bytes clock starts at lam on first dosing day (10 mm increments!
    Public Const DATA 8EGIN_BATTERY_CHANGE_TIMER = 13 * 2 + 1 7 bytes
    Public Const DATA~BEGIN_ERROR_FLAGS = 15 * 2 + 1 '" byte
    Public Const DA TA~BEGIN_PREV_DOSE_PARAMS = 16 * 2 + 1 '16 bytes of copy of prev dosing para s
    '(used for error checKtng internal to dispenser) Public Const DATA_BEGIN_KEY_BITS = 32 * 2 + 1 'activation of keys on device
    Public Const DATA_BEGIN .IFE_COUNT = 33 * 2 + 1 ZSB in 33 MSB in 34
    Public Const DATA~BEGIN_UFE_COMPLETION = 35 * 2 + 1 '=0 wnen life cycle is programmed = 1 when life test completes successfully
    Public Const DATA BEGIN CO PENSATION_FACTOR = 36 * 2 + 1 'values from 64-192 (126= 1 0 factor)
    Public Const DATA~BEGIN~SERIAL_NUMBER = 38 * 2 + 1 '10 bytes
    Public Const DATA_BEGIN~CUSTOM1 = 4β * 2 + 1 '15 bytes of pacent/pharamc-/ ID & names
    Public Const DATA~BEGIN DtJSTOM2 = 64 * 2 ♦ 1 '16 bytes of pahentlpharamcy ID & names
    Public Const DATA_BEGIN_CUSTOM3 = 80 * 2 + 1 '16 bytes of pabent/pharamc ID i names
    Public Const DATA~BEGIN~CUST0M4 = 96 * 2 + 1 16 bytes of paύent pheramcy ID & names
    Public Const DATA_BEGIN~SCORE = 112 * 2 + 1 '"-) bytes
    Public Const DATA_BEGIN~COMPLIANCE_CHECKSUM = 128 * 2 + 1 '2 bytes Includes compliance pointer ana data
    '(up to data word 1 before data pointed to by coma pointer 
 Comm bas - File Declarations
    28
    Public Const OATA_BEGIN_COMPLIANCE_POINTER * 130 * 2 + 1 '2 bytes points to πect location after end of current comol base value = 132 (0x0084) Public Const DATA_BEGIN_COMPLIANCE_DATA = 132 * 2 *■ 1 -7900 bytes max Array of 2 bvte values for dose comαtia t, history p nce 
    'Clock time values (in 10 minutes resolution from start) when each dose was taken Represented by val βs 0-65279 (0-Oχfeff) Bach dose time is changed via the "Set Mode' a value b tw en QxffCO and QxffcS ,s wπtteπ with the LSD byte representing the dose size 'Wen comztiance memory is cleared the current dose size is always wntten as the first location in the compliance memory
    Public Sub ChaπgeBatteries equestO
    Dim rAs Integer, lErrorCode As Long, sMSG As Stnng sMSG « Υou 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 = Msgθox(sMSG vbQuestion + vbYesNo + vbDefaultButton2, "Change Battenes")
    If r = vbNo Then Exit Sub gbKeepPollingDevice = False stop polling for new
    Wait 025
    On Error GoTo Chang eBattenesRequest_Error
    data from the device again when complete " 
 'continue polling device 
 
    ChangeBatteπesRequest_Error Displa ErrorMessage lErrorCode Resume ChangeBatteπesRequest_Exrt
    End Sub
    Public Function Comm_Chec Comm(IErrorCo e As Long) As Integer
    Check the device communication by sending a command and waiting tor a reply 'If no reply is received then return a "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 net good because we would not know whether or not a failed reply is due to a oack caole incorrect comm port or settings etc Hopefully in a future version the comm check can return some sort of 'character to indicate that a common byte was received, but could not be interpreted correctly
    Dim sOut As Stnng, sChecksum As Stnng, sin As Stnng sOut = "Pp" 'this is the coαe for checking communication with device
    CreateChecksum sOut, sChecksum 'calculate a checκs*r~ sOut = sOut + sChecksum + "I" 'append checksum and ending strng identifier
    If Not frmMain CommDevtce PortOpen Then frmMain CommDevice PortOpen = True gbCommSusy = True 'prevent other procedures from communicating wtth device frmMain CommDevice InputLeπ = 0 'clear mput buffer 
 " — [~M frmMain CommDevice Output = sOut send stnng to device gbCommReplyPending = True prevent other procedures from communicating with device
    SetCommTimer giDeviceResponseWait 'set timer to wait for response
     
 slπ - frmMain CommDevice Input 
'Read response from senal oort 
  
    If slπ = "5" Then Comm CheckComm = True ret .m success to calls <■ 
    Co m_Chec Comm_£xrt If frmMain CommDevice PortOpen Then frmMain CommDevice PortOpen ~ False ' Close the senal po* gbCommReplyPending = False 'reset flag gbCommBusy = False 'reset f.ag
    End Function
    Public Function Comm_GetDeviceReply(sRep!y As String, lErrorCode As Long) As Integer' A command snoutd have been just sent to the cevice from another procedure and a reply is penώng 'Get the reply into 'sReply' and return to caller 'Return false if no reply and set lErrorCode to reason 'Return ERR_COMM_TJMEO(JT if no reply from the device error code = 0 if comm is already 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_GetOevιceRepIy_Error gbCommReplyPending •= True 'set busy flag frmMain.MousePoiπter = vbHourglass
    'Open comm port in case it is closed
    'prevent device unavailable error
    If frmMain.CommOevice PortOpen ~ False Then frmMain.CommOevice PortOpen = True 'open port sReply = "" Initreoly
    '20 milliseconds is normally sufficient • OMM TIMEOUT 'return message to caller No resαonse 
 
    First char has oeen receivec
    'Wait for all data to arnve iLastBufferCount = -1 I t ouffer count
    Do While frmMain CommDevice InBufferCount > iLastBufferCount 'characters are still amving iLastBufferCount = frmMain CommDevice InBufferCount 'remember intermediate count SetCommTimer giDeviceResponseWait this value works as low as 25 milliseconds
    - Do Until gbCommTimerExpired = True watt for timer to expire
    DoEvents DoEvents
    - Loop
    Loop 'looo if characters are st.il coming in
    'All data has arnved or time has been too long 
 Comm.bas - Comm 3etDeviceReply r - frmMain. CommOevice.lnBufferCount 'get character length sReply = frmMain. CommDevice. Input 'read stnng from buffer Comm_GetDevιceReply - Leπ(sReply) 'return bufferlength to caller (• checksum)
    Comm_GetDevιceReply_ExιL prevent device unavailable error
    If frmMain.CommOevice. PortOpen = True Then frmMain.CommOevice PortOpen = False 'c'ose port if ocen fπnMain.MαusePomter - vbDefault On Error GoTo 0 'clear error status gbCommReplyPending ~ False 'reset pending Hag gbCσmmBusy - False 'reset busy flag
    Exit Function
    Comm_GetDevιceReply_Error lErrorCode = Err 'return error coce to caller "Resume 0 'for testing only Resume Comm_GetDevιceReply_Exιt
    End Function
    Public Function Comm_ReadFirmwareVersion(DataStruct As DeviceDataStruct, IReturnError As Long) As Int
    Dim sOut As Stnng, sChecksum As Stnng, sin As Stnng, lErrorCode As Loπy, r As Stnng sOut - "W" 'this is the code for version number
    CreateChecksum sOut. sChecksum 'calculate a checksum sOut ~ sOut + sChecksum + "!" 'append checksum and ending stnng identifier
    If Not frmMain. CommDevice.PortOpen Then frmMain. CommDevice. PortOpen = True frmMain.CαmmDevtce.lnputLeπ ~ 0 'clear input buffer frmMain.CommDevice.Output a sOut 'send stnng to device r = Comm_GetDevιceReply(sln, lErrorCode)
    
    Public Sub DisplayCommError(SourceForm As Form) gbCommOK = False
    Source Form. I mg Comm Status.Picture ■= SourceForm. imgRedϋght
    SourceForm. IblCommStatus = "No Device Found"
    'Play disconnect sound and show status visually 'Set properties needed by MC! to open With SourceForm.MMControl1
    .Notify = False
    .Wart = False
    .Shareable « False
    
    'Ooen the MCI WaveAudio device Command ~ "Open" .Command - "sound" Command = "close" End With 
 uomm Das - UisplayCommError
    End Sub
    Public Sub DιsplayCommOk(SourceForm As Form) r^a connec sound and show status vtsuallv Set properties needed by MCI to open gbCommOK = True With SourceForm M ControU
    Notify = False
    Wart = False
    Shareable = False filename = App Path + "Vnorsecode wav"
    Ccen &e 'ΔC< WaveA dio de ics Command → "Open" Command = "sound" Command = "sound" Command = "close" End With
    SourceForm ImgCommStatus Picture = SourceForm imgGreenLight SourceForm IblCommStatus = "Device Ready"
    Public Sub DιsplayErτorMessage(IErrorCo e 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 i re-insert it to ensure that it is seated properly " Case ERR_COMM_CHECKSUM sMSG ~ 'Data retneved from the device is corrupted This probably occurred duππg 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 retrieved " + vbCrLf * VbCrLf + "Please obtain an updated version this software " Case Else sMSG = "An errorwas detected while communicating with the device Please try again " + vbCrLf + bCrLf + ErrorS(IErrorCode)
    — End Select
    MsgBox sMSG App ProductName + " Comm Error - " + CStr(IErrorCode)
    End Sub 
    t.omm oas - UetDrugRelNumrje.
    Public Function GetDrugRefNumber() As Integer
    'Find the tndet to the organ name being using m the global strucluie
    Dim i As Integer c For i = 1 To UBound(gsDrugNames)
    If LCase(PAT_DATA sDrug) = LCase(gsDrugNames(ι)) Then Exit For
    GetDrugRefNumber = i return ret number to caller End Function
    Public Function GetOrganRefNum erf) As Integer r;tϊc' fhe index to the organ name being using in the gtooal structure
    Dim i As Integer
    For i = 1 To UBouπd(gsOrgaπNames)
    LZ If LCase(PAT_DATA sOrgaπ) - LCase(gsOrganNames(ι)) Then Exit For Next )
    GetOrganRefNumber ~ i 'return ret πumoerto caller End Function
    Private Function lnterρretDosingData(DataStruct As DeviceDataStruct, ByVal sData As String, ByVai ^ dCheckSumTally As Double, ByVal ICheckSum As Long, lErrorCode As Long) As integer 'Parse apart the dosing data that ts passed here and put Into global structure 'Each dosmg event is 2 bytes in length. 'The checksum ts passed hem for compaπson to the stnng. 'The checksum includes the pointer bytes which is why it is passed in
    Dim sTemp As Stnng, iLowByte As Integer, IHiByte As Integer, ICurrentDoseAmσunt As Long Dim r As Integer, (position As Integer, iCount As integer, ITemp As Long On Error GoTo lnterpretDosingData_Error
     
 dCheckSumTally = dCheckSumTally Mod 65536 If dCheckSumTally = ICheckSum Then 
 -UII IMI udi> - inierpreiuosiπguata
 
    Inte retDosingData - True return success *o caller _ Else lErrorCode = ERR CO _CHECKSUM _ End If lnteφretDosιπgOata_Exιt. On GoTo 0 Exit Function lπteφretDosmgData_EπOr lE orCode = Err Resume lπteφretDosιngData_Exιt* 
    End Function
    Public Function VaiidateChecksumfByVai sData As Stnng) As Integer Look at the data stnng oassed nere and get tns crecxsum from the 'end of the stnng
    'sDATA should be a stnng ■'hat was re*vmed from the device 'The last char the stnng is a termination char preceeced oy 4 bytes of checksum
    Dim sTemp As Stnng, lByte As Integer, r As Integer, ipositlon As Integer Dim ICheckSum As Long, ICheckSumTally As Long • On Error GoTo ValιdateChecksum_Eπ"or r - Len(sData) _ For Ipositlon -= 1 To r - 5 iByte •= Asc(MidS{sOata, iposrtioπ, 1))
    7fiyfe = Clπtf&H" * MidSfsData φosition, 2))
    ICheckSumTally = ICheckSumTally + iByte 'add to checksum
    — Next tposiboπ
    ICheckSumTally = ICheckSumTally Mod 6S536 sTemp = "&H" + "0" + MidSfsData, r - 2, 2) + MidSfsData, r - 4, 2)
    ICheckSum = CLng(sTe p)
    If ICheckSumTally = ICheckSum Then ValidateChecksum = True 'pass success flag back to caller
    Validate Checksum_Exιt: On Error GoTo 0 Exit Function
    Validate Checksum_Error
    Resume ValidateChecksum Exit
    Private Sub lnterρretErrorFiags(DataStruct As DeviceDataStruct, ByVal iFlagsByte As Integer) 'Break out the bits of the flags bytes passed here 'Put the results into the global amays
    'if any flags exist then set this to twe
    If iFlagsByte Then DataStructbErrorsExist = True
    'P3rse out f.ags sβoaratety DataStructfaErrorFatal ~ (iFlagsByte And 2) DataStruct.bEiTorNonFatal = (iFlagsByte And 4) DataStruct.bErrorDoseSize = (iFlagsByte And 8) DataStruct.bErrorMedRemaiπing = (iFlagsByte And 16) DataStruct bErron emoryFull = (iFlagsByte And 32) DataStruct bErrorBrownOut = (iFlagsByte And 64) 'remaining upoer 3 bits not used at present
    
    Public Function Comm_ReadEntιreiV1emoryConteπts(DataStruct As DeviceDataStruct, IReturnError As onαl
    Dim sOut As Stnng, sChecksum As Stnng sin As Stnng. lErrorCode As Long, r As Stnng "'
    On Error GoTo Com m_ Read Entire M em oryConteπts_Error
    Erase Data InMemory DataStruct sOut = "Rr" this s the code f r rea ing entire memcrj
    CreateChecksum sOut sChecksum calculate a checksum sOut - sOut + sChecksum + ">" acperd checksum ard ending st"ng ιcsrtιrer 
    If Not frmMain CommDevice PortOpen Then frmMain CommDevice PortOpen = True frmMain CommDevice InputLen = 0 ear'nc^t butter frmMain CommDevice Output = sOut send strng >c cevice r = Comm_GetDevιceReply(sln lErrorCode) . If r Then comm was received SnO ' be at teast tnts many bvtes r - ValιdateChecksum(slπ) _ If r = False Then
    IReturnError « ERR_COMM_CHECKSUM Exit Function _ End If r - ParseMemoryContents(DataStruct, sin lErrorCode) parse our the jm g _ If lErrorCode Then
    IReturnError -s lErrorCode Exit Function _ End If
    Co mm_Re ad Entire Memory Contents •= True return success to caller DataStruct dLastDownloadDate = Now gbPatientDataNotSaved - True set this flag to true
    Else
    IReturnError - lErrorCode
    Exit Function End If ιon(DataStruct lErrorCode) 
 
    Comm_ReadEntιreMemoryCoπteπts_Exιt On Error GoTo 0 Exit Function
    Comm_ReadEntιreMemoryContents_Error IReturnError - Err Resume Comm_ReadEntιreMemoryContents_Exιt
    End Function 
    Public Function Comrn_SendResetCIockAπdBattery(|ReturnError As Long) rΘ
    'Resets the device clock to an offset that represents 1.00am 'and resets the battery timer to zero
    Dim sData As Stnng, sOut As Stnng, sReply As Stnng, sChecksum As Stnng Dim r As Integer, lErrorCode As Long, iTemp As Integer iTemp = Clnt(Format(Now, "hh"))
    If iTemp - 0 Then iTemp = 24 'micmςrt iTemp - (iTemp - 1) * 6 'calc number of iQ-mmute oeπod 'hours iTemp •= iTemp + Ctnt((FormatS(No , "nn") - 5) / 10) calc number of lC-min penods in this hcur sData = CStr(Hex(rTemρ))
    If Len(sData) < 2 Then sData = "0M + sData 'ensure stnng is alv/ays 2 oytes long
    ntifier
    
    End Function
    Public Function Comm_SeπdCustomData(DataStruct As DeviceDataStruct, ByVal sLocation As String, IReturn
    'There are 4 locations in the device, each containing a 16 byte stnng "Tiiere 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 Stnng, sReply As Stnng, sChecksum As Stnng Dim r As Integer, lErrorCode As Long, sCustomOata As Stnng Dim i As Integer, sTemp As Stnng
    'Determine the appropπate command for the location of the data to oe stored 'There are 4 fields in the device containing 16 characters each. In the oπgnal 'device design this was Intended to contain 4 sepeate 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 oe one stnng of 64 characters.
    'Data Structure Rev level = gιLEN_REV_DATA STRUCTURE
    'Patient name ~ gιLEN_PATlENT NAME
    'ID ~ gLENJD " 
    'Drug → gLEN DRUG
    TX Center - gιLEN_TX_CENTER
    'Organ = gLEN_ORGAN
    'Create a 64 byte stnng from the vaπous data elements to be saved 'This stnng ider.αfies the format of custom information, if the format 'cnanges tn a future version then this ID can be used to determine whicn version of the software saved the info to the device sCustomData =• gsREV_DATA_STRUCTURE
    'Save the 2 digit number that represents thts drug
    'To save space, a numeπcal index of the Organ name is stored m 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 nu encal tncex of the Organ name is stored in the device 
 i = GetOrganRefNumber() sTemp = CStr(ι)
    If Leπ(sTemp) < 2 Then sTemp = "0" + sTemp 'force code to be 2 digits sCustomData = sCustomOata + sTemp
    name s too long "im letters of first name D - Leπ(sTemp)) name is too short to 111 the designated length 
 sCustomData = sCustomData + sTemp concatenate res.ιιt outbound stnn.
 
    'name is too long tnm letters of first name ER - Len(sTemp)) name 'S roo shot to fill the designated length 
 'concatenate result to outbcurd stnng
 
    ame the designated length 
 
    'Assemble the stnng to be sent Select Case sLocation _ Case DATA_BEGIN_CUSTOM1 sOut = "Ww" sOata = MidSfsCustomOata, 1, 16)
    - Case DATA BEGIN CUSTOM2 sOut = "Xx* sData - MidSfsCustomData, 17, 16)
    - Case DATA_BEGIN_CUSTO 3 sOut = Υy" sData = MιdS(sCustomData. 33, 16)
    _ Case DATA_BEGIN_CUSTO 4 sOut - "Zz" sData = MidSfsCustomData, 49, 16)
    End Select
    tifier
    
    
    Public Function Comm-SendDosingParams(DataStruct As DeviceDataStruct, IReturnError As Long)
    Sends the dostng parameters from the global structure to the device
    Structure 'Ddtiuuwwwxxyyzzmmss " 'Response '$"
    "ft" is Dose Size in pumo ticKS Note that pump ticks per millititer is fi*ed at 40 Hex value from 0 to 0 ff (Maximum dose s.zs is ■rrsntl/
    5 mis or 200 decimal)
    "uu~ ' v' ~ww' "xx" ars four Dosa Interval values in hours oetween doses Hex vaiues between 1 and 0x13
    ' "y " i Number of Doses per day t-.ex value from J to 4
    ' "zz" is Pump Ticks per 10 mg Conversion vaiue Hex vsiue T z.cal value with presen' eαcaticn is 4 tιcκs per 10 milligrams
    "mm" is LocKoυt Hours vaiue Number of hours to orever.t dosing after a dose is taken
    ' Ss" ars the two cnecKsum digits (hex) equal the one s compliment value of the tw s ccmpument sum of the command characters and the data Tne ASCII values are simply addec together.n an 8 bit sum then one is subtracted (modulo 255)
    Dim iData As Integer, sData As Stnng. sOut As Stnng, sReply As Stnng Oim r As Integer, lErrorCode As Long, sChecksum As Stnng, i As Integer Dim iLastlntervalSet As Integer
    On Error GoTo 0 sOut = "Dd" 'put command in stnng
    'Get Dose Size tn ou p ticks iData - Val(DataStruct.sDoseSιze) * 40 / 100 'get dose size from gtooal struct & convert to pump ticks (convert from mg to ml) sOata -= CStr(Hex(lData)) convert value to a hex stnng
    It Leπ(sData) < 2 Then sData = "0" + sOata 'ensure stnng is always 2 bytes long sOut - sOut + sOata
    ILastlntervalSet = 1 '1 00 am is the ref time for the first dosa
    to the last one that is set
    
    'Get number of doses per day sOata = CStr(Hex(DataStructlDosesPerDay)) 'convert value to a hex stnng if Len(sData) < 2 Then sOata = "O" + sData 'ensure stnng is always 2 bytes long sOut = sOut + sOata
    'Ger conversion value
    (Data = 0 In case of error reset temp value iData =- Clπt(DataStruct.sOoseResolutιon) 'get cose resolution from global truc sData = CStr(Hex(iData)) 'convert value to a hex stnng
    If Len(sData) < 2 Then sData = "0' + sData 'ensure stnng is always 2 oytes long sOut = sOut + sData
    'Get Dose locKout nours iData = 0 'in case of error reset te o value iData = Clnt(Data Struct sDoseLockoutHours) 'get lockout hour from global struct sOata = CStr(Hex(iData)} 'coπverr value to a hex stnng
    If Len(sData) < 2 Then sData = "0" + sOata ensure stnng is always 2 oytes lc.ng sOut =- sOut + sData
    CreateChecksum sOut, sChecksum calculate a cnecksum sOut s sOut +■ sChecksum + "I" 'eopsnd checksum and ending stnng identifier 
 Comm_SendDataToOevιce (sOut) send stnng to ccmm port r = Cαmm_GetDevιceReply(sfteply, lErrorCode) HI
    If sReply = "$" Then 'stnng was successfully interpreted bv device
    Comm_SendDosιπgParams = True 'return success to caller
    Elself sReply = "7" Then stnng was not interpreted propeny
    IReturnError = ERR_CO M_8ADREΞPONSE Else
    IReturnError = lErrorCode End If
    Public Function Comm_SeπdSeriaINumber(DataStruct As DeviceDataStruct, IReturnError As Long) As Iπtegei
    Sends the senal number from the glcoal stnscture to die device
    Dim sOata As Stnng. sOut As Stnng, sReply As Stnng, sChecksum As Stnng Dim r As Integer, lErrorCode As Long first 16
    r
    
    End Function
    Private Sub ConvertHexStringToAsciϊ(ByVal sData, sConverted As String)
    'Stnng Data from the device is usually returned as Hex characters Convert the sir.ng (passed in here) to an ASCII st.nng and return to caller 'Such stπngs are items like paπent name, senal number, etc
    
    End Sub 
    Private Sub CreateChecksum(sOut As String, sChecksum As String) z Θ
    'The stnng 'sOut" will be sent to the device by another procedure Before it is sent 'this procedure calculates a Checksum and returns it to 'he caller 'Return the ASCII representation ctthe checksum value
    Dim i As Integer, ICheckSumTally As Long. iChecksumByteLow As Integer
    For i = 1 To Len(sθut) 'calculate cnecKsum
    ICheckSumTally = ICheckSumTally * Asc( ιdS(sOut. i, 1 )) Next i iChecksumByteLow = ICheckSumTally Mod 256 iC ecksumByteHign = ICiiecksumTaliy \ 256 ιor being using by We cevice sChecksum = Hex(ιChecksumByteLow - 1 ) 'checksum is 'he 'one s complement value of a hvo s complement checksum ' 
    /alue must always be 2 chars
    If Len(sChecksum) < 2 Then sChecksum = "0" * sChecksum piece a leading '0' in front of checksum
    End Sub
    Public Sub Establish Device Comm ()
    'This crocedurβ continues to try and establisn communication with the Device until it succeeds When successful control ts 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 
 
    End Sub
    Function Comm_lnitialϊzeCommPort() As Integer
    'Get the imtsl values from INI file and 'Initialize device comm port settings
    Dim IRepty As Long
    Const sSection = "Communications"
    'Get the amount of time needed for a reply to be received from the device giDeviceResponseWait = Clnt(GetINISettιng(gsApplnιFileSpec, sSection, "Device Response Watt", "SO")) If giDeviceResponseWait < 25 Then giDeviceResponseWait = 25 'set a minimum delay tme
    If giDeviceResponseWait > 500 Then giDeviceResponseWait = 500 ' amp upper limit frmMain.CommTimer Interval = giDeviceResponseWait sat up the timer
    'Get the ccmm port speed settings giCommPort ~ Clπt(GetlNISettιng(gsApplnιFιleSpec, sSection, "Port", "1"))
    If giCommPort = 0 Then giCommPort = 2 'sef a derauit of comm 2 if nothing is in the *.;a gsCommDeviceSettings * GetlNISettιng(gsApρlnιFtleSpec, sSection, "Settings", "2400,^8,2") prevent device unavailable error
    If frmMain CommOevice PortOpen - True Then frmMain.CommDevtce PortOpen = False 'close pon it open frmMain CommDevice Settings = gsCommDeviceSettings frmMain CommDevice CommPort = CStr(gιCommPort) 
 frmMain.CommOevice InBufferSize = 1024 frmMain. CommDevice.lnputLen = 0 Comm nitializeCommPort ~ True return success to caller
    Comm_lnιtιalizeCommPort_Exιt Exit Function
    CommJnιtιalιzeCommPort_Error CommJnitializeCommPort = Err "return error to caller On Error GoTo 0 Resume Comm ImttalizeCommPαrt Exit
    End Function
    Sub Device_OnComm() Tnis orocedure is cailed by the OnComm evenet of the comm control located on frmMain This is so that the cede can be shared oetween apolica oπs
    Dim r As Integer, sTemp As Stnng r ~ frmMain. CommDevice.CommEvent
    Itr - MSCOMM_ER_RXOVER Then
    'An overrun error occured Ususally happens when getting events 
 ltr ~ MSCOMMJ=V_EOF Then 'end of f..'e flag received
 
    Exit Sub 'who cares Happens dunng receipt of events
    End If 'break signal received 
 tf r - 3 0rr = 4 0rr = 5 Then 'rts xon xoff. CD error 
 
    MsgBox "Unexpected error occured with the device Piease try again " . "Comm Event - * + StrS(r) 
    
    Private Sub interpretScoreData(DataStruct As DeviceDataStruct, ByVai sData As String, ByVal iCurrentDa Get score data and place into global structure Seems that the pointer :s 0 based ayrC
    'The value is from 0 to 4 doses taπen per day A vaiue of "S.HFF" means that 'he ak.e is cleared and not set yet
    Dim i As Integer, sTemp As Stnng, iTempPoiπter As Integer iTempPoiπter = iCurrentDayPomter + 1 start vι"ι 
fhe current a days or data ce' score for this dav (2 owe save sco<-e 
 * 2 end of circular ouffc Start at oottor- 
 
    End Sub
    Pπvate Function ParseMemoryConteπts(DataStruct As DeviceDataStruct, sAIIData As String, lErrorCode As !
    Gπ Error Resume Next
    Dim I As Integer, sDoseOata As Stnng, ICheckSum As Long
    Dim sTemp As Stnng, sConverted As Suing, ITemp As Long, r As Integer, sCustomData As Stnng
    Dim sLastlntervalTime As Stnng, iStartingLocatioπ As Integer
    ReOim sTempϋst(25) As Stnng
    On Error GoTo ParseMerπoryCαπtents_Error
    'Gef Clock
    '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 = "&H" + "O" + MldSfsAIIData, DATA_BEGIN_CLOCK + 2, 2) ♦ MldSfsAIIData, DATA_BEGIN_CLOCK, 2)
    'calculate back to the date and time the clock should have started
    DataStruct.dDeviceRefDateTime = CDbl(DateAdd("n", -<CLng(sTemp)) * 10, Now))
    DataStruct.lDevicelnitDate = CLng(DataStruct.dDevιceRefDateTime)
    'Gef Battery Change Timer sTemp = "&H" + "0" ♦ MldS(sAIIData, DATA_BEGIN BATTERY CHANGE_TlMER + 2, 2) ♦ MldSfsAIIData,
    > DATA_BEGIN_BATTERY_CHANGE_TI ER, 2)
    ITemp = CLng(sTemp) / 6 'convert to hours (there are δ "ten-minute ' intervals in one houή DataStructsBatteryChangeTimer = For atSfCStrflTemp / 24), "##0.0 days") 'convert to days and store it
    'Get Dosing Event Data sTemp = "&H" + "0" + MldSfsAIIData, DATA BEGIN_COMPLIANCE POINTER + 2, 2) + MιdS(sAIIData, . DATA_BEGIN_COMPLIANCE_POINTΕR, 2) 'get pointer ITemp = CLng(sTemp) 'convert hex value to a long value
    If ITemp Then sDoseData = MldS(sAIIData, DATA_BEGIN_CO PLIANCE_DATA, (ITemp - 132) ' 2) getstπrg
    'Get Compliance Checksum sTemp = "&H" + "0" * MldSfsAIIData, DATA BEGIN_COMPLIANCE_CHECKSUM ♦ 2, 2) ♦ MldSfsAIIData,
    > 0ATA_BEGIN_COMPUANCE_CHECKSUM, 2) ICheckSum = CLng(sTemp) r - InterpretDosingDatafDataStruct, sDoseData, ITemp, ICheckSum, lErrorCode) 'parse out the events and place in gloύal structure
    If r = False Then 'bad hecksum data
    LZ GoTo ParseMemoryCαπtents_Exιt End If
    Gel Patient Score Data sTemp = MldSfsAIIData, DATA_BEGIN_SCORE, 28) parse the 14 days of dosing and store in global structure If LenfsTemp) > 0 Then
    ITemp = CLngfSHO" * MldSfsAIIData, DATA_BEGIN_DOSE_SCORE_DAY_POINTER, 2)) 
 If ITemp Then IπterpretScoreData DataStruct, sTemp, Clnt(ITemp) parse out the scores and place in global structure End If
    Get Error Flags sTemp = MldSfsAIIData, OATA_eEG(N_ERROR_FLAGΞ, 2)
    If Len(sTemρ) > 0 Then InterpretErrorf lags DataStruct, Val(sTemp) 'patse out the Hags and save in glcoai struct re
    'Get Medication remaining in device sTemp = "&H0" + MldSfsAIIData, DATA_BEGIN_MED_REMAINING + 2. 2) + MldSfsAIIData. DATA_8EGIN_MED_REMAINING 2)
    OataStruct sMedRemaiπing = CStr(CSng(sTemρ / 40) * 100) + " mg" pump ticxs are fixed at 40 per mϋlάter (IGG mg υer ml,
    'Get Dose Lockout Hours sTemp = "SHO" + MldSfsAIIData, DATA_BEGIN X)SE_LOCKOUT_HOURS, 2)
    DataStruct.sDαseLockoutHours ~ CStrfCSngfsfemp))
    'Gef Doses per day sTemp = "&H0" + MldSfsAIIData, DATA_BEGIN_DOΞES_PER_DAY, 2)
    DataStruct.iDosesPerDay - Clnt(sTemp)
    'Gef Dose Resolution sTemp -= "-&H0" + MldSfsAIIData, DATA_BEGIN_DOSE_CONVERSION, 2)
    DataStruct.sDoseResolution = CStrfCSπg(sTemp))
    Gef Dose Inter/als sLastlntervalTi e •= "1.00" RVAL1, 2) 'the first dose is relative to 1.00 am
    indicates that no time was received 
 2) first dose is relative to 1.00 am
 
    s that no time was received 
 
    relative to 1.00 am
    
    dose is relative tc 1 00 am
    t no time was received
     
 Comm.bas - ParseMemoryContenti, sTe p - "&H0" + MldSfsAIIData. DATA_BEGIN_DOSE_SIZE. 2) If IsNumeπcfsTemp) Then
 
    DataStruct.sDoseSi∑e =• CStrfCSng(sTemp) / 40 * 100) convert frcm mg to ml Else
    DataStruct sDoseSize → ""* End If
    'There are 4 fields ..n the device containing IS characters each In the or.gmal device cesign this was intended to contain seceate pieces of information The client has now decided that some fields are roo short and others are too r.g 'Thus the tielcs a e combined to be one stnng of 64 craractsrs
    Patient name - giLEN PATIENT _NAME
     •ID = gtLENJD ~
    Drug = giLEN_DRUG Canter = g:LΞN_TX_CEN7~P
    Organ = gtuΞ ^ORGAN
    Send a message to the user if the revision /eve: i πcr.er han the one fhts software :s using to send custom data to the device
    '~he user must upgrade to the cu ent version is order to get accurate custom data
    'This co a should also handle any previous versions that sa*ad csta to trs device
    Get Custom stnng 1 sTemp = MldSfsAIIData, DATA_BEGIN_CUST0M1, 32) ConvertHexStπngToAscfi sTemp, sConverted sCustomData = sConverted
     *Gef Custom stnng 2 sTemp = MldSfsAIIData, DATA_BEGIN_CUSTOM2, 32) CoπvertHexStπngToAscii sTemp, sConverted sCustomData = sCustomData + sConverted
    Get Custom stnng 3 sTemp ~ MldSfsAIIData, DATA_BEGIN_CUSTOM3, 32) ConvertHexStπngToAscii sTemp, sConverted sCustomData = sCustomData + sConverted
    'Gef Custom stnng 4 sTemp = MldSfsAIIData, DATA_BEGIN_CUSTOM4, 32) ConvertHexStπngToAscϋ sTemp, sConverted sCustomData - sCustomData + sConverted
    Full apart the 64 char stnng into its sub-components
    'Get the custom data structure revision level that was previously saved to the device
    'Note this is not the same as the major and minor versions of the host software iStartingLocatioπ ~ 1 sTemp = MldSfsAIIData, iStartingLocation, gιLEN_REV_DATA_STRUCTUR£)
    ConvertHεxStππgToAscii 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 tne real name of the Drug by the reference number received from the device iStartingLocation = iStartingLocatioπ + gιLEN_REV_DATA_STRUCTURE sTemp = TπmfMidSfsCustomData, iStartingLocation, gtLEN_DRUG)) r = ValfsTemp)
    If r > 0 And r < UBoundfgsDrugNames) Then DataStruct sDrug - gsDrugNamesfr)
    'Determine the real name of the Organ by the reference number received from the device iStartingLocation ~ iStartingLocatioπ + gιLEN_DRUG sTemp = Tπm(MιdS(sCustomData, iStartingLocation, gιLEN_ORGAN)) r = ValfsTemp)
    If r > 0 And r < UBoundfgsOrganNa es) Then DataStruct sOrgan = gsOrgaπNamesfr) iStartingLocation = iStartingLocatioπ + gιLEN_ORGAN 
 Comm bas - ParseMemoryConteπts
    OataStruct sPatientlD =- TπmfMldSfsCustomData, iStartingLocation, giLENjD)) iStartingLocation - IStartingLocation + giLEN D
    DataStruct sTxCenter --* TπmfMidSfsCustomData, iStartingLocation, gιLEN_TX_C ENTER)) iStartingLocation = iStartingLocation + gιLEN_TX_C£NTER r = ParseDelιmStπng(Tπm(MιdS(sCustomData, isTartingLocation, gιLEN_PATIENT NAME)), ",", sTempListf))
    DataStruct sPatieπtLastName = TπmSfsTempϋst(l ))
    DataStruct sPatientFtrstName =• TπmSfsTemρϋst(2))
    Get Senal Nu oer sTemp = MldSfsAIIData, DATA_BEGIN_SERIAL_NUMBER, 20)
    ConvertHexStπngToAscii sTemp. sConverted
    DataStruct sSeπalNumber = Tπm(sConverted)
    ParseMemoryContents = True 'se.nc success to cai.'ei
    ParseMemoryContents_Exιt On Error GoTo 0 Exit Function
    ParseMemoryContents__Eiτor tor s a cnecksum error here because any type of error is likely cue to a cnecKsum probie^i lErrorCode = ERR_COMM_CHECKSUM Resume arse Memory Co ntents_Exιt
    End Function
    Public Sub PoIlDeviceContiπuaIly(SourceForm As Form)
    This procedure continues to try and establish communication wth the Device 'until it succeeds When successful control is returned to the calling prccecure 'The purpose of this procedure is to allow the user to try cable changes device movement etc without having to continue pressing keys on the keyboard
    Dim r As Integer, bPrαcedurelπProgress 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
    QueryDevice
    DoEvents 'allow other Windows events to be processed so we dor. t lock uo the computer
    „ need to poll as often if cevice was worxing 
fhe last time we checked amount of time before trying _ 
 
    Wait 0 05 'poll faster until a good comm ts made _ End If
    'poll only if oort not busv
    
    Wa't 005 'allow pcl'ing icon to be viewed If gbKeepPollingDevice = False Then Exit Sub 
 Comm bas - PollDeviceConliπually
    SourceForm tmgPollmg Visible = False
    If r = ERR_COMM_TlMEOUT Then 'send an additional error message (hat 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
    /Tag nas not oeen reset vet
    If gbKeepPollingDevice Then GoTo QueryDevice try comm again bProcedurelnProgress = False 'allow future calls to this prcedure now Via' Λ are finished
    End Sub
    Public Sub Comm_SendDataToDevice(ByVal sOut As String) Dim dGoAheadTime As Double
    'A data stnng snoutd have been assembled oy another procecure and is now ready to sent to the device
    ere
     
 gbCommBusy = True 'sat busy flag (gets reset if timeout or replv not received) if comm pαrtts not open then ooen it
 
    If Not frmMain.CommDevice PortOpen Then frmMain. Co mm Dev ice. Port Open = True frmMain CommDevice IπputLen - 0 'clear input buffer frmMain CommDevice Output = sOut 'send stnng to device
    Private Sub SetCommTimerfiTime As Integer)
    Trie comm timer determines whether or not a reply has come back from the device Tne timer fires an event if the ITimβ 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 άsaoie timerwhile resetting it frmMain CommTϊmer Interval = ΪTime 'setmterva! gb Comm Tim erExptred = False 'reset timer expiration Hag frmMain.CommTimer.Enabled = True 'start timer 
    Comm.bas - SetCommTimer
    Attribute V8_Name * "modPnntlng" ^ Option Explicit
    Public gbPππtFormLoading As Integer
    Public gbPnnterErrorDetected As Integer
    Public giTotalPπntPages As Integer 'track the πumoer of pages being pnevewed
    Public gbPreventPreviewUpdates As Integer
    Public giPnntedPageNumber As Integer
    Public gbPageNumberSuspend As Integer ':f 'rue don I pnr.t page nυmoer or the active page (probably co r picture)
    Public giFontOptSel As Integer Public gsSelectPnntPages As Stnng Public gbPππterError Received As Integer ieiis omer orocs that error occurred Prcc must reset flag Public gbPnntSpoolmglπProgress As Integer 'orsveηr crashes dunng spooling
    Private Sub btnPrinter_Previevv_C!ick_Proc()
    It gTotatPππtFages > 1 Then there is mere than one page to pnnt frmSelectPagss Snow MODAL Select Case gsSelectPnntPages Case 'All" frmPπnt MousePomter = vbHourglass gbPπntSpoolinglnProgress *-• True frmPπnt vsPnnterl .Action = paPππtAil 'pπnt al! cages gbPπntSpoolinglnProgress = False
    Case 'Page' frmPnnt.MouseFαnter = vbHourglass gϋPnntSoooliπglnProgress - True frmPπnt vsPnnterl Action - paPnntPage 'pπnt current page only goPπntSpooltnglnProgress = Faise
    Case " 'nothing to do goPnniSpoolinglnProgress = False End Select
    Else 'pπnttπg a single page that is not a picture frmPπnt MousePomter = vbHourglass gbPnntSpoolmglnProgress = True trmPr.nt.vsPnnten Action = paPnntAll 'pnnt all pages gbPnntSpoolinglnProgress = False
    End If 
    ny udi> DinPπnler_Prevιew c, Proc
    frmPπnt btnClose Enabled ~ True aUow bυrdn to show frmPπnt btnPπntNow Enabled = True frmPππt MousePomter - vbDefauIt DoEvents
    Private Sub DrawHoπzontaiLinefcPπnter As Contro/, IPenColor As Long) fι~"F-nt vsPnnterl Fon'Sιza •= dgβcdy'e tStze tτm0"nt vs^nntsr = " saa a tine 'ron aoc e
    £\ti Suo
    Draw a onzontsl d sidar on the page
    Usja ly divices the neaαer or too c fro ™ ψe -"es of « e Cage cPnnter FontSize = 12 cPπnter = "" skip a ire 'rcn aoo/e cPπnter PenStyle •= 0 O=solιd 2-dot cPππter PeπWidtπ = 10 set pen wtdt cPπnter PenColor = IPenColor set per coic cPπnter BrushColor ~ IPenColor
    Pnr-'lne only across a poncn of page cPπnterXI = (cPπnter PageWidth / 2) - (cPππter PageWidth * 025) cPπnter α •= fcPππter PageWϊdth / 2) + (cPnnter PageWidth " 025) cPπnter Y1 = cPππter CurrentY cPπnter Y2 -= cPππter CurrentY + 50 cPππter Draw •= 2 1=lιπe 2-rectangte
    End Sub
    Private Sub PrιntAIIPatιeπtsSummary()
    Dim i As Integer lErrorCode As Long sTableFormat As Stnng s able As Stnng sϋst As Stnng Dim fFoπtSize As Single iCount As Integer
    On Error Resume Next
    Prepare progress guage With frmPππt pπlProgress FloodPercent - 0 pnlProgressCoπtainer Visible = True pnlProgressCoπtaiπer Refresh End With iπitPageProperties fFontSιre = 10 pπrt the lego on t e first cage With frmPnnt vsPnnterl
    X1 = 700
    X2 = frmPnnt vsPnnterl X1 «• frmPππt picLogo Width
    Y1 = 500
    Y2 - frmPπnt vsPnnterl Y1 + frmPπnt picLogo Height
    Picture = frmPπnt picLogo Picture End With
    Pπrt informal on Header gbPageNumberSuspeπd = False With frmPnnt vsPnnterl 
 
    TextAlign = taCenterTop center text used n paragraphs
    CurreπtY = 1440 * 1 pnnt name on this line
    FontSize = fFoπtSize ' 1 6 set 'on size
    Fontltalic = True frmPnnt vsPnnterl = "All Patient s Summary" pn- name
    FontSize = (FontSize * 1 2 set font s.;°
    Fontltalic = False
    DrawHoπzontalϋne frmPπnt vsPnnterl SH40000 Draw a color in- frmPπnt vsPnnterl = — skip a -e frmPnnt vsPnnterl = fπnAIIPatieπts cmboDataToView Text * " with " ♦ frmAIIPatieπts Label1(0) Caption frmPnnt vsPnnterl = "Date Range " * frmAIIPatients cmboDateSelectioπ Text + " from frmAIIPatients txtStartDate Value * " to
    ♦ frmAIIPatieπts txtEndDate Value frmPπnt vsPnnterl - "" Sι<ιp a ire TextAlign = taCenterTop FontBold = False TableBorder = tbNoπe FontSize = fFontSrze ' 1 f set font size Table = sTable send out taole frmPnnt vsPnnterl = ~ kip a li e frmPπnt vsPπnten = ~ skip a line UneSpacing = 90 % of currert for TextAlign - taCenterTop cen ertext End With
    Pπnt the report Data sTableFormat = "<2400|<1800|>1700|>1700|>1000 " Gef tne column titles from gnd With frmAIIPatients gnd Row = 0 Col = 0 sList = Text Col = 1 sϋst = sList + "|" * Text Col = 2 sList = sList + "|" + Text Col = 3 sϋst = sList + "|" + Text Col = 4 sList = sϋst + "|" ♦ Text End With sTable = sTableFormat + sList
    With frmPnnt vsPnnterl
    TableBorder = tbBottom
    FontSize = 10
    FontBold « True
    Table - sTable send out header frmPππt vsPnnterl = - End With
    Pπrt the information f-om the gnd control With frmAIIPatients gnd iCount = Rows - 1 ount number of patients m gnd + Text ♦ "|" + Text + "|" -*• Text + "|" ♦ Text 
 
 sTable - sTableFormat + sList With frmPπnt vsPnnterl
 
    FontSize = fFαntSize " 09 set 'ort size
    LiπeSpacing ~ 80 % of cursnr fonf 
    TextAlign = taCenterTop
    TableBorder - tbNone
    Table = sTable sθ"G out faL'e
    End With
    On Error GoTo 0 frmPππt pnlProgressContamer visible ~ False t, * o" progress indicator frmPnnt pnlProgressContamer Refresh
    Private Sub PnntPatientDosingReportf)
    Dim i As Integer lErrorCode As Long sTableFormat As Stnng sTable As Stnng, sϋst As Stnng Dim fFσntSize As Single iCount As Integer bltemChecked As Boolean
    On Error Resume Next
    Pπnt Cover Art to the Pπnt preview control if needed and available If frm°πnt IbP ctures Ustlndex -> 0 Then a cover is chosen If Ftie6x!sts('covers\' * sgCurrertCoveπVa e ΕrrorCode) Then look for a bttrraα on disk Pπnt preview the Picture gύPagβNυmberSυspeπd ~ True LcadPictureTαPnnterCσntroi True get cover initPageProperttes frmPnnt vsPnnterl Action ~ 4 start a new page gbPageNumberSuspend ~ False
    End If E-dlf
    Prepare progress gυage With frmPπnt pnlProgress FloodPercent =• 0 pnlProgressContamer isible ~ True pnlProgressContamer Refresh End With
    IπitPageProperties fFontSize = 10
    Pπnt e lego on *he Irst page With frmPππt vsPnnterl
    X1 = 700
    X2 = frmPπnt vsPnnterl X1 + frmPππt picLogo Width
    Y1 =- 500
    Y2 ~ frmPnnt vsPnnterl Y1 + frmPπnt picLogo Height
    Picture = frmPπnt picLogo Picture End With
    Pπnt Information -aader gbPageNumberSuspend = False With frmPπnt vsPnnterl FontName = "Anal" 
    
    End With sTableFormat = "<14O0|<2S00|<14O0J<2800 " sTable •= sTableFormat + gsCustomLblPatientlD + " f + PAT_DATA sPatientID + sTable -= sTable + gsCustomLblTxCenter + " |- + PA T_DATA~sTxC enter + " " sTable = sTable + gsCustomLblDrug + " f + PAT_DATA sDrug + "I" sTable ■* sTable + gsCustomLblOrgan + " |" •*■ PAT_DATA sOrgaπ + " "
    With frmPπnt vsPnnterl frmPππt vsPnnterl ~ *"* s ip a lire
    TextAlign ■= taCenterTop
    FontBold ~ True
    TableBorder •= tbNone
    FontSize → fFontSize * 1 1 set font size
    Table = sTable send out table frmPnnt vsPnnterl = ™ skip a line frmPnnt vsPnnterl = ™ skip a line
    LmeSpacing = 90 % of current font
    TextAlign = taCenterTop center text
    
    
    Pπnt the report Data frmPπnt vsPnnterl = ~ a line frmPππt vsPnnterl TextAlign •= taCenterTop PnntDosingEveπtsHeader sTableFormat Pnnt (he ntorr-aαoπ 
fmm the gπd control With frmPatientDosingReport gπd tCount = Rows - 1 sϋst = — - For i = 1 To iCount ~umber of patie
nts m gπd 
 sTable - sTableFormat -*
• sList With frmPnnt vsPnnterl
 
    FontSize = fFontSize * 09 se' fonι s.ze ϋneSpa πg = SO % of current font
    TextAlign = taCenterTop
    Table = sTable send out table
    End With
    On Error GoTo 0 frmPnnt pnlProgressContamer Visible = False turn of progress indicator frmPnnt pnlProgressContamer Refresh
    End Sub
    Sub PπntDosιπgEventsHeader(sTableFormat As String) Dim sTable As Stnng Dim fPrevFont As Single, bPrevBold As Boolean, sϋst As Stnng fPrevFoπt = frmPπnt vsPnnterl FontSize
    Pnrt the πforration from the gnd control Pass table format back to caller sTableFormat = "<2100|<1600|<1000|<1700|<1700|<1700 " With frmPatientDosingReport gπd sList = "" Row = 0 Col = 0 sList = sList + Text Col = 1 sϋst = sList ♦ 
■"" ♦ Text Col = 2 sList = sList + "I" + Text Col = 3 sList = sList + "I" ♦ Text Col = 4 sList = sList + "I" + Text Col - 5 sList = sList + "J" + Text + " " End With sTable = sTableFormat + sList frmPnnt vsPnnterl TableBorder = IbBottom frmPπnt vsPnnterl FontSize = 10 frmPπnt vsPnnterl FontBold = True frmPπnt vsPnnterl Table = sTable send out header frmPnnt vsPnnterl = "
* 
 
    'Put setting back to previous ones frmPrint.vsPnnteii. TableBorder - tbNone frmPπnt.vsPπnterl. FontSize = fPrevFoπt frmPπnt.vsPπnterl. FontBold = bPrevBold
    Public Sub LoadPictureToPrinterControl(ByVal bCover) 'Set the pnr.ter control to size a cicture and cocy picture from nolding area to the oπnt preview control If the picture to oe cisciayed is a cover 'tn.en the bCover flag should oe set to true by caller Otherwise it is assumed to be a borce1'
    Dim tPaperWϊdth%, ιPaperHeιght%, ιNonPπntWidth%, ιNoπPπntHetght% frmPπnt.vsPπnterl .PhysicalPage = True 'set physical page to paper dmens:on iPaperV dth - frmPnnt vsPnnterl .PageWidth 'determine size of pacer iPaperHeight = frmPπnt.vsPππterl.PageHeight frmPπnt vsPnnterl PhysicalPage = False 'return pnr.ter to pπntaoie area iNonPπntWidth - (iPaperWidth - frmPπnt.vsPπnterl .PageWidth) / 2 iNoπPπntHeight = (iPaperHeight - frmPπntvsPπnterl PageHeight) / 2
    If iNonPπntWidth < 350 Then iNonPπntWidth = 350 'make a minimum margin If iNonPππtHeight < 350 Then iNαπPπntHeight = 350 make a minimum rr.arg frmPπnt.vsPπnterl ,X1 = iNonPπntWidth frm Pπnt .vsPnnterl .X2 -= frmPπnt.vsPnπtert .PageWidth - iNonPπntWϊdth frmPnnt.vsPnnten.Y1 = tNoπPππtHeight frmPπnt.vsPπnterl .Y2 =■ frmPπnt.vsPπnterl. PageHeight - iNonPπntWidth
    ' frmPπnt vsPnnterl Draw = 2 'picture holder only frmPπnt.vsPπnterl .Picture = Load Picture("gra hies V & "deco mf)
    End Sub
    Private Sub InitPageMarginsf)
    'Sef margins
    'Margins dont seem to set properly until the next page is created
    'Thats why they can be set only once before pππting begins frmPnnt vsPnnterl. Margin Top = 1350 'fop margin frmPπnt.vsPπnterl. MargmBottom ~ 1500 'bottom margin frmPnnt.vsPπntert.MarginLeft = 1725 left margin frmPπnt.vsPπnterl .MargmRight - 1700 'πgnt margin (from nght ecge)
    End Sub 
    r-τιπtιng Das - iπitr'dytjriuμt.uieb
    Private Sub IπitPageProρerties()
    'Reset margins for text and initialize other items frmPππt. sPnnterl ϋneSpaciπg = 100 '100% of current font
    Set the normal attnbutes here frmPnnt vsPnnterl TextAlign = 0 set centenng oack normal End Sub
    Private Sub PriπtPageDate() rππ.' Dare
    Dim ITextHeight As Long, ITextWϊdth As Long, sTextS 'pnnt date for the above tabs on.iy
    'Rather than using TextAlign property, text is cemered rere using this method to ensure page centenng regardless of margins or paragrapn settings InitPageProperties frmPπnt.vsPπnterl FontName = "Anal" frmPπnt vsPnnterl FontSize = 8 sText = "Pπnted " + DateS + " with " + App.Title + " software " frmPnnt vsPnnterl Measure = sText 'ser srππg ;c measure
    ITextHeight ~ frmPπnt vsPπnteii.TextHei get text height
    ITextWidth = frmPπnt vsPnnterl .TextWid 'get text width frmPnnt.vsPπnterl.CurrentX = (frmPππt vsPnnterl PageWidth - ITextWϊdth) / 2 If frmPπnt.vsPnnterl .CurrentY < 13000 Then frmPπnt vsPnnterl. CurrentY = fr Pnnt. vsPnnterl PageHeight - (frmPnntvsPnnterl MarginBottom + (2.5 * ITextHeight)) set are *o s
    V bottom Else frmPπnt.vsPπnterl. CurrentY = frmPnntvsPnnterl .PageHeight - (frmPnntvsPnnterl .MarginBottom + (0.1 * ITextHeight))
    V bottom End If frmPnnt vsPnnterl - sText sText = "Copyπght 1993 by SangStat Medical Corporation" frmPπnt.vsPπnterl .Measure = sText 'sef stnng to measure
    ITextWidth = frmPnntvsPnnterl .TextWid 'get text width frmPπnt sPnntert CurrentX = (frmPnntvsPnnterl PageWidth - ITextWidth) / 2 frm Pπnt. vsPnnterl « sText
    next time * ", ' + PAT DATA sPatientFirstName + " " + she 
 
    End Sub 
    Printing bas - RefreshPreview
    Public Sub Refres Prevιe ()
    Static bRefreshPreviewlnProgress As Integer prevent recursive calls to ere If bRefreshPreviewlnProgress = True Then Exit Sub If gbPreveπtPreviewUpdates Then Exit Sub bRefreshPreviewlnProgress = True frmPπnt MousePomter = vbHourglass frmPπnt HScrolll Enabled = False frmPπnt HScrolH Refresh frmPππt HScrolM Value = 1 DoEvents
    On Error GαTo 0 
 frmPπnt btnRefresh Enabled = False frmPπnt btnRefresh Refresh frmPπnt btnPπntNow Enabled = frmPnnt btnPπntNow Refresh frmPπnt btπClose Enabled ~ disable 
 un" ore raw ouitd is ccmolata frmPπnt btnClose Refresh frmPπrt btn
=ormat Enabled = frmPnrt otnFomat Refresn DoEvents giTotalPπntPages = 0 reset the page counter giPπntedPageNumber = frmPπnt vsPnnterl Preview ~ True pπrt to screen frmPπnt vsPnnterl Footer = "" Gear rΛe footer frmPnnt vsPnnterl HdrFontName = 'font name goes hers' Controls footer also trmPrnt vsPnnterl HdrfontSize = ?
? Controls footer also
 
    Send information to the preview screen
    Initialize cnntjoo
    InitPageMargins
    If gbPnnterErrorDetected Then GoTo RefreshPrevιew_Exιt frmPnnt vsPnnterl PreviewPage = 1 show 1st page frmPπnt vsPnnterl PreviewMαde = 0 0=sceen compatible 1=ρnnt compa* 2 = force mcrαchror~e frmPnnt vsPnnterl PageBorder = 0 no page border frmPnnt vsPnnterl TextAlign = 0 left align (e *
    " Call LoadαιctureToPπnterCoπtrot(False) Select Case gsActive Form Name
    _ Case "frmPatientSummary"
    - Case 'frmAIIPatients"
    Call PπntAIIPatieπtsSummary
    Case "frmPatientDosingReport" Call PπntPatientDosiπgReport
    End Select
    PπntPageDate pnnt date tor as* r ci e frmPnnt vsPnnterl Action = paEndDoc frmPnnt vsPnnterl Visible = True says ooiect does not suooort this method ήmFnnt vsPi nterl Refresh Call Update Page Buttons 
 Printing. as - RefreshPreview frmPππt HScrolH Max = giTotalPπntPages — Θ
    RefreshPrevιew_£xιt: frmPπnt btnClose. Enabled = True eπaoie outtons DoEvents bRefreshPreviewlnProgress = False ailow future calls to this procedure frmPπnt btπPπntNow.Enabled = True frmPπnt MousePomter = vbDefault DoEvents
    Public Sub SetPreviewSize()
    Dim bHeιghtLιmιt%, fTemp As Single frmPπnt MousePomter = vbHourglass
    ' frmcr.nt Refresh 'a refrasn of the rcrm causes controls inside a frame to disaccear frrr.°nπt vsPnnterl Visible = False frmPnnt vsViewPortl Visible = False DoEvents
    If (frmPπnt vsPnnterl .PageHeight / frmPπnt vsPnnterl .PageWidth) > (frmPππt vsViewPortl Height / frmPnnt vsViewPortl Width) Then ^ bHeightϋmit ■= True Select Case frτnPπntoptZoom(O). Value Case True 'full page view
    „ If bHeightϋmrt = True Then 'there is a height restπction in the viewooK control for this cnnt oπentation frmPnnt. vsPnnterl .Height -= frmPπnt. vsViewPortl .Height * 0.99 fTemp = frmPnntvsPnnterl .PageWidth / frmPπnt.vsPπnterl. PageHeight
    (Temp = frmPnntvsPnnterl .Height • fTemp frmPnntvsPnnterl .Width - fTemp Else frmPπnt.vsPπnterl .Width = frmPπnt.vsViewPortl.Wϊdth • 0.99 fTemp β frmPnntvsPnnterl .PageHeight / frmPnntvsPnnterl. PageWidth fTemp = frmPπnt.vsPnnterl .Width * fTemp frmPπnt.vsPπnterl .Height - fTemp End If
    'Make viewpod virtual screen large enough to snow full page of pπnt control frmPnπtvsViewPortl VirtualWidth = frmPπnt vsPnnterl .Width * 1 frmPπntvsViewPortl .VirtualHeight = frmPnntvsPnnterl .Height * 1 frmPπntvsViewPortl.BorderStyle = 1 'turn off border Case Else 'Magnify view frmPπnt.vsPπnterl .Width = frmPπnt vsPnnterl .PageWidth * 1 frm Pnnt. vsPnnterl .Height ~ frmPπnt vsPnnterl .PageHeight * 1 fr Pnnt. vsViewPortl .VirtualWidth * frmPπntvsPnπterl.Wtdth * 1 'ensure scroll bars v/iil be shown frmPπntvsViewPortl .VirtualHeight = frmPπnt.vsPπntert .Height * 1 fr PπntvsVtewPortl.BorderStyle = 0 'turn on border End Select frmPnnt vsPnnterl. Visible = True frmPπnt vsViewPortl .Visible = True frmPnnt vsViewPortl Refresn frmPπnt MousePomter = vbDefault DoEvents
    End Sub 
     
 * CStr(frmPππt.HScroll1.Value) <- " of " * CStr(gιTαtalPπntPages) scroll oar needed tor a single page
 
    
    Attπbute V8_Name = "modFax" Option Explicit
    Public gcFax As Control
    Public gsFaxFileSpec As Stnng
    Public gsEditName As Stnng a le pc rary p. ace to notd 'a names being edited or ceated
    Public gsEditVoice As Stnng
    Public gsEditFax As Stnng
    Public gsEditGrouplndexes As Stnng nolcs 'emccrary -"dexeε to at! -ocst ons associated wi a group Public gsEditGroupName As Stnng
    Type FaxDataStπjcture sFaxID As Stnng sDialPrefix As Stnng iRetπes As Integer i Retry Interval As Integer bFaxResolutiαn As Byte sSeπderName As Stnng sSenderCompany As Stnng sSenderFaxNumber As Stnng sSenderVoiceNumber As Stnng iLocTαtal As Integer a count of the •oca ons sLocPersonName(IOO) As Stnng r ~ it may be desirable ,n the future to mane these airajs σyr.amtc sLocFaxNumber(IOQ) As Stnng sLocVoιcεNumber(IOO) As Stnng
    IGroupsTotaf As Integer sGroupTitIe(50) As Stnng sGroupNamesInTitie(50) As Stnng ir.cexes te names separated by ptce (ιe 3\6\ 15) iGroupLastSelected As Integer End Type Public FAX DATA As FaxDataStructure
    Public Sub GetFaxLocatioπs()
    Dim i As Integer, r As Integer, sSection As Stnng
    
    tions " + CStr(i), "") 
 sSection = "User Selections" iGroupLastSelected = Clnt(GetlNISettιπg(gsFaxFtleSpec, sSection, "Last Group Selected", "0")) 
 
    cuuucλ I ur λυιuuμι>
    Public Function GetIndeχToFaxGrouρName{ByVal sGroup As String) As Integer
    'rind sName in the list of tax names If found pass index back to caller 'otherwise return 0
    roup Then = i
    
    End Function
    Public Function GetlndeχToFaxLocName(ByVaI sName As String) As Integer Find sName in the list of tax names If found pass index cack to caster otherwise return 0
    nName(i)) = sName Then Name = i
    
    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 Total 'look through whcie list for name sGroup Then 'found it here
     
 al - 1 1) pNameslπTitlefj + 1) 
 iGroupsTotal - iGroupsTotal - 1 End With End Sub
 
    
    Public Sub RemoveNameFromFaxList(ByVaI sName As Stnng) 'Remove the name from the list and move uo ail ethers in the list Dim I As Integer, j As Integer, ilndexFound As Integer, r As Integer Dim sTempUst(IOO) As Stnng, sNe lndexes As Stnng, iTemp As Integer list for name hers
     
 iLocTotal - 1 - sLocPersoπName(ι + 1) ~ sLocVoiceNumberfi + 1 ) sLocFaxNumber(ι + 1 ) 
 iLocTotal = iLocTotal - 1
 
    
    Fax.bas - SetFaxDeviceLabel
    Public Sub SetFaxDeviceLabelO
    'Tins label on the options tab displays (he status of the fax device. 'If a fax device exists, then the laoel displays the device, otherwise it shows an appropπate message
    dem is connected propery "
    
    End Sub 
    Calendar bas - File Declarations
    Attπbute VB^Name = "modCalendar" Option Explicit
    Pπvate giCompliedDosesCreated As Integer number of Comolied Doses to show on the calendar Private giNoπCompliedDosesCreated As Integer πumoer of non-complied Doses to show on the calendar Pπvate giDoseSizeChangesCreated As Integer Pπvate giZoomDosesCreated As Integer nu oer of Dcsas to show in zoom box Pπvate giDosesMissedCreated As Integer nu oer of objects to show for missed days Pπvate gbCalendarUpdatelnProgress As Integer presents recursive calls while updating calendar
    Public gsngComplianceTimeRange As Single Sr cf 'S on either side of a prescnoec cose in which a dose must oe tauen
    Type CALENDAR_SELECTlONS chkDosesTaken As Byte chkDosesNotComplied As Byte chkDosesMissed As Byte chkDoseChanged As Byte End Type Public CAL_DEFAULTS As CALENDAR_SELECT10NS
    Type SUMMARY_SELECTIONS cmboDataToView As Byte cmboChartType As Byte End Type Public PAT_SUM_DEFAULTS As SUMMARY_S ELECTIONS
    Public Function CaIcDayslnMonth(ByVal iMoπth 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 ~ iMoπth + 1 If f = 13 Then ι = 1 fTemp = CVDate(CStr(ι) + 701/~* + CStrfiYear)) ITemp = (Temp - 1 CalcDayslnMonth = Day(ITemp) End Function
    Public Sub DrawAIIDoseSizeChangesQ
    Dim i As Integer, r As Integer, iDayslπMonth As Integer
    Dim sCalendarStartDate As Stnng, dTime As Double
    Dim iDateDifference As Long, ICalendarStartDate As Long
    Dim bFirstOayAlready Plotted As Boolean, bLastDayA Ire ady lotted As Boolean
    Remove Dose SizeChanges 'remove all of the old doses first iDayslnMonth = CalcDayslnMonthffrmDosingCaleπdar.Calendar. onth, frmOosingCalendar Calendar.Year) sCalendarStartDate = CStr(frm Dosing Calendar Calendar. onth) + 701 r + Stπ5(frmOosιngCalendar Calendar Year) ICalendarStartDate = DateValue(sCalendarStartOate)
    omy med events (not errors etc)
    
    'Tnis section of code ensures that dosing info ts aiways plotted on the first and last αay of the month
    If bFirstDayAlreadyPlotted =- False Then 
 Calendar bas - DrawAIIDoseSιzeChaιiL,_ i - FιndPrescιbedOoseSιzeForSpecιficDay(PAT_DATA, ICalendarStartDate) DrawSmgleDoseSizeChange 1. dTime. r. False ~ End If
    If bLastDayAlreadyPlotted = False Then r = FιndPrescιbedΩoseSιzeForSpecιficOay(PAT_DATA, ICalendarStartDate ♦ iDayslnMonth - 1)
    DrawSmgleDoseSizeChange iDayslnMonth. dTime. r. False End If c For i = 1 To giDoseSizeChangesCreated shew all the Doses frmDosingCalendar shapeOoseSlzeChaπge(ι) Visible = True Next i
    End Sub
    Public Sub DrawAIICompliedDosesTakenO
    Dim i As Integer, r As Integer
    Dim sCalendarStartDate As Stnng. dTime As Double
    Dim IDateDifference As Long, ICalendarStartDate As Long
    Dim iDayDαseCouπt As Integer. iDayNumberBeingPlotted As Integer, iLastDoseDayDrawπ As Integer
    Dim iDayslnMonth As Integer, ITemp As Long
    RemoveCompliedDosesTaken remove al! of the old dcses first
    If frmDosingCalendar chkDosesTakeπ Value = False Then Exit Sub sCalendarStartDate = CStr(frrnDosιngCaleπdar.Caleπdar Month) + 701 Λ ♦ StrSffrmDosingCalendar Calendar. Year) ICalendarStartDate = DateValue(sCalendarStartDate)
    'Calc the number of days in the month being displayed iDayslnMonth = CalcDayslπMonth(frmDosιπgCalendar Calendar Month, frmDosingCalendar Calendar Year)
    
    For i = 1 To giCompliedDosesCreated 'snow all the Doses c frmDosingCalendar shaρeDαse(ϊ) visible = True Next i 
    calendar Das - υrawAllUosesMis.
    63
    Public Sub DrawAIIDoses issed()
    Dim l As Integer, IDayslnMonth As Integer, I As Long Dim sCalendarStartDate As Stnng
    Dim IDateDifference As Long, ICalendarStartDate As Long Dim iDayDoseCount As Integer, iDayθeingPlotted As Integer
    RemoveDosesMissed remove all of the old doses first
    If frmDosingCalendar ChkDosesMissed. Value = False Then Exit Sub iDayslnMonth = CalcDayslnMonth(frmDosιngCalendar.Calendar Month, frmDosingCalendar Calendar Year) sCalendarStartDate = CStr(frmDosιngCalendar Calendar Month) + 01T + CStrtfrmOosingCalendar Calendar Year) ICalendarStartDate = DateValue(sCalendarStartDate)
    _ For I = ICalendarStartDate To ICalendarStartDate + iDayslnMonth - 1 'sequerce throuon al! days in month lf l >= PAT_DATA.dEventDate(1) Then day being plotted is not eamer'har. 1st dose in structure ■ If I < PAT_DATA.dEventDate(PAT_DATA.ιEventData(0)) Then 'day oeiπg plotted is not later than last dose ir ; lDayBe gPlotted = I - ICalendarStartDate + 1 get the current month day to plot iDayDoseCount = CalcDosesSumTakenOnSpecιficDay(PAT_DATA, I) caic isseo αoses 'or this day
    For i = 1 To PAT_OATA.ιDosesPerDay - iDayDoseCount
    DrawSingleOoseMissed lDayBemgPlotted, i 'Plot the current cay
    Next i End If End If Next I
    For i = 1 To giDosesMissedCreated 'snow all the Doses frmDosingCalendar shapeDαseMιssed(ι) Visible = True Next i
    Public Sub DrawAllNonCompliedDosesTakenO
    Dim i As Integer, j As Integer, b Dose OutOfComplia nee As Boolean
    Dim dTimeUmit As Double, dLowUmit As Double, dHighbmit As Double
    Dim sCalendarStartDate As Stnng, dTime As Double
    Dim IDateDifference As Long, ICalendarStartDate As Long
    Dim iDayDoseCount As Integer, iDayNumberBeingPlotted As Integer, ILastDoseDayDrawn As Integer
    Dim iDayslnMonth As Integer
    RemoveNoπCompliedDosesTakeπ remove all of the old doses first
    If frmDosingCalendar chkDosesNotComplied. alue =- False Then Exit Sub iDayslnMonth - CalcOayslnMonth(frrnDosιngCalendar.Calendar Month, frmDosingCalendar Calendar Year) sCalendarStartDate = CStr(frmDosιng Calendar. Calendar Month) + 701 r + StrS(frmDosmgCalendar.Calendar Year) ICalendarStartDate = DateVatue(sCalendarStartDate) dTimeUmit = gsngComplianceTimeRange / 24 _ For ι = 1 To PAT_DATA.ιEventData(0) 'total numoer of events If PAT_DATA byte Eve ntTyρe(i) = gtEVENT_DOSE_TAKEN Then 'show only med events (not errors etc)
    IDateDifference = Int (PAT_ DATA. dEventDatefl)) • ICalendarStartDate
    If IDateDifference >= 0 And IDateDifference <-= iDayslnMonth Then dose occurred dunng this month dTime = PAT_DATA dEventDate(ι) - lnt(PAT_DATA dEventOate(ι)) 'get time of dose 'Determine if the dose occurred within the compliance parameters 'rgn see if we can use cur procedure already created
    If gsngComplianceTimeRange Then 'do test if there is a value set in the compliance time range bDoseOutOfCompliance = True 'ser default to be out of range unless otherw.se set below For i = 1 Tα PAT_DATA.ιDosesPerDay comcare dose time against all of the alarm times dLowUmit = PAT.DATA dPrescπbed Dose Tim e(j) - dTimeUmit - 0 0001 add a factor to prevent rounding eror dHighLimit = PA"f DATA dPrescnbedDoseTimefj) + dTimeUmit + 0 0001 If dTime >= dLowLimit And dTime <= dHighLimit Then this cose ts witnin compliance bDoseOutOfCompliance = False set flag to not co' this dose
    Exit For tio need tor further testing of this dose It is in comcliance End If Next ] 
 
    For i ~ 1 To giNonCαmpiiedDosesCreated shc.v all the Doses frmDosingCalendar shapeDoseNonComply(ι) Visible = True Next i End Sub
    Public Sub Dra SιngleDoseSιzeChaπge(iDay As integer, dTime As Double, iEventNumber As Integer, bHighhf 'Draw dosing Doses for the day of the month and time of day passed in hem Time of time is expressed tn decimal places as a portion of a day (VB time format) 'NO TE 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 plott.ng
    A Dose is not visible when first created The caller snould ώsclay 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) 'When this feature ts on. a dose size is automatically entered on the first and last day of the month
    On Enor Resume Next Dim i As Integer, [WeekDay As Integer Dim IDoseLeft As Single, IDoseTop As Single Dim ITemp As Long, IDayWidth As Long, IDayHeight As Long
    umber)) + " mg
    
    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 simpiy use 'nose prooerties
    'and remove these calculations
    IDay idth = (fr Dosing Calendar Calendar Width - 50) / 7 actual sea ewidth of a single day
    ITemp = (frmDosingCalendar Calendar DayLeft(ιDay) * 26) / IDayWidth approximate location of the day iWeekOay •= Clnt(ITemp)
    IDoseLeft = (iWeekDay * IDayWidth) gef led edge of day to plot
    IDoseLeft = IDoseLef* * ((IDayWidth / 5) ' iFlctPosiiicn ■ 1) - (IDayWidth / 10)
    IDoseLeft = IDoseLeft + (IDayWidth * 0 8) - frmDosingCalendar shaρeDoseSιzeChange(gιDoseSιzeChangesCreated) Width
    If Int(IDayWidth / 150) < 7 Then frmDosingCalendar shapeDoseSιzeChange(gιDoseSιzeChangesCreated) FontBold = False Else 
 frmDosingCalendar shapeOoseSιzeChange(gιDoseSιzeChaπgesCreated). FontSize = IntflDayWdth / 150) frmDosingCalendar shapeΩoseSιzeChaπge(gιDoseSιzeChangesCreated) Left = IDoseLeft
 
    
    IDoseTop = (ITemp * IDayHeight) + 625 'this numoer factors in the title bar
    IDoseTop -= IDoseTop + 50 frmDosιngCalendar.shapeDoseΞιzeChange(gιDoseSιzeChangesCreated) Top = IDoseTop frmDosingCalendar shapeDoseSιzeChange(gιDoseSιzeChangesCreated).Tag = iEventNumber 'keep event number for uodat.r. th° t zoom box
    ' On Error Go To 0 End Sub
    Private Sub DrawSingIeNonCompiiedDoseTaken(iDay As integer, dTime As Double, iEventNumber As Integer, iPlotPosition As integer)
    'Draw dosing Doses for the day of the month and time of day passed tn here
    'Time of time is expressed in decimal daces 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 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 Integer, iWeekDay As Integer
    Dim IDoseLeft As Single, IDoseTop As Single
    Dim ITemp As Long, IDayWidth As Long, IDayHeight As Long giNonCompIiedDosesCreated * giNonCompliedDosesCreated + 1 'increment Doss counter
    Load frmDosιngCalendar.shapeDoseNonComply(gιNonComplιedDosesCreated) 'create a new Dose
    'These lines are a work-around for a bug tn the control that causes it to
    'return the wrong values for day left, day top. etc When fixed, we can simply use those pr oerties
    'and remove these calculations
    IDayWidth = (frmDαsiπgCalendar.Caleπdar.Wϊdth - 50) / 7 'actual scaiewtdth of a single day iWeekDay = (frmDosιπgCaleπdar.Caleπdar.DayLelt(iDay) * 26) / IDayWidth 'approximate location of the cay
    IDoseLeft * (iWeekDay * IDayWidth) 'get left edge of day to plot IDoseLeft = IDoseLeft + ((IDayWidth / 5) * iPlotPosition - 1) - (IDayWidth / 10) frmDosιngCaiendar.shapeDoseNonComply(gιNonComplιedDosesCreated).Left = IDoseLeft
    These lines are a work-around for a bug in the control that causes it to
    'return (he wrong values for day left day tcp etc When fixed we can simpiy use these prooemes 'and remove 'hese calculations
    'The control is even moe stupid than I first supected It can not always return the orocer vertical 'location of a day thus we have toju o through more nooos to figure out what week that a particular 'day is tn IDayHeight = (frmDosingCalendar Calendar.Height - 50) - 625 'an offset is used to compensate for height of title 
 enαar.Das - ura SingieNonCompliedDi. i aκen lOayHeignt = IDayHeight / 6 iWeekDay ~ (frmDosingCalendar Caleπdar.DayLeft(l) * 26) / IDayWidth the approximate location of the day
    ITemp = lπt((ιDay + iWeekOay - 1) / 7)
    IDoseTop = (ITemp * IDayHeight) + 625 ''his numoer -'actors in the title bat
    IDoseTop = IDoseTop + IDayHeight - 50 - frmDosingCalendar shaρeOose(O) Height - frmDosmgCalendar.shapeDoseNonComplyiOi Height craw in ir.icdle of day ' frmDosingCalendar shapeDoseNonComply(gιNonComplιedDαsesCreated) Top -= IDoseTop frmDosingCalendar shapeDoseNonComply(gιNonComplιedDosesCreated).Tag = iEventNumber 'keeo event numoer for updatinc :, room box
    On E or GoTo 0 End Sub
    Public Function IsDoseWithinPrescribedTtmeRangefDataStruct As DeviceDataStruct, ByVal ilndex As Inteqer} 'Test to see that the event at the iπcex passed r.ere is a mecication event and that
    ,t:s witnr. the orescr.bed cms range rcra daily dose If yes. then pass TR E oack to the catier
    Dim i As Integer, dTime As Double
    Dim dTimeLimit As Double, dLowUmit As Double, dHighLimit As Double
    'get time of dose
    'add a factor to prevent rouπαng error
    
    Private Sub PriπtCalendar()
    This routine is calleα when the user presses the pnnt button on the calendar form
     
 ong Dim ocolorpnIZαom As Long Dim bcolorpnlume As Long Dim ocolorForm As Long Dim fcolorPresc.nbed As Long Dim fcoiorMissed As Long Dim fcoιorVeeκ As Long
 
    Dim curTop As Long Dim curWicih As Integer Dim curHetcht As Integer
    Const XC"S3> = 192G Const YOffset = 1890
    On Errcι GoTo Error btr.Pπnt
    CRLF = CnrS
( 13) + Chr$(10) 
 cu Top = Me Top curWidth = Me Width curHeigl'.t =■ Me.hieight
 
    'Hide this guy off the screen while we pπnt Me. Top = -(curHeignt ' 2)
    ' Save current background colors bcotorCalencar = Calendar SackColcr bcoioro i∑com ~ oniZoo 3acκCclcr bcotorc.nlTime - pnlnme BackCclor bcolorForm = Me.BackCclor rcolorPrescπoed ~ chkOosesTaκen.FtllCctcr fcolorMtssec - chkDosesMissed FiilCcicr fcolorWeek = cr.kWeekNumoers.FillColcr
    'hide the buttons btnC.'osa. Visible = False btnPr.nt.Visibte = False
    ' Add date + time info to pn.πted data sPnntlnfo = "Pπ.nted en' ' * Format$(Ncw "dcαdd nh.nn") tblPπnilπfo.Capπon - sPπntinfo
    ' Set titles at top of pπnted page IblTiile. Caption - 'Dosing Calendar" IblPatient.Captioπ - 'Patient: ' + tgDevtcestat.sFaoent Ibldrug.Caption = "Drug- " * tgDevtcestat sDrug
    ' Set background colors Calendar BackCotor= WHITE pnlZoom. BackCclor = WHITE pnlTime BackCoior = WHITE Me.BackColor = WHITE chkDosesTaken.FillColor- WHITE chkDosesMissed. FiliCαlor = WHITE chkWeekNumbers FjlfColcr - WHITE
    
    ' Move resize the form and move objects to give space for pnnting
    Call DeleteAllObjects ' remove extraneous elements from calendar
    Call MoveFαrmObiectsfMe, XOffset. YOffset. True)
    Call UpdateCalendar
    DoEvents
    'Call UpdaieZocmBox
    ' Switch on visibility of titles IblPnnϋnfα. Visible = True IblTiile. Visible - True iblPatient.Vtsibie = Trje Ibldrug.Visible ~ True
    ' Make Check ooxes two dimensional cnkDosesTsken Check3ox2d = True chkDosesMissed CheckBox2d - True chkWeekNumbers.CheckBox2d - True
    Sr.πg the Zoom laoles to the front IblZoomϋme.ZOrder 0 IblZocmTime Visible = True
    
    Me Height = Me Height - YOffset Me Width - Me Width - XCtfset
    DoEvents Me PπntForm DoEvents ftm^Siatus iblS a'^s Caption = 'Sending ca'erdat to pr.nts^
    ' hide the ti'les and show the buttons soiPnntiπto Visible - False IblTitle Visiote = False 
    
    IblPatient Visible - Faise ibid rug Visiϋiβ = False
    ' Move everything back
    Call DeleteAHObjects
    Call MoveFormObjects(Me -XOttsat -YOffset True)
    Call UpdateCalendar
    ' Restore background colors Calendar BackCotor - bcolorCalendar pnlZoom 3acxColor ~ bcctoroniZoom pnlrιme BackCotor ~ ocoiorpπlTime Me BackCoior - ocolorForm chkDosesTaken FiSCoior ~ fcαlorPrescnoed cnkDcsesMissed FsllCclor = fcclorMtssec cr.kWeenNumbers FiilCctcr = fcclαrWee*
    ' Restore buttons btnClcse Visible = True btnPnnt Visible = True
    ' Set check boxes oack to 3d ' Make Check boxes two dimensional chkDosesTaken Check3ox2d - False chkDosesMissed CheckBox2d - False chkWeekNumbers CheckBcx2d = False
    
    Unload frm_Status
    'Exit btnPnnt. Exit Sub
    'Error_btπPnπt
    Resume Exit btnPnnt 
    
    Public Sub RemoveDoseSizeChaπges()
    Dim l As Integer
    On Error Resume Next
    For i = 1 To giDoseSizeChaπgesCreated remove all cevicus Doses rz Unload frmDosingCalendar shapeDoseSιzeChaπge(ι) Next i giDoseSrzeChangesCreated = 0
    On Error GoTo 0 End Sub
    Public Sub RemoveDoses issedQ
    Dim i As Integer
    On Error Resume Next
    For l = 1 To giDosesMissedCreated remove ail previous αo'ecis rz Unload frmDosingCalendar shapeDoseMιssed(ι) Next i giDosesMissedCreated = 0
    On Error GoTo 0 End Sub
    Public Sub RemoveCompliedDosesTaken()
    Dim i As Integer
    On Error Resume Next
    For i = 1 To giCompliedDosesCreated 'remove all previous Doses rz Unload frmDosιngCalendar.shapeDose(i) Next i giCompliedDosesCreated = 0 On Error GoTo 0 End Sub
    Public Sub RemoveNonCompliedDosesTakeπO
    Dim i As Integer
    On Error Resume Next
    For i - 1 To giNonCompliedDosesCreated 'remove all previous Doses rz Unload frmDαsιngCalendar.shapeDoseNoπComply(ι) Next i giNonCompliedDosesCreated - 0
    On Error GoTo 0 End Sub 
    Calendar bas - UpdaleZoomBox
    HS
    Public Sub UpdateZoomBoxQ
    'A tffer-nt day was clicked on the calendar so we need to plot the events for 'ti β current dav into the zoom box
    This procedure draws doses taken for a given dav
    NOTE Nα checks are currently made to ceter tne whether 'he 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
    Dim i As integer, dTime As Double, iDoseDay As Integer, iZoomPanelWidth As Integer
    Static bProcedurelnProgress
    If bProcedurelnProgress Then Exit Sub bProcedurelnProgress •* True orevent ercπf airead/ unloaded 'remove all orevious Doses eZoomDose(ι) 
 giZoomDosesCreated = 0
 
    For i = 1 To 4 Unload frmDosingCalendar shapeZoomPrescπbed(ι) dear the text ox tcr zoom time Unload frmDosingCalendar shapeZoomTimeRaπge(ι) 'αear the te xt box for zoom time
    Next i
    On Error GoTo 0 'resume normal error status
    
    For i = 1 To 4 fnmDosmgCalencar xtZcomTιme(t) Cacticr = ' dear the text oox tor zoom v e Next i
    and speed things o taπen on nter 
 
 — Θ
 
     
 frmDosingCalendar pnlZoom Caption = FormatSffrmDosmgCalendar Calendar Date 'General Dale") * " Detail View*
 
    'update position of time scale For I = 2 To 22 Step 2
    (rmDosιngCalendar.lblDetaιlTime(ϊ).Left = (frmDosingCalendar pnlZoom.Wldth * (i / 24)) - (frmDosingCalendar IblDetaιlTime(i) Width
    12) Next l frmOosingCalendar shapeDayϋght(2).Width = frmOosiπgCalendar.pnIZoom Width * 0.53 frmDostπgCalendar.shapeDayLιght(1).Width = frmOosiπgCalendar.pnIZoom.Wldth " 0.03 frmDosιngCaleπdar.shapeOayUght(3). Width = frnιDosιngCaleπdar.shapeDayUght(1 ).Width frmDosιπgCalendar.shapeDayUght(2).Left = (frmDosingCalendar.pnrZoom.Width - frmDosιngCaleπdar.shapeDayUght(2) Width) / 1.8 frmOosιngCalendar.shapeOayUght(1).Left = 20 + frmDosιngCalendar.shapeDayϋght(2).Left - frmOosιngCalendar.shapeDayUght(1). Width frmDosιngCalendar.shapeDayUght(3).left = frmDosingCalendar shapeOayϋght(2) Left + frτπDosιngCaleπdar.shapeDayLight(2).Width - 15 bProcedurelnProgress = False End Sub
    Private Sub oveFormObjects(frm As Form, XOffset As Integer, YOffset As Integer, VisibleOnly As Integer)
    ' This roubne moves all objects on β form by the sseαfed amount
    ' Argument Descπptton
    ' frm Form object
    ' XOffset offset (in twips) to move in x plane. Posibve is to the nght
    ' YOffset offset fin twipsi to move in y plane Positive is down
    ' VisibleOnly It true only move visible objects
    Dim i As Integer
    On Error GoTo Error_MoveFormObjects
    
    Error_MoveFormOb)ects'
    Resume Exrt_MoveFormObjects
    Private Sub DrawSiπgIeCompIiedDoseTa eπ(iDay As Integer, dTime As Double, iEventNumber As Inteαer iPi Oraiv dosing Doses for the day of the mcntl aπc time of day passed .n r.ere * sxcressec :n decimal places as a portion of a day (VB time 'crmsi 'NQ Ε checks are currently made to ceiermsr.e whether tl'.e event is a med event or a non-Ted event If both events are kept in the same array, then a test et the ec bit must be done oefore plotting
    'A Dose ,s net visible when first created The easier srould sday (he Doses once they 'are ail created, so as to sceβd the recraw eftha screen 'Create another clone of the the Dose snape located m tne array Dose(0; 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 giCompliedDosesCreated = giCompliedDosesCreated + 1 Increment Dose counte'
    Load frmOosingCalendar shapeDose(gιComplιedDosesCreated) 'crea'a a new Dose
    These tines 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 'acrual scaiswidth of a single day
    IWeekDay = (frm Do singCa lend ar. Calendar. Day Le ft (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) fτmDosιngCalendar.shaρeDose(gιComplledDosesCreated).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 simpty use those properties
    'and remove these calculations
    'The control is even moe stupid than I first suoectad It can not always return the oroper 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 - (frmDosingCalendar Calendar.Height - 50) - 625 'an offset is used to compensate for height of title
    IDayHeight = IDayHeight/ 6 iWeekDay = (frmDosingCalendar Calendar DayLeft(1) * 26) / IDayWidth 'the approximate location of the day fTemp = lnt((ιOay + iWeekDay - 1) / 7)
    IDoseTop = (ITemp * IDayHeight) + 625 'this number factors in the title bar IDoseTop = IDoseTop + IDayHeight - 25 - frmDosingCalendar shapeDose(0) Height 'draw in bottom of day frmDosingCalendar. shape Dose (giCompliedDosesCreated). To = IDoseTop frmDosingCalendar shapeDose(gιComplιedDosesCreated) Tag = iEventNumber 'keep event number for ucdats.ng 'he zoom oov
    On Error GoTo 0 End Sub 
    
    Private Sub DrawSingleDoseMissedfiDay As Integer, iPlotPosition As Integer)
    'Draw doses for the day of the month passed in here
    NOTE No checks are currently made to determine whether the event is a meα event or 'a πon- ed event A test of the med bit must be dene before catling this procedure 'A Dose is not visible when first created The caller snould sclay the Doses once they are ail created so as to soeed 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 cour.tar
    'Create another clone of the the Dose snape located in 'he array Dose{0)
    Load frmDosingCalendar shapeDoseMιssed(gιDosesMιssedCreated) create a new Dose
    Tπese n.nes are a work-around for a oug tn the control tnat causes it to
    'return 'he wrong values for day left day top. etc When fixed we can simply use these properties 'and remove these calculations
    IDayWidth - (frmDosingCalendar Calendar. Width - 50) / 7 'actual scalewtdth of a single day iWeekDay = (frmOosmgCaieπdar.Caleπdar.DayLeftfjDay) * 26) / IDayWidth 'apcrcxtmate location et the cay
    IDoseLeft - (iWeekDay * IDayWidth) 'get left edge of day to plot IDoseLeft = IDoseLeft ♦ ((IDayWidth / 5) • iPlotPosition - 1) - (IDayWidth / 10) frmDosingCalendar shapeDoseMιssed(gιDosesMιssedCreated) Left = IDoseLeft
    'These lines are a work-around for a bug tn 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 supected. It can not always return the proper vertical
    'location of a day, thus we have to jump through more hooss to figure out what week that a particular
    'day is in
    IDayHeight = (frmDosingCalendar. Calendar.Height - 50) - 625 'an offset Is used to compensate for height of title
    IDayHeight = IDayHeight / 6 iWeekDay = (frmUαstπgCalendar.Caleπdar.DayLeft(l) " 26) / IDayWidth 'the approximate location of the day
    ITemp ■= lnt((ιDay + iWeekDay - 1) / 7)
    IDoseTop = (ITemp * IDayHeight) + 625 'mis number factors in the title ϋa-
    IDoseTop •= IDoseTop + IDayHeight - 75 - frmDosingCalendar shapeDose(0) Height - frmDosingCalendar shaρeDose(O). Height - frmDosιngCalendar.shapeDose(0).Heιght 'draw in bottom of day frm Do singCalendar. shape DoseMιssed(gιDosesMιssedCreated).Top - IDoseTop
    On Error GoTo 0 End Sub
    Public Sub UpdateCaIendar()
    "The month or year fo the calendar has changed so we need to plot the events for 'the current month and year being sπown
    Static bProcedurelnProgress As Boolean If bProcedurelnProgress Then Exit Sub bProcedurelnProgress = True
    Dim lObjectDiameter As Integer
    'Show custom laoeis from config file if there were any
    If Len(gsCustomLblPatteπtLastNa e) > 0 Then frmOosingCalendar Labell = gsCustomLblPatientLastName frmOosing Calendar IbiPabentName ~ " " + PAT_DATA sPatientLastName + ", ** + PAT_DATA sPatientFirstName lObjectDiameter •= frm DosingCalendar.Caleπdar. Width / 45 'resize the oo<ects drawn on the calendar
    If lObjectDiameter > frmDosingCalendar Calendar.Height / 50 Then lObjectDiameter = frmDosingCalendar Calendar.Height / 50 
 Calendar.bas - UpdateCaleπdar frmDosingCalendar shapeDose(O) Width = lObjectDiameter frmDosingCalendar shapeDose(O) Height = lObjectDiameter frmOosιngCalendar.shapeDoseNonComply(0). width = lObjectOia eter frmDosingCalendar shapeDoseNonComply(O). Height = lObjectOiameter frmOosιπgCalendar.shapeDosefviιssed(0).Width = lObjectDiameter frmOosingCalendar shapeOoseMιssed(O). Height « lObjectDiameter • frmOosingCalendar shaceDoseSizeChangefO) Width - lObiectDiameter frmDosingCalendar ShaceDoseSizeChangefO) Height = iCbjectDiameter
    OrawAIICompliedDosesTaken DrawAIINonCompliedDosesTaken DrawAIIDosesMissed OrawAIIDoseSizeChaπges
    UpdateZoomBox bProcedurelnProgress = False End Sub
    Public Sub RemoveAIIObjectsO
    Remove alt oojects from calendar RemoveCompliedDosesTaken Remove DαsesMissed DoEvents End Sub 
     iiiniviaiπ trm - File Declarations
    Artnbute VB__Name = "frmMain" Attπbute VB_GlobalNameSpace = False Attπbute vβ~Creatable = False Attπbute VB_Predeclaredld = True Attnbute VB_Exposed = False Option Explicit
    Private Sub CommTimer_Timer() gbCommTimerExpired = True CommTimer.Enabled = False End Sub
    Private Sub FaxMaπ1_ConfigurationDone()
    Dim i As Integer frmOptions MousePomter = vbDefault frmOptioπs btπConfigureFax Enabled = True SetFaxDeviceLabel End Sub
    Private Sub FaxMarτf_FaxStatus(Oevice As Integer, Status As Integer)
    Beep _ If gcpax.Status(Devιce) = "Initializing Modem" Or gcFax.Status(Devιce) = "Answeπng" Then frmFaxStatus.Show _ Elself gcFax Status(Devιce) = "Port Closed" Then
    Unload frmFaxStatus _ End If frmFaxStatus IblRemotelD = gcFax.StatusRemotelO(Devιce) peed(Devιce) 
 StatusPagesSent(Device)) + " of " ♦ ≤MføcFax StatusPages(Devιce)) StatusPagesSent(Devιce)) 
 ge(Devlce) > 0 Then nt = CStr(gcFax.StatusPerceπtage(Devιce)) + " % Complete" nt 
s "" 
 frmFaxStatus.lblStatus = gcFax.Status(Devιce) frmFaxStatus.lblDestination = gcFax.StatusDestιnaα
'on(Devιce) frmFaxStatus IblFaxNumber = gcFax.StatusNumber(Devιce) End Sub 
 
    
    Private Sub MDIForm_ oad()
    On Error Resume Next
    Me.Left = CLng(GetlNISettlπg(gsApplnιFιleSpac, "Windows", "Main Left", "1000")) Me Top = CLng(GetlNISettιπg(gsApplnιFιleSpec, "Windows", "Main Top", "1000")) Me Widtti » CLπg(GetlNISertιπg(gsApplnιFileSpec, "Windows", "Main Width", "6500")) Me.Height = CLng(GetlNISettιng(gsApplnιFιleSpec, "Windows". "Main Height", "6500^) Me WindowState = CLnglGetlNISetbngtgsApclniFileSoec 'Windows' 'Mam WinαowState' *0')l On Error GoTo 0 End Sub
    Private Sub MDIForm_Uπload(Cancel As Integer)
    Dim r As Integer cevice data has Hist been sa/ad "Main Left", CStrfMe.Left) "Main Top", CStr(Me.Top) "Main Width", CStrfMe.Wldth) "Main Height", CStr(Me. Height) "Main WindowState", CStrfMe WindowState) 
 
    SaveProgramPreferences End Sub
    Private Sub mπuAccessWebSite_Click()
    'if the form is minimized then set it back to normal
    Call LogonToWebSite
    If frmBrowser. indowState = vbMinimrzed Then fmiBrowser.WϊndowState = vbNormal End If fmiBrowser-JOrder End Sub
    Private Sub mnuFaxCoπfϊgure_CIick() giLatestOptionsTabSelected = 2 'display the fax tab once the dialog is opened fππOptions.Show vbModal End Sub
    Private Sub mnuFaxSeπd_Click() frmFaxSend.Show End Sub
    Private Sub mnuFaxViewLogs_Click() fr FaxLog Show End Sub 
    
    Private Sub mπuFilePropertιes_Clιck() frmOptiαns Show vbModal End Sub
    Private Sub mnuFιleSave_Clιck()
    Dim r As Integer
    _ If PAT_DATA sPatientDataFileName = ™ Then r - SaveOataToNewFile _ Else r = SavePatιentData(PAT_DATA sPatientDataFileName) _ End If
    _ 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
    Pπvate Sub mnuGeπError_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 W will be shown when any error is generated It generates a log file that provides valuable information for me developer This will be H removed from the next build ", vblnformaαoπ, "Test Error Handler"
    En-or 11 End Sub
    Private Sub mnuHelpDeviceDιag_Click()
    Dim sMSG, sReply As Stnng sMSG = "Performing a device diagnostics test could cause loss of vital device information and should be done only with the assistance V of technical support " sMSG = sMSG ♦ vbCrLf + vbCrLf + "Please contact our technical support department at 1-800-777-???? for a password and assistance
    ' Dtspla essage title and default value sReply = IπputBox'sMSG, "Password Required") If LCaseS(sRe ly) = "h2o" Then frmDeviceDiagnostics Show End Sub
    Private Sub mπuHelpTips_Click() frm Tip Show it the torn is minimized then set it back to normal
    If frm Tip WindowState = vbMiπimized Then frm Tip WindowState = vbNormal frm Tip ZOrder End Sub 
    
    Private Sub mnuReadDeviceData_Click() frmReadOeviceData Show 'if the form is minimized then set it back to normal
    If fmiReadDeviceData.WindowState = bMinimized Then frmReadDeviceData WindowState = vbNormal frmReadOeviceData ZOrder End Sub
    Private Sub mnuSendDeviceData_Click() frmDevicelnitialize Show
    'if the term is minimized then set it aack to normal
    If frmDevicelnitialize. WindowState = vbMinimized Then frmDevicelnitialize WindowState - frmDevicelπitializeZOrder
    End Sub
    Private Sub mnuViewAIIPatients_Click() frmAIIPatients Show
    'if the term ts minimized then set it back to normal
    If frmAIIPatieπts WindowState = vbMinimized Then frmAIIPatients WindowState = frmAIIPatιents.ZOrder End Sub
    Private Sub mπuHelpAbout_Click() frmAboutShow vbModal, Me End Sub
    Private Sub mnuViewCalendar_Click() frmDosiπgCalendar.Show 'f the form is minimized then set it back to normal
    If frmDosiπgCalendar.WindowState = vbMinimized Then frmDosingCalendar WindowState = vbNormal frmDosιπgCalendar.ZOrder End Sub
    Private Sub mnuViewExplorer_Click() mnuvIewExplorer.Checked = Not mnuviewExplαrer.Checked 'toggle the state of the check box
    SSUstaarl. Visible = mnuvIewExplorer.Checked End Sub
    Private Sub mnuViewOptions_Click() frmOptions Show vbModal, Me End Sub 
    1 »]
    Private Sub mnuViewPatientDosiπgReρort_Clιck() frmPatientDosingReport Show 'if the form Is minimized then set tt back to normal
    If frmPatieπtΩαsmgRepσrt.WindowState = vbMinimized Then frmPatientDosingReport. WindowState - frmPatientDosin ReportZOrder End Sub
    Private Sub mnuViewPatientSummary_Click() frmPatientSummary. Show '..' the minimized then set it back to norms'
    If frmPatientSummary WindowState - vbMinimized Then frmPatientSummary WindowState = frmPatientSummary ^Order End Sub lick()
    
    Private Sub mnuViewToolbar_Click()
    
    Private Sub SSListBarlJJstltemCIickfByVal ItemClicked As Ustbar.SSListltem)
    Select Case SSUstBarl.CurrentGroupKey - Case "Patient Data" 'patient data Select Case Item Clicked. Key
    Case "Event Calendar" 'calendar mnuVϊewCalendar_CIιck
    Case "Summary" 'summary mnuVtewPattentSummary_Cltck
    Case "Dosing Information" 'gnd mnuVιewPattentDosιngRepσrt_Clιck
    Case "All Patients" 'all pacents mnuViewAIIPatieπts Click
    Case "Device" 'device data Select Case ItemClicked.Key 
 Case "Retneve Data" reac — mnuReadDevtceOata Click Case "Program Device" send to OosPio Device mπuSendDevtceData_Clιck End Select
    _ End Select End Sub
    Private Sub tbToolBar_ButtonClick(ByVal Button As Comctl Lib. Button)
    _ Select Case Button.Key Case "Open" mπuFιleOpen_CIιck Case "Save" mπuFιIeSave_Clιck Case "Pπnt" mnuFιlePπnt_Clιck Case "Cut"
    'mnu EdιiCut__ Cn ck Case "Copy"
    'mπuEdttCopy_ Click
    Ciipoosrd.Ciaar
    If TypeOf ActiveForm ActiveControl Is TextSαx Then Select Case Index Case 0 ' Cut
    Copy selected text to Clipboard
    Clipooard.SetText ActiveForm ActiveContro! SelText Detete selected text. ActiveForm ActiveControl SelText = " Case 1 ' Copy
    Copy selected text to Clipboard
    C.'ioooard SetT ext ActiveForm ActiveControl SelText Case 2 ' Paste
    Put Clipooard text in text oox
    ActiveForm. ActiveControl SelText = Clipboard GetTextQ Case 3 ' Delete
    Delete selected text.
    ActiveForm AcsveControl SelText - '" 
    
    End Select End If
    
    Case "Bold"
    Case "Italic"
    Case "Underline"
    Case "Left"
    Case "Center"
    Case "Right"
    _ End Select End Sub
    Private Sub mnuHelpContents_Click()
    Dim nRet As Integer message 'o the user tn the There is no Help associated with this project.", vblnformation, Me. Caption e, 3, 0) 
 
    Private Sub mnuHelpSearc _Click()
    Dim nRet As Integer message to the user in the There is no Help associated with this project.", vblnformation. Me. Caption e, 261, 0) 
 
 
    -G
    Private Sub mπuWindowArτaπgelcons_Click()
    Me-Arrange vbArraπgelcons End Sub
    Private Sub mπuWiπdowCascade_Click()
    Me.Arraπge vbCascade End Sub
    Private Sub mπuWiπdowTileHorizontal_Click()
    Me„Arrange vbTileHαrizαntal End Sub
    Private Sub mπuWindowTileVertica^ClickO
    MeJVrrange vbTileVertical End Sub
    Private Sub mnuFileOpen_Click()
    Dim r As Integer r = OpenPatientDataf")
    If any of these forms are open at the time a new file is loaded, 'then refresh them.
    
    Private Sub mnuFileSaveAs_Click()
    SaveDataToNewFile End Sub 
    
    Private Sub mπuFilePageSetup_Click()
    On Error GoTo mnuFιlePageSetup_Clιck_Error dlgCommonOialog ShowPππter mπuFιlePageSetup_Clιck_Exιt. On Error GoTo 0 
 mπuFιIePageSetup_Clιck_Error
 
    Resume mπuFιlePageSetup_Clιck_Exιt a error message would have aiready been sent by the common dialog End Sub
    Pπvate Sub mπuFilePππt_Click() frm Pπnt. Show
    'if (he form is minimized then set .t back to normal
    If frmPnnt WindowState = vbMinimized Then fπnPπnLWindowState = vbNormal frrπPπnt.Z0rder End Sub
    Private Sub mπuFileSeπd_Click()
    To Do
    MsgBox "Ability to send a file will be active in a future release" End Sub
    Private Sub mπuFile RU_Click(lndex As Integer)
    Dim r As Integer r = OpenPatιentData(mnuFιleMRU(lndex).Captιoπ) End Sub
    Private Sub mπuFileExit_Click()
    'unload the form Unload Me End Sub 
    Attπbute VB_Name = "frmSplash" Attnbute VB_GlobalNameSρace = False Attnbute VB^Creatable = False Attπbute V8~Predeclaredld = True Attπbute VB_Exposed => False Option Explicit
    Private Sub Fσrm_Load()
    IblVersion. Caption = "Version " & App Major & "." 4 App. inor ' + ' - + App Revision loiProductName Caption - Aop Title End Sub 
    Attnbute VB_Name = "frmLogin" Attπbute VB_GlobalNameSρace = False Attπbute VB_Creatable = False Attnbute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit
    Pπvate Declare Function GetUserName Lib "advapι3Zdll" Alias "GetUserNameA" (B Val Ipbuffer As Stπno nSize As Lonπi , Public OK As Boolean "' >-""yι «5 Long
    Private Sub Form_Load()
    Dim sBuffer As Stnng Dim ISize As Long
    Me Move frmSplash Left ♦ 4000, frmSplash Top + 3500 sBuffer= Space$(255) ISize = Len(sBuffer) Call GetUserNamefsBuffer, ISize) — If ISize > 0 Then txtUserName = LeftSfsBuffer, ISize) _ Else txtUserName = vbNullStπng _ End If End Sub
    Private Sub cmdCancel_Click()
    OK = False ~
    Me.Hide End Sub
    
    
    Private Sub btnConfigureFax_Click() btnConfigureFax.Enabled - False Me MousePomter = vbHourglass gcFax.AutoOetect With IblFaxOevice
    .Caption = "Searching for a Fax Device. Please wait a few seconds "
    .BackCotor = SHCOFFFF highlight background
    .ForeColor = &HO&
    .Refresh End With End Sub
    Private Sub c.mdApply_Click()
    Dim sSection As Stnng giLatestOptioπsTabSelected = sstabl.Tab
    'set the global value to the user's selection gsOateDisplayFormat = ChoosefcmboOates.Ustlπdex + 1, "Short Date", "Medium Date", "Long Date") gsTimeOisplayFormat = Choose(cmboTimes.Ustindex + 1, "Short Time", "Medium Time", "Long Time")
    
    'Save tne Fax Information
    With FAX_DATA
    .sSenderName = txtName .sSeπderCompany = txtCompany .sSenderVoiceNumber = txtVoiceNumber .sSeπderFaxNu ber = txtFaxNumber 
 sFaxlD = txtFaxlD 
 sDialPrefix = txtDlalPrefix iRetnes * Val(txtRetπes) iRetrylnterval = Val(txtRetrylnterval) bFaxResσlution = chkResolution Value 'G-low 1 - high End With
 
    Save values for the Fax control that was last sef ov user sSection = "User Selections"
    With FAX_DATA SavelNISettmg gsFaxFileSpec, sSection, "Sender Name", sSenderName SavelNISetting gsFaxFileSpec, sSection, "Sender Company", sSenderCompany SavelNISettmg gsFaxFileSpec, sSection, "Sender Voice Number", sSenderVoiceNumber SavelNISett g gsFaxFileSpec, sSection, "Sender Fax Number", sSenderFaxNumber SavelNISetting gsFaxFileSpec, sSection, "Fax ID", sFaxlD SavelNISett g gsFaxFileSpec, sSection, "Dial Prefix", sDialPrefix SavelNISetting gsFaxFileSpec, sSection, "Retnes", CStr( iRetnes) SavelNISettmg gsFaxFileSpec, sSection, "Retry Interval", CStrf iRetrylnterval) SavelNISettmg gsFaxFileSpec, sSection, "Resolution", CStrf bFaxResoluπon)
    End With End Sub
    Private Sub cmdCaπcel_Click()
    Unload Me End Sub
    Private Sub cmdOK_Click()
    ' 'Code goes here to set options and dose dialog " cmdApply_Clιck Unload Me End Sub
    Pπvate Sub Form_Activate()
    SetPπntertcoπ False, ™ End Sub
    Private Sub Form_Load()
    Define the mask for the telephone and fax numαers text box 'Load the available choices into the list boxes cmboDates-Addltem FormatSfNow, "Short Date") cmboOates.Addltem FormatSfNow, "Medium Date") cmboDates.AddItem FormatSfNow, "Long Date") cmboTimes.Addltem FormatSfNow, "Short Time") + " (24 hour)" c boTimesΛddltem FormatSfNow, "Medium Time") + " (12 hour)" cmboTimes ddltem FormatSfNow, "Long Time")
    
    
    set e 'ist oe* to the as* setec sd us r state/
    
    Gef Fax ln*o from global settings to the Fax Tab With FAX_DATA txtName ~ sSenderName tκtCompany = sSenderCompany txtVoice Number = sSenderVoiceNumber txtFaxNumber » sSenderFaxNumber txtFaxlD = sFaxlD txtDιa!Prefix = sDialPrefix txtRetπes = CStr( iRetnes) txtRetrylπterval •= CStr( iRetrylnterval) chkResolution Value = bFaxResolution o~,cw 1-high End With sstab Tab = giLatestOptiαnsTabSelected SetFaxDevicelabel oda e the devices labet End Sub
    
    Private Sub sstab1_Click(PrevιousTab As Integer) tax tab
    If sstabl Tab = 2 Then SetFaxDeviceLabel ccate the cevces label
    End Sub
    Private Sub txtFaxlMumber_GotFocus() txtFaxNumber SelStart = 1 End Sub
    Private Sub txtRetπes_GotFocus() txtRetπes SelStart = 1 End Sub
    Private Sub txtRetrylπterval_GotFσcus() txtRetrylnterval SelStart = 1
    End Sub
    Pπvate Sub txtVoιcel\lumber_GotFocus() txtVoiceNumber SelStart = 1 End Sub 
    Attπbute VB_Name = "frmAbout" Attribute VB_GlobalNameSpace = False Attπbute VB_Creatable = False Attπbute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit
    Peg Key Ξecuπty Options Const KEY ALL ACCESS = &H2003F
    Feg Key FOOT Tyoes Const HKEYJ-OCAL MACHINE = SH80000002 Const ERROR_SUCCESS = 0
    Const REG^SZ = 1 Lmcoce nut 'err ma'ec shine
    Const = 4 ' 32-6;.- numoer
    Const gREGKEYSYSINFOLOC = "SOFTWARE\Mιcrosoft\Shared Tools Location- Const gREGVALSYSlNFOLOC = "MSINFO"
    Const gREGKEYSYSINFO Const gREGVALSYSINFO 
 
    Pπvate Declare Function RegOpenKeyEx Lib "advapι32" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal IpSubKey As Stnng, ByVal V ulOptions As Long, ByVal samDesired As Long, ByRef phkResuit As Long) As Long
    Pπvate Declare Function RegQueryValueEx Lib "advapι32" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal IpValueName As Stnng * ByVal IpReserved As Long, ByRef IpType As Long, By al IpOata As Stnng, ByRef IpcbOata As Long) As Long
    Pπvate Declare Function RegCloseKey Lib "advapι32" (ByVal hKey As Long) As Long
    Pπvate Sub Form_Load()
    IblVersion Caption = "Version " + App Major + " " + App Minor + " " + App Revision IblTitle Caption ~ App Title End Sub
    Private Sub cmdSyslnfo_Click()
    Call StartSyslnfo End Sub
    Private Sub cmdOK_C!ick()
    Unload Me End Sub
    Public Sub StartSyslnfoO
    On Error GoTo SyslnfoErr
    Dim re As Long
    Dim SyslnfoPath As Stnng
    ' Try To Get System Info rogram Pat name Regist
    If GetKeyValue(HKEY_LOCAL_MACHINE. gREGKEYSYSINFO, gREGVALSYSINFO, SyslnfoPath) Then
    ' Try To Get System Info Program Path Oπtv From Regtstr/ Elself GetKeyvalue(HKEY_LOCAL_MACWNE. gREGKEYSYSINFOLOC gREGVALSYSlNFOLOC, SyslnfoPath) Then Validate Existence Ot Known 32 Bit File Version 
 H3
    
    Call ShellfSyslnfoPath, vbNormalFocus) 
 
    SyslnfoErr
    MsgBox "System Information Is Unavailable At This Time", vbOKOnly End Sub
    Public Function GetKeyValuefKeyRoot As Long, KeyName As String, SubKeyRef As String, ByRef KeyVal As :
    Dim i As Long ' Loco Counter
    Dim re As Long ' Return Code
    Dim hKey As Long • Hancle To An Open Regstry Key
    Dim hΩepth As Long
    Dim KeyValType As Long ' Data Type Of A Regstry Key
    Dim tmpVal As Stnng ' Tempor Storage For A Regstry Key Value
    Dim Key ValSize As Long ■ Size Of Regstry Key Vaπable
    ' Open RegKey Under KeyPool (HKEY -OCAύ^MACHINE.. ) to = RegOpenKeyExfKeyRoot, KeyName, 0, KEY_ALL_ACCESS, hKey) ' Ooen Regstry Key If (re <> ERROR_SUCCESS) Then GoTo GetKeyError- 'Handle Error tmpVal = Stπngs7l024, 0) 'Allocate Vanable Space
    KeyValSize = 1024 ' Mark Vaπable Size
    ' Retneve Regstry Key Value . re = RegQueryValueExfhKey, SubKeyRef, 0, KeyValType, tmpVal, KeyValSize) ' Get Create Key Value If (re <> ERROR_SUCCESS) Then GoTo GetKeyError 'Handle Errors mpVal, KeyValSize, 1 )) = 0) Then ' WinβS Adds Null Terminated Stnng .. LeftftmpVal, KeyValSize - 1) ' Null round. Extract From Stnng ' WinNT Does NOT Null Terminate Stnng. . LeftftmpVal, KeyValSize) 'Null Λ or Found. Extract Stnng Only 
 
    ' Determine Key Value Type For Conversion.
    Select Case KeyValType ' Search Data Types .. Case REG^SZ ' Stnng Regstry Key Data Type
    KeyVaf = tmpVal ' Copy Stnng Value Case REG_DWORD ' Double Word Regstry Key Data Type
    For i = Len(tmρVal) To 1 Step -1 ' Convert Each Sn
    Key al = KeyVal + Hex(Asc( id(tmρVal, i, 1 ))) ' 3uιιd Vaiue Char Sv Char Next
    KeyVal = FormatS("Sh" ♦ KeyVal) ' Convert Dcuole Word To Stnng End Select
    GetKeyValue = True 1 Return Success re = RegClαseKey(hKey) ' Close Registry Key
    Exit Function
    GetKeyError ' Cleanup After An zrrorH' as Qccured KeyVal = " ' Set Return Val To Emcty Stnng 
 irmADout.irm - GelKeyValue
    GetKeyValue « False ' Return Failure re = RegCloseKey(hKey) ' Close Regstr/ Key End Function
    US 
 frmBrowser frm - File Declarations
    Attnbute VB_Name = "frmBrowser" Attnbute VB_GlobalNameSpace = False — Θ Attπbute VB~Creatable = False Attπbute VB_Predeclaredld » True Attπbute VB_Exposed = False Option Explicit
    Public StartingAddress As Stnng Dim mbDontNavigateNow As Boolean
    Pπvate Sub Form_Load()
    Dim r As Integer
    On Eror Resume .-Vex" Me Show tbToolBar Refresh Form Resize
    
    Private Sub brwWebBrowserJDownioadCompIete()
    On Error Resume Next
    Me Caption ~ brwWebBrowser LocatioπName Me MousePomter = vbDefault End Sub
    Private Sub brwWebBrowserJ\iavιgateComplete(ByVal URL As Stnng)
    Dim i As Integer, r As Integer
    
    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 πe/ date in INI f.te t at an attempt (or success) was made to visit the Internet web site on this date r ■= GetlNISettιng(gsAppInιFιleSpec, "Web Data", "Connection Reminder Days", 100)
    SavelNISettmg gsApplniFileSpec, "Web Data", "Next Web Visit Reminder Date", FormatSfNow +■ r, "Medium Date")
    
    Private Sub cboAddress_Click()
    If mbDontNavigateNow Then Exit Sub timTimer Enabled = True brwWebBrowser.Navtgate cboAddress.Text Me.MousePomter = vbHourglass End Sub
    Private Sub cboAddress_KeyPress(KeyAsciϊ As Integer)
    On Error Resume Next
    If KeyAsαi = vbKeyReturn Then cboAddress_Clιck End Sub
    Private Sub Form_Resize()
    Me Refresh
    If Me. WindowState = vbMinimized Then Exit Sub brwWebBrowser.Move brwWebβrowser.Lelt, brwWebBrowser. Top, Me.ScaleWidth 100, Me.ScaleHeight - (pnlAddress.Top < » pnlAddress. Height) - 100 ' brwWebarowser Width = Me.ScaleWidth - 100 ' brwWebSrowser.H ight - Me.ScaleHetgnt ■ (pnlAddress.Top + pnlAddress.Heignt) ■ too cboAddress.Move cboAddress.Lelt, CboAddress.Top, pnlAddress. Width - CboAddress.Lelt End Sub
    tiαnName
    
    Private Sub tbTool8ar_ButtoπClick(ByVal Button As Button)
    On Error Resume Next timTimer.Enabled = True
    the regstered no e page
     
 tlmTimer Enabled = False -Lid brwWebβrowser.Stop
 
    Me. Caption - brwWe Browser. Location Name _ End Select End Sub 
    Attπbute VB_Name = "frm Tip" 
 Attnbute VB_GlobalNameSpace = False Attπbute VB~Creatable = False Attnbute VB_Predeclaredld = True Attπbute VB^Exposed = False Option Explicit
 
    ' The in-memcry database of cs Dim Tips As New Collection
    Naive of tips file Const TIP FILE = TIPOFDAY TXT"
    Private Sub DoNextTϊpQ
    "«cex in collection of bp currently being dis iaved 'cycle through tne Tios in order giCurrentTip = giCurrentTip + 1
    If Tips Count < giCurrentTip Then giCurrentTip = 1
    ' SΛoiv it frm Tip OisplayCurreπtTip End Sub
    Function LoadTips(sFile As String) As Boolean
    Dim NextTip As Stnng ' Each ttp read in from file Dim IπFile As Integer ' Descnptor for Hie
    ' Obtain the next free file descnptor InFile = FreeFiIe
    ' Make sure a file ts scecified If sFile = " Then
    LoadTips -s False
    Exit Function End If
    ' Make sure the file exists before trying to ooen it If Dιr(sFιle) = "" Then
    LoadTips = False
    Exit Function End If
    ' Read the collection from a text hie Open sFile For Input As InFile While Not EOF(lnFιle)
    Line Input #inFιle, NextTip
    TipsΛdd NextTip Wend Close InFile
    ' Display a tp at random Do NextTip
    LoadTips = True
    End Function 
    Attnbute VB_Name = "frmAIIPatients"
    Attnbute VB_GlobalNameSpace = False
    Attnbute VB~Creatable = False
    Attnbute VB_Predeclaredld ■ True
    Attribute VB~Exposed = False
    Option Explicit Dim xbλllPatientsFormLαading As Boolean Dim xsPatientFileSpecsQ As Stnng a c ■" mis array holding the names of pa ent Was on disk
    Private Function CalculateSιnglePatieπtCompliance(DataStruct As DeviceDataStruct) As Double Calculate the compliance tor the oatiert in memor/ and cass result oacx to caller 'Lisa the settings of the άalcg tc determine calculations ana cats ranges
    Dim IDateBegin As Long, IDateEnd As Long, I As Long, IScoreSum As Long Dim iPlotvalue As Integer keecs a tatty of the vaiue be plotted tor each dav
    IDateBegin = txtStartDate lrt(OaιaStruct sc-seruQa-e; 1 » IDateEnd = txtEndDate 'lnt(DataSιn.ct dZ/entDatet DataStruct lEvenιDaιa(Oi))
    
    Private Sub btπClose_Clic ()
    Unload Me End Sub 
    irmAiiKatieiiib urn - cmDouata ι ovιew_
    Private Sub cmboDataToView_Click()
    CalculateAIIPatleπtsCompliaπceOnOisk Slider] SlideChange
    End Sub ~
    Private Sub cmboDateSelectιon_Click()
    
    CalculateAIIPatientsComplianceOnOlsk Slιder1_SlιdeChange
    End Sub 
    
    Private Sub Form_Activate()
    Me. Re fresh gnd Refresh Sllder1_SlιdeChange
    SetPπnTerlcon True, "Sprint All Patient's Summary End Sub
    Public Sub CafculateAIIPattenisCompliaπceOnDiskO
    T is orocedure -s called when it is necessary to uccate rhe disclay cue to some element or feature oamg cranged .ook at ail ce' tce data files in the scecι*ed directory Retneve apcrecπate data from eac.n fi.e and put into global structure holcmg all pa ents
    If xbAIIPatientsFormLoadiπg - True Then Exit Sub
    Dim r As Integer, i As Integer. dCompliaπce As Double
    Dim sPath As Stnng, sFileName As Stnng, sFileSpec As Stnng
    Dim sTab As Stnng, sTemp As Stnng, lErrorCode As Long
    On Error GoTo CaIculateAIIPabentsCαmplιaπceOπDιsk_error Me MousePomter = vbHourglass Me Refresh array
    e taken out The code is still in the program D |< Start Date |< Last Dose |> Doses " D |< Start Date j< Last Dose |> Score 
* 
 
    Form Resize gnd Col - 1 'sef ro column 1 gnd Redraw = False 'turn off redraw to speed up processing
    sPatientlD + sTab last dose da
fe 
 gπd Addltem sTemp 
 gπd Redra s γπj
e  
    CalculateAIIPatιentsComplιanceOnDιsk_Extt Me MousePomter = vbOefault 
 
    CalcutateAIIPatιentsComplιanceOπOιsk_error " R um 0 test-ng or y
    Resume CalcuIateAHPatιentsCαmpltaπceOnDιsk_Exιt End Sub
    Private Sub Form_Load{) frmMain MousePomter = vbHourglass DoEvents xbAIIPatieπtsFormLoading ~ True
    ReOim xsFatιentFιIeSpecs(2)
    If c bαOateSelection Ustlndex < O Then cmboDateSelection Listlndex = 2 cmboDataToView Ustlndex = 0 xbAIIPatientsFormLoading = False
    Cal ilateAIIPatieπtsComplianceOnDisk gπd Col = 0 gπd Sort - 1 genenc ascending frmMain MousePomter * vbDefault
    RefreshAUOpenForms
    End Sub
    Private Sub Form_Resize()
    Dim iWidthRemaming As Integer
    Static bProcedurelnProgress As Boolean
    If bProcedurelnProgress Then Exit Sub if Me WindowState ~ vbMinimized Then Exit Sub bProcedurelnProgress = True
    _ If Me Width < 5000 Then Me Width - 5000 bProcedurelnProgress =* False
    - End If
    _ If Me Height < 5000 Then Me Height * 5000 bProcedurelnProgress - False
    - End If
    SSPanell Left = Me Width - SSPanel! Width - 100 gπd Width = SSPaneH Left - gπd Left - 150 gπd Height = Me Height - gnd Top - 425 gπd ColWιdth(4) = 625 Score gπd ColWidm(O) = (gπd Width - gπd ColWidth(4)) / (gπd Cols - 1) Name gπd Co(Wιdth(1) - gπd ColWtdth(O) ID iWidthRemaming = gπd Width - gπd ColWldth(O) - gπd ColWidth(1) - gπd ColWidth(4) - 120 gnd Co(Width(2) = iWidthRemaming / 2 Start Date gπd CoIWidth(3) = gnd ColWidth(2) Las.' Dose Da'e 
 
 bProcedurelnProgress = False End Sub
 
    Private Sub gπd_CIιck()
    Dim iRow As Integer
    Find o-r which colum i was clicked
    Sc* the a*rav only if tl'e header .vas c'icxe
    If gπd Rows ■= 2 Then Exit Sub
    
    Private Sub grid_DblClick()
    Dim sFileName As Stnng, r As Integer, iRow As Integer If gnd Rows ■: 2 T en Exit Sub iRow = gπd MouseRow sFileName = xsPatιentFιleSpecs(gπd RowData(ιRow))
    Open the document that was double-clicked r = OpenPatιentData(sFιleName) End Sub
    Private Sub Slideι _SlideChange()
    Dim i As Integer, j As Integer
    LabeH(O) Caption = "Compliance Threshold =< " ♦ CStr(Slιder1 Value) + "%" gnd Redraw = False < Sliden Value Then
     
 gπd Row = 0 gnd Col = 0 grid Redraw = True End Sub 
  
    Private Sub txtEπdDate_HideDropDown()
    DoEvents gsLastEndDateChosen = txtEndDate cmboDateSelection Listlndex = S selec' the custom setting
    CalculateAIIPatlentsComplianceOnDisk Slιder1_SlιdeChange End Sub
    Private Sub txtStartDate_HideDropDowπ()
    DoEvents gsLastStartOateChosen = txtStartDate cmboDateSelection Listlndex = 5 'select *>-5 custom salting
    CalculateAIIPatientsComplianceOnDisk
    Slιder1_SlιdeChange End Sub 
    
    Public Sub UpDatefrmPatientSummaryHeaderO Dim DataStruct As DeviceDataStruct DataStruct = PAT DATA txtPatientLastName = " " + DataStruct sPatieπtLastName txtPatientFirstName = " " + OataStmct sPatientFirstName txtPatientlD = " " ♦ DataStructsPatientlD txtDπjg = " " + DataStruct.sDrug txtTxCenter = " " * DataStruct sTxCeπter Struct dLastDownloadDate. gsOateDisplayFormat) 
 txtSeπalNumber = " " + DataStruct sSeπalNumber MS Chart! Visible = True
 
    If cmboDateSelection Listlndex < 0 Then cmboOateSelection. istlndex = 1 'pick a default range txtStartDate = FormatSlCDatelDafaStnrct dE/en'Data(W gsDateOispiayFormat) 'txtEndDate = FormatSfCDatetDataStruct dEver'.DaleiDataStruct lEventData(O))) gsDateDisclayFormat) Me Refresh
    End Sub
    Public Sub UpdatePatientDosiπgGraphQ
    'Update the grapn due to a check box being changed
    Dim sTab As Stnng, I As Long
    Dim IDateBegin As Long, IDateEnd As Long, IScoreSum As Long
    Dim IPIotValue As Integer 'keeps a tally of the value to be plotted for each day
    Dim dPlotDate As Double, iDayEventsFound As Integer, iDatelndex As Integer
    Me MousePomter = vbHourglass DoEvents
    
    If IsOate(txtEπdDate) Then Date(txtEndDate)) AT_DATA dEventDate(PAT_DATA lEventData(O))) 
 
    MSChartl RowCount = 0 dPlotDate = lnt(PAT_DATA.dEventDate(1 )) get the Inst event cate If IDateBegin Then there is at least a value in there
    - Select Case cmboOataToView Listlndex _ Case 0 Doses per day score tall dcses on this day regardless of lime taken
    For I = IDateBegin To IDateEnd tne numper of even's is stored here iPlotvalue = CalcOayDoseScore_AIIDoses(PAT_DATA, I)
    MSChartl RowCount = MSChartl RowCount ♦ 1 increment the row count
    MSChartl Row = MSChartl RowCount plot in last row
    MSChartl Data = IPIotValue IScoreSum = IScoreSum + iPlotvalue
    3/19/98 
 HH
    
    Case 1 Compliance Doses per day ton time doses per da )
    For I = IDateBegin To IDateEnd 'he ~~mLe*o* e/er s is stereo e e iPlotvalue = CalcOayDoseScore_OπTime(PAT_DATA I)
    MSChartl RowCount = MSChartl RowCount + 1 ncrerent I e -c v count
    MSChartl Row = MSChartl RowCount plot n 'as row
    MSChartl Data = iPlotValue
    IScoreSum = IScoreSum + iPlotValue Next I
    MSChartl Plot Axιs(VtChAxιsldY).AxιsScale Type = VtChScaleTypeϋnear MSChartl Plot AxisfVtChAxisldY) ValueScaleJkuto = False MSChartl Plot AxisfVtChAxisldY) ValueScale Maximum = 100 MSChartl Plot Axιs(VtCnAxιsldY) ValueScale MajorDrvision = 10 MSChartl TitleText = "On-Time Doses Day Score (within prescπbed time)" MSChartl Plot Axιs(VtChAxιsldY)ΛxιsTitle Text = "Percent" txtScore = FormatS(CStr(IScoreSum / (IDateEnd IDateBegin + 1)) " t#") + " %' ;„/ "e most *eceπ score r e lev oox
    Case 2 Doses Taken per day
    For I = IDateBegin To IDateEnd the number of e/e" s is stored here iPlotValue = Calc0osesSumTakenOnSpeclftcDay(PAT_DATA I)
    MSChartl RowCount = MSChartl RowCount + 1 increment fe row count
    MSChartl Row = MSChartl RowCount plot in last row
    MSChartl Data = iPlotValue Next I
    MSChartl Plot Axιs(VtChAxιsldY).AxιsScale Type = VtChScaleTypeϋnear
    MSChartl Plot AxisfVtChAxisldY) ValueScale Auto = False
    MSChartl Plot AxisfVtChAxisldY) ValueScale Maximum = 10 client wants to hard code this at '0
    MSChartl PlotAxls(VtChAxιsldY) ValueScale MajorDivision = 10
    MSChartl Plot Axιs(VtChAxιsldY) ValueScale MinorDrvision = 1
    MSChartl TitleText = " Total Doses Taken Per Day"
    MSChartl Plot Axιs(VtChAxιsldY).AxιsTitle Text = "Doses" txtScore = "" no score apoears for doses sum
    Case 3 Doses Missed ne'e this section ts not used currency C tent deeded to remove it from the display
    For I - IDateBegin To IDateEnd the number of e/erts is stored here iPlotValue = PAT_DATA iDosesPerOay - CalcDosesSumTakenOnSpecιficDay(PAT_DATA I)
    MSChartl RowCount = MSChartl RowCount + 1 increment the row count
    MSChartl Row » MSChartl RowCount plot in last row
    MSChartl Data = IPIotValue Next I
    MSChartl Plot Axιs(VtChAxιsldY)_AxιsScale Type = VtChScaleTypeϋnear MSChartl Plot AxisfVtChAxisldY) ValueScale Auto = False
    MSChartl Plot Axιs(VtChAxιsldY) ValueScale Maximum = 10 clien' wants to hard code ' s at 10 MSChartl Plot Axιs(VtChAxιsldY) ValueScale MajorOrvision = 10 MSChartl Plot AxisfVtChAxisldY) ValueScale MinorDrvision = 1 VSChartl F'ot AxιstVCnAvsldv) AxisSca'e Hide = Fa.se MSChartl TitleText = " Doses Missed Per Day" MSChartl Plot Axιs(VtChAxιsldY)»AxιsTitle Text = "Doses" txtScore = "" "o score appears 'o' oses missed - End Select End If
    WSCham A3* s-"β = "iβs*" Me MousePomter = vbDefault
    
    Private Sub btnC!ose_Click()
    Unload Me End Sub
    Private Sub cmboAverageDays_Click()
    UpdatePatientDosingGraph End Sub
    Private Sub cmboChartType_Click()
    __ Select Case cmboChartType Text Case "Line"
    MSChartl chartType = VtChChartType2dLιne
    Case "Area"
    MSChartl chartType = VtChChartType2dArea
    Case "Bar" MSChartl .chartType = VtChChartType2dCombιnatιoπ
    Case "Step"
    MSChartl ChartType = VtChChartType2dStep
    _ End Select End Sub
    Private Sub cmboDataTov ew_Click()
    UpdatePatientDosingGraph End Sub
    Public Sub cmboDateSelectioπ_Click()
    _ If PAT_DATA lEventData(O) = 0 Then 'no data apcears to oe loaded txtSfartDate = CVDate(Now) txtEndDate = CVOate(Now) _ 
 
    Select Case cmboDateSelection Listlndex Case 0 'recenr 7 days txtEndDate = CDate(lnt(PAT_DATA dEventOate(PAT_DATA.ιEventData(0)))) txtStartDate = CDate(lnt(PAT_DATA dEveπtDate(PAT_DATA lEveπtData(O))) - 7)
    - Case 1 receπf 1 days txtEndDate = CDate(lnt(PAT_DATA dEveπtDate(PAT_DATA lEventData(O)))) txtStartDate = CDate(lnt(PAT_DATA dEventDate(PAT_DATA lEventOata(O))) - 14)
    - Case 2 recent 30 days txtEndDate = CDate(lnt(PAT_DATA dEveπtDate(PAT_DATA lEventDate(O)))) txtStartDate = CDate(lnt(PAT_DATA dEventDate(PAT_DATA lEventData(O))) - 30)
    - Case 3 rscenr 6 months txtEndDate = CDate(lnt(PAT_DATA dEventOate(PAT_DATA lEventData(O)))) txtStartDate = CDate(lnt(PAT_DATA dEventDate(PA
"f DATA lEventData(O))) - 180) 
 pnlControls Lett = Me Width - pnlControls Width - 200 pnlChart Width = pnlControls Left - 100 MSChartl Width = pnlChart Width - 100 pnlChart Height = Me Height - pnlChart Top - SOO MSChartl Height = pnlChart Height - 100 bProcedurelnProgress = False
 
    End Sub
    Private Sub Form_Unload(Cancel As Integer)
    'Save last set ngs selec'ed by user
    PAT_SUM_DEFAULTS cmboDataToView = cmboDataToView Listlndex PAT~SUM_DEFAULTS cmboChartType = cmboChartType Ustlndex End Sub
    Data(O))) Then The starting date is being set to the first dose "
     
 cmboDateSelection Listlndex = 5 'select the user setting UpdatePatientDosingGraph End Sub
 
    last Date(l)) Then dose taken by this patient The starting date is being set to the first dose
     
 cmboDateSelection Listlndex = 'select the user setttrg UpdatePatientDosingGraph End Sub 
 
    Attπbute VB_Name - "frmDosingCalendar" Attπbute V8_GlαbalNameSρace = False tg Attπbute VB~Creatable = False Attπbute V8_Predeclaredld = True Attπbute VB_Exposed ~ False Option Explicit
    Pπvate bgResizedCalendar As Boolean
    Private Sub btnChaπgeCornρliance_CHck() giLatestOptioπsTabSelected *= 1 'asclay the ptoper ao onca tne dialog frmOptions Show vbModal
    End Sub
    Private Sub btnClose_Click() Unload Me
    End Sub
    Private Sub Caleπdar_DayChaπge() Static bProcedurelnProgress As Boolean
    If bProcedurelnProgress Then Exit Sub 'ore'/ent recursive calls bProcedurelnProgress = True frmDosingCalendar.MousePointer ~ vbHourglass 'hourglass
    DoEvents
    UpdateZoomSox frmDosingCalendar.MousePointer = vbDefault 'default glass bProcedurelnProgress = False 'allow another call to this sub
    End Sub
    Private Sub Caieπdar_ oπthChange()
    Static bProcedurelnProgress
    If bProcedurelnProgress Then Exit Sub 'prevent recursive calls bProcedurelnProgress - True frmDosingCalendar.MousePointer = vbHourglass 'hour glass
    DoEvents
    UpdateCalendar frmDosingCalendar MousePomter - vbDefault 'default bProcedurelnProgress - False
    End Sub 
    Private Sub Caleπdar_MouseMove(Buttoπ As Integer, Shift As Integer, X As Single, Y As Single) _ If bgResizedCaleπdar Then Update Calendar bgResizedCaleπdar = False
    - End If
    End Sub
    Private Sub Calendar_YearChange()
    Calendar_MoπthChaπge
    Private Sub chkDoseChanged_Cltck()
    DrawAIIDoseSizeChanges
    UpdateZoomBox End Sub
    Private Sub chkDoses ιssed_Cltck() DrawAIIDosesMissed
    UpdateZoomBox End Sub
    Private Sub chkDosesNotCompiιed_CIιck() DrawAIINonCompliedDosesTaken UpdateZoomBox
    End Sub
    Private Sub chkDosesTaken_CItck()
    DrawAIICompliedDosesTaken
    UpdateZoomBox End Sub
    Private Sub chkWeekNumbers_CIιck()
    RemoveAIIObjects frmDosingCalendar Calendar WeekNumbers = chkWeek Numbers
    DoEvents
    UpdateCalendar
    End Sub 
    frmDosingCalendar frm - Form_Actιvate
    Private Sub Form_Actιvate()
    SetPππterlcon False — End Sub
    Private Sub Form_Load()
    Dim i As Integer srsrr calendar xit date of latest dose _ If PAT_DATA d£veπtDate(PAT_DATA lEventData(O)) > 0 Then fmiDosingCalendar Calendar Date = CVDate(PAT_DATA dEventDate(PAT_OATA lEventDala(O))) _ Else frmDosingCalendar Calendar Date = Now _ End If Me Show
    
    Set the dialog controls to the selϋrgs last set by user chkDosesMissed = CAL_DEFAULTS ChkDosesMissed chkDosesNotComplied = CAL_DEFAULTS chkOosesNotComplied chkDosesTaken = CAL_DEFAULTS chkDosesTaken ChkDoseChanged = chkDoseChanged
    UpdateCalendar End Sub
    Private Sub CreateCaleπdarTιmeScale() On Error Resume Next Create the ϋ e scale on detail area Dim sAM Stnng sPM As Stnng i As Integer
    _ If frmDosingCalendar Width < 5000 Then
     
 lblDetaιlTime(2) Caption = "2" + sAM With lblDetaιlTιme(2)
 
    Left = (Me pnlZoom Width * (i / 24)) - (Me IblDetaιlTime(ι) Width / 2)
    ForeColor = £HFFFFFF
    Visible = True
    ZOrder End With lblDetaιiTime(4) Caption = "4" ♦ sAM With lbl0etaιlTιme(4)
    Left = (Me pnlZoom Width * (l / 24)) - (Me IblDetaιlTιme(ι) Width / 2)
    ForeColor = 4HFFFFFF
    Visible = True 
 josinguaieπu r irm - L-reatet^aienαar 1 1 joaie
     ' 1 114
    ZOrder End With lblDetaιlTime(6) Caption = "6" * sAM With lblDetaιlTime(6)
    Left = (Me pnlZoom Width * (l / 24)) - (Me IblDetaιlTime(ι) Width / 2)
    ForeCclor = iHFF-FFF
    Visible = True
    ZOrder End With lblDetaιlTime(8) Caption = "8" «■ sAM With lblDetaιlTime(8)
    Left = (Me pnlZoom Width * (l / 24)) - (Me IblDetaιlTιme(ι) Width / 2)
    ForeCcior = S.rlF=~FF~
    Visible = True
    ZOrder End With
    IblDetaιlTi e(tO) Caption = "10" * sAM With lblDetaιlTime(IO)
    Left = (Me pnlZoom Width * (i / 24)) - (Me IblDetaιlTime(ι) Width / 2)
     =oreCcor - &HF==FF=
    Visible = True
    ZOrde' End With lblDetaιlTime(12) Caption = "12" + sPM With lblDetaιlTime(12)
    Left = (Me pnlZoom Width * (I / 24)) - (Me IblDetaιlTime(ι) Width / 2)
    FareCcor = &HF-=FFF
    Visible = True
    .ZOrder End With lblDetaιlTime(14) Caption = *2" + sPM With lblDetaιlTϊme(1 )
    Left = (Me pnlZoom Width * (i / 24)) - (Me IblDetaιlTime(l) Width / 2)
    ForeCclor - S.HFFFFFF
    Visible = True
    ZOrder End With lblDetaιiTime(16) Caption = "4" * sPM Wϊth lblDetaιlTime(16)
    Left = (Me pnlZoom Width * (i / 24)) - (Me lblDetaιlTime(r) Width / 2)
    ForeCclor = &HFF-FF=
    Visible = True
    ZOrde' End With lblDetaιlTime(18) Caption = "6" + sPM With lblDetaιlTime{18)
    Left = (Me pnlZoom Width * / 24)) - (Me IblDetaιlTime(ι) Width / 2)
     =oreCccr - &HF~~rF~
    Visible - True
    ZOrder End With lblDetaιlTime(20) Caption = "8" + sPM With lbl0etaιlTime(20)
    Left - (Me pnlZoom Width * (i / 24)) - (Me IblDetaιlTime(ι) Width / 2)
    ForeCo!or = SHFFFFFF
    Visιblβ = True
    ZOrder End With
    4- 
 lblDetaιlTιme(22) Caption = "10" ♦ sPM — E With lblDetaιlTϊme(22)
    Left = (Ma pnlZoom Width * (i / 24)) - (Me IblDetaιlTime(l) Width / 2)
    ForeColor = 4HFFFFFF
    Visible = True
    ZOrder End With
    On Error GoTo 0 End Sub
    Private Sub Form_ ouse ove(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_Resιze()
    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 Width - 6000 bProcedurelnProgress - False
    - End If
    _ If Me Height < 5000 Then Me Height ~ 5000 bProcedurelnProgress - False
    _ End If
    DeiβteAHObjec+s
    CreateCalendarTimeScale pnlControls Left = Me Width - pnlControls Width - 200
    Calendar Width = pnlControls Left - Calendar Left - 150 pnlZoom Top - Me Height - pnlZoom Height - 450 pπlTi e Top - pnlZoom Top
    Calendar Height - pnlZoom Top - Calendar Top - 100 bgResizedCalendar - Tαie med events on form can not be updated ύl resize is done pnlZoom Width = Calendar Width bProcedurelnProgress ■= False End Sub 
    
    Private Sub Form_Unload(Cancel As Integer)
    CAL_DEFAULTS.chkOosesMissed = chkDosesMissed CAL_DEFAULTS.chkOosesNotComplied = chkDosesNotComplied CAL~OEFAULTS. ChkDosesTaken = chkDosesTaken CALlDEFAULTS.chkDoseChanged = chkDoseChanged End Sub
    Private Sub frameVie _MouselVlove(Button As Integer, Shift As Integer, X As Single Y As Siπαlel _ If bgResizedCalendar Then a ' -^mgiej
    UpdateCalendar bgResizedCalendar = False _ End If End Sub
    Private Sub pnlControls_ ouseMove(Buttoπ As Integer, Shift As Integer, X As Single, Y As Single)
    _ If bgResizedCalendar Then
    UpdateCalendar bgResizedCalendar = False _ End If End Sub 
    trmPatienlDosingKpt Irm File Declara is
    —1 117 1
    Attπbute VB_Name = "frmPatientDosingReport Attπbute V8_GlobalNameSpace = False Attnbute VB_Creatable « False Attπbute VB_Predeclaredld = True Attnbute VB_Exposεd = False Option Explicit
    Private Sub RescaleGπd()
    Dim iRemainder As Integer put any *ixed width columns trs' gπd ColWidthfβ) = 0 dor I she / ',- s coι-τπ gnd ColWidt (1) - 1300 gπd CofWidth(2) = 900 gπd ColWidth(3) = 1000 gπd ColWιdth(4) = 950
     (Remainder = gnd Width - gπd ColWidth(4) - gπd ColWidth(3) - gπd ColWιdth(2) - gπd ColWidth(t) gπd ColWidth(O) = iRemainder * 025 gπd CofWidth(5) = iRemainder * 0 75 - 370
    Public Sub UpdatefrmPatientDosingReportHeaderQ
    Snow custom labels from config file if there were any Labell (3) = gsCustomLblPatientLastName Label1(1 ) = gsCustomLblPatlentFirstName Labell (2) = gsCustomLblOrgan LabeM(O) = gsCustomLblPatientlD Labe (6) = gsCustomLblTxCenter Labell (7) = gsCustomLblDrug txtPatlentLastName = " " + PAT.DATA sPatientLastName txtPatientFirstName = " " + PAT_DATA sPatientFirstName txtPatientID = " * * PAT.DATA sPatlentlD txtDrug = " " + PAT_DATA sDrug bctTxCenter = - " + PAT_DATA sTxCenter txtOrgan = " " + PAT_DATA sOrgan
    End Sub
    Public Sub UpdatePatientGndDisplayO
    This prcc is called when it is necessary ro upda'e the dιsp,ay due to some element or feature being changed
    Dim sTab As Stnng, i As Integer sTime As Stnng sDate As Stnng sTemp As Stnng
    Dim bShowDosesTaken As Boolean, bShαwOoseChaπges As Boolean bShowUserEveπts As Boolean sTab = ChrS(9) gπd Clear the erase 'he gπd gπd Rows = 1 gnd FormatStπng = "<Date 4 Time | Event Type | Dose Size |" * gsLabelGπdColumπCustomt * " |" + gsLabelGndCαlumnCustom2 ► ♦ " I" * gsLabelGπdColumnCustom3
    RescaleGπd gπd Row = 0 gπd Col ~ 1 set to columi 1 gπd Redraw = False bShowDosesTaken = chkDoses Value speed o "*e c cla/ n loop b/ assign -α co"t*ol value to a var bShowDoseChanges = chkDoseChanged Value bShσwUserEvents = chkUserDelined Value 
 PatienlDosingPpl Irm - UpdalePatieπtGi isplay
     
 gπd Redraw = True gπd Row = 0 gπd Col = 0 btnDeleteUserEvent Enabled - False
 
    End Sub
    Private Sub btnClose_Clιck()
    Unload Me End Sub 
    auciiiuosiπgKpl frm - btnDeleteUsercveπl_Click
    Private Sub btπDeleteUserEvent_Click()
    Dim r As Integer, ilndex As Integer. sMSG As Stnng " * vbCrLf ♦ bCrLf * "Do you want to delete the event?"
    Then EveπtDelete PAT .OATA, ilndex
    
    Private Sub btπNewUserEvent_Click()
    'Add an event to the gπd for a rime and dale cefined oy the user Dim ilndex As Integer, IDate As Long, i As Integer
    
    Private Sub chkDoseChaπged_Click()
    Call UpdatePatientGπdDisplay End Sub
    Private Sub chkDoses_Click()
    Call UpdatePatientGndDisplay End Sub 
    IrmPaticnlD singPpi frm ctiklkerDefin..-. Click
    Private Sub chkllserDefiπed_Clιck()
    Call UpdatePatientGndDisplay End Sub
    Private Sub Form_Actιvate()
    Me Refresh
    Form_Resιze gnd Refresh
    Call UpdatePatientGndDisplay
    SetPnnterlcon True "SPnnt Dosing Report End Sup
    Private Sub Form_Load()
    UpdatefrmPatlentDosingReportHeader End Sub
    Private Sub Form_Resιze() Static bProcedurelnProgress As Boolean If bProcedurelnProgress Then Exit Sub If Me VvindowState = vbMinimized Then Exit Sub bProcedurelnProgress = True
    _ If Me Width < 8100 Then
    Me Width = 8100 bProcedurelnProgress = False _ End If
    If Me Height < 5000 Then
    Me Height = 5000 bProcedurelnProgress = False End If frameVϊew Left = Me Width - frameView Width - 250 btπClose Lett = Me Width - btnClose Width - 250 gπd Width = btnClose Left + btnClose Width - gnd Left gnd Height = Me Height - gπd Top - 425 RescaleGnd bProcedurelnProgress = False End Sub
    Private Sub gπd_After£dιt(ByVal Row As Long, ByVal Col As Long) Dim ilndex As Integer _ Select Case Col . Case 3 use* column 1
    PAT_0ATA sUserDatal (gπd RowData(Row)) = gπd Text pu f 'he crang° "to the sιn.cure
    — Case 4 user coιur- 2
    PAT_DATA sUserData2(gπd RowData(Row)) = gπd Text p^l 'he c'-.rce no e sfuc "
    — Case 5 usercαlum~ 3
    PAT_DATA sUserOata3(gπd RowData(Row)) = gπd Text p t 'he change i-ro tl e structure
    — End Selec* gbPatientDataNotSaved - True set *-ag to irdtcate hz* '*ι° lie nas danced out not ye' beer save:
     
 iiπi .iiientuosingRpt frm - grιd_Afle .it
 
    πr run time etrot bv looking for last row
    e As Integer, Shift As Integer) table g :c indicate tra' the f.ie nas changed but not vet oeen saved 
 
    Private Sub grid_RowColChange()
    Dim ilndex As Integer low ce / to oe eci'ed /it is a custom column
    
    
    End Sub 
    frmReadDeviceData frm - File Declarations
    Attπbute VB_Name ~ "frmReadOeviceData" Attπbute VB_GlαbalNameSpace ~ False Attribute VB reatadle - False Attπbute VB_Predeclaredld ~ True Attπbute VB^Exposed = False Option Explicit
    Private Sub btnClose_Clιck()
    Unload Me
    End Sub
    Private Sub btnReadEntireConteπts_Click()
    Dim r As Integer, lErrorCode As Long, i As Integer sMSG As Stnng r = ValidatePatientDataSaved ensure trat ore zahe-' da'a ,vas ≤a/etf oercre crocεedng If r = vbCancel Then Exit Sub 
 calls to csvics stco coiltnc for -
1 
 txtPatientLastName = 
™* clear cut the text botes before reading data txtPatientFirstName - ™ clear out the text ooxes before reading data txtDrug ■= " txtPatientlD = "" txtTxCenter = "" txtOrgan = ~
* txtSeπalNumber = 
*" txtDoseSize ~ 
™ txtDoseTime(l) - "" txtDoseTime(2) = " txtDoseTime(3) - "" txtDσseTime(4) - "
* txtDosesPerDay - ~ txtDoseLockoutHours - " txtMedicatiσπRemainiπg = txtEventCount = "" txtLastRetnevalDate = "" txtDe vice Started = 
™ , lErrorCode)
 
     
 btnReadEntire Contents Enabled = True re-enable button R e fre sh A II O pe n F orm s
 
    Compare Latter nme to V3iue retneved from int lie to determine if *-. reminder should oe given to the user to change the oatteres i - Clnt(GetlNISettιng(gsApplnιFιleSpec, "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 'tie eτor lag returned from the device to see ' r'-e orow.nout bit was se' it so append a afferent notice to trie -"essage man the noπ~al c -e
    - If PAT_DATA b Error Brown Out Then sMSG •= sMSG + "The device indicates that power was bnelfy lost due to low voltage "
    - Else sMSG = sMSG + They have been in place for over ' * CStrfi / 30) + " months " 
 fmiReadDeviceOala frm - btnRea JΞntιreContenls_Click
    
    Private Sub Foπm_Activate()
    PopulateDeviceCommDialog PAT_DATA, Me Comm InitializeCommPort 'initialize the comrr. IN! *iιe settings gbKeepPollingDevice = True continue paling device PolIDeviceContinually Me SetPπnterlcσn False, "" End Sub
    Private Sub Form_Load()
    Me Left = 0 Me Top = 0
    Unload frmDevicelnitialize 'don't need (his term gbCommOK = 99 'reset flag that will gve an indication as to the communication status End Sub
    Private Sub Form_Unload(Caπcel As Integer) gbKeepPollingDevice -= False 'stop polling the device
    Wait 0.1 End Sub 
    frm πrιt frm - File Declarations
    Attnbute VB^Name = "frmPnnt" Attnbute 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 btnPriπtNow_Click() btnPπntNow Enabled - False btnPππtNow.Refresh vsPnnterl .Action = paPπntAII btnPπntNow. Enabled - False End Sub
    Private Sub btnPriπtPage_Ciick() btnPπntPage. Enabled = Faise btnPπntPage. Refresh vsPnnterl .Action = paPnntPage btπPπntPage. Enabled - True End Sub
    Private Sub btnRefresh_Click{)
    RefreshPreview End Sub
    Private Sub Form_Load() Dim i As Integer gbPπntFormLoading = True frmPπnt.vsVϊewPortl .BorderStyle = 1 'turn off til needed gbPπnterErrorDetected ~ False
    Me.Width = 7500
    Me.Move (Screen.Width - Me.Width) / 2, (Screen.Height - Me.Height) / 2 'center form on screen ' datPnntlngredieπt DatabaseNam.e = sgDataBaseName
    IblActtvePπnter.Captioπ = " " + vsPnnterl. Device gbPreventPreviewUpdates = False 'allow controls to update when called
    Me. Show DoEvents RefreshPreview SetPπnterlcon False, "H End Sub 
    frmPnnt frm - Form_QueryUnload
    Private Sub Form_QueryUπload(Cancel As Integer, UπloadMode As Integer)
    Dim r As Integer If gbPπntSpoolinglnProgress Then user tπed to exit .vhile pnnt spooling
    Beep r = Msgθox("ttems are still waiting to be pnnted If you continue, the pπnt job may be lost " *■ vbCrLf ■*■ VbCrLf *■ "Do you still want to V close this form?". vbQuestion +■ bYesNo. "Waiting For Pπnter")
    If r = vbNo Then Cancel = Trυe prevent crasr errcr End If gbPπntSpoolinglnProgress = False End Sub
    Private Sub Form_ esize() _ If frmPπnt WindowState <■> vbMinimized Then
    Panel3D1 Left = frmPnnt. idth - Panel3D1 Width - vsViewPortl Height = (frmPπnt Height - 400) VsViewPortl Width = (Paπel3D1 Left - 100) - End If
    SetPreviewSrze End Sub
    Private Sub HScroll1_Change()
    Static bProcedureActrve If bProcedureActive Then
    HScrolH .Refresh 
 bProcedureActrve = True 'prevent recursive calls to this procedure
 
    HScrolH .Enabled = False fππPnnt.vsPπnterl.PreviewPage = HScrolH .Value UpdatePageButtons bProcedureActrve = False 'prevent recursive calls to tnis procedure End Sub
    Private Sub HScrolH_Scroll()
    Static bProcedureActrve
    If bProcedureActive Then Exit Sub bProcedureActrve = True 'prevent recursive calls to this procedure
    IblPageNumber = HScrolH Value UpdatePageButtons bProcedureActrve = False 'prevent recursive calls to this procedure End Sub 
    frmPπnt frm - lblActιvePππter_Clιcκ
    Pπvate Sub IblActivePrιnter__CIick()
    Static bProcedureActive
    If bProcedureActive Then Exit Sub bProcedureActive -= True pievent recursive calls to this oiocsdure
    On Error GoTo btnChangePπnter_Clιck_Error
    CommoπDialogl Mm = 1 set ,owest page number to onnt
    CommonOialogl Max = giTotalPπntPages 'se' highest cage nttnoei to pr-t
    CommonDialogl FromPage = 1 set lowest page πu.moei to pnnt
    CommonDialogl ToPage = gfTotalPπntPages 'set nigrest page number fo pnnt
    Set flags PD^IDE^RINTTCF.LE &. 10CC00S Tne =>::r,t to -'/s cΛecΛ box -s no' disptaved PD_NCPAGENUMS &r~.3& Disables the Pages option button and -r.e associated edit control 'FD^FRINTSETUP 3,h'40& Causes the system αsclay the Pnnt Setuo dialog bcx rather than the ^nr. dialog bcx
    CommonDialogl. Flags = &H40&
    CommonOialogl CancelError = True
    CommonDialogl .Action = 5 'call pnr.ter common αaiog
    Update cac cn to most current pnr.ter seleczeπ
    IblActive Pπnter Caption = " " + vsPnnterl Device frmPπnt.MousePoιnter = vbHourglass
    DoEvents
    SetPreviewSize 'this is mainly for layout ,t portrait landscape <s changec
    RefreshPreview frmPπnt MousePomter = vbDefault
    DoEvents btnChangePπnter_Clιck_Exιt bProcedureActive = False 'prevent recursive calls to this procedure 
 btnChangePπnter_Clιck_EπOr Resume btnChangePnnter_Clιck_Exιt
 
    End Sub
    Private Sub optZoom_Click(lndex As Integer)
    SetPreviewSize End Sub
    Private Sub vsPrinteι _EπdPage()
    Call PπntPageNumber End Sub
    Pnnt"
     
 frmPnnt frm - vsPnnterl Error las not yet been issued it is powered on and is on-line ", , "Can t Pnnt" 
  
    Private Sub vsPπnter _NewPage{)
    Dim fCurrent FontSize As Single bCurrentFσntltalic As Boolean. sCurreπtFontNarne As Stnng Dim iCurrentTextAlign As Integer, ICurrentY As Long
    With frmPnnt vsPnnterl fCurrent Font Size = FontSize eme b r the exisfng se'tirgs so r'ιey can oe cranged oack bCurrentFontltalic = Fontltalic iCu eπtTextAlign - TextAlign ICurrentY = CurrentY sCurrentFαntName = FoπtName
    FoπtName = "Anal" Fontltalic = False TextAlign = taRightTop
    CurrentY •= 14-40 * 05 'pnnt name en of program
    FontSize = 9 set font size
    Fontltalic - False frmPπnt vsPnnterl = App Title
    FontSize = fCurrentFontStze
    Fontltalic ■= bCurrentFoπtltalic .TextAlign - iCurrentTextAlign .CurrentY - ICurrentY
    FontName = sCurrentFontName End With
    _ Select Case gsActive Form Name — Case "frmPatientDosingReport"
    If giTotalPπntPages Then PπntDosmgEventsHeader "" _ End Select giTotalPπntPages = gfTotalPπntPages + 1 End Sub 
    frmDevr.eDiagnostics frm - File Dec.-..
    Attribute VB^Name = "frmOeviceDiagnostics ' Attπbute VB_GlobalNameSpace = False Attnbute VfTcreatable = False Attπbute VB_Predeclaredld = True Attπbute VB^Exposed = False Option Explicit
    Private Sub btnChaπgeBatterιes_Click()
    Call ChangeBatteπes equest End Sub
    Private Sub btnClose_Click()
    Unload Me End Sub
    Private Sub btnReadEntireConteπts_Click()
    Dim r As Integer, lErrorCode As Long, i As Integer r ~ ValidatePatientDataSaved ensure that previous patient data was saved before proceed.ng If r = vbCancel Then Exit Sub 'prevent recursive calls to device prevent recurs.ve calls to device srop polling for now 
 bdPatientlastName = ~ 'clear out the text ooxes before reading data txtPatientFirstName = ~ clear out the text boxes before reading data txtDrug Clear bctPatlentlD = ~ txtTxCeπter = " txtOrgan. Clear txtSeπalNumber = ~ txtDoseSize = ~ txtDoseTime(l) = ~ txtDoseTϊme(2) = ~ txtDoseTime(3) = "" txtDoseTιme(4) = ~ MDosesPerOay = ™ txtDoseLoc outHours = 
™ txtDeviceStarted - " txtMedicationRemaining = " txtBatteryChangeTϊmer = ~ txtEventCouπt = ~ bctFirmwareVer = "" t - Comm_ReadEntιreMemoryContents(PAT_DATA, lErrorCode)
 
     
 gbKeepPollingDevice = True start poll'ng again btnReadEntireContents Enabled = True le-er.able buhon btnSendData Enabled = True RefreshAIIOpenForms End Sub 
 rmDeviceDiagπostics frm - btnSendData _..or,
 
    Private Sub btnSendData_Click()
    Dim i As Integer, r As Integer, lErrorCode As Long r = ValιdateDoseNumbers(Me) If r = False Then Exit Sub cat
ion 
 prevent recursive calls to device 'srop pcl'ing for now 
 
    On Eπor 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 >o device
    If lErrorCoαe Then Error lErrorCode error number l = Comm_SendCustomData(PAT_DATA, DATA_BEGIN_CUSTOM3, lErrorCode) send to device
    If lErrorCode Then Error lErrorCode error number l = Comm_SendCustomOata(PAT_DATA, DATA_BEGIN_CUSTOM4, lErrorCode) send to device
    If lErrorCode Then Eπor lErrorCode error number ensure that the values in the text boxes are converted into the global structure TimeValue(txtDoseTime(ι)) save Dose Interval -1 Indicate that no time was set 
 r = Comm_SeπdDosιngParams(PAT_DATA, lErrorCode) If lErrorCode Then Error lErrorCode 'error number btnSeπdData_ClιcK_Exιt- btnSendData Enabled = True 're-enable button btnReadEntireContents Enabled = True gbKeepPollingDevice = True 'continue polling device Exit Sub btπSendData_Clιcl<_EπOr
 
    DisplayEσorMessage lEπorCode " Resume 0 temp test
    Resume btnSendData_Clιck_Exιt End Sub 
    frmDeviceDiagnostics frm - Forr.,
    Private Sub Form_Activate()
    PopufateDeviceDiagDialog PAT_DATA, Me
    Comm_lπιtlalιzeCommPort initialize the comm port from IN! (lie settings
    IblCommPort. Caption ' " " + CStr(gιCommPort) IblSettings Caption = " " + gsCommDeviceSettings IblOeviceWaitTϊ e = " " + CStr(gιDevιceResponseWaιt) gbCommBusy = False 'reset flag gbCommReplyPencmg = False 'reset Hag gbKeepPollingDevice = True 'continue coil, nc device
    PollDeviceContinually Me SetPππterlcon False, "* End Sub
    Private Sub Form_lπitialize()
    Me. Left = 0 Me.Top = 0 End Sub
    Private Sub Form_Load()
    Unload frmDevicelnitialize Unload fππReadDeviceData gbCommOK = 99 'reset 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 = ValldateΩoseNumbers(Me) if r — False Then Cancel = True gbKeepPollingDevice = False 'sfcp polling the device
    Wait 0 1 End Sub
    Private Sub txtDoseTime_Chaπge(lndex As Integer)
    _ If lsDate(txtDoseTime(lndex)) Then
    PAT DATA.dPrescnbedDoseTime(lndex) = TimeValue(t tDoseTime(lndex)) 'save Dose Inter/al
    _ Else
    PAT DATA.dPrescπbedDoseTime(lndex) = -1 'indicate that no cme was set - End If ~ End Sub 
    frrr .viceDiagnostics frm - txtDoseLockoutHou.-, Change
    Private Sub txtDoseLockoutHours_Change()
    PAT_DATA sOoseLockoutHours - txtDoseLockoutHours 'sate Dose Lockout Hours
    End Sub
    Private Sub txtDoseSize_Chaπge()
    PAT_DATA sOoseSize = txtDoseSize save Dose Sir
    End Sub
    Private Sub txtDosesPerDay_Chaπge() = Val(txtDosesPerDay) save Doses oer ay 
 
    Private Sub txtDrug_Click()
    PAT_DATA sDrug = txtDrug save 1e d
    End Sub
    Private Sub txtOrgan_Click()
    PAT_DATA.sOrgan = txtOrgan 'save Held
    End sub-
    Private Sub txtPatientFirstName_Change()
    PAT.DATA sPatientFirstName = txtPatientFirstName End Sub
    Pπvate Sub txtPatieπtlD_Change()
    PAT_DATA.sPatιentlD = txtPatientlD 'save °atιenl ID End Sub
    Private Sub txtPatientLastName_Change()
    PAT_DATA sPatientLastNa e = txtPatientLastName End Sub
    Private Sub txtSerialNumber_Chaπge()
    PAT_DATA sSeπalNumber = txtSeπalNumber save senal number End Sub 
    
    Private Sub txtTxCenter_Chaπge()
    PAT_OATA sTxCenter = txtTxCeπter 'save field
    End Sub
    Private Sub UρDownDoseTirne_DownClick(lπdex As Integer) Dim fDalylncrement As Single, ilndex As Integer ' 24
     
 fDalylncrement = (ilndex / 24) b<tDoseTime(lndex) = " " f FomιatS(TimeValue(CDate(fDalylπcremeπt)), gsTimeDisplayFormat) End Sub
 
    Private Sub UpDownDoseTime_UρClick(lπdex As Integer)
    Dim fDalylncrement As Single, ilndex As Integer " 24
     
 fDalylncrement = (ilndex / 24) txtDoseTi e(lndex) = " " + FormatS(TimeValue(CDate(fDalylncrement)), gsTimeDisplayFormat) 
 
    iiiiir-dxairfius trm - File Declaration
    Attπbute VB_Name = "frmFaxStatus Attπbute V8_GlobalNameSpace = False Attπbute VB~Creatable = False Attribute VB_Predeclaredld = True Attnbute VB_Exposed = False Option Explicit
    Private Sub cmdCaπcel_Clιck()
    On Eπor Resume Next gc-ax Ca~celFax gcrax axLogιD
    Unload Me
    End Sub
    Private Sub Form_Actιvate()
    SetPπntertcon False ~ End Sub
    Private Sub Form_Load()
    IblDestmation = ~ IblPage = - IblSpeed = "" End Sub 
    
    Attnbute VB_Name → "frmFaxSend" Attnbute VB_GlαbalName Space * Fals Attnbute VB_Creatable = False Attnbute VB_Predeclaredld - True Attπbute VB_Expαsed - False Option Explicit
    Sub Reloa GroupsϋstO Dim i As Integer
    
    End Sub
    Sub ReloadLocatiσnsListQ Dim i As Integer
    With Istlocations Clear _ For i = 1 To FAX_OATA iLocTotal
    Addltem FAX_DATA~sLocPersoπName(ι) ltemData( Newlπdex) - i ee trdex _ Next i
    End With
    End Sub
    Private Sub btπAddGroup_Clιck()
    Dim i As Integer r As integer sSection As Stnng gsEditGroupName = "" gsEditGrouplndexes = ™ 
    Load fr Fa EditGroups frmFaxEditGroups Show vbModal
    If gsEditGroupName = "" Then Exit Sub no name was eπetered
    I - GetlπdexToFaxGroupName(gsEdιtGroupName) see if name is alreac in the list
    . If I ~ 0 Then name is not in list yet sSection =• "Fax Groups" With FAX_DATA
    Add the new name to the fax data structure'
    Before saving new data clea- out the eld stnngs r = WπtePπvateProfileStπng(sSectιon ByVal OS ByVal 0& gsFaxFileSpec) iGroupsTotal = iGroupsTotal > 1 mcemert count bv one sGroupTitle( iGroupsTotal) ~ gsEditGroupName s Group Name si nTitle( iGroupsTotal) = gsEditGrouplndexes
    SavelNISetting gsFaxFileSpec sSection, Total Groups" CStr( iGroupsTotal)
    For i = 0 To iGroupsTotal
    SavelNISettmg gsFaxFileSpec sSection "Group " + CStr(ι) sGroup Title (i)
    SavelNISetting gsFaxFileSpec sSection "Group Locations " + CStr(ι) sGrαupNameslnTitle(ι)
    Next i cmboGroups Addltem gsEditGroupName cmboGroups ltemOata(cmboGroups Newlndex) = iGroupsTotal save index cmboGroups Listlndex - cmboGroups Newlndex 
 
 
    Else this namt* already exist
    MsgBox The name " + gsEditGroupName + " is already entered " 
 
    Private Sub btnClose_Clιck()
    Unload Me End Sub
    Private Sub btπDe!eteGroup_Clιck()
    Dim i As Integer r As Integer, sMSG As Stnng vbCrLf + "Do
    
    RemαveGroupFrσmFaxList gsEditGroupName
    Reloa GroupsList cmboGroups Listlndex = 0 default to manual selections
    End Sub
    Private Sub btnDeIeteName__Click()
    Dim I As Integer, r As Integer, sMSG As Stnng (Ist Locations Listlndex) nd related information will be permanently deleted " + vbCrLf * gsEdilName + vbCrLf + vbCrLf + "Do you
    V vbDefaultButtoπ2 + vbQuestion, "Confirm Name Deletion") 
 
    RemoveNameFromFaxUst gsEdilName
    ReloadLocationsList
    If IstLocations UstCount < 1 Then btnDeleteName Enabled = False End If cmboGroups_Clιck cause appropπata ooxes to oe reselected End Sub 
    
    Private Sub btrιEdιtGroup_CIιc ()
    Oim i As Integer r As Integer, sSection As Stnng
    With cmboGroups gsEditGroupName = Lιst( Listlndex) i ~ GetlπdexToFaxGroupName(gsEdιtGroupName) get 'ce ''cm t>l-..c'ure gsEditGrouplndexes = FAX_DATA sGroupNameslnTille(ι) frmFaxEditGroups Show vbModal
    Ust( Ustlndex) = gsEditGroupName End With
    With FAX_DATA sGroupTitle(ι) = gsEditGroupName sGroupNameslnTitle(ι) = gsEditGrouplndexes r = WπtePπvateProfileStπng(sSectιαn ByVal OS ByVal OS gsFaxFileSpec)
    SavelNISettmg gsFaxFileSpec sSection Total Groups", CStr( iGroupsTotal) For i = 0 To iGroupsTotal
    SavelNISettmg gsFaxFileSpec, sSection, "Group " + CStr(ι), sGroupTitle(ι)
    SavelNISetting gsFaxFileSpec sSection, "Group Locations " + CStr(ι) sGroupNameslnTitΙe(ι) Next l
    End With
    UpCateListBoxSelectioπs gsEditGrouplndexes End Sub
    Private Sub btnEditName_Click() Dim i As Integer gsEditName = IstLocations List'lstLocations Listlndex) i = GetlndexToFaxLocName(gsEdιtName) 'get index tram structure gsEditVoice = FAX_DATA sLocVoιceNumber(i) gsEditFax = FAX_OATA sLocFaxNumber(ι) frmFaxEditLocatlαns Show vbModal IstLocations Lιst(lstLocatιons Ustlndex) = gsEditName FAX_DATA sLocPersoπName(l) = gsEditName FAX_DATA sLocVoιceNumber(ι) = gsEditVoice FAX~DATA sLocFaxNumber(ι) = gsEditFax
    End Sub
    Pπvate Sub btπNew_Click()
    End Sub 
    
    Pπvate Sub btnNewName_Click(J Oιm t As Integer gsEditName = "™ gsEditVoice = "" gsEditFax = ""
    Load rmFa EditLocatioπs frmFaxEditLocatiσπs Caption ~ "Enter New Name" frmFaxEditLocatioπs Show vbModal
    If gsEditName ' "" Then Exit Sub no name .vas sne'e-ed see >f name -s a're-d/ ιr the -' t
    one
    iLocTotal
    
    End Sub
    Private Sub btnSeπdFax_CIick()
    Dim i As Integer, r As Integer, sFileSpec As Stnng, lErrorCode As Long Dim sSourceFileSpec As Stnng, sOestFileSpec As Stnng
    On Error GoTo btπSendFax Error to fax. Please open a patient file ", vbExclamation, "No File Selected" 
 Create Tx (Summary File a fax document atientLastName + " " + PAT_DATA.sPahentFtrstName i ' + PAT DATA ent!D + " " + PAT_DATA sPatientID + " ftnf" car de'enr.tne that e file is already open 
 cover ti" '.Temp 'xf
 
    
    3/19/98 
 irmr-axseπd frm - blnSendFa~_CIιck
    ber
    
    ocatioπs Itεmθata(ι) * 1)
     
 btnSeπdFax_£xιt bn'cad Me must oe unloaded because the sta-us form s a nci — ocs, cι,c fcr— and an not be displayed while a mocal torn- is being displayed 
 btπSendFax_Error
 
    MsgSox "An uncorrectable error occurred while trying to fax the document Please try again " bExclamation, "Fax Error - " + Errors Resume btnSendFax_Exιt
    End Sub
    Pπvate Sub cmboGrouρs_Clιc ()
    Dim i As Integer, r As Integer, j As Integer, sName As Stnng
    With cmboGroups i = GetlndexToFaxGrσupName( Lιst( Listlndex)) UpOateListBoxSelections FAX_DATA sGroupNameslnTϊtle(ι)
    
    End With End Sub 
    i - upuateListBox -fecbons
    Pπvate Sub UρDateϋstBoxSelectιons(Byv'al sGroup As String)
    Dim i A3 Integer J As Integer r As Integer sTempLlst(lOO) As Stnng
    With IstLocations Clear For l = 0 To FAX_DATA iLocTotal 1
    Addltem FAX_OATA sLocPersoπNamefi ♦ 1)
    Item0ata( Newlndex) = i keeo index Next i
    
    End ScD
    Private Sub Form_Actιvate()
    SetPπnterlcoπ False ~ End Sub
    Private Sub Form_Load() brtFileToSeπd = PAT_DATA sPatientDataFileName
    GetFaxLocaαons
    ReloadLocatlσnsList
    ReloadGrαupsLlst maxe sure it is tn range If cmboGroups LlstCouπt >= FAX_DATA iGroupLastSelected Then cmboGroups Listlndex = FAX_OATA iGroupLastSelected End Sub
    Private Sub Form_Unload(Caπce! As Integer)
    Dim i As Integer r As Integer sSection As Stnng
    With FAX_DATA sSection = "User Selections" IGroupLastSelected = cmboGroups Listlndex
    SavelNISettmg gsFaxFileSpec sSection Tast Group Selected" CStr( iGroupLastSelected) End With
    With FAX_OATA sSection 3 "Fax Locations"
     
 sSection = "Fax Groups" 
 nir-axseπd frm - Form_Uπι dd
 
    Before savirg new data clear cut r'*s eld srnngs r = WπtePπvaleProfileStππgtsSection, ByVal OS,, ByVal OS,, gsFaxFileSpec) {
    SavelNISetting gsFaxFileSpec sSection, Total Groups", CStr( iGroupsTotal)
    For t = 0 To iGroupsTotal
    SavelNISetting gsFaxFileSpec, sSection, "Group " + CStr(ι), sGroupTille(i)
    SavelNISetting gsFaxFileSpec, sSection "Group Locations " ♦ CStr(ι), sGroupNameslπTitle(ι)
    Next i
    End With End Sub
    Private Sub lstLocatιons_Clιck()
    Dim i As Integer sTemp As Stnng btnEditName Enabled = True btπDeleteName Enabled = True
    
    Private Sub lstLocations_DblClick() btn£dιtName_Clιc End Sub 
    nraxLog frm File Declara, ^ns
    Attπbute VB_Name = frmFaxLog Attnbute V8j3lobalNameSpace = False Attπbute VB_Crealable = False Attnbute VB_Predeclaredld = True Attnbute V8__Exposed - False Option Explicit
    Private Sub btnClose_Clιck()
    Me Hide sta/ cadec because t concurs End Sub
    Pπvate Sub Foπn_Actιvate()
    SetPπnterlcon False " End Sub
    Private Sub Form_Load() optviewFaxes_Click 1 causα lhα 'Sen * b **or 'o be cιc<ed End Sub
    Private Sub Form_Resιze() btnClose Left = Me Width - btnClose Width - 250 FaxManl Width = Me Width FaxManl Left 250 FaxMant Height = Me Height - FaxMant Top - 500 End Sub
    Private Sub optVιewFaxes_Clιck(lπdex As Integer) - Select Case Index Case 0
    FaxManl Log = Pending Case 1
    FaxMant Log = Completed Case 2
    FaxManl Log = Failed _ End Select End Sub 
    -dxfcdilGroups frm - File Declarations
    Attπbute VB^Name = "frmFaxEditGroups Attribute VB^GIσbalNameSpace = False Attnbute VB_Creatable = False Attπbute VB_Predeclaredld » True Attnbute VB_Exposed = False Option Explicit
    Private Sub btπClose_Clιck()
    Unload Me End Sub
    Private Sub Foιm_Actιvate()
    SetPπnterlcoπ False, ~ End Sub
    Private Sub Form_ oad()
    Dim i As Integer, j As Integer, r As Integer, sTempListf 00) As Stnng txtName = gsEditGroupName With IstLocations FAX_DATA ILocTotal - 1 FAX~DATA sLocPersonName(l * 1) f Newlndex) = l keep index 
 
    check appmpnate ones
    
    Private Sub Form_Unload(Cancel As Integer)
    Dim l As Integer, r As Integer, sSection As Stnng gsEditGrouplndexes = ™ With IstLocations — For i = 0 To UstCouπt - 1 add this index to the list If Selected(ι) Then gsEditGrouplndexes = gsEditGrouplndexes -* CStrf Itemθata(ι)) ■* Next i
    End With gsEditGroupName = txtName End Sub 
 
 
    Private Sub txtName__KeyPress(KeyAscii As Integer)
    . If KeyAscπ = 13 Then the "Enter" es was pressed IstLocations SetFocus KeyAscii = 0 c. ange it to a tao kev
    End If End Sub
     
 dxcuiiLocatioπs fπn - File Dt- ratioπs
 
    Attπbute VB_Name = "frmFaxEditLocatlons' Attnbute VB_GlobalNameSpace = False Attnbute VB_Creatable = False Attπbute VB_Predeclaredld = True Attπbute VB_Exposed = False Option Explicit
    Dim bxSaveΩata As Boolean
    Private Sub btnCancel_Click()
    Unload Me End Sub
    Private Sub btnClose_CIick() bxSaveData = True
    Unload Me End Sub
    Private Sub Form_Actιvate() txtName SetFocus SetPππterlcoπ False ~ Eπd Sub
    Private Sub Form_Loa () txtName = gsEditName txtVoiceNumber = gsEditVoice txtFaxNumber = gsEditFax
    End Sub
    Private Sub Form_Uπload(Caπcel As Integer) _ If bxSaveData Then gsEditName = TπmS(txtName) gsEditVoice = TπmS(txtvαιceNumber) gsEditFax - TπmS(txtFaxNumber) _ End If End Sub
    Private Sub txtFax_KeyPress(KeyAscii As Integer)
    — If KeyAscii ~ 13 Then 'the 'Enter* kev was pressed btnClose SetFocus
    KeyAscii = 0 change it to a tao kev
    _ End If End Suo 
    
    Pπvate Sub txtFaxNumber_KeyPress(KeyAscii As Integer)
    — If KeyAscii - 13 Then 'the "Enter* key was pressed txtvoiceNumber.SetFocus
    KeyAscii = 0 'change it to a tao kev
    _ End If End Sub
    Private Sub txtName_KeyPress(KeyAscii As Integer)
    — If KeyAscii = 13 Then 'the 'Enter* key was pressed
    DctFaxNumber.SetFocus
    KeyAscii = 0 'change it to a tab Key _ End If End Sub
    Private Sub txtTelephoπe_KeyPress(KeyAscii As Integer) — If KeyAscii = 13 Then 'the 'Enter* key was presses txtFaxNumber.SetFocus KeyAscii = 0 'cnange it to e tao key
    _ End If End Sub
    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 
    
    Attnbute VB_Name = "frmDevicelnitialize" Attnbute VB_GlαbalNameSpace -= False i Attnbute VB_Creatable =■ False Attπbute VB_Predeclaredld -= True Attπbute VB_£xposed - False Option Explicit
    Private Sub btπCrtaπgeBatteries_Click() btnCMangeBatteπes Enabled -= False prevent recursive ca-ls to device
    Call ChaπgeBatteπesRequest btnChangeBatteπes Enabled = True enable butter, again
    End Sub
    Private Sub btnC!ose_CIick()
    Unload Me
    Private Sub btnRea EπtireCoπtents_Ciick()
    Dim f As Integer, lErrorCode As Long, i As Integer r = ValidatePatieπtOata Saved '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 = " 'clear out the text boxes before reading data txtPatientFirstName = "" 'dear out the text boxes before reaάng data txtPatleπtlD = ~* txtTxCenter = "" txtDrug. Clear txtOrgan. Clear txtSeπal Numbe = ™* txtDoseSize = "* txtDoserιme(l) ~ ™ txtDoseTime(2) = "" txtDαseTime(3) = "" txtDoseTime(4) = "" txtDosesPerDay = *" txtDoseLoc outHours ■= "" txtDeviceStarted = ™ txtMedicatioπRemaiπiπg - "~ txtBatteryChangeTϊmer = ™ txtEventCount * "™ txtPatientLastName SetFocus 'take focus away from tlstbαx Me Refresh , lErrorCode)
     
 gbKeepPollingDevice = True 'start coiling again btnReadEntireContents Enabled = True 're-enable button 
 btnSendData Enabled s RefreshAIIQpenFαrms
 
    Private Sub btnSendData_Click()
    Dim i As Integer r As Integer, lErrorCode As Long r = ValιdateDoseNumbers(Me) If r - False Then Exit Sub
    Beep r = MsgSoxfPatieπt Information and Dosing Information currently in the CycloTech device will be changed if you continue Medicat
ion ► data will be preserved " + vbCrlf * vbCrLf + "Do you want to continue?', vbYesNo + vbQuestion! "Device Data being changed") J = vbNo Theπ Exit Sub prevert recurs.ve calls to device False stco pα'.rg for now 
 
    On Error GoTo btnSendData Click Error r = Comm_SeπdCu5tomOata(PAT_DATA, DATA_BEGIN_CUSTOM1 lErrorCode) If lErrorCode Then Error lErrorCode error number r ~ Comm_SendCustomOata(PAT_DATA, DATA_BEGIN_CUSTOM2, lErrorCode) send to device If lErrorCode Then Error lErrorCode error nu beF r - Cσmm_SeπdCustomData(PAT_DATA, DATA_B£GIN_CUSTOM3, lErrorCode) serd to device If lErrorCode Then Error lErrorCode 'error number r = Comm_SeπdCustomData(PAT_DATA, DATA_8EGIN_CUSTOM4, lErrorCode) 'send te device If lErrorCode Then Error lErrorCode 'error numbar~
     
 r = Cσmm_SeπdDαsιπgParams(PAT_DATA, lErrorCode) If lErrorCode Then Error lErrorCode 'error number
 
    
    DisplayErrorMessage lErrorCode Resume 0 temo test
    Resume btnSendData_Clιck_Exιt End Sub 
 frmD vicelnitialize frm Form Activate
     
 com—, cor frcrr iNt *le sen **gs gbKeepPollingDevice = True con"nue colling de /ice
 
    PαllDeviceContiπually Me SetPπnterlcon False ™ End Sub
    Private Sub Form_ oad()
    Me Left = 0
    Me Top = 0
    Unload frmReadDeviceData don ' need 'I is 'or— gbCommOK = 99 rase lag "a' will g/e an ncica'on as 'c s communication sta'. End Sub
    Private Sub Form_QueryUnload(Cancel As Integer, UπloadMode As Integer) Dim r As Integer r = ValιdateDoseNumbers(Me) If r = False Then Cancel = True End Sub
    Pπvate Sub Forrπ_Unload(Cancel As Integer) gbKeepPollingDevice = False sfop polling the device Wait 0 1 End Sub
    Private Sub txtDoseLockoutHours_Chaπge()
    PAT_DATA sDoseLockoutHours = octDoseLockoutHours save Dose Lockout ricυrs
    End Sub
    Private Sub txtDoseSιze_Chaπge()
    PAT_DATA sOoseSize = rtDoseSize save Dose Size
    End Sub
    Private Sub txtDosesPerDay_Change()
    PAT_DATA iDosesPerOay - Val(txtDosesPerOay) sa/e Doses per day
    End Sub 
     jeviceinitialize frm - lxtDruL,_ lιck
    Private Sub txtDrug_Click()
    PAT_DATA sDrug = txtDrug End Sub
    Private Sub txtOrgaπ_Click()
    PAT_DATA sOrgaπ = txtOrgan End Sub
    Private Sub txtPatientFirstName_Change()
    PAT_DATA sPatientFirstName = txtPatientFirstName save Patient name
    End Sub
    Pπvate Sob txtPatient!D_Change()
    PAT_DATA sPatientID = btPatientlD End Sub
    Private Sub txtPatιentLastName_Change()
    PAT_DATA.sPatιeπtLastName = txtPatieπtLastName save Patient name
    End Sub
    Private Sub txtSerialNumber_Change()
    PAT_DATA.sSeπalNumber = txtSerialNumber 'save senal number End Sub
    Private Sub txtTxCenter_Change()
    PAT_OATA.sTxCenter = txtTxCenter End Sub
    Private Sub UpDowπDoseTime_DowπClick(lπdex As Integer)
    Oim fDalylncrement As Single, Ilndex As Integer
    If lsOate(txtDoseTime(lndex)) Then ilndex = TimeValue(btDoseTime(lndex)) * 24 Ilndex 
s ilndex - 1 _. If ilndex < 0 Then txtOoseTime(lndex) = " - 
 ilndex = 23 End If fDalylncrement - (ilndex / 24) txtDoseTϊme(lπdex) = 
* " ♦ FormatS(TimeValue(CDate(fDalylncrement)), gsTimeOisplayFormat) 
 fDalylncrement = (ilndex / 24) ^.Dose^meflndex, = 
■ ■ ♦ Forma.
5(T,meVa,ue
(COa,e
(fDa,y,πcremen,
 
    '')) gs i imeOisplayFormat) 
    
    Private Sub btnDateCaπcel_Clιck() gdTempOateTime = ~caιe tc ca ler "iat a ca-ca' occurred giTempCya = 0 gfTempCreatiπine = 0 gsTempCustomlπfo = "" Unload frmGetOateTϊme End Sub
    Private Sub cmdDateOK_Click()
    /aJicete the ~ext oακes before ex't _ If Val(txtCya Text) = 0 Then "Please enter a CYA level", vbExclamation "Value Required etFocus _ 
 0 Then Creatinine level", vbExclamation, "Value Required" 
 
    On Error Res e Next gdTempOateTime = CVDate(txtDate Entry Value) sef date from control gdTempOateTime = gdTempOateTime + CVDate(txtTϊmeEntry Time) giTempCya = txtCya Text gfTempCreatmiπe = txtCreatinine Text gsTempCustomlπfo = txtCustomlπfo
    Unload frmGetDateTime On Error Go To 0 End Sub
    Pπvate Sub Form_Actιvate()
    SetPππterlcoπ False *" End Sub
    Private Sub Form._Load()
    Me Width = pπlGetDate idth * 90 Me Height = pnlGetDate Height * 90 txtTimeEπtry Time = CStr(Time) End Sub 
    ui-u i i uiuex
    brwWebBrowsβr_DownloadComplete (frmBrowser frm) , 95 brwWebBrowser_NavιgateComplete (frmBrowser frm) , 95 btnAddGroup_Clιck (frmFaxSend frm) , 134 btπCancel_Clιck (fr FaxEditLocations frm) , 144 btnChangeBatteπes_Clιck (frmDeviceDiagnostics frm) , 128 btπChangeBatteπes_Clιck (frmDevicelnitialize frm) , 146 btnChaπgeComplιance_Clιck (frmDosingCalendar frm) , 111 btnClose_Clιck (frmAIIPatients frm) , 100 btnClose_Clιck (frmDeviceDiagnostics frm) , 128 btπClose_Clιck (frmDevicelnitialize frm) , 146 btnClose_Clιck (frmDosingCalendar frm) , 1 1 btnClose_Clιck (frmFaxEditGroups frm) , 142 btnClose_Clιck (frmFaxEditLocations frm) , 144 btnClose_Clιck (frmFaxLog frm) , 141 btnClose_Clιck (frmFaxSend frm) , 135 btnClose_Clιck (frmPatientDosingRpt frm) , 118 btnClose_Clιck (frmPπnt frm) , 124 btnClose_Clιck (fπnReadDeviceData frm) , 122 btnClose_Clιck (frmRecentDosingGrapri frm) , 108 btnConfigureFax_Clιck (frmOptioπs frm) , 88 btnDateCancel_Clιck (frmGetDateTime frm) , 151 btnDeleteGroup_Clιck (frmFaxSend frm) , 135 btnDeleteName_Clιck (frmFaxSend frm) , 135 btnDeleteUserEvent_Clιck (frmPatientDosingRpt frm) , 119 btnEdιtGroup_Clιck (frmFaxSend.frm) , 136 btnEdιtName_Clιck (frmFaxSend frm) , 136 btnNew_Clιck (frmFaxSend frm) , 136 btnNewNamej lick (frmFaxSend frm) , 137 btnNewUserEvent_Clιck (frmPatientDosingRpt frm) , 119 btnPπnter_Prevιew_Clιck_Proc (Pnnting bas) , 46 btnPπntNow_Clιck (frmPπnt frm) , 124 btnPπntPage_Clιck (frmPπnt frm) , 124 btnReadEntιreContents_Clιck (frmDeviceDiagnostics frm) , 128 
r unction Index btnReadEntιreContents_Clιck (frmDevicelnitialize frm) 146 btπReadEntιreCoπtents_Clιck (frmReadDeviceOata frm) 122 btnRefresh_Clιck (frmPπnt frm) , 124 btπSendData_Clιck (frmDeviceDiagnostics frm) , 129 btnSendData_Clιck (frmDevicelnitialize frm) , 147 btnSeπdFax_Clιck (frmFaxSend frm) , 137
    C
    CalcDayDoseScore_AIIDo≤es (General bas) , 4 CalcDayDoseScore_OnTιme (General bas) , 4 CalcDaysln onth (Calendar bas) , 61 CalcDosesSumTakenOnSpeαfϊcDay (General bas) 5 CalculateAIIPatientsComplianceOπDisk (frmAIIPatients frm) 102 CalculateSinglePatieπtCompliance (frmAIIPatients frm) , 100 Calendar_DayChange (frmDosingCalendar frm) , 111 Calendar_ onthChaπge (fmiDosingCalendar frm) , 111 Caleπdar_MouseMove (frmDosingCalendar frm) , 112 Caleπdar_YearChange (frmDosingCalendar frm) , 112 cboAddress_Clιck (frmBrowser frm) , 96 cboAddress_KeyPress (frmBrowser.frm) , 96 ChangeBatteπesRequest (Comm bas) , 28 chkDoseChaπged_Clιck (frmDosingCalendar frm) , 112 chkDoseChaπged_Clιck (frmPatientDosingRpt frm) , 119 chkDoses_Clιck (frmPatientDosingRpt frm) , 119 chkDosesMιssed_Clιck (frmDosingCalendar frm) , 112 chkDosesNotComp!ιed_Clιck (frmDosingCalendar frm) , 112 chkDosesTakeπ_Clιck (fmiDosingCalendar frm) , 112 c kLoadTipsAtStartup_Clιck (frmTip frm) , 99 chkUserDefined_Clιck (frmPatientDosingRpt frm) , 120 chkWeekNumbers_Clιck (frmDosingCalendar frm) , 112 cmboAverageDays_Clιck (frmRecentDosiπgGraph frm) , 108 cmboChartTyρe_Clιck (frmRecentDosingGrapri frm) , 108 cmboDataToVιew_Clιck (frmAIIPatients frm) , 101 cmboDataToVιew_Clιck (frmRecentDosingGrapri frm) , 108 cmboDateSelectιon_Clιck (frmAIIPatients frm) , 101 
 UI H-.UUI I iπαex cmboDateSelectιon_Clιck (frmRecentDosiπgGraph frm) 108 cmboGroups_Clιck (frmFaxSend frm) , 138 cmdApplyj lick (frmOptions frm) , 88 cmdCancel_Clιck (frmFaxStatus frm) 133 cmdCancel_Clιck (frmLogin frm) , 86 cmdCancel_Clιck (frmOptions frm) , 89 cmdDateOK_Clιck (frmGetDateTime frm) , 151 cmdNextTιp_Clιck (frmTip frm) , 99 cmdOK_Clιck (frmAbout frm) , 92 cmdOK_Clιck (frmLogin frm) , 86 cmdOKj lick (frmOptions frm) , 89 cmdOK_Clιck (frmTip frm) , 99 cmdSyslnfo_Clιck (frmAbout frm) , 92 Comm_CheckComm (Comm bas) , 28 Comm_Ge(DevιceRep!y (Comm bas) , 29 CommJnitializeCommPort (Comm bas) , 39 Comm_ReadEntirefv1emoryContents (Comm bas) , 34 Comm_ReadFιrmwareVersιoπ (Comm bas) , 30 Comm_SendCustσmData (Comm bas) , 35 Comm_SendDataToDevιce (Comm bas) , 45 Comm_SendDosιngParams (Comm bas) , 37 Comm_SeπdResetC!ockAndBattery (Comm.bas) , 35 Corπm_SeπdSeπalNumber (Comm bas) , 38 CommTιmer_Tιmer (frmMain frm) , 76 ComputelniSectionChecksum (General bas) , 2 ConvertHexStππgToAscii (Comm bas) , 38 CreateCalendarTimeScale (frmDosingCalendar frm) , 113 CreateChecksum (Comm bas) , 39 CreateTxtSummaryFile (General bas) , 6
    D
    Device DnComm (Comm bas) , 40 DisplayCommError (Comm bas) , 30 DisplayCommOk (Comm bas) , 31 DisplayCurrentTip (frmTip frm) , 99 
Function Index
    DisplayErrorfvlessage (Comm bas) , 31 DoNextTip (frmTip frm) , 98 DrawAIICompliedDosesTaken (Calendar bas) , 62 DrawAIIDoseSizeChanges (Calendar bas) , 61 DrawAIIDosesMissed (Calendar bas) , 63 DrawAIINonCompliedDoses Taken (Calendar bas) , 63 DrawHoπzontalLine (Pnnting bas) , 47 DrawSmgleCompliedDoseTaken (Calendar bas) 73 DrawSmgleDoseMissed (Calendar bas) , 74 DrawSmgleDoseSizeChange (Calendar bas) , 64 DrawSiπgleNonCompliedDoseTakeπ (Calendar bas) , 65
    E
    EraseDatalnMemory (General bas) , 5 EstablishDeviceComm (Comm bas) , 39 EventDelete (General bas) , 2 Eveπtlπsert (General bas) , 3
    F
    FaxMaπ1_ConfiguratιonDone (frmMain frm) , 76 FaxMan1_FaxStatus (frmMain frm) , 76 FileExists (General bas) , 7 FiπdClosestDatelnArray (General bas) , 23 FindFirstMatchingDatelnArray (General bas) , 23 FindPrescibedDoseSizeForSpecificDay (General bas) , 3 Form_Actιvate (frmAIIPatients frm) , 102 Form_Aciιvate (frmDeviceDiagnostics frm) , 130 Form_Actιvate (frmDevicelnitialize frm) , 148 Form_Acfιvate (frmDosingCalendar frm) , 113 Fσrτn_Actιvate (frmFaxEditGroups frm) , 142 Form_Actιvate (frmFaxEditLocations frm) , 144 Form_Actιvate (frmFaxLog frm) , 141 Form_Actιvate (frmFaxSend frm) , 139 Form_Actιvate (frmFaxStatus frm) , 133 Form_Aciιvate (frmGetDateTime frm) , 151 Form_Actιvate (frmOptions frm) 89 
i- unction Index
    Form_Actιvate (frmPatientDosingRpt frm) , 120 Form_Actιvate (frmReadDeviceOata frm) , 123 Form_Actιvate (frmRecentDosiπgGraph frm) 109 Form_Actιvate (frmTip frm) , 99 Formjnitialize (frmDeviceDiagnostics frm) 130 Form_Load (frmAbout frm) , 92 Form_Load (frmAIIPatieπts frm) , 103 Fσrm_Load (frmBrowser frm) , 95 Form_Load (frmDeviceDiagnostics frm) , 130 Form_Lσad (frmDevicelnitialize frm) , 148 Form_Lσad (frmDosingCalendar frm) 113 Form_Load (frmFaxEditGroups frm) , 142 Form_Load (frmFaxEditLocations frm) , 144 Form_Load (frmFaxLog frm) , 141 Form_Load (frmFaxSend frm) , 139 Form_Load (frmFaxStatus frm) , 133 Form_Load (frmGetDateTime frm) , 151 Form_Load (frmLogin frm) , 86 Form_Load (frmOptions frm) , 89 Form_Load (frmPatientDosingRpt frm) , 120 Form_Load (frmPnnt frm) , 124 Form_Load (frmReadDeviceData frm) , 123 Form_Load (frmRecentDosingGraph frm) , 109 Form_Load (frmSplash frm) , 85 Forτn_Load (frmTip frm) , 99 Form_MouseMove (frmDosingCalendar frm) , 115 Form_QueryUnload (frmDevicelnitialize frm) , 148 Form_QueryUnload (frmPnnt frm) , 125 Form_Resιze (frmAIIPatieπts frm) , 103 Form_Resιze (frmBrowser frm) , 96 Foπn_Resιze (frmDosingCalendar frm) , 115 Form_Resιze (frmFaxLog frm) , 141 Form_Resιze (frmPatientDosingRpt frm) , 120 Form_Resιze (frmPπnt frm) , 125 Form_Resιze (frmRecentDosiπgGraph frm) , 109 
 uι I LI I i mαex
    Form_Unload (frmDeviceDiagnostics frm) , 130 Form_Unload (frmDevicelnitialize frm) , 148 Form_Unload (frmDosingCalendar frm) , 116 Form_Unload (frmFaxEditGroups frm) , 142 Form_Uπload (frmFaxEditLocations frm) , 144 Form_Unload (frmFaxSend frm) , 139 Form_Unload (frmReadDeviceOata frm) , 123 Form_Uπload (frmRecentDosingGraph frm) , 110 frameView_MouseMove (frmDosingCalendar frm) , 116
    G
    GetDrugRefNumber (Comm bas) , 32 GetFaxLocations (Fax bas) , 57 GetFileNameFromSpec (General bas) , 17 GetlπdexToFaxGroupName (Fax bas) , 58 GetlndexToFaxLocName (Fax bas) , 58 GetlNISetting (General bas) , 7 GetKeyValue (frmAbout frm) , 93 GetOrganRefNumber (Comm bas) , 32 GetPatientDataFromDisk (General bas) , 7 GetProgra Preferences (General bas) , 9 gπd_AfterEdιt (frmPatientDosingRpt frm) , 120 gπd_Clιck (frmAIIPatients frm) , 104 gπd_DblClιck (frmAIIPatients frm) , 104 gnd_KeyDowπ (frmPatientDosingRpt frm) , 121 gπd_RowColChange (frmPatientDosingRpt frm) , 121
    H
    HScroll1_Change (frmPπnt frm) , 125 HScroll1_Scroll (frmPππt frm) , 125
    I
    InitPageMargins (Pnnting bas) , 52 InitPageProperties (Pnnting bas) , 53 InterpretDosiπgData (Comm bas) , 32 InterpretErrorFlags (Comm bas) , 33 
 .IUI I iuuex
    IπterpretScoreData (Comm bas) 41 IsDoseWithinPrescπbedTimeRange (Calendar bas) , 66
    L lblActιvePπnter_Clιck (frmPπnt frm) , 126 LoadPictureToPπnterControl (Pnnting bas) , 52 LoadTips (frmTip frm) 98 lstLocatιons_Clιck (frmFaxSend frm) , 140 lstLocatιons_DblClιck (frmFaxSend frm) , 140 lstLocatιons_Key Press (frmFaxEditGroups frm) 143
    M
    Main (General bas) , 11 MDIForm_Lσad (frmMain frm) , 77 MDIForm_Unload (frmMain frm) , 77 mnuAccessWebSιte_Clιck (frmMain frm) , 77 mπuFaxConfigure_Clιck (frmMain frm) , 77 mnuFaxSend_Clιck (frmMain frm) , 77 mnuFaxViewLogs_Clιck (frmMain frm) , 77 mnuFιleExιt_Clιck (frmMaiπ.frm) , 84 mπuFιleMRU_Clιck (frmMain frm) , 84 mnuFιleOρen_Clιck (frmMain frm) , 83 mnuFtlePageSetup_Clιck (frmMain frm) , 84 mnuFιlePπnt_Clιck (frmMain frm) , 84 mnuFιlePropertιes_Clιck (frmMain frm) , 78 mnuFιleSave_Clιck (frmMain frm) , 78 mnuFιleSaveAs_Clιck (frmMain frm) , 83 mnuFιleSend_Clιck (frmMain frm) , 84 mπuGenError_Clιck (frmMain frm) , 78 mnuHelpAbout_Clιck (frmMain frm) , 79 mπuHelρContents_Clιck (frmMain frm) , 82 mπuHelρDevιceDιag_Clιck (frmMain frm) , 78 mnuHelpSearch_Clιck (frmMain frm) , 82 mπuHelρTips_Clιck (frmMain frm) , 78 mnuReadDevιceOata_Clιck (frmMain frm) , 79 mnuSendDevιceData_Clιck (frmMain frm) , 79 
Function Index mnuVιewAIIPatιeπts_Clιck (frmMain frm) , 79 mnuVιewCaleπdar_Clιck (frmMain frm) , 79 mπuVιewExplorer_Clιck (frmMain frm) , 79 mnuVιewOptιons_Clιck (frmMain frm) , 79 mnuVιewPatιentDosιngReport_Clιck (frmMain frm) , 80 mnuVιewPatιeniSummary_Clιck (frmMain frm) , 80 mnuVιewStatusBar_Clιck (frmMain frm) , 80 mnuViewToolbar_Clιck (frmMain frm) , 80 mnuWιπdowArrangelcons_Clιck (frmMain frm) , 83 mnuWιπdowCascade_Clιck (frmMain frm) , 83 mnuWιndowTιleHoπzontal_Clιck (frmMain frm) , 83 mnuWiπdowTιleVertιcal_Clιck (frmMain frm) , 83 MoveFormObjects (Calendar bas) , 72
    O
    OpenPatlentOata (General bas) , 13 optViewFaxes_Clιck (frmFaxLog frm) , 141 optZoom_Clιck (frmPπnt frm) , 126
    P
    ParseDelimStπng (Geπeral.bas) , 18 ParseMemoryContents (Comm bas) , 41 pπlControls_MouseMove (frmDosingCalendar frm) , 16 PollDeviceContiπually (Comm.bas) , 44 PopulateDeviceCommDialog (General bas) , 21 PopulateDeviceDiagDialog (General bas) , 14 PπntAIIPatieπtsSummary (Pnnting bas) , 47 PπntCaleπdar (Calendar bas) , 66 PππtDosiπgEventsHeader (Pnnting bas) , 51 PπntPageDate (Pnnting bas) , 53 PπntPageNumber (Pnnting bas) , 53 PππtPatientDosiπgReport (Pnnting bas) , 49
    R
    RefreshAIIOpenForms (General bas) , 16 RefreshPreview (Pnnting bas) , 54 
i- unction index
    ReloadGroupsϋst (frmFaxSend frm) , 134 ReloadLocatioπsϋst (fπnFaxSeπd frm) , 34 RemoveAIIObjects (Calendar bas) , 75 RemoveCompliedDσsesTaken (Calendar bas) , 70 RemoveDoseSizeChanges (Calendar bas) , 70 RemoveDosesMissed (Calendar bas) , 70 RemoveGroupFromFaxList (Fax bas) , 58 RemαveNameFromFaxList (Fax bas) , 59 RemoveNonCompliedDosesTakeπ (Calendar bas) 70 RescaleGπd (frmPatientDosingRpt frm) , 117
    S
    SaveOataToNewFile (General bas) , 18 SavelNISetting (General bas) , 24 SavePatientData (General bas) , 19 SaveProgramPreferences (General bas) , 22 SetCommTimer (Comm bas) , 45 SetFaxDeviceLabel (Fax bas) , 60 SetPreviewSize (Pnnting bas) , 55 SetPπnterlcon (General bas) , 16 Slιder1_SlιdeChange (frmAIIPatients frm) , 104 SSListBarlJjstltemClick (frmMain frm) , 80 sstab1_Clιck (frmOptions frm) , 91 StartSyslπfo (frmAbout frm) , 92
    T tbToolBar_ButtonC!ιck (frmBrowser frm) , 96 tbToolBar_ButtonClιck (frmMain frm) , 81 tιmTimer_Timer (frmBrowser frm) , 96 txtDoseLockoutHours_Change (frmDeviceDiagnostics frm) , 131 txtDoseLockoutHours_Change (frmDevicelnitialize frm) , 148 txtDαseSιze_Change (frmDeviceDiagnostics frm) , 131 txtDoseSιze_Chaπge (frmDevicelnitialize frm) , 148 txtDosesPerDay_Change (frmDeviceDiagnostics frm) , 131 txtDosesPerDay_Change (frmDevicelnitialize frm) , 148 txtDoseTιme_Change (frmDeviceDiagnostics frm) , 130 
i-unction inαeλ txtDrug_Clιck (frmDeviceDiagnostics frm) 131 txtDrug_Clιck (frmDevicelnitialize frm) , 149 txtEndDate_Change (fπnRecentDosingGraph frm) , 110 txtEndDate_HιdeDropDown (frmAIIPatients frm) 105 txtFax_Key Press (frmFaxEditLocations frm) 144 txtFaxNumber_GotFocus (frmOptions frm) 91 txtFaxNumber_Key Press (frmFaxEditLocations fπn) 145 txtName_Key Press (frmFaxEditGroups frm) 143 txtName_Key Press (frmFaxEditLocations frm) , 145 txtOrgan_Clιck (frmDeviceDiagnostics frm) 131 txtOrgan_Clιck (frmDevicelnitialize frm) , 149 txtPatιentFιrstName_Change (frmDeviceDiagnostics frm) 131 txtPatιentFιrstName_Change (frmDevicelnitialize frm) , 149 txtPatιentlD_Change (frmDeviceDiagnostics frm) , 131 txtPatιentlD_Change (frmDevicelnitialize frm) , 149 txtPatιentLastName_Change (frmDeviceDiagnostics frm) , 131 txtPatιentLastName_Change (frmDevicelnitialize frm) , 149 txtRetπes_GotFocus (frmOptions frm) , 91 txtRetrylnterval_GotFocus (frmOptions frm) , 91 txtSeπalNumber_Change (frmDeviceDiagnostics frm) , 131 txtSeπalNumber_Change (frmDevicelnitialize frm) , 149 txtStartDate_Change (frmRecentDosingGraph frm) , 110 txtStartDate_HιdeDropDown (frmAIIPatients frm) , 105 txtTelephone_KeyPress (frmFaxEditLocations frm) , 145 txtTxCenter_Change (frmDeviceDiagnostics frm) , 132 txtTxCenter_Change (frmDevicelnitialize frm) , 149 txtVoιceNumber_GotFocus (frmOptions frm) , 91 txtVoιceNumber_KeyPress (frmFaxEditLocations frm) , 145
    U
    UpdateCalendar (Calendar bas) , 74
    UpdatefrmPatientDosingReportHeader (frmPatientDosingRpt frm) , 117 UpDatefrmPatientSummaryHeader (frmRecentDosingGraph frm) 106 UpDateListBoxSelections (frmFaxSend frm) , 139 UpdatePageButtons (Pnnting bas) , 56 
UpdatePatientDosingGraph (frmRecentDosiπgGraph frm) 106 UpdatePatientGπdDisplay (frmPatientDosingRpt frm) , 117 UpDateRecentFileMenu (General bas) , 17 UpdateZoomBox (Calendar bas) , 71
    UpDownDoseTιme_DownClιck (frmDeviceDiagnostics frm) , 132 UpDownDoseTιme_DowπClιck (frmDevicelnitialize frm) , 149 UpDownDoseTimeJJpClick (frmDeviceDiagnostics frm) , 132 UpDownDoseTimeJJpClick (frmDevicelnitialize frm) , 150
    V
    ValidateChecksum (Comm bas) , 33 ValidateDoseNumbers (General bas) , 24 ValidatePatientDataSaved (General bas) , 24 vsPπnter1_EndPage (frmPπnt.frm) , 126 vsPπnter1_Error (frmPπnt frm) , 126 vsPπnter1_NewPage (frmPπnt frm) , 127
    W
    Wait (General bas) , 25
    B b LogonToWebSite (General bas) , 8046736
    F
    File Declarations (Calendar bas) , 61
    File Declarations (Comm bas) , 26
    File Declarations (Fax bas) , 57
    File Declarations (frmAbout frm) , 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 
Function inuex
    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 (frmPatientDosingRpt frm) , 117
    File Declarations (frmPnnt frm) , 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 (Pnnting bas) , 46