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

Dovrei catturare tutti i tasti premuti da tastiera, diretti alla mia
applicazione e non.
ho pensato a farmi una funzioncina in assembler per leggere i caratteri
direttamente dal buffer di tastiera, ma funzionerebbe??? O riceverei sempre
e solo quelli diretti alla mia applicazione (a me sembra strano, ma con
windows tutto è possibile...).
Inoltre: le applicazioni a cui sono dirette quei tasti, li riceverebbero
comunque???
In alternativa ci sono altre soluzioni??
Merci.
K

 
SetWindowsHookEx e WH_KEYBOARD, oppure un driver che si metta tra il 
S.O. e il vero driver della tastiera.
Il secondo approccio č piů complicato e puň essere utile solo se devi 
intercettare anche i tasti premuti quando non ci possono essere 
applicazioni attive (praticamente la password di login).
-- 
Valter Minute
min...@inwind.it
 (the reply address of this message is invalid)


Quindi la mia funzione assembly è bocciata??? Bo, pensavo che leggendo
direttamente dal buffer potevo prendere tutti i tasti...
Cmq provero' con la SetWindowsHookEx, sperando di capirci qualcosa, tanto sò
che se non capisco posso contare su di voi!!! ;o)
K


dove posso trovare documentazione su queste 2 procedure in ITA???
Grazie mille!!!
K

 Grazie mille!!!
In italiano non saprei. Prova a scrivere il nome della funzione nella 
ricerca avanzata di google e richiedi solo pagine in italiano.
Su 
msdn.microsoft.com
 puoi trovare la documentazione "ufficiale" in 
inglese .
P.S. è una funzione API sola (SetWindowsHookEx), WH_KEYBOARD è un flag 
da utilizzare per dirgli di installare un Hook per i messaggi da 
tastiera.


 tastiera.
ho detto 2 perche' intendevo anche la creazione del driver!!
Cmq, sono riuscito a creare la dll con dentro la mia bella SetWindowsHookEx,
problemi: nella dll devo mettere la "creazione" dell'Hook, la "distruzione"
e la KeyboardHookProc oppure qualcosa va nel
mio progetto principale???
mettendo tutto nella dll funziona solamente se come ultimo parametro della
SetWindowsHookEx() gli passo GetCurrentThreadId(), e quindi prende solamente
i tasti premuti nella mia applicazione, quindi non e' cambiato nulla, se
invece come dice nell'msdn metto 0 per leggere i tasti di tutte i thread
(credo di aver capito giusto) non funziona nulla, non legge neanche quelli
premuti nella mia applicazione...
Help Please!!!


Controlla il ritorno della  SetWindowsHookEx():
An error may occur if the hMod parameter is NULL and the dwThreadId
parameter is zero or specifies the identifier of a thread created by another
process.
Maurus


Niente, ci sono riuscito, non gli passavo l'HINSTANCE della dll, non credevo
ce l'avrei mai fatta, WOW!!!
GRAZIEE!!!!
K

Emh... ora però i tasti non arrivano alle applicazioni a cui dovevano
arrivare!!!!
Devo mandarceli io??????????????
K


risolto anche questo, ritorno "return
CallNextHookEx(hKeyboardHook,nCode,wParam,lParam);" si che intercetto il
tasto sia che non lo intercetto. è giusto cosi???

 
Puoi anche ritornare TRUE e evitare così che il tasto venga 
intercettato.
P.S. quando rispondi a un messaggio riporta solo le parti 
indispensabili (
http://www.uwasa.fi/~ts/http/quote.html
).



perche' cos'altro ho riportato?!?!?
vabbè, cmq, ora ho dei problemi con delle variabili, e cioe': dal programma
principale passo il puntatore a una stringa  alla funzione della dll che
chiama la SetWindowsHookEx, da li il puntatore diventa globale e dopodiche
nella KeyboardHookProc() viene utilizzato.
Nel caso in cui quando vengono schiacciati i tasti, e il focus e' nella
finestra chiamante la dll, tutto va bene, nel caso in cui invece il focus e'
su un'altra finestra la stringa non viene riempita.
Che devo fare???

 
La DLL con l'hook globale viene caricata nello spazio di 
indirizzamento dei diversi processi attivi e la memoria di un 
processo non è normalmente leggibile/scrivibile per gli altri.
In pratica tu hai un'instanza della stringa diversa in ogni processo.
Per risolvere il problema dovresti allocare della memoria condivisa 
(l'ho utilizzata una sola volta e ricordo che ha a che fare con 
CreateFileMapping) oppure un file su disco.
In entrambi i casi dovrai sincronizzare con un mutex l'accesso alla 
risorsa condivisa (file o memoria). Nel caso del file dovrai aprirlo 
e richiuderlo a ogni operazione (più lento ma non perdi dati in caso 
di crash del processo o del PC) oppure tenerlo aperto lasciando agli 
altri processi la possibilità di scriverci (se scrivi più di un byte 
alla volta dovresti comunque sincronizzare l'acesso, anche se è 
abbastanza difficile che qualcuno riesca a premere tasti più 
velocemente di quanto tu riesca a scrivere su disco).


 leggendo direttamente dal buffer potevo prendere tutti i tasti...
ripeto: e il buffer dove diavolo sarebbe? e perchè assembly?
-- 
 < 
http://www.reactos.com/
 >  Open source clone of Windows NT. Current
     Don't stand, REACT!      version 0.0.19. C, C++ and ASM developers
                              and beta testers are welcome!

 caratteri direttamente dal buffer di tastiera, ma funzionerebbe???
sono curiosa di vedere questa funzioncina :-P


aspetta 2 o 3 giorni allora.. devo ripassare...


come diavolo sarebbe??
perchè assembly??? assembly perchè 2 anni fa feci appunto un editor (quasi
un editor) di testo e usando gli interrupt leggevo direttamente dal buffer
di tastiera
(ogni tasto dopo essere premuto si "inficca nel buffer di tastiera) e quindi
pensavo che leggendo da li riesco a "fregare" windows prima che processi lui
il tasto...

 direttamente dal buffer di tastiera
seeeee, sogna



considera che è un pò datata, quindi qualche cosa si poteva fare sicuramente
meglio, e non l'ho neanche riguardata, la riporto solo cosi come l'ho
ritrovata....
ok??'
file://Silva Danilo
file://4ia
file://23/11/2000
file://editor di testo
file://defines tasti speciali
#define LSHIFT_P 42
#define RSHIFT_P 54
#define LSHIFT_R 170
#define RSHIFT_R 182
#define INVIO 28
#define BS 14
#define SPACE 57
file://defines indice
#define INDICE 16
file://defines booleani
#define TRUE 1
#define FALSE 0
file://defines ASM
#define TASTIERA_INT 0X09
#define REG_DATO 0X60
#define REG_CONTROLLO 0X61
#define PIC_CONTROL 0X20
file://includes
#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <dos.h>
file://dichiarazione variabili
short tabella[36];
short tasto=NULL;
short stato = FALSE;
file://variabile per la gestione delle righe
short y = 1;
short x = 1;
file://puntatore alla prima istruzione della funzione handler.
file://Servira' per salvare l'indirizzo di memoria.
void interrupt (*handler)(__CPPARGS);
file://funzione di gestione della tastiera che andra' a sostituire
file://quello messo a disposizione dal SO Dos
void _interrupt _far tastiera()
{
 _asm{ in al, REG_DATO
   mov ah,0
   mov tasto, ax
   in al, REG_CONTROLLO
   or al, 82H
   out REG_CONTROLLO, al
   and al, 7FH
   out REG_CONTROLLO, al
   mov al, 20H
   out PIC_CONTROL, al
   sti
  }
 file://Nel casp in cui venga premuto il tasto INVIO
 if(tasto==INVIO)
 {
  file://Stampa i caratteri 10h e 13h
  printf("%c%c",10,13);
  file://Aggiorna le coordinate
  y++;
  x=1;
 }
 file://nel caso in cui viene premuto il tasto SPAZIO
 else if(tasto==SPACE)
 {
  file://Stampa un carattere vuoto e aggiorna le
  file://coordinate della Y
  printf("%c",32);
  x++;
 }
 file://Nel caso in cui viene premuto SHIFT (destra
 file://o sinistra)
 else if( (tasto==LSHIFT_P) || (tasto==RSHIFT_P) )
 {
  file://Modifica il valore della variabile "stato"
  stato=TRUE;
 }
 file://se invece il tasto SHIFT (destra o sinistra)
 file://viene rilasciato
 else if( (tasto==LSHIFT_R) || (tasto==RSHIFT_R) )
 {
  file://La variabile stato viene posta come FALSE
  stato=FALSE;
 }
 file://Se viene premuto il tasto BACKSPACE
 else if(tasto==BS)
 {
  file://Se ci si trova all'inizio della riga
  if(x<1)
  {
   file://prima aggiorna le coordinate
   x=80;
   y--;
   file://riposiziona il cursore alle
   file://nuove coordinate
   gotoxy(x,y);
   file://stampa un carattere vuoto per
   file://cancellare il carattere già
   file://presente
   printf("%c%c",255,8);
   file://dal momento che stampando lo spazio
   file://la linea viene nuovamente mandata
   file://a capo, è necessario posizionare
   file://nuovamente il cursore.
   gotoxy(x,y);
  }
  file://altrimenti....
  else
   file://si limita a cancellare il carattere
   file://precedente e ad aggiornare
   file://le coordinate
   printf("%c%c%c",8,255,8);
   x--;
  }
 }
 file://Se il tasto premuto non è nessuno di quelli sopra
 file://specificati
 else
 {
  file://controlla se è uno dei caratteri stampabili previsti
  if ((tasto-16<=37)&&(tasto-16>=0))
  {
   file://In caso affermativo controlla che esista un
   file://codice ASCII corrispondente al tasto premuto
   if(tabella[tasto-16]!=NULL)
   {
    file://Se STATO == TRUE, allora stampa in
    file://maiuscolo, altrimenti stampa in minuscolo
    if(stato == FALSE)
     printf("%c",tabella[tasto-16]);
    else
     printf("%c",tabella[tasto-16]-32);
    file://aggiorna la variabile X
    x++;
    file://Se si è alla fine della riga, aggiorna,
    file://oltre alla X, anche la Y
    if(x>80)
    {
     y++;
     x=1;
    }
   }
  }
 }
}
void main (void)
{
 file://INIZIALIZZAZIONE TABELLA
  tabella[0] = 113;
  tabella[1] = 119;
  tabella[2] = 101;
  tabella[3] = 114;
  tabella[4] = 116;
  tabella[5] = 121;
  tabella[6] = 117;
  tabella[7] = 105;
  tabella[8] = 111;
  tabella[9] = 112;
 tabella[10] = NULL;
 tabella[11] = NULL;
 tabella[12] = NULL;
 tabella[13] = NULL;
 tabella[14] = 97;
 tabella[15] = 115;
 tabella[16] = 100;
 tabella[17] = 102;
 tabella[18] = 103;
 tabella[19] = 104;
 tabella[20] = 106;
 tabella[21] = 107;
 tabella[22] = 108;
 tabella[23] = NULL;
 tabella[24] = NULL;
 tabella[25] = NULL;
 tabella[26] = NULL;
 tabella[27] = NULL;
 tabella[28] = 122;
 tabella[29] = 120;
 tabella[30] = 99;
 tabella[31] = 118;
 tabella[32] = 98;
 tabella[33] = 110;
 tabella[34] = 109;
 tabella[35] = 44;
 tabella[36] = 46;
 file://salva l'indirizzo di memoria della funzione di gestione
 file://della tastiera originaria
 handler = getvect(TASTIERA_INT);
 file://imposta l'indirizzo di memoria della nuova funzione
 file://di gestione della tastiera
 setvect(TASTIERA_INT,tastiera);
 file://inizializzazione del programma...
 file://pulisce lo schermo
 clrscr();
 file://ciclo che termina quando viene premuto ESC
 while(tasto != 1){};
 file://reimposta l'indirizzo originario
 setvect(TASTIERA_INT, handler);
}