Newsgroup: it.comp.lang.delphi
Titolo: Messaggio movimento Mouse

Ciao a tutti
Ho un problemino....
Dovendo fare un logout da una mia applicazione se non viene mosso il mouse o
toccata la tastiera per un certo periodo di tempo, chi mi sa dire come fare?
Purtroppo non posso usare le properties ONMouseMove, OnkeyDown....ecc.
dell'applicazione ed un oggetto TTimer che mi si resetta se queste sono
valide, perché se l'applicazione è ridotta, o mi muovo in un altra
applicazione, oppure se sono dentro una Form che non è la principale (ed è
scomodo settare le properties in tutte le form) il tutto non funziona.
Mi sembra che Windows riceva un messaggio se vengono usate tastiera e/o
Mouse, (per lo screen saver ad esempio), ma non ho idea di come si possa
fare....
 Help Me!
    Ciao
___________________> Giulio <____
E-Mail address: 
NOSPAM_g...@iol.it
Ricorda; togli NOSPAM_ per rispondermi.

 Mi sembra che Windows riceva un messaggio
Questa frase ha un che di strano ... casomai invia un messaggio alle
applicazioni in certe situazioni ...
ma non ho idea di come si possa fare....
Devo costruirti un Message-Handler, ovvero una procedura che è in grado di
manipolare i messaggi inviati alla tua applicazione ...
Public
 procedure Gestore (var Msg : TMsg; var Manipola : boolean );
Ecco il codice della procedura :
procedure TForm1.Gestore(var Msg : TMsg; var Manipola : boolean );
begin
  if (Msg.Message = WM_SYSCOMMAND) and
     (Msg.wParam = SC_SCREENSAVE) then
     Manipola := True;
     // tempo trascorso
end;
Il parametro boolean Manipola è proprio l'handler, infatti sulla base di
quello si decide se "accettare" o meno il messaggio inviato dal sistema.
Per ottenere/impostare il timeout dello screensaver devi utilizzare
SystemParametersInfo con, rispettivamente,
SPI_GETSCREENSAVETIMEOUT/SPI_SETSCREENSAVETIMEOUT.
Ciao!
--
- Carlo -
c.b...@libero.it

applicazioni in certe situazioni ...
  OOPS! hai ragione.
    Grazie Mille, provo subito.
    Ciao
___________________> Giulio <_______

fare....
Se hai uno screensaver installato nel sistema, sei soggetto alle sue
regole e quindi non lo puoi sfruttare per i tuoi scopi.
--
Andrea Laforgia (ICQ 87230455)
http://www.geocities.com/AndreaLaforgia
"ci sono tre tipi di persone nel mondo : quelli che
 sono bravi in matematica e quelli che non lo sono."

 regole e quindi non lo puoi sfruttare per i tuoi scopi.
Se hai uno screensaver installato nel sistema è sufficiente conoscere il suo
timeout e, se necessario, modificarlo (SystemParametersInfo).
Sconsiglio l'utilizzo di Hook globali se non prettamente necessario: rendono
il sistema più instabile, possono entrare in conflitto con altri hook dello
stesso tipo e rallentano il sistema.


stesso tipo e rallentano il sistema.
Non c'e' nessun problema a lavorare con gli hook.
Sul newsgroup Borland, qualche tempo fa, e' apparso un "Hook
Framework", in grado di installare/gestire/deinstallare gli hook
system-wide in modo molto efficiente.  Io consiglio questa soluzione.

Io consiglio questa soluzione.
Io la sconsiglio ... ma il mondo è bello perchè è vario!


tipo.
Non e' un problema in questo caso. 
Applicazioni che installano hook del mio tipo non faranno altro che
cedere il controllo, se sono scritte bene, alla mia funzione filtro.
Gli hook installano delle funzioni filtro linkate l'una all'altra.
Le funzioni filtro non fanno altro che costituire una catena in cui e'
sempre bene passare la staffetta.
Possono sicuramente affliggere le risorse del sistema, ma sicuramente
non in modo significativo (anche perche' non sono tante le
applicazioni che utilizzano hook contemporaneamente). 
Questo significa che, se sono implementati bene, non arrecano alcun
rischio per il sistema.  
Io ho scritto DLL per l'uso di hook in programmi di controllo remoto,
senza generare alcun problema per la macchina ospite.
Ci tengo a precisare che non voglio alimentare un'inutile polemica,
per cui rimaniamo tutti e due dei nostri punti di vista, senza
proseguire oltre.


 senza generare alcun problema per la macchina ospite.
Anche io ho avuto rari problemi con gli hooks, ma posso assicurarti che le
rogne non mancano.
In conclusione di tutto ciò posso dire che è praticamente impossibile avere
la certezza di funzionamento di un applicazione di questo tipo ... forse il
problema che ho messo in risalto (relativamente ai tasti filtrati) si
ripresenta anche con lo screen-saver, bisognerebbe vedere come Windows
gestisce il messaggio WM_SYSCOMMAND.
La soluzione che si avvicina maggiormente alla richiesta consiste nella
dispendiosissima installazione di tanti hook attivi a livello di thread
(così si sormonterebbero eventuali hook globali) ma il problema rimarrebbe
proprio per altri thread-hooks che potrebbero essere installati nel sistema,
ripeto che la semantica delle API non garantisce alcun ordine di preferenza.


CallNextHookEx() e il testimone non ti arriverà mai. 
E' proprio questo il caso in cui, secondo me, la funzione filtro NON
E' scritta bene.  Le funzioni filtro devono prevedere di lasciare il
controllo alle altre in cascata.
--
Andrea Laforgia (ICQ 87230455)


Per la tastiera non ti saprei dire [senza dover usare hook di cui so ben
poco] ma per il mouse potresti semplicemente verificarne la posizione con
"GetCursorPos" a tempo (che sò... ogni 200 millisecondi per esempio)...
TForm1.Timer1Timer(Sender : TObject);   //Suppogno di inserirla all'interno
del Timer1
var
 p :TPoint;
begin
 GetCursorPos(p);
 .....
 .....
 .....
end;
in p.x avresti le coordinata X del mouse e in p.y la coordinata Y...
Rimane il problema della tastiera... [sfogliando l'help ho visto che ci sono
delle funzioni tipo GetKeyboardState e GetKeyState... non ho la minima idea
a cosa possano servire perché non ho avuto tempo di leggere ma io ci darei
un occhiata se fossi in te... magari puoi usarle un po' come
GetCursorPos...]
Ciao
  Luca

Manco per qualche giorno e vedo che la mia domanda ha scatenato un dibattito
da talk-show  :-)
Ricordo che volevo ottenere un Logout da una mia applicazione.
Sono d'accordo anche io sul fatto che non voglio modificare il timeout dello
screen-saver, io l'ho citato solo come esempio perché pensavo di utilizzare
lo stesso principio di intercettazione del mouse/tastiera per la mia
applicazione non essendo pratico dei messaggi di Windows (forse ho creato
confusione).
Comunque penso di aver risolto così, non è certo la maniera + brillante
ma..... (consigli ben accetti):
Grazie al consiglio iniziale di Carlo Bertuccini ho scoperto come usare i
mex che Windows manda alle applicazioni, quindi....
tramite l'intercettazione di WM_SYSCOMMAND  ho provveduto a disattivare un
Timer che si riattivava subito dopo (Provocando un reset RESET).
Quando scadeva il tempo facevo un Log Out.
Il tutto funzionava, ma quando l'applicazione faceva uso della porta COM,
anche se non si toccava tastiera o mouse il Timer si resettava.
Allora, ho intercettato WM_MOUSEMOVE o WM_KEYDOWN.
Il tutto sembra funzionare.
procedure TForm1.Logout(var Msg : TMsg);
begin
if (Msg = WM_MOUSEMOVE) or (Msg = WM_KEYDOWN) then
  Timer_Logout.Enabled := False;
Timer_Logout.Enabled := TRUE;
end;
......
OnTimer -> Logout
    Ciao a Tutti.


Errorino nel riportare la procedure.....
Di seguito la procedure riveduta e corretta.
procedure TForm1.Logout(var Msg : TMsg);
begin
if (Msg.message = WM_MOUSEMOVE) or (Msg.message = WM_KEYDOWN) then
  Timer_Logout.Enabled := False;
Timer_Logout.Enabled := TRUE;
end;
......
OnTimer -> Logout
Ri-Ciao a Tutti.
