Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

SetWaitableTimer() API and FILETIME structure

Status
Not open for further replies.

gevli

Programmer
Sep 8, 2011
4
NL
I try to use the Windows API Function SetWaitableTimer() together with WaitForMultipleObjects() so the program waits either for a timeout or for some other action (a change in a certain folder).

Description of SetWaitableTimer:

BOOL WINAPI SetWaitableTimer(
__in HANDLE hTimer,
__in const LARGE_INTEGER *pDueTime,
__in LONG lPeriod,
__in_opt PTIMERAPCROUTINE pfnCompletionRoutine,
__in_opt LPVOID lpArgToCompletionRoutine,
__in BOOL fResume
);

The parameter pDueTime should be a FILETIME structure. Does anyone know how to create this FILETIME structure in VFP?

Thanks.





 
Well, according to MSDN, a Filetime structure is a 64-bit integer, containing the number of 100 nanosecond intervals since 1st January 1600 (see
So, you could take a VFP datetime, subtract 1/1/1600 from it (to give the value in seconds), then multiply by 10^7 (to convert to 100 ns intervals). Finally, you would have to convert it to a binary number (using CREATEBINARY() perhaps - not sure about that).

All of which leads me to ask why you are using this API function in the first place. I'm not familiar with SetWaitableTime, but is it possible that you could do the same job with a native VFP timer, or perhaps with a WAIT .... TIMEOUT command?

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Mike is right to question why you would need to use a Windows API to do as you suggest.

Between the capabilities provided by the VFP Timer object and/or the WAIT command, you should be able to do whatever you need without any need for any 'external' API calls.

Good Luck,
JRB-Bldr
 
Since the OP mentions "changes in a specific folder" he might also be interested in the BindEvents sample in the tools folder that shows binding to Windows events (like FileCreate).

Again, the API call may not be necessary.
 
The app i'm working on is monitoring a folder. Whenever the folder changes (a new file is dropped into it) this app has to read the file and pass it to another app that is waiting for input.

Monitoring the folder is done with the FindFirstChange() API call that creates a handle to a change notification handle. As soon as the new file is written, this app responds to process is.

But the second app isn't running, this app has to retry it's action, say every 5 minutes, until this second app becomes active. I want to use a timer for this. I can use something like Sleep() (another API) but that freezes the app.

The app should get in a wait state until the times elapses OR there is a change in the folder being watched.

With the SetWaitabletimer() is it posible to create a handle to the timer. Combining both handles from FindFirstChange() and from the SetWaitableTime(), the WaitForMultipleObjects() can respond to either the timer that elapses or a change in the folder.

I also intend to create a third handle for the WaitForMultipleObjects(), to let it act on console input (keyboard or mouse). The app should be running on a server, as a service, but could also run 'visible' as a regular exe. It then shows a status form with an exit button.

I don't see how to do this in plain VFP.

I've got the MSDN info regarding the FILETIME structure, but still have no clue how, in VFP, to transform a 5 minute timer in a FILETIME structure parameter.


 
I hope you know news2news.com

SystemTimeToFileTime() will give you the FILETIME corresponding to the system time, and to add 5 minutes to that you need to add 5*60*10000000 (a nanosecond is a really short time, 100 nanoseconds are still rather short).

Also, as Mike said "structure" is giving a false impression. a FILETIME simply is a 64 bit long integer number. VFP does not support this, but 64 bits simply is 2 32bit integers...

Bye, Olaf.
 
Thanks for the help!

But the WairForMulipleObjects() has an extra timeout parameter so i don't need this extra handle to a timer. I guess i looked to long at it and did not see this immediatly.


 
Gevli,

Your explanation is very clear.

I'm still not convinced that you need these API calls, but since you have already gone this far, I'll try to answer your question.

I've never worked with FileTimes before, but it seems fairly straightforward. To get the FileTime of a time five minutes in the future, I guess you would do something like this:

Code:
* VFP datetime
ltTime = DATETIME() + (5 * 60)
* Number of seconds since base date
lnFileTime = ltTime - DATETIME(1600, 1, 1, 0, 0, 0)
* Convert to 100 nanosecond units
lnFileTime = lnFileTime * (10^7)
* Convert to required format
lcFileTime = CREATEBINARY("lnFileTime")

NOTE: I am not sure about the last line. You need to convert lnFileTime, which is a VFP numeric, to a binary format. I'm not sure if this is the right way to do it.

Olaf: Can you advise on this point.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
suggest you use this , 50 independent timers , works when users are waiting for old-style input etc etc


Set Library To cpptimer.fll
inittimers(1,100)
setuptimer(1,1000,"dowork()")

wehre dowork is any vfp proc you need
 
The app i'm working on is monitoring a folder. Whenever the folder changes (a new file is dropped into it) this app has to read the file and pass it to another app that is waiting for input.

You do realize that you could do this with a VFP Timer don't you?

You merely create a special, stand-alone EXE whose 'job' it is to check the directory. That application can run in parallel (concurrently) with any other VFP application that needs to be running.
You would use a Timer to examine the ADIR() of the desired folder. And since the Timer intervals are set in milliseconds you can check pretty much as often as needed.

When you see that a new file has been added to the desired directory, you do whatever you need to do such as set a semaphore (an 'alert' flag) or move the file, etc. - and then go right back into the 'looking' mode.

Good Luck,
JRB-Bldr
 
@Mike, the conversion would rather be done by BINTOC(Value,"8R"), or you do it piece by pice (as news2news does with word2num and num2word) and concatenate the partial results.

But I fear you'd get a problem with the supported value range of numeric variables by calculaing the filetime from seconds since 1st January 1600.

For example this is about 12991673319 now and multiplied by 10^7 this gives 129916733190000000 of course, 18 decimals.

From the perspecitive of N(20) being the maximum numeric field width, this means about 100 times more would be supported, but from the perspecitve of exact calculations vfp does allow about 16 digits accuracy only, not counted from the decimal point but from the highest value digit.

That's why I suggested using SystemTimeToFiletime, and then manipulating the result word wise.

Nevertheless I think gevli has found a totally different solution in WaitForMulipleObjects().

Bye, Olaf.
 
Thanks again, but yes, i found a different solution in the WaitForMultipleObjects() function that has a timeout parameter by itself.

Gevli
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top