L_art_ment
Messages postés302Date d'inscriptionvendredi 21 septembre 2007StatutMembreDernière intervention 6 février 2013
-
2 juil. 2009 à 15:54
L_art_ment
Messages postés302Date d'inscriptionvendredi 21 septembre 2007StatutMembreDernière intervention 6 février 2013
-
2 juil. 2009 à 19:03
Mes cieux d'âmes,
Je vous reviens avec une merveilleuse question, sur laquelle je me casse la tête depuis quelques heures... J'm'en va vous expliquer :
Mon but est de pouvoir mettre en veille un poste (veille normale ou veille prolongée), et de le reveiller; jusque là, j'y parviens, j'arrive à mettre en veille et à le reveiller en choisissant mon interval, par exemple 10secondes, pour ce faire, j'utilise cette procedure :
//Mise en veille
procedure standby;
begin
if IsPwrSuspendAllowed then
SetSuspendState(false, false, false) //le premier parametre, s'il vaut true alors Veille prolongée
else
MessageDlg('La mise en veille n'est pas gérée sur ce system.', mtWarning, [mbOK], 0);
end;
Pour déclencher la remise en route, j'utilise les evenement "d'alimentation" et les thread de cette manière :
//Cette fonction va detecter la mise en veille (ou veille prolongée), et va lancer le thread avec le délai avant la remise en route
procedure TForm1.WMPowerBroadcast(var Msg: TMessage);
begin
//Check for suspend operation
case Msg.wParam of
//Query for allowing suspend
PBT_APMQUERYSUSPEND : ;
PBT_APMSUSPEND : TWakeupThread.Create(-400000000); // Ici je detecte la veille
// Resuming from event, we want monitor display
PBT_APMRESUMEAUTOMATIC : SetThreadExecutionState(ES_DISPLAY_REQUIRED);
PBT_APMSTANDBY : TWakeupThread.Create(-400000000); //detect veille prolongée
end;
// Set message result
Msg.Result:=1;
end;
//Création du thread
constructor TWakeupThread.Create(Time: Int64);
begin
inherited Create(False);
FreeOnTerminate:=True;
FTime:=Time;
end;
//Execution
procedure TWakeupThread.Execute;
var hTimer: THandle;
begin
// Create a waitable timer.
hTimer:=CreateWaitableTimer(nil, True, 'WaitableTimer');
if (hTimer <> 0) then
begin
if (SetWaitableTimer(hTimer, FTime, 0, nil, nil, True)) then
begin
WaitForSingleObject(hTimer, INFINITE);
end;
CloseHandle(hTimer);
end;
end;
Donc en résumé, quand on detect la mise en veille, on déclanche le timer pour un délai souhaité, à la fin du délai, le paramétre à True de la fonction SetWaitableTimer permet la remise en route du system, si il était à False, ca resterai en veille...
Mais moi ce que j'aimerai, c'est remettre en route le system, à l'heure que je désire... J'ai vu dans la MSDN que le paramétre FTime de la fonction SetWaitableTimer pouvait être une heure (si j'ai bien compris) : http://msdn.microsoft.com/en-us/library/ms686289(VS.85).aspx
mais je ne parvient pas à utiliser cette fonction de cette manière et n'ai trouvé aucun exemple... Et c'est là que je solicite vos lumiéres !
J'ai pourtant essayé une methode palliative mais qui ne fonctionne pô (l'idée étant d'executer le timer avec SetWaitableTimer avec le paramétre false tant qu'il ne trouve pas dans l'heure actuelle l'heure à laquelle je veux redémarrer le system, si il le trouve il execute le timer avec le paramétre true), la voici :
//Execution
procedure TWakeupThread.Execute;
var hTimer: THandle;
begin
// Create a waitable timer.
hTimer:=CreateWaitableTimer(nil, True, 'WaitableTimer');
while (hTimer <> 0) do
begin
if (SetWaitableTimer(hTimer, FTime, 0, nil, nil, False)) then
begin
WaitForSingleObject(hTimer, INFINITE);
if pos('10:30',DateTimeToStr(gettime))<>0 then
begin
closeHandle(hTimer);
hTimer:=0;
end
end;
hTimer:=CreateWaitableTimer(nil, True, 'WaitableTimer');
if (hTimer <> 0) then
begin
if (SetWaitableTimer(hTimer, FTime, 0, nil, nil, True)) then
begin
WaitForSingleObject(hTimer, INFINITE);
end;
CloseHandle(hTimer);
end;
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 2 juil. 2009 à 16:39
Mais moi je comprends pas pourquoi tu passes par un WaitForSingleObject ? La fonction SetWaitableTimer attend un pointeur vers un callback, qui sera appelé dès que le timer sera enclenché à l'heure désirée ! Et toi tu envoies "nil" pour le callback ...
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 2 juil. 2009 à 16:43
procedure MyCallback(lpArg: Pointer; dwTimerLo: Longword; dwTimerHi: Longword); stdcall;
begin
// Le timer est enclenché, faire divers traitements ...
CloseHandle(hTimer);
end;
hTimer := CreateWaitableTimer(nil, True, 'WaitableTimer');
if hTimer <> 0 then SetWaitableTimer(hTimer, FTime, 0, @MyCallback, nil, True);
Enfin moi c'est comme ça que je conçois l'utilisation de cette fonction au vu de la description MSDN ... mais je n'ai pas testé le code.
L_art_ment
Messages postés302Date d'inscriptionvendredi 21 septembre 2007StatutMembreDernière intervention 6 février 2013 2 juil. 2009 à 19:03
Salut Bacterius, merci de m'avoir répondu !
Je passe par un WaitForSingleObject car ca y été dans l'exemple que j'ai trouvé, à vrai dire je n'ai passé de temps à comprendre cette fonction mais surtout le SetWaitableTimer...
Et j'arrive enfin mon but !!
Voici le code que j'utilise :
//Ici je detecte toujours les messages de mise hors tension, retour au system...
procedure TForm1.WMPowerBroadcast(var Msg: TMessage);
begin
//Check for suspend operation
case Msg.wParam of
//Query for allowing suspend
PBT_APMQUERYSUSPEND : ;
//We ARE being suspended (1 seconde = -10000000)
PBT_APMSUSPEND : TWakeupThread.Create('10/06/2009 18:45:00'); //Je passe maintenant en variable la date et l'heure à laquelle je veux relancer mon system
// Resuming from event, we want monitor display
PBT_APMRESUMEAUTOMATIC : SetThreadExecutionState(ES_DISPLAY_REQUIRED);
PBT_APMSTANDBY : ; //TWakeupThread.Create(-200000000); //detect veille prolongée
end;
// Set message result
Msg.Result:=1;
end;
//La création (HWakeUp est l'heure que j'ai passé en variable quand on a detecté la mise en veille)
constructor TWakeupThread.Create(HWakeUp: string);
begin
//Et l'Execute, bon je ne comprend pas toute toute les étapes (comme la manipulation de la date que je lui envoie), mais ca fonctionne..
procedure TWakeupThread.Execute;
var hTimer: THandle;
WakeUpTme: LARGE_INTEGER;
SysTime : _SystemTime;
FTime : _FileTime;
WT,hThread:THandle;
begin
DateTimeToSystemTime(StrToDateTime(HeureWakeUp), SysTime);
SystemTimeToFileTime(SysTime, FTime);
LocalFileTimeToFileTime(FTime, FTime);
WakeUpTme.LowPart:=FTime.dwLowDateTime;
WakeUpTme.HighPart:=FTime.dwHighDateTime;
WT := CreateWaitableTimer(nil,TRUE,'WakeUpThread');
SetWaitableTimer(WT,WakeUpTme.quadpart,0,nil,nil,true);
WaitForSingleObject(WT, INFINITE);
CloseHandle(WT);
end;