Newsgroup: it.comp.lang.delphi
Titolo: Intercettare la tastiera

sono messo male !
devo intercettare un click del mouse ma non sono riuscito a fare
niente
l'unico codice che mi funziona è il seguente ma solo quando la window
attiva è la mia.
procedure TForm1.Timer1Timer(Sender: TObject);
var
   msg    : TMsg;
begin
   if GetMessage( msg , Handle , WM_KEYFIRST , WM_KEYLAST ) Then
   begin
     if msg.message = WM_KEYDOWN Then
     begin
       Memo1.lines.add('Handle: ' + IntToStr(handle));
       Memo1.lines.add(IntToStr(msg.wParam));
       Memo1.lines.add(IntToStr(msg.lParam));
       Memo1.lines.add('');
     end;
   end;
end;
un Timer fa il partire questa procedura ogni TOT millisecondi
ma non funziona che vorrei
aiutatemi, vi prego ....
grazie
 
 ---==[ BlacK Bird ]==---
     ICQ#: 14491159
 
 
b...@blackbird.cjb.net
 
 
     Web Site
 
http://www.blackbird.cjb.net

   if GetMessage( msg , Handle , WM_KEYFIRST , WM_KEYLAST ) Then
Il problema giace nella chiamata a GetMessage...
GetMessage riceve solo i messaggi relativi all'applicazione chiamante,
ovvero la tua. Ti riporto lo spezzone di SDK relativo...
"The GetMessage function retrieves a message from the calling thread's
message queue and places it in the specified structure....GetMessage does
not retrieve messages for windows that belong to other threads or
applications."
Cosa significa ciò; tu quel particolare messaggio lo rilevi se e solo se è
destinato alla tua applicazione, ecco perchè "L'unico codice che mi funziona
è il seguente ma solo quando la window attiva è la mia." Prima di proseguire
faccio una "critica" al metodo che hai utilizzato per operare...Utilizzare
un timer che si mette in attesa di un messaggio non è affatto una buona
soluzione, soprattutto quando la VCL mette a disposizione metodi quali
OnMessage dell'oggetto TApplication.
Detto questo vediamo di capire bene cosa vuoi fare...forse sono io che non
ho ben capito, cmq dici di voler intercettare un click e poi lavori su
WM_KEYDOWN. (???)
L'unica soluzione che hai per intercettare questo click a livello di sistema
è un hook...l'hook praticamente "si infila" in altre applicazioni attive e
ti permette di lavorarci.
Adesso quello che ti serve è un hook che si vada ad infilare in tutte le
applicazioni (prende il nome di SystemWide Hook) e, da ciascuna
applicazione, controlli se viene effettuato un click su di essa. Ahimè per
utilizzare gli hook a livello di sistema devi utilizzare una DLL, quindi il
lavoro si complica un po' [soprattutto se devi far comunicare la DLL con
l'EXE].
Ecco uno spezzone di codice che ti intercetta tutti i click effettuati con
il tasto sinistro :
[dovrebbe funzionare...lo ho appena scritto e mai testato! :)]
Questa è la DLL....
library Gancio;
uses
  SysUtils,
  Windows,
  Messages,
  Classes;
{$R *.RES}
Var
 HookHandle : Integer;
Function HookProc(Codice:Integer; WP : Wparam; LP:Lparam) : Integer;
Stdcall;
Begin
 If (Codice=HC_Action) and (WP=WM_LBUTTONDOWN) then
 //Tuo Codice - Qui ci va quello che vuoi fare....
 Result := CallNextHookEx(HookHandle,Codice,WP,LP);
end;
Procedure CaricaHook; stdcall;
Begin
   HookHandle:=SetWindowsHookEx(WH_MOUSE,@HookProc,hInstance,0);
end;
Procedure RimuoviHook; stdcall;
Begin
   UnHookWindowsHookEx(HookHandle);
end;
Exports
CaricaHook,RimuoviHook;
begin
end.
File Eseguibile :
Procedure CaricaHook; stdcall; External 'Gancio.DLL';
Procedure RimuoviHook; stdcall; External 'Gancio.DLL';
.....
procedure TForm1.Button1Click(Sender: TObject);
begin
CaricaHook;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
RimuoviHook;
end;
Purtroppo gli Hook sono un argomento molto vasto che implicitamente ne
coinvolgono altri [vedi tecniche IPC, iniezione di Thread etc..], quindi non
posso fare altro che postarti questo codice sperando che ne cavi fuori
qualcosa. Un appunto, se ti interessa "filtrare" il click [ovvero se vuoi
che quel messaggio non vada mai alla coda dei msg o alla WindowProc
dell'applicazione destinataria] rimuovi la chiamata a CallNextHookEx (e a
quel punto fai diventare la funzione una procedura.)
Ciao! :)
--
- Carlo -



Ahimč per utilizzare gli hook a livello di sistema devi utilizzare una DLL
Non sempre, comunque.
Esistono WH_JOURNALPLAYBACK e WH_JOURNALRECORD che sono tipi di hook
impostabili solo a livello di sistema e che non necessitano che le
funzioni di filtro risiedano nella DLL.