tags:

views:

109

answers:

3

I have a very simple application with a form, a richedit and a menu. I'm trying to automatically save the text on the richedit and perform other tasks but only when the application is idle - when the user is not writing or the app loses focus or whatever.

I tried creating an OnIdle event handler from a gazillion sample codes found on the internet, but it does the opposite, it activates when I am using the app. This link is an example.

I also tred with a timer and check when was the last time the user wrote to the richedit, but I rather not use a timer if possible.

Anyone knows how to detect that an application is idle and run some code when it is? I'm using delphi 7.

+1  A: 

You might be best off with a timer. OnIdle will fire often. What that message means, I believe, is that all messages in the queue have been handled. So every time you have messages processed, when its done, an OnIdle is fired.

What you could do is set a variable to a time stamp after every OnChange event in the rich edit. Then, using a timer, check every X seconds to see if that timestamp is more than say 5 seconds old. If it is, do your saves then.

GrandmasterB
thank you, so there is no way to do this via a windows API, messages or other ways except for a timer. OK...
Jessica
A timer per-se isnt strictly necessary. You could, for instance, have a worker thread just looping in the background, checking every second to see if the data should be saved. Thats a good approach if you're watching a lot of things, or need something thats not tied to the GUI. But thats not something I would do if a basic timer would work. Just curious - is there a reason you dont want to use a timer?
GrandmasterB
+3  A: 

I would recommend an timer also, but would "reset" the countdown (toggle off and then back on) in response to any keyboard event occurring within the richedit. That way, you aren't saving while the user is trying to type.

As Andreas pointed out, here's how to actually implement this: Every time the user performs some action, e.g. changes the caret pos of the editor, do Timer1.Enabled := false; Timer1.Enabled := true. This will reset the timer. In effect, the timer will never fire until there has been no user activity for the last Timer1.Interval milliseconds

Chris Thornton
thanks Chris, I'm trying to understand. Do you want me to create a timer and check a variable, if it's `0` then write (user is idle) if it's `1` don't write, user is currently writing on the richedit. is this correct?
Jessica
Every time the user performs some action, e.g. changes the caret pos of the editor, do `Timer1.Enabled := false; Timer1.Enabled := true`. This will reset the timer. In effect, the timer will never fire until there has been no user activity for the last `Timer1.Interval` milliseconds.
Andreas Rejbrand
@Andreas - thank you, I've added your example to make the answer stronger.
Chris Thornton
Plus you should disable the timer after the text was saved. Next user action will then re-enable it.
gabr
A: 

function GetIdleTime:DWORD; var lastI:TLastInputInfo; begin lasti.cbSize:=SizeOf(lasti); GetLastInputInfo(lastI); Result:=(gettickcount -lastI.dwTime) div 1000; end;

procedure TForm1.Timer1Timer(Sender: TObject); begin if getidletime=60 then Memo1.savetofile('C:\jgs.tmp'); end;

Use this

Tavi