PDA

View Full Version : [C++] capire se in un preciso momento un tasto e' premuto


AngeL)
06-09-2007, 13:07
come da titolo, in c++, come faccio a sapere in un dato momento se un tasto (es CTRL) e' premuto (anche in una finestra diversa da quella del programma) ?

variabilepippo
06-09-2007, 13:13
Sistema operativo? Compilatore?

AngeL)
06-09-2007, 13:22
Sistema operativo? Compilatore?

il sistema operativo e' win xp - win vista
compilatore credo sia il gcc (dev-cpp)

mi sono dimenticato di indicarli nel primo post :mc:

stdecden
06-09-2007, 17:20
Non saprei,
forse potresti riuscirci con directinput??

tomminno
06-09-2007, 18:28
come da titolo, in c++, come faccio a sapere in un dato momento se un tasto (es CTRL) e' premuto (anche in una finestra diversa da quella del programma) ?

Devi installare un hook globale, per farlo devi creare una DLL. Nel DllMain (o in un thread a parte) chami SetKeyboardHook(TRUE) a questo punto tutte le volte che viene premuto Ctrl (ma solo Ctrl, non una combinazione di tasti) ti dovresti ritrovare alla riga "//...". A quel punto sta a te scegliere cosa fare.

[Edit] Questo metodo non funziona con il Ctrl+Alt+Canc, intercettarlo è un pò più complicato.

Non è C++ ma semplicemente C, visto che si deve lavorare direttamente con le Win32


HHOOK hKeyboardHook;

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION && hookKey)
{
if (p->vkCode == VK_CONTROL)
//...
}

return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}

int DLL_EXP WINAPI SetKeyboardHook(BOOL setHook)
{
if (setHook)
{
if (!hKeyboardHook)
{
hKeyboardHook =SetWindowsHookEx(WH_KEYBOARD_LL,LowLevelKeyboardProc,
hInst, 0);
if (!hKeyboardHook)
return 0;
}
return 1;
}
else
{
UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = NULL;
return 0;
}
}

AngeL)
06-09-2007, 21:26
Devi installare un hook globale, per farlo devi creare una DLL. Nel DllMain (o in un thread a parte) chami SetKeyboardHook(TRUE) a questo punto tutte le volte che viene premuto Ctrl (ma solo Ctrl, non una combinazione di tasti) ti dovresti ritrovare alla riga "//...". A quel punto sta a te scegliere cosa fare.

[Edit] Questo metodo non funziona con il Ctrl+Alt+Canc, intercettarlo è un pò più complicato.

Non è C++ ma semplicemente C, visto che si deve lavorare direttamente con le Win32


HHOOK hKeyboardHook;

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION && hookKey)
{
if (p->vkCode == VK_CONTROL)
//...
}

return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}

int DLL_EXP WINAPI SetKeyboardHook(BOOL setHook)
{
if (setHook)
{
if (!hKeyboardHook)
{
hKeyboardHook =SetWindowsHookEx(WH_KEYBOARD_LL,LowLevelKeyboardProc,
hInst, 0);
if (!hKeyboardHook)
return 0;
}
return 1;
}
else
{
UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = NULL;
return 0;
}
}



ma come faccio ad installare una dll? non ci ho mai lavorato :stordita:

comunque ti spiego meglio il mio problema:
devo inviare delle frasi alla tastiera tramite SendInput... so gia' come fare, ma il problema e' che se mentre il testo viene inviato l'utente sta premendo ctrl (o alt, o entrambi), questo testo non verra' scritto ma verranno eseguite delle azioni (es. copia, incolla, taglia..), mentre se sta premendo shift il testo verra' scritto in maiuscolo
quindi io vorrei usare SendInput per rilasciare i tasti premuti, mandare il testo, e poi ripremerli.
provo a scrivere qualcosa in pseudo-codice perche' stasera non mi riesce di spiegarmi :fagiano:


bool ctrlPressed = false, shiftPressed = false, altPressed = false;

if(alt.isPressed())
altPressed=true;
if(ctrl.isPressed())
ctrlPressed=true;
if(shift.isPressed())
shiftPressed=true;

if(altPressed)
//rilascia alt
if(ctrlPressed)
//rilascia ctrl
if(shiftPressed)
//rilascia shift

// invia del codice alla tastiera

if(altPressed)
//ripremi alt
if(ctrlPressed)
//ripremi ctrl
if(shiftPressed)
//ripremi shift


la parte che non so fare e' quella con "isPressed()".. come posso farla?

cionci
06-09-2007, 23:41
Se ti serve quando il focus è solamente sulla tua applicazione si può installare l'hook anche senza DLL. Suppongo basti WH_KEYBOARD...
Installarlo dalla DLL serve perché funzioni per tutto il sistema.

AngeL)
06-09-2007, 23:56
Se ti serve quando il focus è solamente sulla tua applicazione si può installare l'hook anche senza DLL. Suppongo basti WH_KEYBOARD...
Installarlo dalla DLL serve perché funzioni per tutto il sistema.

a me serve per tutto il sistema... ma non so come usare ste dll :fagiano:

cionci
07-09-2007, 00:16
Guarda qui:
http://www.codeguru.com/cpp/w-p/system/keyboard/article.php/c5699/
Su per giù devi fare la stessa cosa.
Quando un determinato tasto viene premuto o rilasciato invii dalla dll un messaggio alla tua applicazione che si occuperà di fare le operazioni che servono (se serve solo una sendinput puoi anche richiamarla dalla dll stessa).
Come funziona la funzione di callback lo trovi qui: http://msdn2.microsoft.com/en-us/library/ms644985.aspx

AngeL)
07-09-2007, 09:34
Guarda qui:
http://www.codeguru.com/cpp/w-p/system/keyboard/article.php/c5699/
Su per giù devi fare la stessa cosa.
Quando un determinato tasto viene premuto o rilasciato invii dalla dll un messaggio alla tua applicazione che si occuperà di fare le operazioni che servono (se serve solo una sendinput puoi anche richiamarla dalla dll stessa).
Come funziona la funzione di callback lo trovi qui: http://msdn2.microsoft.com/en-us/library/ms644985.aspx

uhm.. ho capito piu' o meno tutto, ma mi e' rimasto un dubbio:

dalla dll come faccio a capire qual e' la mia applicazione? cioe' quali parametri devo dare a FindWindow?

Quando uso PostMessage, come faccio ad intercettare (dall'applicazione vera e propria) i dati che la dll mi manda?
o semplicemente PostMessage simula un keystroke nella finestra (che posso catturare con getch() ) ?

cionci
07-09-2007, 09:48
Devi passare l'handle alla tua finestra (HWND) ad una funzione della DLL che richiami dalla tua applicazione.

//This function installs the Keyboard hook:
KEYDLL3_API void installhook(HWND h);

Infatti basta richiamare questa funzione della DLL passandogli l'handle alla finestra della tua applicazione.

Il PostMessage serve per inviare un messaggio "utente" (WM_USER + X) alla tua applicazione in base al tipo di messaggio utente agirai di conseguenza.
Potrai definire più messaggi utente a seconda del tasto premuto e rilasciato.

La tua applicazione può anche essere .Net, ma non mi chiedere come si fa ad intercettare un messaggio utente in una applicazione .Net perché non lo so.