This is a follow-up article to 'How to poll for files in an unattended application' in which I described a method whereby a UNIFACE application could periodically scan for the existence of files so that they could be read in, processed, then deleted. That method makes use of the $timeout
setting which means that the interval between scans cannot go below 60 seconds. This article shows how I overcame that obstacle in order to allow intervals as low as 1 second.
In brief the solution is obtained by generating a DDE conversation between a Visual Basic program and the UNIFACE application. In this conversation the VB program is the client and the UNIFACE application is the server.
The <application execute> trigger contains the following code:
$appltitle = $logical("appltitle") activate "POLL_001".EXEC() if ($procerror) call PROC_ERROR($procerrorcontext) endif apstart apexit
The <operations> trigger contains the following code:
operation INIT perform "UDDESTARTCONV" ; start DDE conversation end INIT ;================================================ operation CLEANUP perform "UDDESTOPCONV" ; end DDE conversation end CLEANUP ;================================================
This registers this application as the DDE server.
The <async interrupt> trigger contains the following code:
variables string lv_FileName endvariables getitem/id lv_Filename,$result,"FILE" call LP_PROCESS_FILE(lv_Filename) if ($procerror) call PROC_ERROR($procerrorcontext) return(-1) endif
Whenever the DDE client sends a message this trigger is fired, with the message made available in $result
. In this example the message is in the format 'file=xxx', so I need to extract the 'xxx' portion before passing it to the LP_PROCESS_FILE proc.
The <local proc modules> trigger contains the following code:
entry LP_PROCESS_FILE params string pi_FileName : IN endparams creocc "dummy",-1 timestamp.dummy = $datim filename.dummy = pi_Filename file_load pi_FileName, contents.dummy if ($status <= 0) putmess "No data loaded from file %%pi_FileName" exit(-1) endif $1 = "del %%"%%pi_FileName%%"%%^cls" $2 = "doscmnd.bat" file_dump $1,"%%$2" ; create batch file to delete file if ($status < 0) return(-1) spawn "#%%$2" ; execute this file if ($status < 0) return(-1) return(0) end LP_PROCESS_FILE
In this example all I am doing with the file is loading its details into the screen area before deleting it, but a real-world application may extract values and update the database.
This is a little program which I wrote while teaching myself VB6. This makes use of the TIMER control which allows the pause interval to be specified in units of less than 1 minute. Figure 1 shows a screen shot:
Figure 1 - The DIRWATCH program
This contains details for 2 sets of files, but the processing for each one is the same.
FILE PATH - this identifies the directory which needs to be watched.
FILE MASK - this identifies the files names to scan for. In this example only those files which end in '.txt' will qualify.
DDE PREFIX - when the filename is transmitted to the DDE server you may wish to add a prefix. In this example it is 'file=' to create an associative list. If I were scanning for two types of file I could use different prefixes, such as 'file1=' and 'file2=', so that the DDE server could detect the difference in order to perform separate processing.
INTERVAL - This is a value between 1 and 60 seconds.
APPLICATION - This is set to 'uniface|poll_001' to indicate that DDE interrupts will only be sent to the UNIFACE application if component 'poll_001' is currently active. If this were to be set to 'uniface|system' then the interrupt would be sent regardless of which component were currently active.
LOGGING - If this switch is set ON then all events will be recorded in a log file called DIRWATCH.LOG
FILES FOUND - This simply displays the names of the files that were detected with the latest scan. As each file is processed and deleted by the DDE server its name will disappear from the list. When the lists have been emptied the program will pause for the specified interval before initiating a new scan.
PAUSE/RESUME button - Use this to suspend the scanning process without terminating the program. If the program is active the label will be PAUSE. This will change to RESUME if the program has been suspended.
TRAFFIC LIGHT - this will show GREEN if scanning is in progress, AMBER if scanning is to be suspended after the current pause interval has expired, and RED if scanning has been suspended.
EXIT button - Use this to terminate the program.
STATUS window - This shows either Watching... or Paused depending on the use of the PAUSE/RESUME button.
Note that all settings are saved in a file called DIRWATCH.INI so that they can be used again when the program is next activated. I use a shortcut with a separate 'Start in' value so that I can maintain separate .INI and .LOG files for different applications.
All my sample code, plus the executable for the DIRWATCH program, can be downloaded from here. If you need the full setup files for DIRWATCH then they can be downloaded from here.
Tony Marston
21st November 2001
mailto:tony@tonymarston.net
mailto:TonyMarston@hotmail.com
http://www.tonymarston.net