PasjaGSM.pl
  Jesteś w: Forum > Symulacja powtarzania naciśniętego klawisza


Symulacja powtarzania naciśniętego klawisza

Forum.PasjaGSM.pl » ...:Sprzęt:... » Nokia » DCT-3 » [DCT3] Modyfikacje HW i SW » NokiX » Programowanie » Symulacja powtarzania naciśniętego klawisza
Poprzedni temat «» Następny temat
Autor Wiadomość
 
yak 
Starszyzna



Telefon: Kilka DCT3
Operator: Vodafone
Pomógł: 20 razy
Wiek: 36
Dołączył: 21 Gru 2004
Posty: 774
Skąd: Bochum / Niemcy
Wysłany: 2006-08-11, 15:04   Symulacja powtarzania naciśniętego klawisza

Witam.

Na PW dostałem prośbę o opisanie sposobu na symulację powtarzania naciśniętego klawisza. Postanowiłem opisać to tu aby wszyscy mogli to obejrzeć.

Jak wiemy, system informuje masz dispatcher o naciśnięciach klawiszy poprzez kilka wiadomości (eventów).

MSG_KEYPRESS - przychodzi, gdy klawisz wciśnięto
MSG_KEYRELEASE - przychodzi, gdy klawisz puszczono
MSG_KEYPRESS_CHAR - informuje o kodzie Ascii wciśniętego klawisza

Do symulacji powtarzania ostatnia wiadomość nie jest nam potrzebna ale jest ważna z innego powodu. Oprócz infomowania o kodzie Ascii, powoduje ona także zamknięcie wszystkich dispatcherów (a więc naszego a potem dispatchera od menu) i wyświetlenie znaku na "blacie". Jest to celowe działanie Nokii, aby w aplikacjach, w których nie potrzebne są klawisze numeryczne, ich naciśnięcie powodowało wyjście na blat. Dzięki temu można szybko wpisać np. numer telefonu "112".

Skoro piszemy o symulacji powtarzania a więc pewnie nie chcemy żeby nam zamykało dispatcher. Rozwiązanie jest proste, musimy zaNOPować tę wiadomość.
Kod:
case MSG_KEYPRESS_ASCII:
msg=MSG_NOP;
break;


Ok, wróćmy jednak do powtarzania. Pomysł jest dość prosty. Po wykryciu naciśnięcia klawisza (MSG_KEYPRESS) oprócz wywołania jego obsługi tworzymy timer, ktory po krotkim czasie spowoduje powtorzenie ostatniego klawisza. W razie odebrania wiadomości MSG_KEYRELEASE po prostu przerywamy timer. To wszystko.

Potrzebne nam będzie miejsce w którym zapamiętamy kod wciśniętego klawisza podczas gdy timer będzie odliczał czas. W tym celu stworzymy nowe pole w strukturze application w pliku main.h (zakładam, że stworzyliśmy projekt w VisualHAMie).

Kod:
struct application
{
   ...
   unsigned char key;
   ...
};


Po dodaniu pola możemy przystąpić do głównej części. Po pierwsze musimy stworzyć timer wysyłający wiadomość. Załatwią to dwie następujące linie umieszczone na początku pliku .c z dispatcherem.

Kod:
#define OMSG_KEYREPEAT (0x1faa)
static const unsigned timer_keyrepeat = OMSG_KEYREPEAT;


Na koniec dodajemy obsługę klawiszy do dispatchera.

Kod:
case MSG_KEYPRESS_CHAR:
   // wylacz wychodzenie z dispatchera po nacisnieciu klawiszy numerycznych
   msg=MSG_NOP;
   break;
 
case MSG_KEYPRESS: // nacisnieto klawisz
   // zapamietujemy kod klawisza
   app.key=own_get_unify_keycode(UKM_NONE);

   // wywolujemy obsluge zapamietanego klawisza
   send_message(OMSG_KEYREPEAT|MSG_1P,0);
   break;

case MSG_KEYRELEASE: // puszczono klawisz
   // zatrzymujemy powtarzanie
   own_timer_abort(&timer_keyrepeat);
   break;

case OMSG_KEYREPEAT: // nasza obsluga klawisza
   {
      bool repeat=false;

      switch(app.key) // sprawdzamy jaki klawisz nacisnieto
      {
         case KEY_1:
        // ten klawisz przykladowo nie ma byc powtarzany
        break;

         case KEY_4:
            // np. przesuniecie w lewo
        repeat=true; // powtarzaj klawisz
        break;

         case KEY_6:
            // np. przesuniecie w prawo
        repeat=true; // powtarzaj klawisz
        break;
      }
     
      if(repeat) // czy powtarzac klawisz?
      {
         unsigned time;

         if(msg_argc==1) time=70; // czas do rozpoczecia powtarzania (mniej = wczesniej)
         else time=10; // predkosc powtarzania (mniej = szybciej)

         own_timer_start(&timer_keyrepeat,TT_MESSAGE,time);
      }
      msg=MSG_NOP;
   }
   break;


Kod z zadadzie sam się objaśnia. Główną częścią, w której znajduje się obsługa samych klawiszy, jest wiadomość OMSG_KEYREPEAT. Tutaj przy każdym klawiszu, który ma być powtarzany, wstawiamy linię repeat=true. Poniżej mamy ustawione czasy powtarzania. Pierwszy (70) to czas jaki ma minąć od naciśnięcia klawisza do rozpoczęcia jego powtarzania. Drugi (10) to prędkość samego powtarzania. Czasy podane są w standardowych tickach gdzie 1s równa się w przybliżeniu 125. Im mniej tym czas krótszy.

Mam nadzieję że to rozwiewa wszelkie wątpliwości na temat powtarzania klawiszy.

Ewentualne dalsze pytania proszę umieszczać poniżej.

Pozdrawiam
[Yak]
_________________
NokiX Ci się podoba? Kliknij i wyraź to!
^
 
 
 
     
AdSense


seba123 
Expert
=)



Telefon: SE W810
Operator: Orange
Pomógł: 66 razy
Wiek: 25
Dołączył: 07 Kwi 2006
Posty: 1327
Skąd: Łódź
Wysłany: 2006-08-13, 15:15   

Yak a mam pytanie czy da się ustawić prędkość dla każdego klawisza??
_________________
pobierz
^
 
  Skype
     
yak 
Starszyzna



Telefon: Kilka DCT3
Operator: Vodafone
Pomógł: 20 razy
Wiek: 36
Dołączył: 21 Gru 2004
Posty: 774
Skąd: Bochum / Niemcy
Wysłany: 2006-08-18, 16:58   

seba123, musiałbyś zmienić blok obsługi wiadomości OMSG_KEYREPEAT na przykład następująco:

Kod:
case OMSG_KEYREPEAT: // nasza obsluga klawisza
   {
      bool repeat=false;
      unsigned repeat_start=70; // domyslny czas do rozpoczecia powtarzania (mniej = wczesniej)
      unsigned repeat_speed=10; // domyslna predkosc powtarzania (mniej = szybciej)

      switch(app.key) // sprawdzamy jaki klawisz nacisnieto
      {
         case KEY_1:
            // ten klawisz przykladowo nie ma byc powtarzany
            break;

         case KEY_4:
            // np. przesuniecie w lewo
            repeat=true; // powtarzaj klawisz (z domyslnymi ustawieniami czasow, patrz wyzej)
            break;

         case KEY_6:
            // np. przesuniecie w prawo
            repeat=true; // powtarzaj klawisz
        repeat_speed=5; // powtarzaj klawisz szybciej niz inne klawisze
            break;

    case KEY_8:
        // np. przesuniecie w dol
        repeat=true; // powtarzaj klawisz
        repeat_start=30; // zacznij powtarzac klawisz wczesniej
        repeat_speed=5; // powtarzaj klawisz szybciej niz inne klawisze
            break;
      }
     
      if(repeat) // czy powtarzac klawisz?
      {
         unsigned time;

         if(msg_argc==1) time=repeat_start;
         else time=repeat_speed;

         own_timer_start(&timer_keyrepeat,TT_MESSAGE,time);
      }
      msg=MSG_NOP;
   }
   break;


W ten sposób możesz dla każdego klawisza osobno ustawić czy ma być powtarzany (repeat=true, brak tej lini oznacza brak powtarzania), po jakim czasie od naciśnięcia ma zacząć być powtarzany (repeat_start=xxx, brak oznacza użycie wartości domyślnej: 70) oraz jak szybko ma być powtarzany (repeat_speed=xxx, brak oznacza użycie wartości domyślnej: 10).
_________________
NokiX Ci się podoba? Kliknij i wyraź to!
^
 
 
 
     
MaximusResetus 
Wie co mówi
Shoot 'Em Up !



Telefon: 55,33,e398
Operator: Era
Pomógł: 3 razy
Wiek: 33
Dołączył: 23 Lip 2004
Posty: 456
Skąd: Nowy Sącz - okolice
Wysłany: 2006-09-09, 00:13   

Kod:

# ERROR: MSG_ARGC: Unknown object!
#    165 +++    fail func": Unknown object!"
#    155 +++ msg_argc=locate("msg_argc")
# Error 4 running "C:\NokiX\scripts\LOCATE.rx", line 165: Program interrupted

# ERROR: Script failure!


Taki bład mi wywala kiedy zmienię czas tutaj z 10 na jakikolwiek inny:

Kod:

         if(msg_argc==1) time=70; // czas do rozpoczecia powtarzania (mniej = wczesniej)
         else time=10; // predkosc powtarzania (mniej = szybciej)


Jeśli jest 10 to wsio działa ok. nokix i sdk najnowsze.
_________________
http://www.kwitnaceogrody.pl - projektowanie ogrodów - aranżacje zieleni - realizacja nasadzeń
^
 
     
yak 
Starszyzna



Telefon: Kilka DCT3
Operator: Vodafone
Pomógł: 20 razy
Wiek: 36
Dołączył: 21 Gru 2004
Posty: 774
Skąd: Bochum / Niemcy
Wysłany: 2006-09-09, 00:39   

MaximusResetus, baaardzo dziwne. Co ma jedno do drugiego? Błąd mówi, że makra LOCATE nie znają obiektu "msg_argc". Ten obiekt był dodany z 5 snapshotów temu, tylko wcześniejsze makra mogą zwrócić taki błąd. Mówię tu o dwóch makrach: LOCATE.rx i LOCATE_DATA.rx. Poszukaj ciągu "msg_argc" w makrze LOCATE_DATA.rx. Powinieneś je znaleźć w takiej linii:
Kod:
if func="MESSAGE" | func="MESSAGE_ARGS" | func="MSG_ID" | func="MSG_ARGC" | func="MSG_ARGV" then do


Jeśli nie ma to znaczy że masz jakieś stare. Pamiętaj że katalog z makrami ustawia się dla każdego projektu osobno.
_________________
NokiX Ci się podoba? Kliknij i wyraź to!
^
 
 
 
     
MaximusResetus 
Wie co mówi
Shoot 'Em Up !



Telefon: 55,33,e398
Operator: Era
Pomógł: 3 razy
Wiek: 33
Dołączył: 23 Lip 2004
Posty: 456
Skąd: Nowy Sącz - okolice
Wysłany: 2006-09-09, 11:09   

A no faktycznie mam chyba jakiegos przedwojennego snapshota :]

No ale to mnie dziwi że dla czasu
Kod:

else time=10;


skrypt przechodzi gładkona tym straymm snapshocie. Czy wtedy nie wyszukuje tej funkcji msg_argc? Przecież musi jej szukac ckoro jest wymieniona w pliku źródłowym...?
_________________
http://www.kwitnaceogrody.pl - projektowanie ogrodów - aranżacje zieleni - realizacja nasadzeń
^
 
     
yak 
Starszyzna



Telefon: Kilka DCT3
Operator: Vodafone
Pomógł: 20 razy
Wiek: 36
Dołączył: 21 Gru 2004
Posty: 774
Skąd: Bochum / Niemcy
Wysłany: 2006-09-09, 16:32   

MaximusResetus, no musi, nie wiem co to może być. Prześlij mi to wszystko to zobaczę.

[ Dodano: 2006-09-10, 12:58 ]
MaximusResetus, ok, dostałem Twój projekt i rzuciłem okiem.

Więc po pierwsze te skrypty locate są stare, to już wiemy.

A dziwny efekt szukania obiektu "msg_argc" w przypadku podania innej wartości niż 10 wynika stąd, że Twój kod wygląda tu następująco:
Kod:
               if(msg_argc==1) time=10; // czas do rozpoczecia powtarzania (mniej = wczesniej)
               else time=10; // predkosc powtarzania (mniej = szybciej)

Zauważ że we wcześniejszym poście podałeś 70 jako pierwszą wartość podczas gdy na prawdę masz tam również 10. Masz więc w obu tę samą wartość. W takim wypadku optymalizator kompilatora "widzi", że te dwie linie to to samo co:
Kod:
               time=10;

A to oznacza że msg_argc (użyte w if'ie) już nie jest potrzebne więc nie będzie go szukał makrem locate.

Jeśli zmienisz to na cokolwiek innego to if musi zostać a więc msg_argc jest potrzebne.

Pozdrawiam
[Yak]
_________________
NokiX Ci się podoba? Kliknij i wyraź to!
^
 
 
 
     
MaximusResetus 
Wie co mówi
Shoot 'Em Up !



Telefon: 55,33,e398
Operator: Era
Pomógł: 3 razy
Wiek: 33
Dołączył: 23 Lip 2004
Posty: 456
Skąd: Nowy Sącz - okolice
Wysłany: 2006-09-10, 13:38   

A no to teraz rozumiem już wszystko :) Dzięki za pomoc. Teraz wszystko działa.
_________________
http://www.kwitnaceogrody.pl - projektowanie ogrodów - aranżacje zieleni - realizacja nasadzeń
^
 
     
NoRiN 
Nowicjusz



Telefon: Nokia 3310
Operator: Plus
Wiek: 28
Dołączył: 22 Sty 2007
Posty: 11
Skąd: Warszawa
Wysłany: 2007-02-05, 12:08   

A co może być nie tak jak wyskakuje mi błąd:
Cytat:
game.c:107: error: 'struct application' has no member named 'key'
game.c:118: error: 'struct application' has no member named 'key'

Tyczy się to linii:
Kod:
app.key=own_get_unify_keycode(UKM_NONE); // zapamietujemy kod klawisza

oraz:
Kod:
switch(app.key) // sprawdzamy jaki klawisz nacisnieto


Zdaje mi się, że robię wszystko jak podał Yak. Dodaje ten cały kod na nowym projekcie Game.
_________________
Tu był podpis, ale mi uciekł :/
Ostatnio zmieniony przez NoRiN 2007-02-05, 12:11, w całości zmieniany 1 raz  
^
 
 
     
seba123 
Expert
=)



Telefon: SE W810
Operator: Orange
Pomógł: 66 razy
Wiek: 25
Dołączył: 07 Kwi 2006
Posty: 1327
Skąd: Łódź
Wysłany: 2007-02-05, 12:11   

NoRiN, w menu.h w strukturze app dodaj zmienną key.
_________________
pobierz
^
 
  Skype
     
druidbartek 
Expert



Telefon: DCT-3
Operator: Era
Pomógł: 39 razy
Wiek: 31
Dołączył: 13 Wrz 2005
Posty: 1006
Skąd: Wrocław
Wysłany: 2007-02-05, 12:39   

seba123 napisał/a:
NoRiN, w menu.h w strukturze app dodaj zmienną key.

nie tak szybko ;)

zauważ że w /sdk/include/nokix/ również mamy biblioteke menu.h wiec dochodzimy do małego nieporozumienia :)


ja bym powiedział inaczej - dodaj do struktury która utworzyłeś, czyli application, zmienną key
unsigned char key;
^
 
     
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Nie możesz ściągać załączników na tym forum
Dodaj temat do Ulubionych
Wersja do druku

Skocz do: