Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Slanje keyboard evenata DirectInput aplikaciji

[es] :: C/C++ programiranje :: Slanje keyboard evenata DirectInput aplikaciji

[ Pregleda: 3193 | Odgovora: 4 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Milos Stojanovic
Belgrade

Član broj: 10343
Poruke: 1864
213.244.208.*

ICQ: 282954730
Sajt: www.sietf.org


+7 Profil

icon Slanje keyboard evenata DirectInput aplikaciji13.09.2005. u 17:37 - pre 226 meseci
Evo već nekoliko dana pretražujem po netu i nikako da nađem odgovor. Možda tema i nije za ovde, ali nisam našao bolje mesto. Dakle:

Da li postoji način da se sintetiše keyboard event i da se pošalje aplikaciji koja keyboard koristi preko DirectInput APIja? Za aplikacije koje koriste standardne win32 evente, rešenje je vrlo prosto i svodi se na poziv SendInput funkcije, ili keybd_event funkcije ili SendMessage pa pošaljem WM_KEYDOWN... mogućnosti neograničene :)
Ali džaba sve to, kad ni jedan od ovih metoda ne radi sa DirectInput aplikacijama... Razmišljao sam da pišem neki driver za tastaturu, al opet, možda DirectInput lagano zaobiđe i to?

Spasite me, molim vas. :(
ex. trooper
Oh goody... it's my Illudium PU-36 Explosive Space Modulator!
Softversko Inženjerstvo
♪♫♪
 
Odgovor na temu

Milos Stojanovic
Belgrade

Član broj: 10343
Poruke: 1864
213.244.208.*

ICQ: 282954730
Sajt: www.sietf.org


+7 Profil

icon Re: Slanje keyboard evenata DirectInput aplikaciji14.09.2005. u 01:40 - pre 226 meseci
heh, nevermind :)
Našao sam rešenje, radi keybd_event, ali treba malo drugačij proslediti parametre:

Code:

// TheKey = 'a' // neki keycode, nebitno
keybd_event(VkKeyScan(TheKey), MapVirtualKey(VkKeyScan(TheKey), 0), 0, 0);
Sleep(30); //da nahvata event? ovo mi nije bas najjasnije
keybd_event(VkKeyScan(TheKey), MapVirtualKey(VkKeyScan(TheKey), 0), KEYEVENTF_KEYUP, 0);

ex. trooper
Oh goody... it's my Illudium PU-36 Explosive Space Modulator!
Softversko Inženjerstvo
♪♫♪
 
Odgovor na temu

((BugA))
Igor Djordjevic
Bor, Srbija

Član broj: 29241
Poruke: 196
79.101.220.*

ICQ: 66516695
Sajt: www.MalamutKlub.com


+17 Profil

icon Re: Slanje keyboard evenata DirectInput aplikaciji26.12.2008. u 20:34 - pre 186 meseci
Ja se iskreno, najiskrenije izvinjavam sto vadim ovu temu iz naftalina, ali nadam se da ce mi biti oprosteno, jer ova tema to zasluzuje :)

Brate mili, sad bih te izljubio da mogu! (ili mozda i ne bih bas :p )

Ne znam gde sve nisam trazio i sta sve nisam pokusavao, i preko SendKeys, i keybd_event, i SendMessage, i SendInput, i uvek sve lepo radi kada su neke "obicnije" Windows aplikacije u pitanju, ali kada sam dosao do DirectX programa (igre), jednostavno nikako nisam mogao da simuliram pritisak tastera. Nigde na netu nisam nasao resenje, a ne znam ni sam na koliko foruma sam video isto pitanje - kako simulirati pritisak tastera koristeci DirectInput.

Odakle ti ovo resenje? :))

Da malo osvezim temu, ako neko ima problema sa gorepomenutim kodom, evo dopune (Visual Studio 2008, C#):

Dodati u listu using:
Code:
using System.Threading; // potrebno zbog Thread.Sleep

Ovo ubaciti u klasu forme:
Code:
// prototipovi procedure i funkcija
[DllImport("user32.dll")]
static extern void keybd_event(short bVk, uint bScan, uint dwFlags, int dwExtraInfo);

[DllImport("user32.dll")]
public static extern uint MapVirtualKey(short uCode, uint uMapType);

[DllImport("user32.dll")]
public static extern short VkKeyScan(char ch);

Ovo staviti u proceduru koja ce da simulira pritisak:
Code:
const int KEYEVENTF_KEYUP = 0x2; // deklaracija i definicija KEYEVENT_KEYUP konstante

char TheKey = 'd'; // neki keycode, nebitno
keybd_event(VkKeyScan(TheKey), MapVirtualKey(VkKeyScan(TheKey), 0), 0, 0);
Thread.Sleep(30); // da nahvata event? ovo mi nije bas najjasnije
keybd_event(VkKeyScan(TheKey), MapVirtualKey(VkKeyScan(TheKey), 0), KEYEVENTF_KEYUP, 0);

Meni ovako radi bez greske :) Ne mogu ni da zamislim za sta sve ovo moze da se iskoristi, ja odoh da se igram i istrazujem :)

Jos jednom se izvinjavam zbog ovog "skoka u proslost", mislim da ova tema to svakako zasluzuje ;)

[Ovu poruku je menjao ((BugA)) dana 28.12.2008. u 16:12 GMT+1]
 
Odgovor na temu

((BugA))
Igor Djordjevic
Bor, Srbija

Član broj: 29241
Poruke: 196
79.101.220.*

ICQ: 66516695
Sajt: www.MalamutKlub.com


+17 Profil

icon Re: Slanje keyboard evenata DirectInput aplikaciji27.12.2008. u 01:26 - pre 186 meseci
Evo i prvog problema... (nisam se bas dugo radovao :p)

Sve ovo lepo radi kada zelimo da "posaljemo" (simuliramo pritisak) tastera koji ima ASCII kod, ali sta radimo sa tasterima koji ga nemaju - strelice (levo/desno/gore/dole)?

Opet se javlja problem sa pocetka price. Ako koristimo
Code:
const int KEYEVENTF_KEYUP = 0x2;
const char VK_DOWN = (char)Keys.Down; // jedna od mogucnosti

keybd_event(VK_DOWN, 0, 0, 0);
keybd_event(VK_DOWN, 0, KEYEVENTF_KEYUP, 0);

... poruka o pritisnutom tasteru (kursorska strelica, dole) se salje i lepo se moze videti kako radi u npr. Notepad-u (izudaramo par puta "enter", pa se vratimo koji red na gore i cekamo da nas program spusti red dole, kao da smo pritisnuli taster "dole"). Medjutim, DirectInput ovo ne hvata.

Ako zelimo da koristimo postupak za koji znamo da radi sa npr. slovima...
Code:
keybd_event(VkKeyScan(TheKey), MapVirtualKey(VkKeyScan(TheKey), 0), 0, 0);
keybd_event(VkKeyScan(TheKey), MapVirtualKey(VkKeyScan(TheKey), 0), KEYEVENTF_KEYUP, 0);

... javlja se problem - koju vrednost dodeliti promenljivoj TheKey, kada taster - strelica na dole nema ekvivalentan karakter koji bi je predstavljao, niti ima ASCII kod...?

I zasto uopste prvi slucaj DirectInput ne vidi, a drugi prepoznaje i reaguje?

Za slovo 'd' smo pisali TheKey = 'd' (moze i npr. TheKey = Convert.ToChar(100)), za ESC (escape) mozemo pisati TheKey = Convert.ToChar(0x1B), a jedino sto nam ostaje a vezano je za kursorske strelice jesu virtuelni kodovi, za strelicu dole VK_DOWN = 0x28, tj. VK_DOWN = 40, ali kako to iskoristiti u keybd_event, preko VkKeyScan i MapVirtualKey, a da naglasimo da unosimo virtual keycode, a ne ASCII...? Da prepravljamo deklaracije prototipova procedure i funkcija, ili nesto drugo?

[Ovu poruku je menjao ((BugA)) dana 28.12.2008. u 16:13 GMT+1]
 
Odgovor na temu

((BugA))
Igor Djordjevic
Bor, Srbija

Član broj: 29241
Poruke: 196
93.86.187.*

ICQ: 66516695
Sajt: www.MalamutKlub.com


+17 Profil

icon Re: Slanje keyboard evenata DirectInput aplikaciji27.12.2008. u 11:15 - pre 186 meseci
Uspeo sam :))

Bilo je potrebno samo (cuj, "samo" :)) ukljuciti KEYEVENTF_EXTENDEDKEY flag kod keybd_event procedure, obzirom da se scan code tastera/strelice "dole" sastoji od dva bajta - e0 50 :) (e0 je dodatni bajt koje je potrebno "preskociti", upravo postavljanjem KEYEVENTF_EXTENDEDKEY flega).

Sa ovom ispravkom, pritisak na kursorsku strelicu "dole" izgleda ovako:

Dodatno deklarisemo i definisemo KEYEVENTF_EXTENDEDKEY flag (KEYEVENTF_KEYUP nam je ostao od malopre):
Code:
const int KEYEVENTF_EXTENDEDKEY = 0x1;
const int KEYEVENTF_KEYUP = 0x2;

Postupak za simuliranje izgleda ovako:
Code:
keybd_event(0x28, MapVirtualKey(0x28, 0), KEYEVENTF_EXTENDEDKEY, 0);
Thread.Sleep(30);
keybd_event(0x28, MapVirtualKey(0x28, 0), KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);

Ovde primecujemo jos dve stvari - prvo da smo izbacili promenljivu TheKey koju smo prethodno deklarisali kao char jer char (karakter) oznaka tastera "DOWN" ne postoji, a zatim da smo izbacili i VkKeyScan(TheKey) funkciju iz istog razloga - nemamo TheKey karakter, pa ne mozemo ni naci virtual key code "ni iz cega", vec key code tastera "DOWN" (cija je vrednost 0x28) prinosimo kao direktan parametar u proceduri keybd_event.

I jos jedna napomena/objasnjenje za ovo Thread.Sleep(30) - potrebno je na trenutak zaustaviti thread kako bi aplikacija uspela da procita pritisak tastera (dovoljna pauza je vec od 20 milisekundi, za manje vrednosti je pitanje) pre no sto posaljemo signal da je taster otpusten. Ako je pauza manja od 20 milisekundi ili je uopste nema, citav dogadjaj simulacije pritiska tastera ce vrlo verovatno proci neopazeno jer se desio previse brzo. U primeru koristimo pauzu od 30 milisekundi, za svaki slucaj :)

Na kraju bih samo podsetio kako smo deklarisali prototip procedure keybd_event:
Code:
static extern void keybd_event(short bVk, uint bScan, uint dwFlags, int dwExtraInfo);

... gde su parametri sledeci:

bVk // "Virtual Keycode" vrednost tastera, npr. VK_RETURN, VK_TAB…
bScan // "Scan Code" vrednost tastera, npr. 0xb8 za taster "Left Alt" (levi "Alt" taster)
dwFlags // fleg koji se postavlja za trenutno stanje tastera, npr. KEYEVENTF_KEYUP (taster podignut)
dwExtraInfo // dodatna 32-bit-na informacija o stanju tastera


Koga zanima vise o ovome (npr. ove dodatne informacije poslednjeg parametra) moze pogledati link - http://www.codeproject.com/KB/system/keyboard.aspx?display=Print, a za tabelu "scan code"-ova pogledajte npr. ovaj link - http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html .

PoZz svima, i srecni Vam praznici!

BugA :)

[Ovu poruku je menjao ((BugA)) dana 28.12.2008. u 16:15 GMT+1]
 
Odgovor na temu

[es] :: C/C++ programiranje :: Slanje keyboard evenata DirectInput aplikaciji

[ Pregleda: 3193 | Odgovora: 4 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.