[c++] Symulacja wcisniecia klawiszy

0

Witam.
Mam dzisiaj dość nietypowy problem. Pisze pewien program, i w ramach testu pewnego modułu program miął wpisywać kombinacje liczb od 0 do 9999, symulując wciśniecie klawiszy na klawiaturze. Z kodem jako takim nie ma problemu, jednak przy tysięczno którymś powtórzeniu program się "krzyczy". Nie mam pojęcia czemu (sprawdzany na 3 komputerach z czego na jednym podobno działa dobrze O.o)

a oto kod źródłowy (przepraszam za jego długość ale nie miałem pomysłu jak go skrócić. Kod opisałem komentarzami) :

#include <iostream.h>
#include <windows.h>
#include <conio.h>

void wcisnij_zero(int x = 0)  //funkcja imitujaca wcisniecie klawisza
{                             //zera okreslona ilosc razy (aby zachowac zapis 0001 (...) )
        for(int k = 0; k<x;k++)
        {
                  keybd_event(VK_NUMPAD0, 0, 0, 0);
                  keybd_event(VK_NUMPAD0, 0, KEYEVENTF_KEYUP, 0);     
        }     
}

void wcisnij_enter(int x = 0) //analogicznie dla entera
{
        for(int k = 0;k<x;k++)
        {
                  keybd_event(VK_RETURN, 0, 0, 0);
                  keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);     
        }     
}

inline void wcisnij_cyfre(int cyfra) // a tutaj funkcja imitujaca wcisniecie okreslonych cyfr
{
     char tabl[5]; //tablica jako bufor dla itoa()
     
     for(int test = 0; test<5; test++) // dla pewnosci zerowanie elementow tablicy
     {
             tabl[test] = NULL;
     }
     
     char *wsk = itoa(cyfra, tabl, 10); // wywolanie funkcji i przypisanie zwroconej wartosci do wskaznika
     
     
     for(int w = 0; w<5; w++) // "rozklad" liczby na cyfry, i symulacja wcisniecia ich na klawiaturze
     {
          if(tabl[w] != NULL)
          {
                     switch(tabl[w]) // aby bylo prosciej gotowe makra dla odpowiednich wartosci
                     {
                                case '0':
                                  keybd_event(VK_NUMPAD0, 0, 0, 0);
                                  keybd_event(VK_NUMPAD0, 0, KEYEVENTF_KEYUP, 0);
                                break;
                                
                                case '1':
                                  keybd_event(VK_NUMPAD1, 0, 0, 0);
                                  keybd_event(VK_NUMPAD1, 0, KEYEVENTF_KEYUP, 0);
                                break;
                                
                                case '2':
                                  keybd_event(VK_NUMPAD2, 0, 0, 0);
                                  keybd_event(VK_NUMPAD2, 0, KEYEVENTF_KEYUP, 0);
                                break;
                                
                                case '3':
                                  keybd_event(VK_NUMPAD3, 0, 0, 0);
                                  keybd_event(VK_NUMPAD3, 0, KEYEVENTF_KEYUP, 0);
                                break;
                                
                                case '4':
                                  keybd_event(VK_NUMPAD4, 0, 0, 0);
                                  keybd_event(VK_NUMPAD4, 0, KEYEVENTF_KEYUP, 0);
                                break;
                                
                                case '5':
                                  keybd_event(VK_NUMPAD5, 0, 0, 0);
                                  keybd_event(VK_NUMPAD5, 0, KEYEVENTF_KEYUP, 0);
                                break;
                                
                                case '6':
                                  keybd_event(VK_NUMPAD6, 0, 0, 0);
                                  keybd_event(VK_NUMPAD6, 0, KEYEVENTF_KEYUP, 0);
                                break;
                                
                                case '7':
                                  keybd_event(VK_NUMPAD7, 0, 0, 0);
                                  keybd_event(VK_NUMPAD7, 0, KEYEVENTF_KEYUP, 0);
                                break;
                                
                                case '8':
                                  keybd_event(VK_NUMPAD8, 0, 0, 0);
                                  keybd_event(VK_NUMPAD8, 0, KEYEVENTF_KEYUP, 0);
                                break;
                                
                                case '9':
                                  keybd_event(VK_NUMPAD9, 0, 0, 0);
                                  keybd_event(VK_NUMPAD9, 0, KEYEVENTF_KEYUP, 0);
                                break;
                                }
                     }
     }     
}
main()
{
      int i = 0; // zmienna dla petli, i jako liczba wysylana do funkcji
        
        
        Sleep(10000); // zatrzymanie dzialania programu na 10sek, aby mozna bylo przygotowac dowolny edytor tekstu :)

        while(i<10000) 
        {
                  if(i<10) // jesli liczba jest mniejsza od 10 wywolanie odpowiednich funkcji
                  {        // majacych zachowac zapis 0001 itp
                   wcisnij_zero(3);
                   wcisnij_cyfre(i);
                   wcisnij_enter(1);

                  }
                  
                  else if(i<100) // analogicznie
                  {
                   wcisnij_zero(2);
                   wcisnij_cyfre(i);
                   wcisnij_enter(1);
                  }
                  
                  else if(i<1000) // analogicznie
                  {
                   wcisnij_zero(1);
                   wcisnij_cyfre(i);
                   wcisnij_enter(1);
                  }
                  
                  else if(i<10000) // analogicznie
                  {
                   wcisnij_cyfre(i);
                   wcisnij_enter(1);
                  }
                  i++;
        }
getch();
}

Prosze o jaką kolwiek wskazuówke co jest nie tak :) Z góry dziękuje i pozdrawiam.
Rezor.

0

Nie bardzo rozumiem co masz na myśli, że się krzaczy, trochę słabo to jest wyjaśnione. Ale robiłem kiedyś program, który korzystał z takiej metody jak symulacja klawiszy i rzeczywiście pojawiło się kilka nieoczekiwanych problemów. Zwróć uwagę, że uruchamiasz program, który generuje 40000 zdarzeń poprzez wywołanie funkcji. Program nie sprawdza co się dzieje dalej, a tym czasem inny program musi w odpowiedzi na zdarzenie wypisać literkę. Najprawdopodobniej nie zdąży tego zrobić przed wywołaniem następnej symulacji wciśnięcia i stąd może się pojawić problem po tym przekroczeniu tysiąca. Zwłaszcza, że nie jest to zawsze przy tej samej liczbie i na jednym kompie zadziałało (byc może był szybszy, wystarczająco szybki).
Ja swój problem rozwiązałem wprowadzając pauzy czasowe pomiędzy kolejnymi wywołaniami, ale miałem tych wywołań kilka, więc mogłem sobie pozwolić. Przy 40000 to bym się zastanowił. Jak pamiętam są metody, które wywołują funkcję callback po wykonaniu zadania takiego jak wypisanie czegoś w oknie edytora. Tylko to było dawno, ostatecznie takiego sposobu nie użyłem i teraz nie bardzo pamiętam jak by to miało wyglądać.
Może jest jakaś inna droga do tego, co chcesz zrobić? Z tego co piszesz to tylko program pomocniczy.

0

U mnie też zadziałało dobrze.
Pewnie rozwiązaniem będą pauzy o czym wspomniał mój poprzednik.

0

'switch(tabl[w]) ...' proponuje zamienić na:

int vk = VK_NUMPAD0 + tab[w] - '0';
keybd_event(vk, 0, 0, 0);
keybd_event(vk, 0, KEYEVENTF_KEYUP, 0);
0

Dziękuje za odpowiedzi :) Rzeczywiscie problem byl związany z prędkością wykonywania :)

A @adf88 dziekuje za ten kod ;) jest czytelniejszy i krotszy :)

Jeszcze raz dziękuje i pozdrawiam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1