2010-09-16 6 views
1

J'ai une application très simple avec un formulaire, un Richedit et un menu. J'essaye d'enregistrer automatiquement le texte sur le richedit et d'effectuer d'autres tâches mais seulement quand l'application est inactive - quand l'utilisateur n'écrit pas ou l'application perd le focus ou peu importe.Exécution d'une action lorsque l'application est inactive

J'ai essayé de créer un gestionnaire d'événements OnIdle à partir d'un code d'échantillons gazillion trouvés sur Internet, mais il fait le contraire, il active quand je am en utilisant l'application. Ce link est un exemple.

Je ai également truqué avec un minuteur et vérifier quand était la dernière fois que l'utilisateur a écrit sur le richedit, mais je préfère ne pas utiliser un minuteur si possible.

Quelqu'un sait-il détecter qu'une application est inactive et exécuter du code quand c'est le cas? J'utilise delphi 7.

+1

Votre solution sûrement besoin d'une minuterie quelque part: sinon comment allez-vous Spécifiez si «inactif» signifie inactif pendant une milliseconde ou inactif pendant quelques secondes? – frogb

+0

inactif signifie inactif. l'utilisateur ne fait rien. si vous voulez que ce soit pendant 1 sec, puis 1 sec, 1 min, puis une minute. alors choisissez celui qui ne fait pas de différence – Jessica

+0

Une minuterie est le moyen de le faire! Pourquoi ne voulez-vous pas utiliser une minuterie? BTW, enregistrer un petit document RTF sur le disque prend quelques millisecondes; l'utilisateur final ne le remarquerait jamais même si vous l'aviez sauvegardé dix fois par seconde! En outre, un 'TTimer' n'est rien d'étrange Borland-ish, mais seulement un wrapper pour la fonctionnalité native de Win32. –

Répondre

3

Je recommanderais également une minuterie, mais je "réinitialiserais" le compte à rebours (désactiver, puis rallumer) en réponse à tout événement de clavier se produisant dans le fichier richedit. De cette façon, vous ne sauvegardez pas pendant que l'utilisateur essaie de taper. Comme Andreas l'a souligné, voici comment implémenter réellement ceci: Chaque fois que l'utilisateur effectue une action, par ex. change le caret pos de l'éditeur, faites Timer1.Enabled: = false; Timer1.Enabled: = true. Cela réinitialisera la minuterie. En effet, la minuterie ne sera jamais le feu jusqu'à ce qu'il n'y a pas eu d'activité de l'utilisateur pour les dernières millisecondes Timer1.Interval

+0

merci Chris, j'essaie de comprendre.Voulez-vous que je crée une minuterie et que je vérifie une variable, si c'est '0' alors écrivez (l'utilisateur est inactif) si c'est' 1' n'écrivez pas, l'utilisateur écrit actuellement sur le richedit. est-ce correct? – Jessica

+1

Chaque fois que l'utilisateur effectue une action, par ex. change le signe pos de l'éditeur, fait 'Timer1.Enabled: = false; Timer1.Enabled: = true'. Cela réinitialisera la minuterie. En effet, la minuterie ne se déclenche jamais tant qu'il n'y a pas eu d'activité de l'utilisateur pour les dernières millisecondes 'Timer1.Interval'. –

+0

@Andreas - merci, j'ai ajouté votre exemple pour rendre la réponse plus forte. –

1

Vous pourriez être mieux avec une minuterie. OnIdle tirera souvent. Ce que ce message signifie, je crois, c'est que tous les messages dans la file d'attente ont été traités. Donc, chaque fois que vous avez traité des messages, quand c'est fait, un OnIdle est déclenché.

Ce que vous pouvez faire est de définir une variable sur un horodatage après chaque événement OnChange dans l'édition enrichie. Ensuite, en utilisant une minuterie, vérifiez toutes les X secondes pour voir si cet horodatage a plus de 5 secondes. Si c'est le cas, faites vos économies alors.

+0

merci, donc il n'y a aucun moyen de le faire via une API Windows, des messages ou d'autres moyens, sauf pour une minuterie. OK ... – Jessica

0
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; 

Utilisez cette

+0

Vous devriez vérifier GetIdleTime> = 60, sinon vous pourriez manquer le moment. –

Questions connexes