CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Screenshot z okna
Strona 4 z 4

Re: Screenshot z okna

Nowy postNapisane: niedziela, 25 września 2016, 18:00
przez polymorphism
Heh, Baron, nie chodziło mi o sam fakt użycia pętli, tylko o wielokrotne wywołanie funkcji SendInput, co być może ma wpływ na kolejność docierania komunikatów.

Re: Screenshot z okna

Nowy postNapisane: niedziela, 25 września 2016, 18:10
przez Cyfrowy Baron
Na pewno ma wpływ, bo niektóre komunikaty mogą być blokowane.

Re: Screenshot z okna

Nowy postNapisane: wtorek, 27 września 2016, 22:30
przez Arnold_S
Panowie! Lepszej odpowiedzi nie mogłem się spodziewać. Bardzo dziękuje i zabieram się do pracy. Wrócę z kolejnym problemem lub prośbą o wiedzę.
8-)


/edit
Tak zastanawiałem się nad tą tablicą struktury INPUT i mam kilka pytań.

1. W moim kodzie, dla "podniesienia" klawisza użyłem następującej instrukcji:
KOD cpp:     UKRYJ  
aaa.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;    //podniesienie klawisza

Czy "flaga" KEYEVENTF_SCANCODE jest tutaj do czegoś potrzebna, czy wystarczy samo KEYEVENTF_KEYUP. W sumie program działa jednakowo i tak ...i tak. hmmm


2. Tablica "INPUT-ów" musiałaby zawierać 2x tyle pól ile jest liter w stringu przygotowywanym do wysłania. Każda literka zajmie 2 pola w tablicy (jedno dla wduszenia klawisza, a drugie dla zwolnienia klawisza). Przykładowy kod:
KOD cpp:     UKRYJ  
INPUT aaa[4] = {0};

// wduszenie klawisza 'A' - 0x1E
aaa[0].type = INPUT_KEYBOARD;
aaa[0].ki.dwFlags = 0;
aaa[0].ki.time = 0;
aaa[0].ki.dwExtraInfo = 0;
aaa[0].ki.wScan = 0x1E;
aaa[0].ki.dwFlags = KEYEVENTF_SCANCODE;

// zwolnienie klawisza 'A' - 0x1E
aaa[1] = aaa[0];
aaa[1].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;  //tutaj wstawiam te dwie flagi bo nie mam pewności jak to naprawdę powinno być.

// wduszenie klawisza 'B' - 0x30
aaa[2] = aaa[0];
aaa[2].ki.wScan = 0x30;
aaa[2].ki.dwFlags = KEYEVENTF_SCANCODE;

// zwolnienie klawisza 'B' - 0x30
aaa[3] = aaa[0];
aaa[3].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;

SendInput(4,in,sizeof(INPUT));
 

Tak myślę, że jeśli zdefiniowałbym tą tablicę struktur poza tą feralną funkcją, w feralnym timerze, to zyskałbym trochę czasu w [ms]. Ponieważ wewnątrz funkcji odwoływałbym się do tych pól wskaźnikiem. To byłoby chyba szybsze niż wypełnianie tego wszystkiego wewnątrz funkcji. Jest tylko jeden problem...
Gdy robię to na piechotę, bez tablicy INPUT-ów, to między wduszeniem a zwolnieniem kolejnych klawiszy mogę umieścić Sleep(); Tutaj nie widzę takiej możliwości. Jest aaa[?].ki.time. Na MSDN piszą, że to "time stamp" ale szukam informacji i nigdzie nie mogę znaleźć czy to faktycznie jest opóźnienie w [ms], czy po prostu czas pozostawiony do dyspozycji dla tego zdarzenia. Jak to rozumieć? Czy ktoś z Was testował jak to naprawdę jest?


3. Ostatnie pytanie: jak często używać funkcji Application->ProcessMessages(); ? Czy przed wywołaniem funkcji SendInput();? Czy pomiędzy wduszeniem a zwolnieniem przycisku? Czy po każdym wywołaniu funkcji SendInput(); nie zależnie czy chodzi o wduszenie, czy zwolnienie klawisza?
Jak odnieść się z Application->ProcessMessages(); do przykładu z tablicą INPUT-ów? gdzie to wcisnąć w kodzie?

Re: Screenshot z okna

Nowy postNapisane: środa, 28 września 2016, 11:33
przez polymorphism
1. Wydaje mi się, że jeśli wysłałeś key down z tą flagą, to i key up także powinien ją mieć.
2. W tym przypadku nie musisz walczyć o każdą milisekundę. Najpierw napisz kod tak, żeby działał, a później optymalizuj, o ile to konieczne. Co do pola time, możesz spróbować poustawiać tam jakieś odstępy czasowe (w ms), jeśli dla zera kolejność docierania komunikatów jest nieprawidłowa.
3. Nie używać.

Re: Screenshot z okna

Nowy postNapisane: środa, 28 września 2016, 22:51
przez Cyfrowy Baron
Co do KEYEVENTF_SCANCODE. Jest chyba tak, że jeżeli pomijasz argument wVk to musisz użyć tej flagi.



polymorphism napisał(a):3. Nie używać.


Tutaj się nie zgodzę. Jeżeli używasz funkcji Sleep() powinieneś zaraz po niej użyć funkcji ProcessMessages(). Poza tym w sytuacji gdy aplikacja wykonuje długi ciąg instrukcji i operacja zajmuje dużo czasu, a w tym czasie będziesz chciał np. przesunąć formularz, zmienić jego rozmiar, zakończyć pracę programu, to bez funkcji ProcessMessages() wywoływanej regularnie w trakcie wykonywania takich operacji, nie będzie możliwe zrobienie niczego innego, dopóki instrukcje nie dobiegną końca.

Re: Screenshot z okna

Nowy postNapisane: czwartek, 29 września 2016, 09:29
przez Mironas
Albo kiedy podczas jakiejś cyklicznej operacji chcesz wyświetlać okienko z paskiem postępu.

Re: Screenshot z okna

Nowy postNapisane: czwartek, 29 września 2016, 10:49
przez polymorphism
Panowie, pisałem o tym konkretnym przypadku. Jeśli w zdarzeniu timera wysyła serię komunikatów jednym wywołaniem SendInput, to nie ma sensu wywoływanie ProcessMessages. Nie wiem, jak działa funkcja SendInput, ale jeśli wysyła serie komunikatów dość długo (po to, żeby zasymulować pisanie na klawiaturze), wtedy trzeba by napisać jakąś klasę (wykorzystującą wątek) do asynchronicznego wysyłania komunikatów.

Re: Screenshot z okna

Nowy postNapisane: czwartek, 6 października 2016, 22:26
przez Arnold_S
Panowie bardzo Wam dziękuję!! Naprawdę wiele mi pomogliście. Sporo się nauczyłem i jestem wdzięczny.
Z tym SendInputem to jest ciekawostka: gdy stosowałem metodę wysyłania znak po znaku to moja funkcja wysyłająca te sygnały osiągała minimum 722 ms.
Gdy skorzystałem z Waszej porady i skonstruowałem tablicę inputów, to przy najdłuższym loginie i haśle, tj.: 16 znaków wychodzi mi max. 122 ms.
Muszę to jeszcze dopracować ponieważ na wolniejszym komputerze już nie bardzo chce to działać tak bezbłędnie. Niestety muszę zniknąć na miesiąc lub dwa i nie będę miał czasu na programowanie ale gdy wrócę mam nadzieję, że Was tu zastanę :D

Pozdrawiam!!