Newsgroup: it.comp.programmare.win32
Titolo: tastiera

Ciao a Tutti!!!
Come faccio a ricevere i messaggi dalla tastiera tipo WM_CHAR
anche quando NON ho il focus della finestra?
Praticamente vorreri ricevere i caratteri premuti anche se
l'utente sta usando un altro programma.
(Con le API di windows.)
GRAZIE un milione!!!
Francesco

 ha scritto nel messaggio
news:i8t%a.245653$Ny5.7...@twister2.libero.it...

Devi creare un hook di sistema, che deve stare in una dll, poi il tuo
programma istanziera' la dll e dovrai farti passare i "dati" da essa.

 ha scritto nel messaggio
news:lKv%a.44863$sj6.1...@tornado.fastwebnet.it...

tutto questo legale solo se sei administrator o hai tali permessi di
raggiungere la kernel area giusto ???
in user mode non hai possibilita' di riuscirci no ?
ciao

 sta usando un altro programma.
installa un hook di basso livello per la tastiera, SetWindowsHookEx con 
tipo WH_KEYBOARD_LL. E' molto meglio di un hook globale: prima di tutto 
perchè è più semplice da gestire (non c'è bisogno di scrivere una DLL e 
non serve fare giri strani di IPC per comunicare gli eventi al processo 
principale), poi perchè funziona anche quando un hook globale, per ovvi 
motivi di sicurezza, non verrebbe installato (ad esempio in presenza di 
processi che girano come altri utenti)
-- 
  < 
http://www.reactos.com/
 >  Open source clone of Windows NT. Current
      Don't stand, REACT!      version 0.1.2. C, C++ and ASM developers
                               and beta testers are welcome!

 processi che girano come altri utenti)
Su questo punto mi servono chiarimenti: l'hook WH_KEYBOARD funziona solo
se globale (se locale non serve a niente perché intercetta solo i messaggi
per l'applicazione), ma da quanto sto capendo dal tuo post, l'hook
WH_KEYBOARD_LL funziona su tutto il sistema anche se locale, giusto?
Qualcuno mi risponda, che questa informazione mi serve!!!
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 Qualcuno mi risponda, che questa informazione mi serve!!!
io ero dubbioso, xo' ho provato ed effetivamente funziona....
quindi si, ho creato un applicazione che intercetta i tasti premuti anche in
altre finestre,
e tutto questo con 2 righe di codice e senza dll, ottimo ;o)
anche se questo metodo funziona solo con i messaggi della tastiera e del
mouse,
per intercettare gli altri credo proprio sia obbligatoria la dll
(corregetemi se sbaglio).

 raggiungere la kernel area giusto ???
No, lo hook non richiede permessi ne accessi in modalità KM: è direttamente
il mm di Windows che si incarica di caricare i moduli da mappare nei vari
processi.
Diciamo che è una delle poche vie "legali" che Windows fornisce in UM per
ottenere informazioni altrimenti irrecuperabili.
--
- Carlo -

 su tutto il sistema anche se locale, giusto?
tutto documentato:
"LowLevelKeyboardProc Function
[...]
Remarks
[...]
This hook is called in the context of the thread that installed it. The 
call is made by sending a message to the thread that installed the 
hook. Therefore, the thread that installed the hook must have a message 
loop.
[...]"
Da tenere anche presente che:
"[...]
The hook procedure should process a message in less time than the data 
entry specified in the LowLevelHooksTimeout value in the following 
registry key:
HKEY_CURRENT_USER\Control Panel\Desktop
The value is in milliseconds. If the hook procedure does not return 
during this interval, the system will pass the message to the next 
hook.
[...]"


 ha scritto nel messaggio
news:lKv%a.44863$sj6.1...@tornado.fastwebnet.it...

Grazie a Te e A Tutti per i preziosi consigli!!!
Ho fatto come suggerito ma ho un problema:
La  " KeyboardProc" (hook) inserita nella dll mi restituisce in wParam il
virtual-key code
MA solo con la mia applicazione quella dove carico la dll
mentre in tutte le altre applicazioni ad esempio digito nel notepad.exe
la "KeyboardProc" intercetta la pressione dei tasti (ho inserito un Beep()
per essere sicuro)
ma wParam non mi restituisce il virtual-key code.
Aiutino?
GRAZIE!

 ha scritto nel messaggio
news:Xns93DA2438...@127.0.0.1...

Il mio vecchio BCPP3 (tempi di windows 95)
non supporta il tipo  WH_KEYBOARD_LL
ho dovuto creare la dll.
Comunque Grazie!!!

 WH_KEYBOARD_LL
mica deve supportarle lui. "WH_KEYBOARD_LL" è solo una costante, se non 
c'è negli header la si aggiunge


 ha scritto nel messaggio
news:Xns93E0A6B...@127.0.0.1...

Ho letto in un messaggio precedente che andava usata con
LowLevelKeyboardProc
e questa funzione Non è presente nelle api che accompagnano il mio vecchio
compilatore.
Comunque proverò a inserirla e usarla con KeyboardProc.
GRAZIE!!!
Ciao!

 accompagnano il mio vecchio compilatore.
quella funzione devi definirla tu, col nome che ti pare, e passarla per 
puntatore a SetWindowsHookEx. Guarda, vuoi un po' di codice d'esempio?


 puntatore a SetWindowsHookEx. Guarda, vuoi un po' di codice d'esempio?
piacerebbe vederlo anche a me' qualche esempietto ;-)
tnx ciao

 GRAZIE!
Io ho provato anche la soluzione riportata da Juliet ed effetivamente e'
molto piu comoda,
quindi se ti serve intercettare solo i messaggi di mouse e/o tastiera ti
conviene non usare la dll.
se invece vuoi far pratica anche con questo metodo, in quanto ti puo' poi
servire per intercettare altri
tipi di messaggi, allora spiega meglio che non ho capito :oD
Intendi che la dll intercetta solo i tasti premuti nella tua applicazione
mentre negli altri no??
se e' cosi puo' darsi che non hai passato i giusti parametri alla
SetWindowsHoock, prova a mettere 0
a dwThreadId
HHOOK SetWindowsHookEx(
  int idHook,        // type of hook to install
  HOOKPROC lpfn,     // address of hook procedure
  HINSTANCE hMod,    // handle to application instance
  DWORD dwThreadId   // identity of thread to install hook for
);
Se invece intendevi che il tasto premuto poi non arriva a notepad
forse perche' devi chiamare la CallNextHookEx().
cmq specifica qualche informazione in piu' e vediamo se riusciamo a
risolvere ;o)

> puntatore a SetWindowsHookEx. Guarda, vuoi un po' di codice d'esempio?
Con Molto Piacere!!!
Ciao!

 forse perche' devi chiamare la CallNextHookEx().
La mia dll intercetta i tasti premuti in notepad
e notepad stampa il carattere premuto perchè uso CallNextHookEx()
Ma la funzione nella dll
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam,  LPARAM lParam)
{
Beep(...);
...........
}
mi restituisce correttamente il il virtul-key code   in  wParam   dei tasti
digitati nella mia applicazione quella che carica la dll
mentre i tasti premuti in notepad  wParam  non mi restituisce il il
virtul-key code ma un valore (forse) casuale
nota: sono sicuro che intercetta i tasti premuti con notepad perchè dentro
KeyboardProc ho inserito un Beep() per test.
CIAO!!!

 piacerebbe vederlo anche a me' qualche esempietto ;-)
ecco qua:
#include <stdlib.h>
#include <stdio.h>
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#define KBDLLTOLPARAM(__S__) \
 ( \
  0L | \
  ((1 & 0xFFFFL) << 0) | \
  (((__S__)->scanCode & 0x7FL) << 16) | \
  ((((((__S__)->flags) & (LLKHF_EXTENDED)) >> 0) & 1) << 24) | \
  ((((((__S__)->flags) & (LLKHF_ALTDOWN)) >> 5) & 1) << 29) | \
  ((((((__S__)->flags) & (LLKHF_UP)) >> 7) & 1) << 31) \
 )
HHOOK g_hKbdHook = NULL;
_TCHAR g_a_tcAltBuf[255];
_TCHAR * g_ptcAltName = _T("ALT");
LRESULT CALLBACK ShowKeysCallback
(
 int nCode,
 WPARAM wParam,
 LPARAM lParam
)
{
 PKBDLLHOOKSTRUCT pklHookData = (PKBDLLHOOKSTRUCT)lParam;
 if(nCode >= 0 && (wParam == WM_SYSKEYUP || wParam == WM_KEYUP))
 {
  _TCHAR a_tcBuf[255];
  _TCHAR * ptcName = a_tcBuf;
  /* get the key's name in the current locale */
  if(!GetKeyNameText(KBDLLTOLPARAM(pklHookData), a_tcBuf, 255))
   /* unknown key, print the virtual key code */
   if(!_sntprintf(a_tcBuf, 255, _T("<0x%X>"), pklHookData->vkCode))
    /* _sntprintf failed */
    ptcName = _T("???");
  /* ALT + key */
  if(wParam == WM_SYSKEYUP) _tprintf(_T("%s + %s\n"),  g_ptcAltName, ptcName);
  /* key */
  else _tprintf(_T("%s\n"),  ptcName);
 }
 return CallNextHookEx(g_hKbdHook, nCode, wParam, lParam);
}
int _tmain(int argc, _TCHAR * argv[])
{
 BOOL bRet;
 MSG msgCur;
 UINT nLAltScan;
 (void)argc;
 (void)argv;
 /* Try to get the localized name of the left ALT key */
 /* get the left ALT key's scan code in the current locale */
 nLAltScan = MapVirtualKey(VK_LMENU, 0);
 if(nLAltScan)
  /* get the left ALT key's name in the current locale */
  if(GetKeyNameText((nLAltScan & 0x7FL) << 16, g_a_tcAltBuf, 255))
   g_ptcAltName = g_a_tcAltBuf;
 /*
  Set the output codepage to the current ANSI codepage for correct output of
  international characters
  */
 SetConsoleOutputCP(GetACP());
 /* Install the hook */
 g_hKbdHook = SetWindowsHookEx
 (
  WH_KEYBOARD_LL,
  &ShowKeysCallback,
  GetModuleHandle(NULL),
  0
 );
 /* failure */
 if(g_hKbdHook == NULL) return EXIT_FAILURE;
 /* Message loop */
 while(GetMessage(&msgCur, NULL, 0, 0) > 0) DispatchMessage(&msgCur);
 /* Uninstall the hook */
 UnhookWindowsHookEx(g_hKbdHook);
 /* Success */
 return EXIT_SUCCESS;
}
/* EOF */
Questo programma intercetta il rilascio dei tasti e, per ogni tasto, ne 
stampa il nome. Non č perfetto (per stampare il nome corretto, dovrebbe 
prima collegarsi all'input del thread che gestisce la finestra attiva), 
ma puň andare cosě com'č. Ultima cosa: PAUSA premuto in una finestra di 
console ne interrompe l'output (INVIO per annullare); non vi stupite se 
premendolo si blocca tutto :-)
